Merge remote-tracking branch 'origin/master' into Menu
# Conflicts: # include/Engine/Rendering/RenderSystem.h # resources/Schema/Entities/RenderingWorld.xml # resources/Shaders/ForwardPlus.frag.glsl # src/Engine/Rendering/RenderSystem.cpp
This commit is contained in:
@@ -31,7 +31,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
}
|
||||
if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
|
||||
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
||||
cPhysics["Velocity"] = glm::vec3(0, 0, 0);
|
||||
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Inv
|
||||
|
||||
bool EntityWrapper::HasComponent(const std::string& componentName)
|
||||
{
|
||||
if (!Valid()) {
|
||||
return false;
|
||||
}
|
||||
return World->HasComponent(ID, componentName);
|
||||
}
|
||||
|
||||
@@ -17,6 +20,34 @@ EntityWrapper EntityWrapper::Parent()
|
||||
}
|
||||
}
|
||||
|
||||
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
|
||||
{
|
||||
auto itPair = this->World->GetChildren(this->ID);
|
||||
if (itPair.first == itPair.second) {
|
||||
return EntityWrapper::Invalid;
|
||||
}
|
||||
|
||||
for (auto it = itPair.first; it != itPair.second; ++it) {
|
||||
if (this->World->GetName(it->second) == name) {
|
||||
return EntityWrapper(this->World, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
return EntityWrapper::Invalid;
|
||||
}
|
||||
|
||||
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
|
||||
{
|
||||
EntityWrapper entity = *this;
|
||||
while (entity.Parent().Valid()) {
|
||||
entity = entity.Parent();
|
||||
if (entity == potentialParent) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EntityWrapper::Valid()
|
||||
{
|
||||
if (this->World == nullptr) {
|
||||
|
||||
@@ -276,7 +276,7 @@ std::vector<int> Child::childIndicesContainingBox(const AABB& box) const
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Child::hasChildren() const
|
||||
bool Child::hasChildren() const
|
||||
{
|
||||
return m_Children[0] != nullptr;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#include "Core/Transform.h"
|
||||
|
||||
glm::vec3 Transform::AbsolutePosition(EntityWrapper entity)
|
||||
{
|
||||
return AbsolutePosition(entity.World, entity.ID);
|
||||
}
|
||||
|
||||
glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
||||
{
|
||||
glm::vec3 position;
|
||||
@@ -14,6 +19,11 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
||||
return position;
|
||||
}
|
||||
|
||||
glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
|
||||
{
|
||||
return AbsoluteOrientation(entity.World, entity.ID);
|
||||
}
|
||||
|
||||
glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
|
||||
{
|
||||
glm::quat orientation;
|
||||
@@ -27,6 +37,11 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
|
||||
return orientation;
|
||||
}
|
||||
|
||||
glm::vec3 Transform::AbsoluteScale(EntityWrapper entity)
|
||||
{
|
||||
return AbsoluteScale(entity.World, entity.ID);
|
||||
}
|
||||
|
||||
glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
||||
{
|
||||
glm::vec3 scale(1.f);
|
||||
@@ -40,6 +55,11 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
||||
return scale;
|
||||
}
|
||||
|
||||
glm::mat4 Transform::ModelMatrix(EntityWrapper entity)
|
||||
{
|
||||
return ModelMatrix(entity.ID, entity.World);
|
||||
}
|
||||
|
||||
glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
|
||||
{
|
||||
glm::vec3 position = Transform::AbsolutePosition(world, entity);
|
||||
|
||||
@@ -39,7 +39,7 @@ void EditorRenderSystem::Update(double dt)
|
||||
continue;
|
||||
} catch (const std::exception&) {
|
||||
try {
|
||||
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
|
||||
model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
|
||||
} catch (const std::exception&) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,11 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
||||
m_EditorWorldSystemPipeline->AddSystem<EditorWidgetSystem>(0, m_Renderer);
|
||||
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
||||
|
||||
m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
|
||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
|
||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
|
||||
m_DebugCameraInputController = new DebugCameraInputController<EditorSystem>(m_EventBroker, -1);
|
||||
m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
|
||||
m_ActualCamera = m_EditorCamera;
|
||||
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform");
|
||||
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera");
|
||||
m_EditorCameraInputController = new EditorCameraInputController<EditorSystem>(m_EventBroker, -1);
|
||||
|
||||
m_EditorGUI = new EditorGUI(m_World, m_EventBroker);
|
||||
m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1));
|
||||
@@ -33,38 +34,70 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
||||
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorSystem::OnSetCamera);
|
||||
|
||||
m_EditorStats = new EditorStats();
|
||||
|
||||
Events::SetCamera e;
|
||||
e.CameraEntity = m_Camera;
|
||||
m_EventBroker->Publish(e);
|
||||
if (m_Enabled) {
|
||||
Enable();
|
||||
}
|
||||
}
|
||||
|
||||
EditorSystem::~EditorSystem()
|
||||
{
|
||||
delete m_EditorStats;
|
||||
delete m_EditorGUI;
|
||||
delete m_DebugCameraInputController;
|
||||
delete m_EditorCameraInputController;
|
||||
delete m_EditorWorldSystemPipeline;
|
||||
delete m_EditorWorld;
|
||||
}
|
||||
|
||||
void EditorSystem::Update(double dt)
|
||||
{
|
||||
m_EventBroker->Process<EditorGUI>();
|
||||
m_EditorGUI->Draw();
|
||||
m_EditorStats->Draw(dt);
|
||||
double now = glfwGetTime();
|
||||
double actualDelta = now - m_LastTime;
|
||||
m_LastTime = now;
|
||||
|
||||
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
|
||||
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
|
||||
if (m_Enabled) {
|
||||
m_EventBroker->Process<EditorGUI>();
|
||||
m_EditorGUI->Draw();
|
||||
m_EditorStats->Draw(actualDelta);
|
||||
|
||||
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
|
||||
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
|
||||
}
|
||||
|
||||
m_EditorWorldSystemPipeline->Update(actualDelta);
|
||||
|
||||
ComponentWrapper& cameraTransform = m_EditorCamera["Transform"];
|
||||
glm::vec3& ori = cameraTransform["Orientation"];
|
||||
ori.x = m_EditorCameraInputController->Rotation().x;
|
||||
ori.y = m_EditorCameraInputController->Rotation().y;
|
||||
glm::vec3& pos = cameraTransform["Position"];
|
||||
pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta;
|
||||
}
|
||||
}
|
||||
|
||||
m_EditorWorldSystemPipeline->Update(dt);
|
||||
void EditorSystem::Enable()
|
||||
{
|
||||
m_EditorCameraInputController->Enable();
|
||||
m_EventBroker->Publish(Events::UnlockMouse());
|
||||
Events::SetCamera e;
|
||||
e.CameraEntity = m_EditorCamera;
|
||||
m_EventBroker->Publish(e);
|
||||
(glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera);
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
m_DebugCameraInputController->Update(dt);
|
||||
m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position();
|
||||
m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation());
|
||||
void EditorSystem::Disable()
|
||||
{
|
||||
m_EditorCameraInputController->Disable();
|
||||
m_EventBroker->Publish(Events::LockMouse());
|
||||
Events::SetCamera e;
|
||||
e.CameraEntity = m_ActualCamera;
|
||||
m_EventBroker->Publish(e);
|
||||
m_Enabled = false;
|
||||
}
|
||||
|
||||
void EditorSystem::OnEntitySelected(EntityWrapper entity)
|
||||
@@ -148,6 +181,33 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
|
||||
{
|
||||
if (e.PlayerID != -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.Command == "ToggleEditor" && e.Value > 0) {
|
||||
if (m_Enabled) {
|
||||
Disable();
|
||||
} else {
|
||||
Enable();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditorSystem::OnSetCamera(const Events::SetCamera& e)
|
||||
{
|
||||
if (m_Enabled && e.CameraEntity != m_EditorCamera) {
|
||||
m_ActualCamera = e.CameraEntity;
|
||||
Events::SetCamera e2;
|
||||
e2.CameraEntity = m_EditorCamera;
|
||||
m_EventBroker->Publish(e2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath)
|
||||
{
|
||||
if (parent.World == nullptr) {
|
||||
|
||||
@@ -5,14 +5,20 @@ using namespace boost::asio::ip;
|
||||
|
||||
Client::Client(ConfigFile* config) : m_Socket(m_IOService)
|
||||
{
|
||||
Network::initialize();
|
||||
|
||||
// Asumes root node is EntityID 0
|
||||
insertIntoServerClientMaps(0, 0);
|
||||
// Init timer
|
||||
m_TimeSinceSentInputs = std::clock();
|
||||
// Default is local host
|
||||
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
||||
int port = config->Get<int>("Networking.Port", 13);
|
||||
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||
// Set up network stream
|
||||
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
||||
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
|
||||
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
@@ -37,19 +43,24 @@ void Client::Update()
|
||||
readFromServer();
|
||||
if (m_IsConnected) {
|
||||
hasServerTimedOut();
|
||||
// Don't sent 1 input in 1 packet, bunch em up.
|
||||
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
|
||||
sendInputCommands();
|
||||
m_TimeSinceSentInputs = std::clock();
|
||||
}
|
||||
}
|
||||
Network::Update();
|
||||
}
|
||||
|
||||
void Client::readFromServer()
|
||||
{
|
||||
while (m_Socket.available()) {
|
||||
bytesRead = receive(readBuf, INPUTSIZE);
|
||||
bytesRead = receive(readBuf);
|
||||
if (bytesRead > 0) {
|
||||
Packet packet(readBuf, bytesRead);
|
||||
parseMessageType(packet);
|
||||
}
|
||||
}
|
||||
sendInputCommands();
|
||||
}
|
||||
|
||||
void Client::parseMessageType(Packet& packet)
|
||||
@@ -66,12 +77,9 @@ void Client::parseMessageType(Packet& packet)
|
||||
case MessageType::Connect:
|
||||
parseConnect(packet);
|
||||
break;
|
||||
case MessageType::ClientPing:
|
||||
case MessageType::Ping:
|
||||
parsePing();
|
||||
break;
|
||||
case MessageType::ServerPing:
|
||||
parseServerPing();
|
||||
break;
|
||||
case MessageType::Message:
|
||||
break;
|
||||
case MessageType::Snapshot:
|
||||
@@ -81,6 +89,13 @@ void Client::parseMessageType(Packet& packet)
|
||||
break;
|
||||
case MessageType::PlayerConnected:
|
||||
parsePlayerConnected(packet);
|
||||
break;
|
||||
case MessageType::Kick:
|
||||
parseKick();
|
||||
break;
|
||||
case MessageType::OnPlayerSpawned:
|
||||
parsePlayersSpawned(packet);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -99,11 +114,6 @@ void Client::parsePlayerConnected(Packet & packet)
|
||||
}
|
||||
|
||||
void Client::parsePing()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Client::parseServerPing()
|
||||
{
|
||||
// Might miss connect message so set it here instead.
|
||||
m_IsConnected = true;
|
||||
@@ -112,11 +122,26 @@ void Client::parseServerPing()
|
||||
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
|
||||
m_StartPingTime = std::clock();
|
||||
|
||||
Packet packet(MessageType::ServerPing, m_SendPacketID);
|
||||
Packet packet(MessageType::Ping, m_SendPacketID);
|
||||
packet.WriteString("Ping recieved");
|
||||
send(packet);
|
||||
}
|
||||
|
||||
void Client::parseKick()
|
||||
{
|
||||
LOG_WARNING("You have been kicked from the server.");
|
||||
m_IsConnected = false;
|
||||
}
|
||||
|
||||
void Client::parsePlayersSpawned(Packet& packet)
|
||||
{
|
||||
Events::PlayerSpawned e;
|
||||
e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
||||
e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
||||
e.PlayerID = -1;
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
// Fields with strings will not work right now
|
||||
void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
|
||||
{
|
||||
@@ -153,8 +178,12 @@ void Client::parseSnapshot(Packet& packet)
|
||||
{
|
||||
std::string componentType = packet.ReadString();
|
||||
while (packet.DataReadSize() < packet.Size()) {
|
||||
// HACK
|
||||
std::string entityName = packet.ReadString();
|
||||
// Components EntityID
|
||||
EntityID receivedEntityID = packet.ReadPrimitive<EntityID>();
|
||||
// HACK
|
||||
m_World->SetName(receivedEntityID, entityName);
|
||||
// Parents EntityID
|
||||
EntityID receivedParentEntityID = packet.ReadPrimitive<EntityID>();
|
||||
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
|
||||
@@ -211,15 +240,20 @@ void Client::parseSnapshot(Packet& packet)
|
||||
}
|
||||
}
|
||||
|
||||
int Client::receive(char* data, size_t length)
|
||||
int Client::receive(char* data)
|
||||
{
|
||||
boost::system::error_code error;
|
||||
|
||||
int bytesReceived = m_Socket.receive_from(boost
|
||||
::asio::buffer((void*)data, length),
|
||||
::asio::buffer((void*)data, INPUTSIZE),
|
||||
m_ReceiverEndpoint,
|
||||
0, error);
|
||||
|
||||
// Network Debug data
|
||||
if (isReadingData) {
|
||||
m_NetworkData.TotalDataReceived += bytesReceived;
|
||||
m_NetworkData.DataReceivedThisInterval += bytesReceived;
|
||||
m_NetworkData.AmountOfMessagesReceived++;
|
||||
}
|
||||
if (error) {
|
||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||
}
|
||||
@@ -232,6 +266,12 @@ void Client::send(Packet& packet)
|
||||
packet.Data(),
|
||||
packet.Size()),
|
||||
m_ReceiverEndpoint, 0);
|
||||
// Network Debug data
|
||||
if (isReadingData) {
|
||||
m_NetworkData.TotalDataSent += packet.Size();
|
||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||
m_NetworkData.AmountOfMessagesSent++;
|
||||
}
|
||||
}
|
||||
|
||||
void Client::connect()
|
||||
@@ -250,14 +290,6 @@ void Client::disconnect()
|
||||
send(packet);
|
||||
}
|
||||
|
||||
void Client::ping()
|
||||
{
|
||||
//Packet packet(MessageType::Connect, m_SendPacketID);
|
||||
//packet.WriteString("Ping");
|
||||
//m_StartPingTime = std::clock();
|
||||
//send(packet);
|
||||
}
|
||||
|
||||
bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||
{
|
||||
if (e.Command == "ConnectToServer") { // Connect for now
|
||||
@@ -275,6 +307,15 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||
if (e.Value > 0) {
|
||||
becomePlayer();
|
||||
}
|
||||
} else if (e.Command == "LogNetworkBandwidth") {
|
||||
if (e.Value > 0) {
|
||||
// Save to file if we no longer want to read data.
|
||||
if (isReadingData) {
|
||||
saveToFile();
|
||||
}
|
||||
isReadingData = !isReadingData;
|
||||
m_SaveDataTimer = std::clock();
|
||||
}
|
||||
} else {
|
||||
m_InputCommandBuffer.push_back(e);
|
||||
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
@@ -305,7 +346,7 @@ bool Client::hasServerTimedOut()
|
||||
{
|
||||
// Time in ms
|
||||
float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||
if (timeSincePing > TIMEOUTMS) {
|
||||
if (timeSincePing > m_TimeoutMs) {
|
||||
// Clear everything and go to menu.
|
||||
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
|
||||
m_IsConnected = false;
|
||||
@@ -319,7 +360,7 @@ EntityID Client::createPlayer()
|
||||
EntityID entityID = m_World->CreateEntity();
|
||||
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
|
||||
ComponentWrapper model = m_World->AttachComponent(entityID, "Model");
|
||||
model["Resource"] = "Models/Core/UnitSphere.obj";
|
||||
model["Resource"] = "Models/Core/UnitSphere.mesh";
|
||||
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
|
||||
return entityID;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "Network/Network.h"
|
||||
|
||||
void Network::Update()
|
||||
{
|
||||
updateNetworkData();
|
||||
}
|
||||
|
||||
void Network::saveToFile()
|
||||
{
|
||||
std::ofstream outfile;
|
||||
time_t t = time(0);
|
||||
// get time now
|
||||
struct tm * now = localtime(&t);
|
||||
// Get current time and date
|
||||
std::string dateAndTime = "BandwidthData - " + std::to_string(now->tm_year + 1900) + '-'
|
||||
+ std::to_string(now->tm_mon + 1) + '-'
|
||||
+ std::to_string(now->tm_mday) + '_'
|
||||
+ std::to_string(now->tm_hour) + "h."
|
||||
+ std::to_string(now->tm_min) + "m."
|
||||
+ std::to_string(now->tm_sec) + 's';
|
||||
|
||||
outfile.open(dateAndTime + ".csv");
|
||||
outfile << "Total time," + std::to_string(m_NetworkData.TotalTime) + "\n";
|
||||
outfile << "Total data received," + std::to_string(m_NetworkData.TotalDataReceived) + "\n";
|
||||
outfile << "Total data sent," + std::to_string(m_NetworkData.TotalDataSent) + "\n";
|
||||
outfile << "Total messages received," + std::to_string(m_NetworkData.AmountOfMessagesReceived) + "\n";
|
||||
outfile << "Total messages sent," + std::to_string(m_NetworkData.AmountOfMessagesSent) + "\n";
|
||||
|
||||
float messagesReceivedPerSec = (float)m_NetworkData.AmountOfMessagesReceived / (m_NetworkData.TotalTime / 1000);
|
||||
float messagesSentPerSec = (float)m_NetworkData.AmountOfMessagesSent / (m_NetworkData.TotalTime / 1000);
|
||||
float dataReceivedPerSec = (float)m_NetworkData.TotalDataReceived / (m_NetworkData.TotalTime / 1000);
|
||||
float dataSentPerSec = (float)m_NetworkData.TotalDataSent / (m_NetworkData.TotalTime / 1000);
|
||||
outfile << "Avarage messages received / s: " + std::to_string(messagesReceivedPerSec) + "\n";
|
||||
outfile << "Avarage messages sents / s: " + std::to_string(messagesSentPerSec) + "\n";
|
||||
outfile << "Avarage data received B/s: " + std::to_string(dataReceivedPerSec) + "\n";
|
||||
outfile << "Avarage data sents B/s: " + std::to_string(dataSentPerSec) + "\n";
|
||||
|
||||
outfile << "time, avg receive B, avg send B\n";
|
||||
for (int i = 0; i < m_NetworkData.BandwidthBytes.size(); i++) {
|
||||
outfile << std::to_string(i) + ",";
|
||||
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].first) + ",";
|
||||
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].second) + "\n";
|
||||
}
|
||||
outfile.close();
|
||||
|
||||
}
|
||||
|
||||
void Network::updateNetworkData()
|
||||
{
|
||||
std::clock_t currentTime = std::clock();
|
||||
// Send snapshot
|
||||
if (m_SaveDataIntervalMs < (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC)) {
|
||||
// Set values
|
||||
m_NetworkData.TotalTime += (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC);
|
||||
m_NetworkData.BandwidthBytes.push_back(std::pair<unsigned int, unsigned int>(m_NetworkData.DataReceivedThisInterval, m_NetworkData.DataSentThisInterval));
|
||||
// Reset interval stuff
|
||||
m_SaveDataTimer = std::clock();
|
||||
m_NetworkData.DataSentThisInterval = 0;
|
||||
m_NetworkData.DataReceivedThisInterval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Network::initialize()
|
||||
{
|
||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
m_MaxConnections = config->Get<int>("Networking.MaxConnections", 8);
|
||||
m_TimeoutMs = config->Get<int>("Networking.TimeoutMs", 20000);
|
||||
}
|
||||
@@ -39,6 +39,7 @@ void Packet::Init(MessageType type, unsigned int & packetID)
|
||||
Packet::WritePrimitive<int>(messageType);
|
||||
Packet::WritePrimitive<int>(packetID);
|
||||
packetID++;
|
||||
m_HeaderSize = m_Offset;
|
||||
}
|
||||
|
||||
void Packet::WriteString(const std::string& str)
|
||||
|
||||
+116
-41
@@ -1,7 +1,13 @@
|
||||
#include "Network/Server.h"
|
||||
|
||||
Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13))
|
||||
{ }
|
||||
Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))
|
||||
{
|
||||
Network::initialize();
|
||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05);
|
||||
pingIntervalMs = config->Get<float>("Networking.PingIntervalMs", 1000);
|
||||
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
{
|
||||
@@ -14,7 +20,8 @@ void Server::Start(World* world, EventBroker* eventBroker)
|
||||
m_EventBroker = eventBroker;
|
||||
// Subscribe to events
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
||||
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
|
||||
for (size_t i = 0; i < m_MaxConnections; i++) {
|
||||
m_PlayerDefinitions[i].StopTime = std::clock();
|
||||
}
|
||||
LOG_INFO("I am Server. BIP BOP\n");
|
||||
@@ -24,14 +31,17 @@ void Server::Update()
|
||||
{
|
||||
readFromClients();
|
||||
m_EventBroker->Process<Server>();
|
||||
}
|
||||
if (isReadingData) {
|
||||
Network::Update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Server::readFromClients()
|
||||
{
|
||||
while (m_Socket.available()) {
|
||||
try {
|
||||
bytesRead = receive(readBuffer, INPUTSIZE);
|
||||
bytesRead = receive(readBuffer);
|
||||
Packet packet(readBuffer, bytesRead);
|
||||
parseMessageType(packet);
|
||||
} catch (const std::exception& err) {
|
||||
@@ -46,7 +56,7 @@ void Server::readFromClients()
|
||||
}
|
||||
|
||||
// Send pings each
|
||||
if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
|
||||
if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
|
||||
sendPing();
|
||||
previousePingMessage = currentTime;
|
||||
}
|
||||
@@ -70,11 +80,8 @@ void Server::parseMessageType(Packet& packet)
|
||||
case MessageType::Connect:
|
||||
parseConnect(packet);
|
||||
break;
|
||||
case MessageType::ClientPing:
|
||||
//parseClientPing();
|
||||
break;
|
||||
case MessageType::ServerPing:
|
||||
parseServerPing();
|
||||
case MessageType::Ping:
|
||||
parsePing();
|
||||
break;
|
||||
case MessageType::Message:
|
||||
break;
|
||||
@@ -97,21 +104,47 @@ void Server::parseMessageType(Packet& packet)
|
||||
}
|
||||
}
|
||||
|
||||
int Server::receive(char * data, size_t length)
|
||||
int Server::receive(char * data)
|
||||
{
|
||||
length = m_Socket.receive_from(
|
||||
unsigned int length = m_Socket.receive_from(
|
||||
boost::asio::buffer((void*)data
|
||||
, length)
|
||||
, INPUTSIZE)
|
||||
, m_ReceiverEndpoint, 0);
|
||||
// Network Debug data
|
||||
if (isReadingData) {
|
||||
m_NetworkData.TotalDataReceived += length;
|
||||
m_NetworkData.DataReceivedThisInterval += length;
|
||||
m_NetworkData.AmountOfMessagesReceived++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
void Server::send(Packet& packet, int userID)
|
||||
void Server::send(Packet& packet, UserID user)
|
||||
{
|
||||
int bytesSent = m_Socket.send_to(
|
||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||
m_ConnectedUsers[userID].Endpoint,
|
||||
m_ConnectedUsers[user].Endpoint,
|
||||
0);
|
||||
// Network Debug data
|
||||
if (isReadingData) {
|
||||
m_NetworkData.TotalDataSent += packet.Size();
|
||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||
m_NetworkData.AmountOfMessagesSent++;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::send(PlayerID player, Packet& packet)
|
||||
{
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
void Server::send(Packet & packet)
|
||||
@@ -122,6 +155,11 @@ void Server::send(Packet & packet)
|
||||
packet.Size()),
|
||||
m_ReceiverEndpoint,
|
||||
0);
|
||||
if (isReadingData) {
|
||||
// Network Debug data
|
||||
m_NetworkData.TotalDataSent += packet.Size();
|
||||
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||
}
|
||||
}
|
||||
|
||||
void Server::broadcast(Packet& packet)
|
||||
@@ -143,9 +181,12 @@ void Server::sendSnapshot()
|
||||
Packet packet(MessageType::Snapshot);
|
||||
ComponentPool* componentPool = it.second;
|
||||
ComponentInfo componentInfo = componentPool->ComponentInfo();
|
||||
|
||||
// Component Type
|
||||
packet.WriteString(componentInfo.Name);
|
||||
for (auto& componentWrapper : *componentPool) {
|
||||
// HACK: Send entity name
|
||||
packet.WriteString(m_World->GetName(componentWrapper.EntityID));
|
||||
// Components EntityID
|
||||
packet.WritePrimitive(componentWrapper.EntityID);
|
||||
// Parents EntityID
|
||||
@@ -160,7 +201,9 @@ void Server::sendSnapshot()
|
||||
}
|
||||
}
|
||||
}
|
||||
broadcast(packet);
|
||||
if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) {
|
||||
broadcast(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +217,7 @@ void Server::sendPing()
|
||||
}
|
||||
}
|
||||
// Create ping message
|
||||
Packet packet(MessageType::ServerPing);
|
||||
Packet packet(MessageType::Ping);
|
||||
packet.WriteString("Ping from server");
|
||||
// Time message
|
||||
m_StartPingTime = std::clock();
|
||||
@@ -191,7 +234,7 @@ void Server::checkForTimeOuts()
|
||||
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
int stopPing = 1000 * m_ConnectedUsers[i].StopTime /
|
||||
static_cast<double>(CLOCKS_PER_SEC);
|
||||
if (startPing > stopPing + TIMEOUTMS) {
|
||||
if (startPing > stopPing + m_TimeoutMs) {
|
||||
LOG_INFO("User %i timed out!", i);
|
||||
disconnect(i);
|
||||
}
|
||||
@@ -199,35 +242,40 @@ void Server::checkForTimeOuts()
|
||||
}
|
||||
}
|
||||
|
||||
void Server::disconnect(int i)
|
||||
void Server::disconnect(UserID user)
|
||||
{
|
||||
//broadcast("A player disconnected");
|
||||
LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str());
|
||||
LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[user].Name.c_str());
|
||||
// Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have)
|
||||
m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint();
|
||||
m_PlayerDefinitions[i].EntityID = -1;
|
||||
m_PlayerDefinitions[i].Name = "";
|
||||
m_PlayerDefinitions[i].PacketID = 0;
|
||||
m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i);
|
||||
Events::PlayerDisconnected e;
|
||||
e.Entity = m_PlayerDefinitions[user].EntityID;
|
||||
e.PlayerID = user;
|
||||
m_EventBroker->Publish(e);
|
||||
|
||||
m_PlayerDefinitions[user].Endpoint = boost::asio::ip::udp::endpoint();
|
||||
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)
|
||||
{
|
||||
int playerID = -1;
|
||||
PlayerID player = -1;
|
||||
// Check which player it was who sent the message
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
for (int i = 0; i < m_MaxConnections; i++) {
|
||||
// if the player is connected set playerID to the correct PlayerID
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()
|
||||
&& m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
|
||||
playerID = i;
|
||||
player = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (playerID != -1) {
|
||||
if (player != -1) {
|
||||
while (packet.DataReadSize() < packet.Size()) {
|
||||
Events::InputCommand e;
|
||||
e.Command = packet.ReadString();
|
||||
e.PlayerID = playerID; // Set correct player id
|
||||
e.PlayerID = player; // Set correct player id
|
||||
e.Value = packet.ReadPrimitive<float>();
|
||||
m_EventBroker->Publish(e);
|
||||
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
@@ -292,17 +340,17 @@ void Server::parseDisconnect()
|
||||
void Server::parseClientPing()
|
||||
{
|
||||
LOG_INFO("%i: Parsing ping", m_PacketID);
|
||||
int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
||||
if (playerID == -1) {
|
||||
PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
||||
if (player == -1) {
|
||||
return;
|
||||
}
|
||||
// Return ping
|
||||
Packet packet(MessageType::ClientPing, m_PlayerDefinitions[playerID].PacketID);
|
||||
Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID);
|
||||
packet.WriteString("Ping received");
|
||||
send(packet);
|
||||
}
|
||||
|
||||
void Server::parseServerPing()
|
||||
void Server::parsePing()
|
||||
{
|
||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
||||
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||
@@ -328,7 +376,7 @@ void Server::createPlayer()
|
||||
LOG_WARNING("Already connected!");
|
||||
return;
|
||||
}
|
||||
int userIndex;
|
||||
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()) {
|
||||
@@ -340,14 +388,14 @@ void Server::createPlayer()
|
||||
LOG_WARNING("Not a recognized user!");
|
||||
return;
|
||||
}
|
||||
for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) {
|
||||
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["Resource"] = "Models/Core/UnitSphere.mesh";
|
||||
model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f);
|
||||
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
|
||||
m_PlayerDefinitions[playerIndex].EntityID = entityID;
|
||||
@@ -355,12 +403,19 @@ void Server::createPlayer()
|
||||
}
|
||||
}
|
||||
LOG_WARNING("Server is full!");
|
||||
|
||||
|
||||
}
|
||||
|
||||
int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
|
||||
void Server::kick(PlayerID player)
|
||||
{
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
disconnect(player);
|
||||
Packet packet = Packet(MessageType::Kick);
|
||||
send(packet);
|
||||
}
|
||||
|
||||
PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
|
||||
{
|
||||
for (int i = 0; i < m_MaxConnections; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() &&
|
||||
m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) {
|
||||
return i;
|
||||
@@ -372,5 +427,25 @@ int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
|
||||
bool Server::OnInputCommand(const Events::InputCommand & e)
|
||||
{
|
||||
//LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
if (e.Command == "LogNetworkBandwidth" && e.Value > 0) {
|
||||
if (isReadingData) {
|
||||
saveToFile();
|
||||
}
|
||||
isReadingData = !isReadingData;
|
||||
m_SaveDataTimer = std::clock();
|
||||
}
|
||||
if (e.Command == "KickPlayer" && e.Value > 0) {
|
||||
kick(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e)
|
||||
{
|
||||
Packet packet = Packet(MessageType::OnPlayerSpawned);
|
||||
packet.WritePrimitive<EntityID>(e.Player.ID);
|
||||
packet.WritePrimitive<EntityID>(e.Spawner.ID);
|
||||
send(e.PlayerID, packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer)
|
||||
{
|
||||
m_Renderer = renderer;
|
||||
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||
|
||||
InitializeTextures();
|
||||
InitializeBuffers();
|
||||
|
||||
@@ -4,8 +4,8 @@ DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer)
|
||||
{
|
||||
m_Renderer = renderer;
|
||||
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||
m_Exposure = 1; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||
m_Exposure = 0.4; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
|
||||
|
||||
InitializeShaderPrograms();
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
||||
|
||||
|
||||
//TODO: Render: Add code for more jobs than modeljobs.
|
||||
for (auto &job : scene.ForwardJobs) {
|
||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||
@@ -72,6 +73,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
||||
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
|
||||
glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor));
|
||||
|
||||
glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(modelJob->FillColor));
|
||||
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), modelJob->FillPercentage);
|
||||
@@ -84,22 +86,35 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
||||
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
||||
|
||||
/*if(modelJob->GlowMap != nullptr) {
|
||||
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
|
||||
if (modelJob->IncandescenceTexture != nullptr) {
|
||||
glBindTexture(GL_TEXTURE_2D, modelJob->IncandescenceTexture->m_Texture);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
||||
}
|
||||
|
||||
/*if(modelJob->GlowMap != nullptr) {
|
||||
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
||||
}*/
|
||||
|
||||
//TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running");
|
||||
if (animation != nullptr) {
|
||||
std::vector<glm::mat4> frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones(
|
||||
*animation,
|
||||
0.0f
|
||||
);
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(modelJob->Model->VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
|
||||
|
||||
continue;
|
||||
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
||||
}
|
||||
}
|
||||
m_FinalPassFrameBuffer.Unbind();
|
||||
GLERROR("DrawFinalPass::Draw: END");
|
||||
delete state;
|
||||
}
|
||||
@@ -137,4 +152,4 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
GLERROR("MipMap Texture initialization failed");
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ DrawScreenQuadPass::DrawScreenQuadPass(IRenderer* renderer)
|
||||
{
|
||||
m_Renderer = renderer;
|
||||
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||
|
||||
InitializeShaderPrograms();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ Model::Model(std::string fileName)
|
||||
if (!group.SpecularMapPath.empty()) {
|
||||
group.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.SpecularMapPath));
|
||||
}
|
||||
if (!group.IncandescenceMapPath.empty()) {
|
||||
group.IncandescenceMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.IncandescenceMapPath));
|
||||
}
|
||||
}
|
||||
|
||||
// Generate GL buffers
|
||||
@@ -32,7 +35,7 @@ Model::Model(std::string fileName)
|
||||
GLERROR("GLEW: BufferFail4");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4, 4, 4, 4, 4 };
|
||||
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4 };
|
||||
int stride = 0;
|
||||
for (int size : structSizes) {
|
||||
stride += size;
|
||||
@@ -48,10 +51,6 @@ Model::Model(std::string fileName)
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||
}
|
||||
GLERROR("GLEW: BufferFail5");
|
||||
|
||||
@@ -62,10 +61,6 @@ Model::Model(std::string fileName)
|
||||
glEnableVertexAttribArray(4);
|
||||
glEnableVertexAttribArray(5);
|
||||
glEnableVertexAttribArray(6);
|
||||
glEnableVertexAttribArray(7);
|
||||
glEnableVertexAttribArray(8);
|
||||
glEnableVertexAttribArray(9);
|
||||
glEnableVertexAttribArray(10);
|
||||
GLERROR("GLEW: BufferFail5");
|
||||
|
||||
//CreateBuffers();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "Rendering/RawModel.h"
|
||||
#include "Rendering/RawModelAssimp.h"
|
||||
|
||||
RawModel::RawModel(std::string fileName)
|
||||
#ifdef USING_ASSIMP_AS_IMPORTER
|
||||
|
||||
RawModelAssimp::RawModelAssimp(std::string fileName)
|
||||
{
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate);
|
||||
@@ -38,7 +40,7 @@ RawModel::RawModel(std::string fileName)
|
||||
//LOG_DEBUG("Index count %i", numIndices);
|
||||
|
||||
//LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
|
||||
|
||||
|
||||
std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
|
||||
std::map<std::string, int> boneNameMapping;
|
||||
|
||||
@@ -74,21 +76,7 @@ RawModel::RawModel(std::string fileName)
|
||||
auto uv = mesh->mTextureCoords[0][vertexIndex];
|
||||
desc.TextureCoords = glm::vec2(uv.x, uv.y);
|
||||
}
|
||||
|
||||
// Material diffuse color
|
||||
aiColor3D diffuse;
|
||||
material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
|
||||
float opacity;
|
||||
material->Get(AI_MATKEY_OPACITY, opacity);
|
||||
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
|
||||
|
||||
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
|
||||
|
||||
// Material specular color
|
||||
aiColor3D specular;
|
||||
material->Get(AI_MATKEY_COLOR_SPECULAR, specular);
|
||||
desc.SpecularVertexColor = glm::vec4(specular.r, specular.g, specular.b, 1.f);
|
||||
|
||||
m_Vertices.push_back(desc);
|
||||
}
|
||||
|
||||
@@ -128,7 +116,7 @@ RawModel::RawModel(std::string fileName)
|
||||
}
|
||||
for (auto& vertex : m_Vertices) {
|
||||
vertex.Tangent = glm::normalize(vertex.Tangent);
|
||||
vertex.BiTangent = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal)));
|
||||
vertex.BiNormal = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal)));
|
||||
}
|
||||
|
||||
// Material info
|
||||
@@ -201,10 +189,7 @@ RawModel::RawModel(std::string fileName)
|
||||
LOG_WARNING("Vertex weights (%i) greater than max weights per vertex (%i)", weights.size(), maxWeights);
|
||||
}
|
||||
for (int weightIndex = 0; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 4; ++weightIndex) {
|
||||
std::tie(desc.BoneIndices1[weightIndex], desc.BoneWeights1[weightIndex]) = weights[weightIndex];
|
||||
}
|
||||
for (int weightIndex = 4; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 8; ++weightIndex) {
|
||||
std::tie(desc.BoneIndices2[weightIndex - 4], desc.BoneWeights2[weightIndex - 4]) = weights[weightIndex];
|
||||
std::tie(desc.BoneIndices[weightIndex], desc.BoneWeights[weightIndex]) = weights[weightIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,14 +275,14 @@ RawModel::RawModel(std::string fileName)
|
||||
}
|
||||
}
|
||||
|
||||
RawModel::~RawModel()
|
||||
RawModelAssimp::~RawModelAssimp()
|
||||
{
|
||||
if (m_Skeleton) {
|
||||
delete m_Skeleton;
|
||||
}
|
||||
}
|
||||
|
||||
void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID)
|
||||
void RawModelAssimp::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID)
|
||||
{
|
||||
std::string nodeName = node->mName.C_Str();
|
||||
|
||||
@@ -317,3 +302,5 @@ void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &b
|
||||
CreateSkeleton(boneInfo, boneNameMapping, child, parentID);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -8,6 +8,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned);
|
||||
|
||||
m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);
|
||||
}
|
||||
@@ -47,15 +48,22 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityWrapper entity(m_World, modelComponent.EntityID);
|
||||
|
||||
// Don't render the local player
|
||||
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Model* model;
|
||||
try {
|
||||
model = ResourceManager::Load<::Model, true>(resource);
|
||||
} catch (const Resource::StillLoadingException&) {
|
||||
//continue;
|
||||
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.obj");
|
||||
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.mesh");
|
||||
} catch (const std::exception&) {
|
||||
try {
|
||||
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
|
||||
model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
|
||||
} catch (const std::exception&) {
|
||||
continue;
|
||||
}
|
||||
@@ -81,6 +89,14 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||
{
|
||||
if (e.PlayerID == -1) {
|
||||
m_LocalPlayer = e.Player;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderSystem::fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
|
||||
{
|
||||
auto pointLights = m_World->GetComponents("PointLight");
|
||||
@@ -168,12 +184,13 @@ void RenderSystem::Update(double dt)
|
||||
{
|
||||
m_EventBroker->Process<RenderSystem>();
|
||||
|
||||
if (m_CurrentCamera) {
|
||||
ComponentWrapper cameraTransform = m_CurrentCamera["Transform"];
|
||||
m_Camera->SetPosition(cameraTransform["Position"]);
|
||||
m_Camera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"]));
|
||||
// Update the current camera used for rendering
|
||||
if (m_CurrentCamera.Valid()) {
|
||||
m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera));
|
||||
m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera));
|
||||
}
|
||||
|
||||
|
||||
RenderScene scene;
|
||||
scene.Camera = m_Camera;
|
||||
scene.Viewport = Rectangle(1280, 720);
|
||||
|
||||
@@ -13,9 +13,9 @@ void Renderer::Initialize()
|
||||
m_TextPass->Initialize();
|
||||
|
||||
|
||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||
/* m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
||||
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
|
||||
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");*/
|
||||
|
||||
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation& animation, doubl
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) {
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID);
|
||||
@@ -84,10 +84,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
|
||||
positionInterp.z = 0;
|
||||
}
|
||||
|
||||
|
||||
boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = parentMatrix * bone->Parent->OffsetMatrix; // * glm::inverse(bone->OffsetMatrix);
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix; // * glm::inverse(bone->OffsetMatrix);
|
||||
}
|
||||
boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix;
|
||||
}
|
||||
|
||||
@@ -95,6 +98,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
|
||||
std::string name = child->Name;
|
||||
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int Skeleton::GetBoneID(std::string name)
|
||||
|
||||
@@ -198,7 +198,7 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e)
|
||||
(float&)(double)emitter["RollOffFactor"] = e.RollOffFactor;
|
||||
(float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance;
|
||||
auto model = m_World->AttachComponent(emitterID, "Model");
|
||||
(std::string&)model["Resource"] = "Models/Core/UnitCube.obj";
|
||||
(std::string&)model["Resource"] = "Models/Core/UnitCube.mesh"; // 360NoScope UnitCube
|
||||
source->Type = SoundType::SFX;
|
||||
m_Sources[emitterID] = source;
|
||||
playSound(source);
|
||||
|
||||
Reference in New Issue
Block a user