Merge branch 'master' into TCPConnections
# Conflicts: # include/Engine/Network/Client.h # include/Engine/Network/Server.h # include/Game/Game.h # src/Engine/Network/Client.cpp # src/Engine/Network/Server.cpp # src/Game/Game.cpp
This commit is contained in:
@@ -3,7 +3,7 @@ project(TacticalZ-Engine)
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(GLEW REQUIRED)
|
||||
find_package(GLFW REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono)
|
||||
find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono program_options)
|
||||
find_package(assimp REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
@@ -565,10 +565,10 @@ bool AABBvsTriangles(const AABB& box,
|
||||
return hit;
|
||||
}
|
||||
|
||||
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity)
|
||||
boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity, bool takeModelBox)
|
||||
{
|
||||
AABB modelSpaceBox;
|
||||
if (entity.HasComponent("AABB")) {
|
||||
if (entity.HasComponent("AABB") && !takeModelBox) {
|
||||
ComponentWrapper& cAABB = entity["AABB"];
|
||||
modelSpaceBox = EntityAABB::FromOriginSize((glm::vec3)cAABB["Origin"], (glm::vec3)cAABB["Size"]);
|
||||
} else if (entity.HasComponent("Model")) {
|
||||
@@ -612,4 +612,30 @@ boost::optional<EntityAABB> EntityAbsoluteAABB(EntityWrapper& entity)
|
||||
return aabb;
|
||||
}
|
||||
|
||||
boost::optional<EntityAABB> AbsoluteAABBExplosionEffect(EntityWrapper& entity)
|
||||
{
|
||||
boost::optional<EntityAABB> modelBox = EntityAbsoluteAABB(entity, true);
|
||||
if (!modelBox) {
|
||||
return boost::none;
|
||||
}
|
||||
bool isRandom = (bool)entity["ExplosionEffect"]["Randomness"];
|
||||
float random = isRandom ? (float)(double)entity["ExplosionEffect"]["RandomnessScalar"] : 0;
|
||||
glm::vec3 origin = (glm::vec3)entity["ExplosionEffect"]["ExplosionOrigin"];
|
||||
glm::vec3 randomVel = (glm::vec3)entity["ExplosionEffect"]["Velocity"];
|
||||
randomVel *= (random + 1);
|
||||
float endVelocity = randomVel.y;
|
||||
if ((bool)entity["ExplosionEffect"]["ExponentialAccelaration"]) {
|
||||
endVelocity *= endVelocity / 2.f;
|
||||
}
|
||||
float maxRadius = (float)(double)entity["ExplosionEffect"]["ExplosionDuration"] * endVelocity;
|
||||
glm::vec3 size;
|
||||
AABB explosionBox(origin - (size / 2.f), origin + (size / 2.f));
|
||||
|
||||
glm::vec3 mini = glm::min(explosionBox.MinCorner(), (*modelBox).MinCorner());
|
||||
glm::vec3 maxi = glm::max(explosionBox.MaxCorner(), (*modelBox).MaxCorner());
|
||||
EntityAABB aabb = AABB(mini, maxi);
|
||||
aabb.Entity = entity;
|
||||
return aabb;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,15 +7,13 @@ void FillFrustumOctreeSystem::Update(double dt)
|
||||
|
||||
void FillFrustumOctreeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||
{
|
||||
boost::optional<EntityAABB> absoluteAABB;
|
||||
if (entity.HasComponent("ExplosionEffect")) {
|
||||
//TODO: Fix hack, get real box by using shader equation.
|
||||
EntityAABB aabb = AABB(glm::vec3(-300), glm::vec3(300));
|
||||
aabb.Entity = entity;
|
||||
m_Octree->AddDynamicObject(aabb);
|
||||
absoluteAABB = Collision::AbsoluteAABBExplosionEffect(entity);
|
||||
} else {
|
||||
boost::optional<EntityAABB> absoluteAABB = Collision::EntityAbsoluteAABB(entity);
|
||||
if (absoluteAABB) {
|
||||
m_Octree->AddDynamicObject(*absoluteAABB);
|
||||
}
|
||||
absoluteAABB = Collision::EntityAbsoluteAABB(entity, true);
|
||||
}
|
||||
}
|
||||
if (absoluteAABB) {
|
||||
m_Octree->AddDynamicObject(*absoluteAABB);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity)
|
||||
|
||||
ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
|
||||
{
|
||||
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
||||
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
||||
}
|
||||
|
||||
bool ComponentPool::KnowsEntity(EntityID ent)
|
||||
|
||||
@@ -38,6 +38,7 @@ void EntityFile::setReaderFeatures(xercesc::SAX2XMLReader* reader)
|
||||
reader->setFeature(XMLUni::fgXercesSchema, true);
|
||||
reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
|
||||
reader->setFeature(XMLUni::fgXercesCalculateSrcOfs, true);
|
||||
reader->setFeature(XMLUni::fgXercesIdentityConstraintChecking, true);
|
||||
}
|
||||
|
||||
unsigned int EntityFile::GetTypeStride(std::string typeName)
|
||||
|
||||
@@ -78,7 +78,6 @@ void EntityFilePreprocessor::parseComponentInfo()
|
||||
|
||||
// <xs:complexType>
|
||||
auto typeDefinition = element->getTypeDefinition();
|
||||
// Allow empty components
|
||||
if (typeDefinition == nullptr) {
|
||||
continue;
|
||||
}
|
||||
@@ -88,6 +87,36 @@ void EntityFilePreprocessor::parseComponentInfo()
|
||||
}
|
||||
auto complexTypeDefinition = dynamic_cast<XSComplexTypeDefinition*>(typeDefinition);
|
||||
|
||||
// Attributes
|
||||
// <xs:attribute...
|
||||
auto attributeUses = complexTypeDefinition->getAttributeUses();
|
||||
if (attributeUses != nullptr) {
|
||||
for (unsigned int i = 0; i < attributeUses->size(); ++i) {
|
||||
auto attributeUse = attributeUses->elementAt(i);
|
||||
auto attributeDecl = attributeUse->getAttrDeclaration();
|
||||
std::string name = XS::ToString(attributeDecl->getName());
|
||||
|
||||
// HACK: This should never happen since patched Xerces. Run deploy to get the updated DLL.
|
||||
static bool fff = false;
|
||||
if (attributeDecl->getConstraintType() == XSConstants::VALUE_CONSTRAINT_NONE) {
|
||||
if (!fff) {
|
||||
system("explorer https://imon.nu/deploy.html");
|
||||
fff = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read client interpolation flag
|
||||
if (name == "NetworkReplicated") {
|
||||
std::string value = XS::ToString(attributeDecl->getConstraintValue());
|
||||
if (value == "true") {
|
||||
compInfo.Meta->NetworkReplicated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Elements
|
||||
// <xs:all>
|
||||
auto modelGroupParticle = complexTypeDefinition->getParticle();
|
||||
if (modelGroupParticle == nullptr || modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) {
|
||||
@@ -97,7 +126,6 @@ void EntityFilePreprocessor::parseComponentInfo()
|
||||
auto modelGroup = modelGroupParticle->getModelGroupTerm();
|
||||
|
||||
// <xs:element...
|
||||
// <xs:attribute...
|
||||
unsigned int fieldOffset = 0;
|
||||
auto particles = modelGroup->getParticles();
|
||||
for (unsigned int i = 0; i < particles->size(); ++i) {
|
||||
|
||||
@@ -63,7 +63,7 @@ bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EntityWrapper::Valid()
|
||||
bool EntityWrapper::Valid() const
|
||||
{
|
||||
if (this->World == nullptr) {
|
||||
return false;
|
||||
@@ -74,7 +74,6 @@ bool EntityWrapper::Valid()
|
||||
}
|
||||
|
||||
if (!this->World->ValidEntity(this->ID)) {
|
||||
this->ID = EntityID_Invalid;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,9 @@ BaseEventRelay::~BaseEventRelay()
|
||||
void EventBroker::Unsubscribe(BaseEventRelay& relay) // ?
|
||||
{
|
||||
auto identifier = std::make_tuple(relay.m_EventID, relay.m_ContextTypeName, relay.m_EventTypeName);
|
||||
|
||||
relay.m_Broker = nullptr;
|
||||
if (m_IsProcessing) {
|
||||
m_RelaysToUnsubscribe.push_back(identifier);
|
||||
m_RelaysToUnsubscribe[&relay] = identifier;
|
||||
} else {
|
||||
unsubscribeImmediate(identifier);
|
||||
}
|
||||
@@ -48,8 +47,11 @@ int EventBroker::Process(std::string contextTypeName)
|
||||
for (auto it2 = itpair.first; it2 != itpair.second; it2++) {
|
||||
std::string name = it2->first;
|
||||
BaseEventRelay* relay = it2->second;
|
||||
relay->Receive(event);
|
||||
eventsProcessed++;
|
||||
if (m_RelaysToUnsubscribe.count(relay) != 0) {
|
||||
continue;
|
||||
}
|
||||
relay->Receive(event);
|
||||
eventsProcessed++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,8 +64,8 @@ int EventBroker::Process(std::string contextTypeName)
|
||||
m_RelaysToSubscribe.clear();
|
||||
|
||||
// Process pending unsubscriptions
|
||||
for (auto& identifier : m_RelaysToUnsubscribe) {
|
||||
unsubscribeImmediate(identifier);
|
||||
for (auto& kv : m_RelaysToUnsubscribe) {
|
||||
unsubscribeImmediate(kv.second);
|
||||
}
|
||||
m_RelaysToUnsubscribe.clear();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Core/UniformScaleSystem.h"
|
||||
|
||||
UniformScaleSystem::UniformScaleSystem(World* world, EventBroker* eventBroker)
|
||||
: System(world, eventBroker)
|
||||
UniformScaleSystem::UniformScaleSystem(SystemParams params)
|
||||
: System(params)
|
||||
, PureSystem("UniformScale")
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &UniformScaleSystem::OnSetCamera);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Editor/EditorRenderSystem.h"
|
||||
|
||||
EditorRenderSystem::EditorRenderSystem(World* m_World, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame)
|
||||
: System(m_World, eventBroker)
|
||||
EditorRenderSystem::EditorRenderSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame)
|
||||
: System(params)
|
||||
, m_Renderer(renderer)
|
||||
, m_RenderFrame(renderFrame)
|
||||
{
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#include "Editor/EditorRenderSystem.h"
|
||||
#include "Editor/EditorWidgetSystem.h"
|
||||
|
||||
EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame)
|
||||
: System(world, eventBroker)
|
||||
EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame)
|
||||
: System(params)
|
||||
, m_Renderer(renderer)
|
||||
, m_RenderFrame(renderFrame)
|
||||
{
|
||||
m_EditorWorld = new World();
|
||||
m_EditorWorldSystemPipeline = new SystemPipeline(m_EditorWorld, eventBroker);
|
||||
m_EditorWorldSystemPipeline = new SystemPipeline(m_EditorWorld, m_EventBroker, IsClient, IsServer);
|
||||
m_EditorWorldSystemPipeline->AddSystem<UniformScaleSystem>(0);
|
||||
m_EditorWorldSystemPipeline->AddSystem<EditorWidgetSystem>(0, m_Renderer);
|
||||
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
||||
@@ -100,9 +100,9 @@ void EditorSystem::Enable()
|
||||
}
|
||||
|
||||
// Pause the world we're editing
|
||||
Events::Pause ePause;
|
||||
ePause.World = m_World;
|
||||
m_EventBroker->Publish(ePause);
|
||||
//Events::Pause ePause;
|
||||
//ePause.World = m_World;
|
||||
//m_EventBroker->Publish(ePause);
|
||||
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "Editor/EditorWidgetSystem.h"
|
||||
|
||||
EditorWidgetSystem::EditorWidgetSystem(World* world, EventBroker* eventBroker, IRenderer* renderer)
|
||||
: System(world, eventBroker)
|
||||
EditorWidgetSystem::EditorWidgetSystem(SystemParams params, IRenderer* renderer)
|
||||
: System(params)
|
||||
, PureSystem("EditorWidget")
|
||||
, m_Renderer(renderer)
|
||||
{
|
||||
|
||||
@@ -1,34 +1,44 @@
|
||||
#include "Network/Client.h"
|
||||
using namespace boost::asio::ip;
|
||||
|
||||
Client::Client(ConfigFile* config)
|
||||
Client::Client(World* world, EventBroker* eventBroker)
|
||||
: Network(world, eventBroker)
|
||||
{
|
||||
Network::initialize();
|
||||
|
||||
// Asumes root node is EntityID_Invalid
|
||||
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
|
||||
// Init timer
|
||||
m_TimeSinceSentInputs = std::clock();
|
||||
// Default is local host
|
||||
address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
||||
port = config->Get<int>("Networking.Port", 27666);
|
||||
// Set up network stream
|
||||
|
||||
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
||||
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
|
||||
LOG_INFO("Client initialized");
|
||||
}
|
||||
|
||||
Client::Client(World* world, EventBroker* eventBroker, std::unique_ptr<SnapshotFilter> snapshotFilter)
|
||||
: Client(world, eventBroker)
|
||||
{
|
||||
m_SnapshotFilter = std::move(snapshotFilter);
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{ }
|
||||
|
||||
void Client::Start(World* world, EventBroker* eventBroker)
|
||||
// Need to call connect at start
|
||||
void Client::Connect(std::string address, int port)
|
||||
{
|
||||
m_EventBroker = eventBroker;
|
||||
m_World = world;
|
||||
|
||||
// Subscribe to events
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
|
||||
LOG_INFO("I am client. BIP BOP");
|
||||
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
m_Address = address;
|
||||
if (address.empty()) {
|
||||
m_Address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
||||
}
|
||||
m_Port = port;
|
||||
if (port == 0) {
|
||||
m_Port = config->Get<int>("Networking.Port", 27666);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::Update()
|
||||
@@ -63,6 +73,7 @@ void Client::Update()
|
||||
sendInputCommands();
|
||||
m_TimeSinceSentInputs = std::clock();
|
||||
}
|
||||
// HACK: Send absolute player positions for now to avoid desync until we have reliable messages
|
||||
sendLocalPlayerTransform();
|
||||
|
||||
hasServerTimedOut();
|
||||
@@ -198,40 +209,64 @@ void Client::parseComponentDeletion(Packet & packet)
|
||||
}
|
||||
}
|
||||
|
||||
// Fields with strings will not work right now
|
||||
void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
|
||||
{
|
||||
int sizeOfFields = 0;
|
||||
for (auto field : componentInfo.FieldsInOrder) {
|
||||
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field);
|
||||
sizeOfFields += fieldInfo.Stride;
|
||||
}
|
||||
// Is the size correct?
|
||||
boost::shared_array<char> eventData(new char[componentInfo.Stride]);
|
||||
memcpy(eventData.get(), packet.ReadData(componentInfo.Stride), componentInfo.Stride);
|
||||
//Send event to interpolat system
|
||||
Events::Interpolate e;
|
||||
e.Entity = entityID;
|
||||
e.DataArray = eventData;
|
||||
m_EventBroker->Publish(e);
|
||||
|
||||
}
|
||||
|
||||
void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
|
||||
void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID)
|
||||
{
|
||||
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;
|
||||
m_World->GetComponent(entityID, componentInfo.Name)[fieldInfo.Name] = value;
|
||||
} else {
|
||||
memcpy(m_World->GetComponent(entityID, componentType).Data + fieldInfo.Offset, packet.ReadData(fieldInfo.Stride), fieldInfo.Stride);
|
||||
memcpy(m_World->GetComponent(entityID, componentInfo.Name).Data + fieldInfo.Offset, packet.ReadData(fieldInfo.Stride), fieldInfo.Stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SharedComponentWrapper Client::createSharedComponent(Packet& packet, EntityID entityID, const ComponentInfo& componentInfo)
|
||||
{
|
||||
// Create shared allocation
|
||||
char* data = new char[sizeof(EntityID) + componentInfo.Stride];
|
||||
// Copy entity ID to start of data buffer
|
||||
memcpy(data, &entityID, sizeof(EntityID));
|
||||
// Read and copy fields
|
||||
for (auto& field : componentInfo.FieldsInOrder) {
|
||||
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field);
|
||||
if (fieldInfo.Type == "string") {
|
||||
new (data + sizeof(EntityID) + fieldInfo.Offset) std::string(packet.ReadString());
|
||||
} else {
|
||||
memcpy(data + sizeof(EntityID) + fieldInfo.Offset, packet.ReadData(fieldInfo.Stride), fieldInfo.Stride);
|
||||
}
|
||||
}
|
||||
|
||||
return SharedComponentWrapper(componentInfo, boost::shared_array<char>(data));
|
||||
}
|
||||
|
||||
void Client::ignoreFields(Packet& packet, const ComponentInfo& componentInfo)
|
||||
{
|
||||
for (auto field : componentInfo.FieldsInOrder) {
|
||||
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field);
|
||||
if (fieldInfo.Type == "string") {
|
||||
packet.ReadString();
|
||||
} else {
|
||||
packet.ReadData(fieldInfo.Stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::parseSnapshot(Packet& packet)
|
||||
{
|
||||
// Read input commands
|
||||
std::size_t numInputCommands = packet.ReadPrimitive<std::size_t>();
|
||||
for (std::size_t i = 0; i < numInputCommands; ++i) {
|
||||
Events::InputCommand e;
|
||||
e.PlayerID = packet.ReadPrimitive<EntityID>();
|
||||
e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive<EntityID>()));
|
||||
e.Command = packet.ReadString();
|
||||
e.Value = packet.ReadPrimitive<float>();
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
// Read world state
|
||||
while (packet.DataReadSize() < packet.Size()) {
|
||||
EntityID serverEntityID = packet.ReadPrimitive<EntityID>();
|
||||
EntityID serverParentID = packet.ReadPrimitive<EntityID>();
|
||||
@@ -239,26 +274,32 @@ void Client::parseSnapshot(Packet& packet)
|
||||
int ammountOfComponents = packet.ReadPrimitive<int>();
|
||||
for (int i = 0; i < ammountOfComponents; i++) {
|
||||
std::string componentType = packet.ReadString();
|
||||
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
|
||||
const ComponentInfo& componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
|
||||
if (serverClientMapsHasEntity(serverEntityID)) {
|
||||
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
|
||||
EntityWrapper localEntity(m_World, localEntityID);
|
||||
|
||||
// Update entity
|
||||
if (m_World->HasComponent(localEntityID, componentType)) {
|
||||
// Update component
|
||||
if (componentType == "Transform") {
|
||||
// Interpolate only transform components
|
||||
InterpolateFields(packet, componentInfo, localEntityID, componentType);
|
||||
} else if (componentType == "Physics" && m_World->HasComponent(localEntityID, "Player")) {
|
||||
// HACK: Ignore velocity of physics
|
||||
packet.ReadData(componentInfo.Stride);
|
||||
} else {
|
||||
// Set component values
|
||||
updateFields(packet, componentInfo, localEntityID, componentType);
|
||||
SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo);
|
||||
bool shouldApply = true;
|
||||
// Apply potential filter function
|
||||
if (m_SnapshotFilter != nullptr) {
|
||||
shouldApply = m_SnapshotFilter->FilterComponent(localEntity, newComponent);
|
||||
}
|
||||
if (shouldApply) {
|
||||
ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType);
|
||||
memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride);
|
||||
}
|
||||
//if (localEntity != m_LocalPlayer && !localEntity.IsChildOf(m_LocalPlayer)) {
|
||||
// updateFields(packet, componentInfo, localEntityID);
|
||||
//} else {
|
||||
// ignoreFields(packet, componentInfo);
|
||||
//}
|
||||
} else {
|
||||
// Has entity but no component
|
||||
m_World->AttachComponent(localEntityID, componentType);
|
||||
updateFields(packet, componentInfo, localEntityID, componentType);
|
||||
updateFields(packet, componentInfo, localEntityID);
|
||||
}
|
||||
} else {
|
||||
// Create Entity and component
|
||||
@@ -271,7 +312,7 @@ void Client::parseSnapshot(Packet& packet)
|
||||
m_World->SetName(newLocalEntityID, serverEntityName);
|
||||
insertIntoServerClientMaps(serverEntityID, newLocalEntityID);
|
||||
m_World->AttachComponent(newLocalEntityID, componentType);
|
||||
updateFields(packet, componentInfo, newLocalEntityID, componentType);
|
||||
updateFields(packet, componentInfo, newLocalEntityID);
|
||||
}
|
||||
}
|
||||
// Parent logic
|
||||
@@ -295,10 +336,14 @@ void Client::disconnect()
|
||||
|
||||
bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||
{
|
||||
if (e.PlayerID != -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.Command == "ConnectToServer") { // Connect for now
|
||||
if (e.Value > 0) {
|
||||
m_Reliable.Connect(m_PlayerName, address, port);
|
||||
m_Unreliable.Connect(m_PlayerName, address, port);
|
||||
m_Reliable.Connect(m_PlayerName, m_Address, m_Port);
|
||||
m_Unreliable.Connect(m_PlayerName, m_Address, m_Port);
|
||||
}
|
||||
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
#include "Network/Network.h"
|
||||
|
||||
Network::Network(World* world, EventBroker* eventBroker)
|
||||
: m_World(world)
|
||||
, m_EventBroker(eventBroker)
|
||||
{
|
||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
m_MaxConnections = config->Get<int>("Networking.MaxConnections", 8);
|
||||
m_TimeoutMs = config->Get<int>("Networking.TimeoutMs", 20000);
|
||||
}
|
||||
|
||||
void Network::Update()
|
||||
{
|
||||
updateNetworkData();
|
||||
@@ -74,10 +83,3 @@ void Network::updateNetworkData()
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
#include "Network/Server.h"
|
||||
|
||||
Server::Server()
|
||||
Server::Server(World* world, EventBroker* eventBroker, int port)
|
||||
: Network(world, eventBroker)
|
||||
{
|
||||
Network::initialize();
|
||||
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05f);
|
||||
pingIntervalMs = config->Get<float>("Networking.PingIntervalMs", 1000);
|
||||
}
|
||||
Server::~Server()
|
||||
{ }
|
||||
void Server::Start(World* world, EventBroker* eventBroker)
|
||||
{
|
||||
m_World = world;
|
||||
m_EventBroker = eventBroker;
|
||||
// Subscribe to events
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
|
||||
LOG_INFO("I am Server. BIP BOP\n");
|
||||
|
||||
// Bind
|
||||
if (port == 0) {
|
||||
port = config->Get<float>("Networking.Port", 27666);
|
||||
}
|
||||
m_Port = port;
|
||||
LOG_INFO("Server initialized and bound to port %i", port);
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Server::Update()
|
||||
@@ -141,10 +145,24 @@ void Server::unreliableBroadcast(Packet& packet)
|
||||
void Server::sendSnapshot()
|
||||
{
|
||||
Packet packet(MessageType::Snapshot);
|
||||
addInputCommandsToPacket(packet);
|
||||
addChildrenToPacket(packet, EntityID_Invalid);
|
||||
unreliableBroadcast(packet);
|
||||
}
|
||||
|
||||
void Server::addInputCommandsToPacket(Packet& packet)
|
||||
{
|
||||
// Number of input commands
|
||||
packet.WritePrimitive(m_InputCommandsToBroadcast.size());
|
||||
for (auto& command : m_InputCommandsToBroadcast) {
|
||||
packet.WritePrimitive(command.PlayerID);
|
||||
packet.WritePrimitive(m_ConnectedPlayers.at(command.PlayerID).EntityID);
|
||||
packet.WriteString(command.Command);
|
||||
packet.WritePrimitive(command.Value);
|
||||
}
|
||||
m_InputCommandsToBroadcast.clear();
|
||||
}
|
||||
|
||||
void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
|
||||
{
|
||||
auto itPair = m_World->GetChildren(entityID);
|
||||
@@ -428,7 +446,10 @@ void Server::parseOnInputCommand(Packet& packet)
|
||||
e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID);
|
||||
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);
|
||||
if (e.Command == "PrimaryFire") {
|
||||
m_InputCommandsToBroadcast.push_back(e);
|
||||
}
|
||||
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
|
||||
|
||||
if(skeleton == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -24,7 +22,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]);
|
||||
|
||||
if (animation == nullptr) {
|
||||
return;
|
||||
continue;;
|
||||
}
|
||||
|
||||
double animationSpeed = (double)animationComponent["Speed" + std::to_string(i)];
|
||||
@@ -33,21 +31,55 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
||||
double nextTime = (double)animationComponent["Time" + std::to_string(i)] + animationSpeed * dt;
|
||||
|
||||
|
||||
if (!(bool)animationComponent["Loop" + std::to_string(i)] && glm::abs(nextTime) > animation->Duration) {
|
||||
(double&)animationComponent["Time" + std::to_string(i)] = glm::sign(nextTime) * animation->Duration;
|
||||
if (!(bool)animationComponent["Loop" + std::to_string(i)]) {
|
||||
if (nextTime > animation->Duration) {
|
||||
nextTime = animation->Duration;
|
||||
} else if (nextTime < 0) {
|
||||
nextTime = 0;
|
||||
}
|
||||
|
||||
(double&)animationComponent["Speed" + std::to_string(i)] = 0.0;
|
||||
Events::AnimationComplete e;
|
||||
e.Entity = entity;
|
||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||
m_EventBroker->Publish(e);
|
||||
} else {
|
||||
if (glm::abs(nextTime) > animation->Duration) {
|
||||
(double&)animationComponent["Time" + std::to_string(i)] = glm::abs(nextTime) - animation->Duration;
|
||||
} else {
|
||||
(double&)animationComponent["Time" + std::to_string(i)] = nextTime;
|
||||
if (nextTime > animation->Duration) {
|
||||
nextTime -= animation->Duration;
|
||||
} else if (nextTime < 0) {
|
||||
nextTime += animation->Duration;
|
||||
}
|
||||
}
|
||||
|
||||
(double&)animationComponent["Time" + std::to_string(i)] = nextTime;
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate bone transforms
|
||||
if (skeleton != nullptr) {
|
||||
std::vector<Skeleton::AnimationData> animations;
|
||||
if (entity.HasComponent("Animation")) {
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
Skeleton::AnimationData animationData;
|
||||
animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(entity["Animation"]["AnimationName" + std::to_string(i)]);
|
||||
if (animationData.animation == nullptr) {
|
||||
continue;
|
||||
}
|
||||
animationData.time = (double)entity["Animation"]["Time" + std::to_string(i)];
|
||||
animationData.weight = (double)entity["Animation"]["Weight" + std::to_string(i)];
|
||||
|
||||
animations.push_back(animationData);
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.HasComponent("AnimationOffset")) {
|
||||
Skeleton::AnimationOffset animationOffset;
|
||||
animationOffset.animation = skeleton->GetAnimation(entity["AnimationOffset"]["AnimationName"]);
|
||||
animationOffset.time = (double)entity["AnimationOffset"]["Time"];
|
||||
skeleton->CalculateFrameBones(animations, animationOffset);
|
||||
} else {
|
||||
skeleton->CalculateFrameBones(animations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,8 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1));
|
||||
glm::mat4 boneTransform = skeleton->GetBoneTransformSuper(id);
|
||||
//glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1));
|
||||
|
||||
glm::vec3 scale;
|
||||
glm::quat rotation;
|
||||
@@ -48,7 +49,9 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
glm::vec4 perspective;
|
||||
glm::decompose(boneTransform, scale, rotation, translation, skew, perspective);
|
||||
|
||||
glm::vec3 angles;
|
||||
glm::vec3 angles = glm::vec3(-glm::pitch(rotation), -glm::yaw(rotation), -glm::roll(rotation));
|
||||
/*
|
||||
|
||||
angles.y = asin(-boneTransform[0][2]);
|
||||
if (cos(angles.y) != 0) {
|
||||
angles.x = atan2(boneTransform[1][2], boneTransform[2][2]);
|
||||
@@ -56,7 +59,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp
|
||||
} else {
|
||||
angles.x = atan2(-boneTransform[2][0], boneTransform[1][1]);
|
||||
angles.z = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
if ((bool)entity["BoneAttachment"]["InheritPosition"]) {
|
||||
(glm::vec3&)entity["Transform"]["Position"] = translation + (glm::vec3)entity["BoneAttachment"]["PositionOffset"];
|
||||
|
||||
@@ -328,11 +328,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_ExplosionEffectProgram->Bind();
|
||||
@@ -355,11 +351,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -400,11 +392,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
//bind textures
|
||||
BindModelTextures(forwardSkinnedHandle, modelJob);
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -428,11 +416,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list<std::shared_ptr<RenderJob>>&
|
||||
BindModelTextures(forwardSplatMapSkinnedHandle, modelJob);
|
||||
GLERROR("asdasd");
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -476,13 +460,8 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::list<std::shared_ptr<RenderJo
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
m_ShieldToStencilProgram->Bind();
|
||||
GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle();
|
||||
@@ -535,11 +514,7 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (explosionEffectJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations);
|
||||
}
|
||||
frameBones = explosionEffectJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
if (GLERROR("Animation")) {
|
||||
@@ -574,11 +549,7 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list<std::shared_ptr<Rende
|
||||
BindModelTextures(forwardHandle ,modelJob);
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
|
||||
@@ -610,11 +581,7 @@ void DrawFinalPass::DrawToDepthBuffer(std::list<std::shared_ptr<RenderJob>>& job
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
|
||||
@@ -135,7 +135,7 @@ Model::Model(std::string fileName)
|
||||
maxi = glm::max(maxi, v.Position);
|
||||
}
|
||||
|
||||
m_Box = AABB(maxi, mini);
|
||||
m_Box = AABB(mini, maxi);
|
||||
}
|
||||
|
||||
Model::~Model()
|
||||
|
||||
@@ -103,11 +103,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
}
|
||||
@@ -160,11 +156,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
} else {
|
||||
m_PickingProgram->Bind();
|
||||
@@ -215,11 +207,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
} else {
|
||||
@@ -276,11 +264,7 @@ void PickingPass::Draw(RenderScene& scene)
|
||||
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||
|
||||
std::vector<glm::mat4> frameBones;
|
||||
if (modelJob->AnimationOffset.animation != nullptr) {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset);
|
||||
} else {
|
||||
frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations);
|
||||
}
|
||||
frameBones = modelJob->Skeleton->GetBones();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
#include "Collision/Collision.h"
|
||||
#include "Core/Frustum.h"
|
||||
|
||||
RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRenderer* renderer, RenderFrame* renderFrame, Octree<EntityAABB>* frustumCullOctree)
|
||||
: System(world, eventBroker)
|
||||
RenderSystem::RenderSystem(SystemParams params, const IRenderer* renderer, RenderFrame* renderFrame, Octree<EntityAABB>* frustumCullOctree)
|
||||
: System(params)
|
||||
, m_Renderer(renderer)
|
||||
, m_RenderFrame(renderFrame)
|
||||
, m_World(world)
|
||||
, m_Octree(frustumCullOctree)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
||||
@@ -62,14 +61,14 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs)
|
||||
}
|
||||
|
||||
// Only render children of a camera if that camera is currently active
|
||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||
continue;
|
||||
}
|
||||
if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hide things parented to local player if they have the HiddenFromLocalPlayer component
|
||||
if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) {
|
||||
continue;
|
||||
}
|
||||
if ((entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid()) && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Model* model;
|
||||
try {
|
||||
|
||||
@@ -51,7 +51,7 @@ void Renderer::InitializeWindow()
|
||||
ss << " DEBUG";
|
||||
#endif
|
||||
LOG_INFO(ss.str().c_str());
|
||||
glfwSetWindowTitle(m_Window, ss.str().c_str());
|
||||
SetWindowTitle(ss.str());
|
||||
|
||||
// Initialize GLEW
|
||||
if (glewInit() != GLEW_OK) {
|
||||
|
||||
+159
-252
@@ -29,6 +29,32 @@ Skeleton::~Skeleton()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::CalculateFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||
for (auto& b : Bones) {
|
||||
m_BoneLocalTransforms[b.first] = glm::mat4(1);
|
||||
m_BoneTransforms[b.first] = glm::mat4(1);
|
||||
}
|
||||
} else {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, RootBone, glm::mat4(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::CalculateFrameBones(std::vector<AnimationData> animations, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0) {
|
||||
for (auto& b : Bones) {
|
||||
m_BoneLocalTransforms[b.first] = glm::mat4(1);
|
||||
m_BoneTransforms[b.first] = glm::mat4(1);
|
||||
}
|
||||
} else {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, RootBone, glm::mat4(1));
|
||||
}
|
||||
}
|
||||
|
||||
const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
{
|
||||
auto it = Animations.find(name);
|
||||
@@ -39,129 +65,10 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name)
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0) {
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(true, animations, frameBones, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
|
||||
std::vector<glm::mat4> Skeleton::GetFrameBones(std::vector<AnimationData> animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/)
|
||||
{
|
||||
if (animations.size() <= 0 || animationOffset.animation == nullptr) {
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto& b : Bones) {
|
||||
finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
|
||||
|
||||
std::map<int, glm::mat4> frameBones;
|
||||
AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1));
|
||||
|
||||
std::vector<glm::mat4> finalMatrices;
|
||||
for (auto &kv : frameBones) {
|
||||
finalMatrices.push_back(kv.second);
|
||||
}
|
||||
return finalMatrices;
|
||||
}
|
||||
/*
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
Animation::Keyframe currentFrame;
|
||||
Animation::Keyframe nextFrame;
|
||||
|
||||
if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||
|
||||
if(boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone
|
||||
for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame
|
||||
if (time >= boneKeyFrames.at(index).Time) {
|
||||
currentFrame = boneKeyFrames.at(index);
|
||||
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float progress;
|
||||
|
||||
if(nextFrame.Index == 0) {
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
LOG_INFO("Progress: %f", progress);
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
glm::vec3 positionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
positionInterp.x = 0;
|
||||
positionInterp.z = 0;
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
boneMatrix = parentMatrix *(glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale));
|
||||
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
// LOG_INFO("%s Has no keyframe", bone->Name.c_str());
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
|
||||
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
@@ -189,6 +96,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
float progress;
|
||||
|
||||
if (nextFrame.Index == 0) {
|
||||
nextFrame = currentFrame;
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
@@ -197,130 +105,6 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
LOG_INFO("Progress: %f", progress);
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(JointTransforms.size() <= 0) {
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
}
|
||||
} else if (JointTransforms.size() == 1) {
|
||||
boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms)
|
||||
{
|
||||
if(jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, AnimationOffset animationOffset, std::map<int, glm::mat4>& boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
|
||||
|
||||
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||
|
||||
Animation::Keyframe currentFrame;
|
||||
Animation::Keyframe nextFrame;
|
||||
|
||||
if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone
|
||||
for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame
|
||||
if (time >= boneKeyFrames.at(index).Time) {
|
||||
currentFrame = boneKeyFrames.at(index);
|
||||
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float progress;
|
||||
|
||||
if (nextFrame.Index == 0) {
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
LOG_INFO("Progress: %f", progress);
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
@@ -363,10 +147,12 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
boneMatrix = parentMatrix *((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix));
|
||||
|
||||
}
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
boneMatrix = offset * glm::inverse(bone->OffsetMatrix);
|
||||
boneMatrices[bone->ID] = parentMatrix;
|
||||
m_BoneLocalTransforms[bone->ID] = parentMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -395,21 +181,142 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<Animation
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (offset != glm::mat4(1)) {
|
||||
boneMatrix = parentMatrix * ((glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) + offset);
|
||||
} else {
|
||||
boneMatrix = parentMatrix * (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
}
|
||||
|
||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix);
|
||||
AccumulateBoneTransforms(noRootMotion, animations, animationOffset, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector<AnimationData> animations, const Bone* bone, glm::mat4 parentMatrix)
|
||||
{
|
||||
glm::mat4 boneMatrix;
|
||||
std::vector<JointFrameTransform> JointTransforms;
|
||||
|
||||
for (const AnimationData animationData : animations) {
|
||||
const Animation* animation = animationData.animation;
|
||||
const float time = animationData.time;
|
||||
|
||||
JointFrameTransform jointTransform;
|
||||
jointTransform.Weight = animationData.weight;;
|
||||
|
||||
if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) {
|
||||
std::vector<Animation::Keyframe> boneKeyFrames = animation->JointAnimations.at(bone->ID);
|
||||
|
||||
Animation::Keyframe currentFrame;
|
||||
Animation::Keyframe nextFrame;
|
||||
|
||||
if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone
|
||||
for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame
|
||||
if (time >= boneKeyFrames.at(index).Time) {
|
||||
currentFrame = boneKeyFrames.at(index);
|
||||
nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float progress;
|
||||
|
||||
if (nextFrame.Index == 0) {
|
||||
nextFrame = currentFrame;
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties;
|
||||
|
||||
jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress;
|
||||
jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress);
|
||||
jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress;
|
||||
|
||||
// Flag for no root motion
|
||||
if (bone == RootBone && noRootMotion) {
|
||||
jointTransform.PositionInterp.x = 0;
|
||||
jointTransform.PositionInterp.z = 0;
|
||||
}
|
||||
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
} else { // 1 keyframes for the current bone
|
||||
currentFrame = boneKeyFrames.at(0);
|
||||
jointTransform.PositionInterp = currentFrame.BoneProperties.Position;
|
||||
jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation;
|
||||
jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale;
|
||||
JointTransforms.push_back(jointTransform);
|
||||
|
||||
}
|
||||
} else { // 0 keyframes for the current bone
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (JointTransforms.size() <= 0) {
|
||||
if (bone->Parent) {
|
||||
boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix;
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
boneMatrix = glm::inverse(bone->OffsetMatrix);
|
||||
m_BoneLocalTransforms[bone->ID] = parentMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
} else if (JointTransforms.size() == 1) {
|
||||
boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp));
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
} else {
|
||||
|
||||
glm::vec3 finalPosInterp;
|
||||
glm::quat finalRotInterp;
|
||||
glm::vec3 finalScaleInterp;
|
||||
float totalWeight = 0;
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
totalWeight += jointTransform.Weight;
|
||||
}
|
||||
|
||||
|
||||
for (JointFrameTransform jointTransform : JointTransforms) {
|
||||
if (jointTransform.Weight == 1.0f) {
|
||||
finalPosInterp = jointTransform.PositionInterp;
|
||||
finalRotInterp = jointTransform.RotationInterp;
|
||||
finalScaleInterp = jointTransform.ScaleInterp;
|
||||
break;
|
||||
} else {
|
||||
finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight);
|
||||
finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight));
|
||||
finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp));
|
||||
|
||||
m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||
m_BoneTransforms[bone->ID] = boneMatrix;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (auto &child : bone->Children) {
|
||||
AccumulateBoneTransforms(noRootMotion, animations, child, boneMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset)
|
||||
{
|
||||
@@ -438,15 +345,14 @@ glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animati
|
||||
float progress;
|
||||
|
||||
if (nextFrame.Index == 0) {
|
||||
nextFrame = currentFrame;
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (progress > 1.0f || progress < 0.0f) {
|
||||
LOG_INFO("Progress: %f", progress);
|
||||
progress = glm::clamp(progress, 0.0f, 1.0f);
|
||||
}
|
||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties;
|
||||
@@ -491,6 +397,7 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio
|
||||
float progress;
|
||||
|
||||
if (nextFrame.Index == 0) {
|
||||
nextFrame = currentFrame;
|
||||
progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time);
|
||||
} else {
|
||||
progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time);
|
||||
|
||||
@@ -30,9 +30,10 @@ Texture::Texture(std::string path)
|
||||
glBindTexture(GL_TEXTURE_2D, m_Texture);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, image.Width, image.Height, 0, format, GL_UNSIGNED_BYTE, image.Data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
GLERROR("Texture load");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user