diff --git a/Editor/resources/Models/Camera.gltf b/Editor/resources/Models/Camera.gltf index b1df5287..b3228a9a 100644 --- a/Editor/resources/Models/Camera.gltf +++ b/Editor/resources/Models/Camera.gltf @@ -16,22 +16,23 @@ { "mesh" : 0, "name" : "Cube", - "scale" : [ - 0.21287661790847778, - 0.14901362359523773, - 0.14901362359523773 + "rotation" : [ + 0, + -0.7071067690849304, + 0, + 0.7071068286895752 ], "translation" : [ - 0.007667064666748047, 0, - 0 + 0, + 0.06328082829713821 ] } ], "materials" : [ { "doubleSided" : true, - "name" : "Material", + "name" : "Material.002", "pbrMetallicRoughness" : { "baseColorFactor" : [ 0.800000011920929, @@ -46,7 +47,7 @@ ], "meshes" : [ { - "name" : "Cube", + "name" : "Cube.002", "primitives" : [ { "attributes" : { @@ -64,64 +65,64 @@ { "bufferView" : 0, "componentType" : 5126, - "count" : 143, + "count" : 261, "max" : [ - 0.2293514609336853, - 0.20000004768371582, - 0.19999998807907104 + 0.13640516996383667, + 0.2530915439128876, + 0.43141499161720276 ], "min" : [ - -0.3706485629081726, - -0.19999998807907104, - -0.19999998807907104 + -0.14359483122825623, + -0.19999995827674866, + -0.4257279336452484 ], "type" : "VEC3" }, { "bufferView" : 1, "componentType" : 5126, - "count" : 143, + "count" : 261, "type" : "VEC3" }, { "bufferView" : 2, "componentType" : 5126, - "count" : 143, + "count" : 261, "type" : "VEC2" }, { "bufferView" : 3, "componentType" : 5123, - "count" : 204, + "count" : 270, "type" : "SCALAR" } ], "bufferViews" : [ { "buffer" : 0, - "byteLength" : 1716, + "byteLength" : 3132, "byteOffset" : 0 }, { "buffer" : 0, - "byteLength" : 1716, - "byteOffset" : 1716 + "byteLength" : 3132, + "byteOffset" : 3132 }, { "buffer" : 0, - "byteLength" : 1144, - "byteOffset" : 3432 + "byteLength" : 2088, + "byteOffset" : 6264 }, { "buffer" : 0, - "byteLength" : 408, - "byteOffset" : 4576 + "byteLength" : 540, + "byteOffset" : 8352 } ], "buffers" : [ { - "byteLength" : 4984, - "uri" : "data:application/octet-stream;base64,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" + "byteLength" : 8892, + "uri" : "data:application/octet-stream;base64,MO2MvVzOvj2RMhU+MO2MvVzOvj2RMhU+MO2MvVzOvj2RMhU+MO2MvVzOvj2RMhU+MO2MvVzOvj2RMhU+MO2MvVzOvj2RMhU+MO2MvVTOvr2RMhU+MO2MvVTOvr2RMhU+MO2MvVTOvr2RMhU+MO2MvVTOvr2RMhU+MO2MvVTOvr2RMhU+MO2MvVTOvr2RMhU+bGd8PVzOvj2SMhU+bGd8PVzOvj2SMhU+bGd8PVzOvj2SMhU+bGd8PVzOvj2SMhU+bGd8PVzOvj2SMhU+bGd8PVzOvj2SMhU+bGd8PVTOvr2SMhU+bGd8PVTOvr2SMhU+bGd8PVTOvr2SMhU+bGd8PVTOvr2SMhU+bGd8PVTOvr2SMhU+bGd8PVTOvr2SMhU+lQ4CvnKJNL5s4tw+lQ4CvnKJNL5s4tw+lQ4CvnKJNL5s4tw+lQ4CvnKJNL5s4tw+vjUGvj54Or5IPNY+vjUGvj54Or5IPNY+vjUGvj54Or5IPNY+vjUGvj54Or5IPNY+vjUGvj54Or5IPNY+vjUGvj54Or5IPNY+AbL9PT54Or5JPNY+AbL9PT54Or5JPNY+AbL9PT54Or5JPNY+AbL9PT54Or5JPNY+AbL9PT54Or5JPNY+AbL9PT54Or5JPNY+sGP1PXKJNL5t4tw+sGP1PXKJNL5t4tw+sGP1PXKJNL5t4tw+sGP1PXKJNL5t4tw+AbL9PUJ4Oj5JPNY+AbL9PUJ4Oj5JPNY+AbL9PUJ4Oj5JPNY+AbL9PUJ4Oj5JPNY+AbL9PUJ4Oj5JPNY+AbL9PUJ4Oj5JPNY+sGP1PXKJND5t4tw+sGP1PXKJND5t4tw+sGP1PXKJND5t4tw+sGP1PXKJND5t4tw+lQ4CvnKJND5s4tw+lQ4CvnKJND5s4tw+lQ4CvnKJND5s4tw+lQ4CvnKJND5s4tw+vjUGvkJ4Oj5IPNY+vjUGvkJ4Oj5IPNY+vjUGvkJ4Oj5IPNY+vjUGvkJ4Oj5IPNY+vjUGvkJ4Oj5IPNY+vjUGvkJ4Oj5IPNY+ggoTvq6nQz7LcNO+ggoTvq6nQz7LcNO+ggoTvq6nQz7LcNO+ggoTvq6nQz7LcNO+ggoTvq6nQz7LcNO+ggoTvq6nQz7LcNO+vKMMvs7MTD7KcNO+vKMMvs7MTD7KcNO+vKMMvs7MTD7KcNO+vKMMvs7MTD7KcNO+vKMMvs7MTD7KcNO+vKMMvs7MTD7KcNO+vqMMvq6nQz4D+dm+vqMMvq6nQz4D+dm+vqMMvq6nQz4D+dm+vqMMvq6nQz4D+dm+vqMMvq6nQz4D+dm+vKMMvsrMTL7KcNO+vKMMvsrMTL7KcNO+vKMMvsrMTL7KcNO+vKMMvsrMTL7KcNO+vKMMvsrMTL7KcNO+ggoTvqqnQ77LcNO+ggoTvqqnQ77LcNO+ggoTvqqnQ77LcNO+ggoTvqqnQ77LcNO+ggoTvqqnQ77LcNO+vqMMvqqnQ74D+dm+vqMMvqqnQ74D+dm+vqMMvqqnQ74D+dm+vqMMvqqnQ74D+dm+vqMMvqqnQ74D+dm+vqMMvqqnQ74D+dm+BEcFPq6nQz4B+dm+BEcFPq6nQz4B+dm+BEcFPq6nQz4B+dm+BEcFPq6nQz4B+dm+BEcFPq6nQz4B+dm+BEcFPq6nQz4B+dm+BkcFPs7MTD7IcNO+BkcFPs7MTD7IcNO+BkcFPs7MTD7IcNO+BkcFPs7MTD7IcNO+BkcFPs7MTD7IcNO+zK0LPq6nQz7JcNO+zK0LPq6nQz7JcNO+zK0LPq6nQz7JcNO+zK0LPq6nQz7JcNO+zK0LPq6nQz7JcNO+BEcFPqqnQ74B+dm+BEcFPqqnQ74B+dm+BEcFPqqnQ74B+dm+BEcFPqqnQ74B+dm+BEcFPqqnQ74B+dm+zK0LPqqnQ77JcNO+zK0LPqqnQ77JcNO+zK0LPqqnQ77JcNO+zK0LPqqnQ77JcNO+zK0LPqqnQ77JcNO+zK0LPqqnQ77JcNO+BkcFPsrMTL7IcNO+BkcFPsrMTL7IcNO+BkcFPsrMTL7IcNO+BkcFPsrMTL7IcNO+BkcFPsrMTL7IcNO+BkcFPsrMTL7IcNO+vqMMvqqnQ76QMhU+vqMMvqqnQ76QMhU+vqMMvqqnQ76QMhU+vqMMvqqnQ76QMhU+vqMMvqqnQ76QMhU+vqMMvqqnQ76QMhU+vqMMvqqnQ76QMhU+hgoTvqqnQ74fIgg+hgoTvqqnQ74fIgg+hgoTvqqnQ74fIgg+hgoTvqqnQ74fIgg+hgoTvqqnQ74fIgg+hgoTvqqnQ74fIgg+vqMMvsrMTL4eIgg+vqMMvsrMTL4eIgg+vqMMvsrMTL4eIgg+vqMMvsrMTL4eIgg+vqMMvsrMTL4eIgg+vqMMvsrMTL4eIgg+AkcFPsrMTL4hIgg+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" } ] } diff --git a/Editor/resources/Scripts/Scene.wren b/Editor/resources/Scripts/Scene.wren index 4b870cbd..b6bfd84a 100644 --- a/Editor/resources/Scripts/Scene.wren +++ b/Editor/resources/Scripts/Scene.wren @@ -44,6 +44,7 @@ class Scene { foreign static GetTranslation_(e) foreign static SetTranslation_(e, x, y, z) foreign static SetRotation_(e, x, y, z) + foreign static SetLookAt_(e, x, y, z) foreign static GetRotation_(e) //foreign static SetScale_(e, x, y, z) @@ -111,6 +112,9 @@ class TransformComponent { Scene.SetRotation_(_entityId, t.x, t.y, t.z) } + SetLookAt(t) { + Scene.SetLookAt_(_entityId, t.x, t.y, t.z) + } } class Light { diff --git a/Editor/src/Misc/GizmoDrawer.cpp b/Editor/src/Misc/GizmoDrawer.cpp index a33cbcc9..3a9524ee 100644 --- a/Editor/src/Misc/GizmoDrawer.cpp +++ b/Editor/src/Misc/GizmoDrawer.cpp @@ -36,7 +36,7 @@ GizmoDrawer::GizmoDrawer() _gizmos = std::map>(); _gizmos["cam"] = loader.LoadModel("resources/Models/Camera.gltf"); _gizmos["light"] = loader.LoadModel("resources/Models/Light.gltf"); - _gizmos["player"] = loader.LoadModel("resources/Models/Player.gltf"); + _gizmos["player"] = loader.LoadModel("resources/Models/Camera.gltf"); } void GizmoDrawer::GenerateSphereGizmo() diff --git a/Editor/src/Windows/EditorInterface.cpp b/Editor/src/Windows/EditorInterface.cpp index 7e2b9412..5af71753 100644 --- a/Editor/src/Windows/EditorInterface.cpp +++ b/Editor/src/Windows/EditorInterface.cpp @@ -182,53 +182,63 @@ namespace Nuake { if (Selection.Type == EditorSelectionType::Entity && !Engine::IsPlayMode()) { TransformComponent& tc = Selection.Entity.GetComponent(); - ParentComponent& parent = Selection.Entity.GetComponent(); Matrix4 transform = tc.GetGlobalTransform(); - - auto editorCam = Engine::GetCurrentScene()->GetCurrentCamera(); + const auto& editorCam = Engine::GetCurrentScene()->GetCurrentCamera(); Matrix4 cameraView = editorCam->GetTransform(); Matrix4 cameraProjection = editorCam->GetPerspective(); + // Imguizmo calculates the delta from the gizmo, ImGuizmo::Manipulate( glm::value_ptr(cameraView), glm::value_ptr(cameraProjection), CurrentOperation, CurrentMode, glm::value_ptr(transform) ); - Matrix4 oldTransform = transform; + if (ImGuizmo::IsUsing()) { - Vector3 globalPos = Vector3(); - Entity currentParent = Selection.Entity; + // Since imguizmo returns a transform in global space and we want the local transform, + // we need to multiply by the inverse of the parent's global transform in order to revert + // the changes from the parent transform. + Matrix4 localTransform = Matrix4(transform); + ParentComponent& parent = Selection.Entity.GetComponent(); if (parent.HasParent) { - Matrix4 inverseParent = glm::inverse(parent.Parent.GetComponent().GetGlobalTransform()); - oldTransform *= inverseParent; + const auto& parentTransformComponent = parent.Parent.GetComponent(); + const Matrix4& parentTransform = parentTransformComponent.GetGlobalTransform(); + localTransform = glm::inverse(parentTransform) * localTransform; } - Vector3 scale = Vector3(); - Quat rotation = Quat(); - Vector3 pos = Vector3(); - Vector3 skew = Vector3(); - Vector4 pesp = Vector4(); - glm::decompose(oldTransform, scale, rotation, pos, skew, pesp); + // Decompose local transform + float decomposedPosition[3]; + float decomposedEuler[3]; + float decomposedScale[3]; + ImGuizmo::DecomposeMatrixToComponents(glm::value_ptr(localTransform), decomposedPosition, decomposedEuler, decomposedScale); - tc.Translation = pos; - tc.Rotation = rotation; - tc.Scale = scale; - tc.LocalTransform = oldTransform; - - Vector3 gscale = Vector3(); - Quat grotation = Quat(); - Vector3 gpos = Vector3(); - Vector3 gskew = Vector3(); - Vector4 gpesp = Vector4(); - glm::decompose(transform, gscale, grotation, gpos, skew, pesp); - - tc.SetGlobalPosition(gpos); - tc.SetGlobalRotation(grotation); - tc.SetGlobalScale(gscale); - tc.SetGlobalTransform(transform); + const auto& localPosition = Vector3(decomposedPosition[0], decomposedPosition[1], decomposedPosition[2]); + const auto& localScale = Vector3(decomposedScale[0], decomposedScale[1], decomposedScale[2]); + + localTransform[0] /= localScale.x; + localTransform[1] /= localScale.y; + localTransform[2] /= localScale.z; + const auto& rotationMatrix = Matrix3(localTransform); + const Quat& localRotation = glm::normalize(Quat(rotationMatrix)); + + const Matrix4& rotationMatrix4 = glm::mat4_cast(localRotation); + const Matrix4& scaleMatrix = glm::scale(Matrix4(1.0f), localScale); + const Matrix4& translationMatrix = glm::translate(Matrix4(1.0f), localPosition); + const Matrix4& newLocalTransform = translationMatrix * rotationMatrix4 * scaleMatrix; + + tc.Translation = localPosition; + + if (CurrentOperation != ImGuizmo::SCALE) + { + tc.Rotation = localRotation; + } + + tc.Scale = localScale; + tc.LocalTransform = newLocalTransform; + tc.Dirty = true; } } @@ -361,9 +371,9 @@ namespace Nuake { if (ImGui::Selectable("Focus camera")) { Ref editorCam = Engine::GetCurrentScene()->m_EditorCamera; - editorCam->Translation = entity.GetComponent().GetGlobalPosition(); Vector3 camDirection = entity.GetComponent().CameraInstance->GetDirection(); - editorCam->SetDirection(camDirection); + camDirection.z *= -1.0f; + editorCam->SetTransform(glm::inverse(entity.GetComponent().GetGlobalTransform())); } ImGui::Separator(); } diff --git a/Nuake/src/Core/Maths.cpp b/Nuake/src/Core/Maths.cpp index e0889bce..884f4339 100644 --- a/Nuake/src/Core/Maths.cpp +++ b/Nuake/src/Core/Maths.cpp @@ -2,12 +2,79 @@ using namespace Nuake; +Quat Nuake::LookAt(Vector3 sourcePoint, Vector3 destPoint) +{ + Vector3 forwardVector = glm::normalize(destPoint - sourcePoint); + + float dot = glm::dot(Vector3(0, 0, 1), forwardVector); + if (glm::abs(dot - (-1.0f)) < 0.000001f) + { + return Quat(0, 1, 0, 3.1415926535897932f); + } + if (glm::abs(dot - (1.0f)) < 0.000001f) + { + return Quat(); // identity + } + + float rotAngle = acos(dot); + Vector3 rotAxis = glm::cross(Vector3(0, 0, 1), forwardVector); + rotAxis = glm::normalize(rotAxis); + return CreateFromAxisAngle(rotAxis, rotAngle); +} + +// just in case you need that function also +Quat Nuake::CreateFromAxisAngle(Vector3 axis, float angle) +{ + float halfAngle = angle * .5f; + float s = sin(halfAngle); + Quat q; + q.x = axis.x * s; + q.y = axis.y * s; + q.z = axis.z * s; + q.w = cos(halfAngle); + return q; +} + Quat Nuake::QuatFromEuler(float x, float y, float z) { - return Quat(Vector3(Rad(z), Rad(y), Rad(x))); + glm::quat pitchQuat = glm::angleAxis(Rad(x), glm::vec3(1.0f, 0.0f, 0.0f)); + glm::quat yawQuat = glm::angleAxis(Rad(y), glm::vec3(0.0f, 1.0f, 0.0f)); + glm::quat rollQuat = glm::angleAxis(Rad(z), glm::vec3(0.0f, 0.0f, -1.0f)); + glm::quat orientation = yawQuat * pitchQuat * rollQuat; + + return glm::normalize(orientation); + + return Quat(Vector3(Rad(x), Rad(y), Rad(z))); + + Quat q; + + float cr = cos(x * 0.5); + float sr = sin(x * 0.5); + float cp = cos(y * 0.5); + float sp = sin(y * 0.5); + float cy = cos(z * 0.5); + float sy = sin(z * 0.5); + + q.w = cr * cp * cy + sr * sp * sy; + q.x = sr * cp * cy - cr * sp * sy; + q.y = cr * sp * cy + sr * cp * sy; + q.z = cr * cp * sy - sr * sp * cy; + return q; } Vector3 Nuake::QuatToDirection(const Quat& quat) { - return glm::rotate(glm::inverse(quat), glm::vec3(1.0, 0.0, 0.0)); + return glm::normalize(quat * Vector3(0, 0, -1)); +} + +void Nuake::Decompose(const Matrix4& m, Vector3& pos, Quat& rot, Vector3& scale) +{ + pos = m[3]; + for (int i = 0; i < 3; i++) + scale[i] = glm::length(Vector3(m[i])); + const glm::mat3 rotMtx( + glm::vec3(m[0]) / scale[0], + glm::vec3(m[1]) / scale[1], + glm::vec3(m[2]) / scale[2]); + rot = glm::quat_cast(rotMtx); } \ No newline at end of file diff --git a/Nuake/src/Core/Maths.h b/Nuake/src/Core/Maths.h index c16fba0e..ba3b1c18 100644 --- a/Nuake/src/Core/Maths.h +++ b/Nuake/src/Core/Maths.h @@ -20,6 +20,9 @@ namespace Nuake using Matrix3 = glm::mat3; #define Rad(degrees) glm::radians(degrees) + Quat LookAt(Vector3 sourcePoint, Vector3 destPoint); + Quat CreateFromAxisAngle(Vector3 axis, float angle); Quat QuatFromEuler(float x, float y, float z); Vector3 QuatToDirection(const Quat& quat); + void Decompose(const Matrix4& m, Vector3& pos, Quat& rot, Vector3& scale); } diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index a83d77b0..1d674c8a 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -292,8 +292,16 @@ namespace Nuake settings->mShape = GetJoltShape(cc->Shape); settings->mGravityFactor = 0.0f; - auto& joltPos = JPH::Vec3(cc->Position.x, cc->Position.y, cc->Position.z); - JPH::Character* character = new JPH::Character(settings, joltPos, JPH::Quat::sIdentity(), cc->GetEntity().GetID() , _JoltPhysicsSystem.get()); + auto& joltPosition = JPH::Vec3(cc->Position.x, cc->Position.y, cc->Position.z); + + Quat& bodyRotation = cc->Rotation; + + // We need to add 180 degrees because our forward is -Z. + const auto& yOffset = Vector3(0.0f, Rad(180.0), 0.0f); + bodyRotation = glm::normalize(bodyRotation * Quat(yOffset)); + + const auto& joltRotation = JPH::Quat(bodyRotation.x, bodyRotation.y, bodyRotation.z, bodyRotation.w); + JPH::Character* character = new JPH::Character(settings, joltPosition, joltRotation, cc->GetEntity().GetID() , _JoltPhysicsSystem.get()); character->AddToPhysicsSystem(JPH::EActivation::Activate); @@ -362,17 +370,16 @@ namespace Nuake transformComponent.SetLocalPosition(pos); transformComponent.SetLocalRotation(Quat(bodyRotation.GetW(), bodyRotation.GetX(), bodyRotation.GetY(), bodyRotation.GetZ())); transformComponent.SetLocalTransform(transform); - transformComponent.Dirty = false; + transformComponent.Dirty = true; } } - + void DynamicWorld::SyncCharactersTransforms() { // TODO(ANTO): Finish this to connect updated jolt transforms back to the entity. // The problem was that I dont know yet how to go from jolt body ptr to the entity // Combinations of find and iterators etc. I do not have the brain power rn zzz. // const auto& bodyInterface = _JoltPhysicsSystem->GetBodyInterface(); - for (const auto& e : _registeredCharacters) { Entity entity { (entt::entity)e.first, Engine::GetCurrentScene().get()}; @@ -399,7 +406,7 @@ namespace Nuake transformComponent.SetLocalPosition(pos); transformComponent.SetLocalRotation(Quat(bodyRotation.GetW(), bodyRotation.GetX(), bodyRotation.GetY(), bodyRotation.GetZ())); transformComponent.SetLocalTransform(transform); - transformComponent.Dirty = false; + transformComponent.Dirty = true; } } @@ -437,29 +444,24 @@ namespace Nuake SyncCharactersTransforms(); } - void DynamicWorld::Clear() { _stepCount = 0; - if (_registeredBodies.empty()) + if (!_registeredBodies.empty()) { - return; + _JoltBodyInterface->RemoveBodies(reinterpret_cast(_registeredBodies.data()), _registeredBodies.size()); + _registeredBodies.clear(); } - _JoltBodyInterface->RemoveBodies(reinterpret_cast(_registeredBodies.data()), _registeredBodies.size()); - _registeredBodies.clear(); - - if (_registeredCharacters.empty()) + if (!_registeredCharacters.empty()) { - return; + for (auto& character : _registeredCharacters) + { + character.second->RemoveFromPhysicsSystem(); + } + _registeredCharacters.clear(); } - - for (auto& character : _registeredCharacters) - { - character.second->RemoveFromPhysicsSystem(); - } - _registeredCharacters.clear(); } void DynamicWorld::MoveAndSlideCharacterController(const Entity& entity, const Vector3 velocity) diff --git a/Nuake/src/Rendering/Camera.cpp b/Nuake/src/Rendering/Camera.cpp index 42557112..f44b340c 100644 --- a/Nuake/src/Rendering/Camera.cpp +++ b/Nuake/src/Rendering/Camera.cpp @@ -45,14 +45,15 @@ namespace Nuake void Camera::SetDirection(Vector3 direction) { - //cam->cameraDirection.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - //cam->cameraDirection.y = sin(glm::radians(Pitch)); - //cam->cameraDirection.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - //cam->cameraFront = glm::normalize(cam->cameraDirection); - //cam->cameraRight = glm::normalize(glm::cross(cam->up, cam->cameraFront)); Direction = glm::normalize(direction); Right = glm::normalize(glm::cross(Vector3(0, 1, 0), Direction)); - //Up = glm::normalize(glm::cross(Direction, Right)) + m_View = lookAt(Translation, Translation + glm::normalize(Direction), Vector3(0, 1, 0)); + } + + void Camera::SetDirection(const Quat& direction) + { + // TODO: Calculate forward and Right from quaternion. + assert("Not implemented!"); } Vector3 Camera::GetTranslation() { @@ -70,17 +71,21 @@ namespace Nuake return m_Perspective; } + void Camera::SetTransform(const Matrix4& transform) + { + m_View = transform; + } + Matrix4 Camera::GetTransform() { - glm::mat4 tr = lookAt(Translation, Translation + Direction, Vector3(0, 1, 0)); - return tr; + return m_View; } Matrix4 Camera::GetTransformRotation() { return lookAt(glm::vec3(), Direction, Up); } - + bool Camera::BoxFrustumCheck(const AABB& aabb) { m_Frustum = Frustum(GetPerspective() * GetTransform()); @@ -98,6 +103,8 @@ namespace Nuake BEGIN_SERIALIZE(); SERIALIZE_VAL(m_Type); SERIALIZE_VAL(AspectRatio); + SERIALIZE_VEC3(Translation) + SERIALIZE_VEC3(Direction) SERIALIZE_VAL(Fov); SERIALIZE_VAL(Exposure); SERIALIZE_VAL(Speed); @@ -109,6 +116,12 @@ namespace Nuake BEGIN_DESERIALIZE(); j = j["CameraInstance"]; this->m_Type = (CAMERA_TYPE)j["m_Type"]; + if(j.contains("Translation")) + DESERIALIZE_VEC3(j["Translation"], Translation); + + //if (j.contains("Direction")) + // DESERIALIZE_VEC3(j["Direction"], Direction); + this->AspectRatio = j["AspectRatio"]; this->Fov = j["Fov"]; this->Exposure = j["Exposure"]; diff --git a/Nuake/src/Rendering/Camera.h b/Nuake/src/Rendering/Camera.h index c52c9361..a2e20590 100644 --- a/Nuake/src/Rendering/Camera.h +++ b/Nuake/src/Rendering/Camera.h @@ -24,13 +24,15 @@ namespace Nuake Vector3 Rotation = { 0.0f, 0.0f, 0.0f }; Vector3 Scale = { 1.0f, 1.0f, 1.0f }; Vector3 Up = Vector3(0, 1, 0); - Vector3 Right = Vector3(1, 0, 0); Matrix4 m_Perspective; + Matrix4 m_View; public: float AspectRatio = 16.0f / 9.0f; Vector3 Direction = Vector3(0, 0, 1); + Vector3 Right = Vector3(1, 0, 0); + Vector3 Translation = { 0.0f, 0.0f, 0.0f }; float Fov = 88.0f; float Exposure = 1.0f; @@ -44,12 +46,14 @@ namespace Nuake void OnWindowResize(float x, float y); void SetDirection(Vector3 direction); + void SetDirection(const Quat& direction); Vector3 GetTranslation(); Vector3 GetDirection(); Matrix4 GetPerspective(); Matrix4 GetTransform(); Matrix4 GetTransformRotation(); + void SetTransform(const Matrix4& transform); inline Vector3 GetRight() const { return Right; } inline Vector3 GetUp() const { return glm::cross(Direction, Right); } bool BoxFrustumCheck(const AABB& aabb); diff --git a/Nuake/src/Scene/Components/TransformComponent.h b/Nuake/src/Scene/Components/TransformComponent.h index 146263e2..dbc8062f 100644 --- a/Nuake/src/Scene/Components/TransformComponent.h +++ b/Nuake/src/Scene/Components/TransformComponent.h @@ -46,11 +46,13 @@ namespace Nuake json Serialize() { - Rotation = glm::normalize(Rotation); BEGIN_SERIALIZE(); SERIALIZE_VAL_LBL("Type", "TransformComponent"); SERIALIZE_VEC3(Translation); + SERIALIZE_VEC3(GlobalTranslation); SERIALIZE_VEC4(Rotation); + SERIALIZE_VEC4(GlobalRotation); + SERIALIZE_VEC3(GlobalScale); SERIALIZE_VEC3(Scale); END_SERIALIZE(); } @@ -59,6 +61,16 @@ namespace Nuake { BEGIN_DESERIALIZE(); this->Translation = Vector3(j["Translation"]["x"], j["Translation"]["y"], j["Translation"]["z"]); + + if (j.contains("GlobalTranslation")) + { + float x = j["GlobalTranslation"]["x"]; + float y = j["GlobalTranslation"]["y"]; + float z = j["GlobalTranslation"]["z"]; + + this->GlobalTranslation = Vector3(x, y, z); + } + if (j.contains("Rotation")) { float w = j["Rotation"]["w"]; @@ -68,11 +80,31 @@ namespace Nuake this->Rotation = Quat(w, x, y, z); } + + if (j.contains("GlobalRotation")) + { + float w = j["GlobalRotation"]["w"]; + float x = j["GlobalRotation"]["x"]; + float y = j["GlobalRotation"]["y"]; + float z = j["GlobalRotation"]["z"]; + + this->GlobalRotation = Quat(w, x, y, z); + } + + if (j.contains("GlobalScale")) + { + float x = j["GlobalScale"]["x"]; + float y = j["GlobalScale"]["y"]; + float z = j["GlobalScale"]["z"]; + + this->GlobalScale = Vector3(x, y, z); + } this->Scale = Vector3(j["Scale"]["x"], j["Scale"]["y"], j["Scale"]["z"]); LocalTransform = Matrix4(1); GlobalTransform = Matrix4(1); + this->Dirty = true; return true; } }; diff --git a/Nuake/src/Scene/EditorCamera.cpp b/Nuake/src/Scene/EditorCamera.cpp index 6df9d0a8..9d80a962 100644 --- a/Nuake/src/Scene/EditorCamera.cpp +++ b/Nuake/src/Scene/EditorCamera.cpp @@ -148,7 +148,8 @@ namespace Nuake Direction.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); Direction.y = sin(glm::radians(Pitch)); Direction.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); - Direction = glm::normalize(Direction); + + SetDirection(glm::normalize(Direction)); Right = glm::normalize(glm::cross(Up, Direction)); } else if (Input::IsMouseButtonDown(2)) diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 18f7f6c5..3979488f 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -135,22 +135,14 @@ namespace Nuake { void Scene::Draw(FrameBuffer& framebuffer) { Ref cam = nullptr; - Matrix4 camTransform = Matrix4(); + const auto& view = m_Registry.view(); + for (const auto& e : view) { - auto view = m_Registry.view(); - for (auto e : view) - { - auto [transform, camera, parent] = view.get(e); - cam = camera.CameraInstance; + auto [transform, camera, parent] = view.get(e); + cam = camera.CameraInstance; - cam->Translation = transform.GetGlobalPosition(); - - const Vector3& forward = QuatToDirection(transform.GetGlobalRotation()); - cam->SetDirection(forward); - - camTransform = transform.GetGlobalTransform(); - break; - } + cam->Translation = transform.GetGlobalPosition(); + break; } if (!cam) diff --git a/Nuake/src/Scene/Systems/TransformSystem.cpp b/Nuake/src/Scene/Systems/TransformSystem.cpp index 86d9ceb8..793f8c75 100644 --- a/Nuake/src/Scene/Systems/TransformSystem.cpp +++ b/Nuake/src/Scene/Systems/TransformSystem.cpp @@ -1,13 +1,13 @@ #include "TransformSystem.h" #include "src/Core/Maths.h" - #include "src/Scene/Scene.h" #include #include #include -#include "src/Vendors/glm/gtx/matrix_decompose.hpp" -namespace Nuake { + +namespace Nuake +{ TransformSystem::TransformSystem(Scene* scene) { m_Scene = scene; @@ -36,15 +36,6 @@ namespace Nuake { void TransformSystem::UpdateTransform() { - auto camView = m_Scene->m_Registry.view(); - for (auto e : camView) - { - auto [transform, camera] = camView.get(e); - Matrix4 cameraTransform = camera.CameraInstance->GetTransformRotation(); - - camera.CameraInstance->Translation = transform.GlobalTranslation; - } - // Calculate all local transforms auto localTransformView = m_Scene->m_Registry.view(); for (auto tv : localTransformView) @@ -52,15 +43,15 @@ namespace Nuake { TransformComponent& transform = localTransformView.get(tv); if (transform.Dirty) { - Matrix4 localTransform = Matrix4(1.0f); - auto& localTranslate = transform.GetLocalPosition(); - auto& localRot = transform.GetLocalRotation(); - auto& localScale = transform.GetLocalScale(); - localRot.w *= -1.0; - localTransform = glm::translate(localTransform, localTranslate); - localTransform = localTransform * glm::toMat4(localRot); - localTransform = glm::scale(localTransform, localScale); - transform.SetLocalTransform(localTransform); + const Vector3& localTranslate = transform.GetLocalPosition(); + const Quat& localRot = glm::normalize(transform.GetLocalRotation()); + const Vector3& localScale = transform.GetLocalScale(); + const Matrix4& translationMatrix = glm::translate(Matrix4(1.0f), localTranslate); + const Matrix4& rotationMatrix = glm::mat4_cast(localRot); + const Matrix4& scaleMatrix = glm::scale(Matrix4(1.0f), localScale); + const Matrix4& newLocalTransform = translationMatrix * rotationMatrix * scaleMatrix; + + transform.SetLocalTransform(newLocalTransform); transform.Dirty = false; } } @@ -70,9 +61,8 @@ namespace Nuake { for (auto e : transformView) { auto [parent, transform] = transformView.get(e); - if (!parent.HasParent) - { + { // If no parents, then globalTransform is local transform. transform.SetGlobalTransform(transform.GetLocalTransform()); transform.SetGlobalPosition(transform.GetLocalPosition()); @@ -93,21 +83,41 @@ namespace Nuake { { TransformComponent& transformComponent = parentComponent.Parent.GetComponent(); - globalPosition = transformComponent.GetLocalPosition() + (transformComponent.GetLocalRotation() * globalPosition); + globalPosition = transformComponent.GetLocalPosition() + (globalPosition); + + globalScale *= transformComponent.GetLocalScale(); + globalOrientation = transformComponent.GetLocalRotation() * globalOrientation; globalTransform = transformComponent.GetLocalTransform() * globalTransform; - globalOrientation = transformComponent.GetLocalRotation() * globalOrientation; - globalScale *= transformComponent.GetLocalScale(); - NameComponent& nameComponent = parentComponent.Parent.GetComponent(); - parentComponent = parentComponent.Parent.GetComponent(); } - + transform.SetGlobalPosition(globalPosition); transform.SetGlobalRotation(globalOrientation); transform.SetGlobalScale(globalScale); transform.SetGlobalTransform(globalTransform); } + + auto camView = m_Scene->m_Registry.view(); + for (auto& e : camView) + { + auto [transform, camera] = camView.get(e); + Matrix4 cameraTransform = camera.CameraInstance->GetTransformRotation(); + + camera.CameraInstance->Translation = transform.GlobalTranslation; + + auto globalRotation = transform.GetGlobalRotation(); + auto& translationMatrix = glm::translate(Matrix4(1.0f), transform.GetGlobalPosition()); + const Matrix4& rotationMatrix = glm::mat4_cast(globalRotation); + Vector4 forward = Vector4(0, 0, -1, 1); + const auto globalForward = rotationMatrix * forward; + + Vector4 right = Vector4(1, 0, 0, 1); + const auto globalRight = rotationMatrix * right; + camera.CameraInstance->Direction = globalForward; + camera.CameraInstance->Right = globalRight; +; camera.CameraInstance->SetTransform(glm::inverse(translationMatrix * rotationMatrix)); + } } } diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index 2e0087d7..fbaa0ac5 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -40,6 +40,8 @@ namespace Nuake { RegisterMethod("SetTranslation_(_,_,_,_)", (void*)SetTranslation); RegisterMethod("GetRotation_(_)", (void*)GetRotation); RegisterMethod("SetRotation_(_,_,_,_)", (void*)SetRotation); + RegisterMethod("SetLookAt_(_,_,_,_)", (void*)SetLookAt); + RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity); RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity); @@ -263,6 +265,20 @@ namespace Nuake { transform.SetLocalRotation(QuatFromEuler(x, y, z)); } + static void SetLookAt(WrenVM* vm) + { + double handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& transform = ent.GetComponent(); + // set the slots + float x = (float)wrenGetSlotDouble(vm, 2); + float y = (float)wrenGetSlotDouble(vm, 3); + float z = (float)wrenGetSlotDouble(vm, 4); + Vector3 targetPosition = Vector3(x, y, z); + Quat rotation = LookAt(transform.GetGlobalPosition(), transform.GetGlobalPosition() + targetPosition); + transform.SetLocalRotation(rotation); + } + static void SetTranslation(WrenVM* vm) { double handle = wrenGetSlotDouble(vm, 1);