diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index cf7a6533..496be0a3 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -2,12 +2,12 @@ #include #include -#include +#include #include #include -#include +#include #include -#include "../Scene/Entities/Components/BoxCollider.h" +#include "../Scene/Components/BoxCollider.h" #include "src/EditorInterface.h" #include "../Core/Input.h" #include diff --git a/Editor/resources/Interface/Testing.css b/Editor/resources/Interface/Testing.css index 2eead7f5..f9e2ad81 100644 --- a/Editor/resources/Interface/Testing.css +++ b/Editor/resources/Interface/Testing.css @@ -1,13 +1,7 @@ - - -.hello{ - width: 400px; - height: 200px; -} - .screen{ height: 100%; width: 100%; + display: flex; justify-content: center; flex-direction: row; align-content:flex-start; @@ -16,5 +10,4 @@ .rect{ height: 200px; width: 200px; - } diff --git a/Editor/resources/Interface/Testing.interface b/Editor/resources/Interface/Testing.interface index 90534fc3..e90073cd 100644 --- a/Editor/resources/Interface/Testing.interface +++ b/Editor/resources/Interface/Testing.interface @@ -1,12 +1,11 @@

Hello, world!

+ groups="rect">
diff --git a/Editor/resources/Scenes/test.scene b/Editor/resources/Scenes/test.scene index 53b30e83..d5ac24ae 100644 --- a/Editor/resources/Scenes/test.scene +++ b/Editor/resources/Scenes/test.scene @@ -1,13 +1,17 @@ { "Entities": [ { - "CharacterControllerComponent": { - "Height": 1.2000000476837158, - "Mass": 2500.0, - "Radius": 0.20000000298023224 + "CameraComponent": { + "CameraInstance": { + "AspectRatio": 1.774647831916809, + "Exposure": 1.0, + "Fov": 88.0, + "Speed": 1.0, + "m_Type": 1 + } }, "NameComponent": { - "Name": "Player" + "Name": "Camera" }, "ParentComponent": { "HasParent": false @@ -24,45 +28,15 @@ "z": 1.0 }, "Translation": { - "x": -15.681736946105957, - "y": 17.139999389648438, - "z": 10.975672721862793 + "x": -25.119064331054688, + "y": 19.491336822509766, + "z": 4.5285515785217285 }, "Type": "TransformComponent" }, "WrenScriptComponent": { - "Class": "PlayerScript", - "Script": "Scripts/Player.wren" - } - }, - { - "NameComponent": { - "Name": "Trenchbroom map" - }, - "ParentComponent": { - "HasParent": false - }, - "QuakeMapComponent": { - "HasCollisions": true, - "Path": "C:\\Dev\\Nuake\\Editor\\resources\\Maps\\texture_test.map" - }, - "TransformComponent": { - "Rotation": { - "x": 0.0, - "y": 0.0, - "z": 0.0 - }, - "Scale": { - "x": 1.0, - "y": 1.0, - "z": 1.0 - }, - "Translation": { - "x": 9.199999809265137, - "y": 5.599999904632568, - "z": 0.0 - }, - "Type": "TransformComponent" + "Class": "CamScript", + "Script": "Scripts/Cam.wren" } }, { @@ -78,7 +52,7 @@ "y": 0.9591699838638306, "z": 0.20000000298023224 }, - "IsVolumetric": true, + "IsVolumetric": false, "Strength": 10.0, "SyncDirectionWithSky": true, "Type": 0 @@ -113,17 +87,43 @@ } }, { - "CameraComponent": { - "CameraInstance": { - "AspectRatio": 1.7106741666793823, - "Exposure": 1.0, - "Fov": 88.0, - "Speed": 1.0, - "m_Type": 1 - } + "NameComponent": { + "Name": "Trenchbroom map" + }, + "ParentComponent": { + "HasParent": false + }, + "QuakeMapComponent": { + "HasCollisions": true, + "Path": "C:\\Dev\\Nuake\\Editor\\resources\\Maps\\texture_test.map" + }, + "TransformComponent": { + "Rotation": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "Scale": { + "x": 1.0, + "y": 1.0, + "z": 1.0 + }, + "Translation": { + "x": 9.199999809265137, + "y": 5.599999904632568, + "z": 0.0 + }, + "Type": "TransformComponent" + } + }, + { + "CharacterControllerComponent": { + "Height": 1.2000000476837158, + "Mass": 2500.0, + "Radius": 0.20000000298023224 }, "NameComponent": { - "Name": "Camera" + "Name": "Player" }, "ParentComponent": { "HasParent": false @@ -140,15 +140,15 @@ "z": 1.0 }, "Translation": { - "x": 0.0, - "y": 0.75, - "z": 0.0 + "x": -25.119064331054688, + "y": 18.649978637695313, + "z": 4.5285515785217285 }, "Type": "TransformComponent" }, "WrenScriptComponent": { - "Class": "CamScript", - "Script": "Scripts/Cam.wren" + "Class": "PlayerScript", + "Script": "Scripts/Player.wren" } } ], diff --git a/Editor/resources/Scripts/Cam.wren b/Editor/resources/Scripts/Cam.wren index 0997ee99..2ae7eab0 100644 --- a/Editor/resources/Scripts/Cam.wren +++ b/Editor/resources/Scripts/Cam.wren @@ -5,21 +5,24 @@ import "Scripts/Math" for Vector3, Math import "Scripts/Input" for Input class CamScript is ScriptableEntity { - construct new() { _Pitch = 0 _Yaw = 0 _mouseLastX = 0 _mouseLastY = 0 + _BobHeight = 0.1 + _BobSpeed = 5.0 + _CamHeight = 0.5 + + _deltaTime = 0 Input.HideMouse() } - init() { - - } + init() {} update(ts) { + _deltaTime = _deltaTime + ts var x = Input.GetMouseX() var y = Input.GetMouseY() @@ -35,6 +38,7 @@ class CamScript is ScriptableEntity { _Yaw = _Yaw + diffx _Pitch = _Pitch + diffy + if(_Pitch > 89) _Pitch = 89 if(_Pitch < -89) _Pitch = -89 @@ -48,13 +52,27 @@ class CamScript is ScriptableEntity { var newDir = Vector3.new(camX, camY, camZ) + + var player = Scene.GetEntity("Player") + + var playerScript = player.GetComponent("Script") + var velocity = playerScript.Velocity.Duplicate() + velocity.y = 0 // Dont count gravity in bob. + velocity = velocity.Sqrt() + + var amount = (Math.Sin(_deltaTime * (velocity * 0.01)) / 2 + 1) * _BobHeight + Engine.Log("BobAmount: %(amount)") + + var pTransform = player.GetComponent("Transform") + var pPos = pTransform.GetTranslation() + if(amount < 1 && amount > -1) amount = 0 + + var transform = this.GetComponent("Transform") + var newPos = Vector3.new(pPos.x, pPos.y + _CamHeight + amount , pPos.z) + transform.SetTranslation(newPos) + cam.SetDirection(newDir) } - CheckInput() { - - } - - exit() { - } + exit() {} } \ No newline at end of file diff --git a/Editor/resources/Scripts/Math.wren b/Editor/resources/Scripts/Math.wren index b97a7b04..7b254fec 100644 --- a/Editor/resources/Scripts/Math.wren +++ b/Editor/resources/Scripts/Math.wren @@ -49,6 +49,16 @@ class Vector3 { } } + /(other) { + if(other is Vector3) { + return Vector3.new(_x / other.x, + _y / other.y, + _z / other.z) + } else if(other is Num) { + return Vector3.new(_x / other, _y / other, _z / other) + } + } + +(other) { if(other is Vector3) { return Vector3.new(_x + other.x, @@ -79,6 +89,10 @@ class Vector3 { _z = z } + Duplicate() { + return Vector3.new(_x, _y, _z) + } + Sqrt() { return Math.Sqrt_(_x, _y, _z) } @@ -94,4 +108,12 @@ class Vector3 { var z = _z / length return Vector3.new(x, y, z) } + + Angle(vec) { + this.Normalize() * vec.Normalize() + } + + Length() { + this.Sqrt() + } } \ No newline at end of file diff --git a/Editor/resources/Scripts/Player.wren b/Editor/resources/Scripts/Player.wren index 57750e05..2607a01f 100644 --- a/Editor/resources/Scripts/Player.wren +++ b/Editor/resources/Scripts/Player.wren @@ -7,16 +7,18 @@ import "Scripts/Physics" for Physics, CollisionResult class PlayerScript is ScriptableEntity { + + Velocity {_Velocity} construct new() { _InputDir = Vector3.new(0, 0, 0) _Velocity = Vector3.new(0, 0, 0) - _Accel = 150 + _Accel = 25 _Deccel = 0.92 _AirDeccel = 0.7 - _Gravity = 20 + _Gravity = 10 _MaxSpeed = 20 - _Jump = 800 + _Jump = 200 //Input.HideMouse() } @@ -24,7 +26,7 @@ class PlayerScript is ScriptableEntity { Engine.Log("Player init") } - update(ts) { + fixedUpdate(ts) { this.CheckInput() var camEntity = Scene.GetEntity("Camera") @@ -37,25 +39,26 @@ class PlayerScript is ScriptableEntity { var right = cam.GetRight() right.y = 0 right = right.Normalize() - var new_Velocity = (dir * _InputDir.z) + (right * _InputDir.x) + + var move = _InputDir + var new_Velocity = (dir * move.z) + (right * move.x) var controller = this.GetComponent("CharacterController") var transform = this.GetComponent("Transform") - var from = transform.GetTranslation() var to = from - Vector3.new(0, 1, 0) - var normal = Physics.Raycast(from, to).Normal.Normalize() - - Engine.Log("Normal col: (%(normal.x), %(normal.y), %(normal.z))") - + var normal = Physics.Raycast(from, to).Normal + if(!controller.IsOnGround()) { - _Velocity.y = _Velocity.y - _Gravity + _Velocity.y = _Velocity.y -_Gravity //_Velocity.x = _Velocity.x * _AirDeccel //_Velocity.z = _Velocity.z * _AirDeccel } else { - _Velocity.y = -20 + _Velocity.y = -10 + + Engine.Log("Grav: %(_Velocity.y)") if(Input.IsKeyPressed(32)) _Velocity.y = _Jump @@ -65,6 +68,8 @@ class PlayerScript is ScriptableEntity { _Velocity.x = _Velocity.x * _Deccel _Velocity.z = _Velocity.z * _Deccel } + + Engine.Log("Grav: %(_Velocity.y)") controller.MoveAndSlide(_Velocity * ts) } diff --git a/Editor/resources/Scripts/Scene.wren b/Editor/resources/Scripts/Scene.wren index f82f1a94..89b7af0f 100644 --- a/Editor/resources/Scripts/Scene.wren +++ b/Editor/resources/Scripts/Scene.wren @@ -26,7 +26,9 @@ class Scene { return Camera.new(id) } else if (component == "Transform") { return TransformComponent.new(id) - } + } else if (component == "Script") { + return this.GetScript_(id) + } } @@ -34,8 +36,10 @@ class Scene { // Components // // Transform + + foreign static GetScript_(e) foreign static GetTranslation_(e) - //foreign static SetTranslation_(e, x, y, z) + foreign static SetTranslation_(e, x, y, z) //foreign static SetRotation_(e, x, y, z) //foreign static SetScale_(e, x, y, z) @@ -111,6 +115,9 @@ class TransformComponent { return Vector3.new(result[0], result[1], result[2]) } + SetTranslation(t) { + Scene.SetTranslation_(_entityId, t.x, t.y, t.z) + } } diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index bf1d8803..56822da7 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -3,9 +3,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include #include "src/Scene/Entities/ImGuiHelper.h" @@ -13,13 +13,14 @@ #include #include "../Resource/FontAwesome5.h" -#include +#include #include #include #include "src/Resource/Project.h" -#include +#include #include -#include +#include +#include Ref userInterface; ImFont* normalFont; ImFont* EditorInterface::bigIconFont; @@ -923,7 +924,7 @@ void NewProject() void OpenProject() { // Parse the project and load it. - std::string projectPath = FileDialog::OpenFile(".project"); + std::string projectPath = "C:/Dev/Nuake/Editor/resources/test.project";//FileDialog::OpenFile(".project"); FileSystem::SetRootDirectory(projectPath + "/../"); Ref project = Project::New(); diff --git a/Editor/src/FileSystemUI.cpp b/Editor/src/FileSystemUI.cpp index 9dba73df..dde7f83a 100644 --- a/Editor/src/FileSystemUI.cpp +++ b/Editor/src/FileSystemUI.cpp @@ -1,7 +1,7 @@ #include "FileSystemUI.h" #include #include -#include +#include "src/Scene/Components/ParentComponent.h" #include #include #include "EditorInterface.h" diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index 7ac8358b..43bb0a6f 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -15,6 +15,8 @@ Ref Engine::CurrentProject; Ref Engine::CurrentWindow; float Engine::m_LastFrameTime = 0.0f; +float Engine::m_FixedUpdateRate = 1.0 / 60.0f; +float Engine::m_FixedUpdateDifference = 0.f; bool Engine::IsPlayMode = false; void Engine::Init() @@ -46,11 +48,23 @@ void Engine::Tick() m_LastFrameTime = time; // Play mode update vs editor update. - if (Engine::IsPlayMode) + if (Engine::IsPlayMode) { CurrentWindow->Update(timestep); + m_FixedUpdateDifference += timestep; + // Fixed update + if (m_FixedUpdateDifference >= m_FixedUpdateRate) + { + // call update here. + CurrentWindow->FixedUpdate(m_FixedUpdateRate); + m_FixedUpdateDifference = 0.f; + } + } else GetCurrentScene()->EditorUpdate(timestep); + + + Input::Update(); } diff --git a/Nuake/Engine.h b/Nuake/Engine.h index 3ddc81cd..035cde98 100644 --- a/Nuake/Engine.h +++ b/Nuake/Engine.h @@ -29,7 +29,8 @@ private: static Ref CurrentWindow; static Ref CurrentProject; static Ref CurrentScene; - + static float m_FixedUpdateRate; + static float m_FixedUpdateDifference; public: static bool IsPlayMode; // True if is playing a scene diff --git a/Nuake/src/Core/Physics/CharacterController.cpp b/Nuake/src/Core/Physics/CharacterController.cpp index 51000a5e..2d0e7ea3 100644 --- a/Nuake/src/Core/Physics/CharacterController.cpp +++ b/Nuake/src/Core/Physics/CharacterController.cpp @@ -1,29 +1,9 @@ #include "CharacterController.h" #include "../Core/Physics/PhysicsManager.h" +#include "../Core/Physics/RaycastResult.h" namespace Physics { - class IgnoreBodyAndGhostCast : - public btCollisionWorld::ClosestRayResultCallback - { - private: - btRigidBody* m_pBody; - btPairCachingGhostObject* m_pGhostObject; - - public: - IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject) - : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), - m_pBody(pBody), m_pGhostObject(pGhostObject) - { - } - - btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) - { - if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject) - return 1.0f; - - return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); - } - }; + CharacterController::CharacterController(float height, float radius, float mass, Vector3 position) { @@ -141,13 +121,15 @@ namespace Physics } } + + void CharacterController::UpdatePosition() { // Ray cast, ignore rigid body IgnoreBodyAndGhostCast rayCallBack_bottom(m_Rigidbody, m_GhostObject); btVector3 from = m_Rigidbody->getWorldTransform().getOrigin(); - btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight, 0.0f); + btVector3 toBt = m_Rigidbody->getWorldTransform().getOrigin() - btVector3(0.0f, m_bottomYOffset + m_stepHeight , 0.0f); PhysicsManager::Get()->GetWorld()->GetDynamicWorld()->rayTest(from, toBt, rayCallBack_bottom); // Bump up if hit @@ -155,16 +137,24 @@ namespace Physics { float previousY = m_Rigidbody->getWorldTransform().getOrigin().getY(); - m_Rigidbody->getWorldTransform().getOrigin().setY(previousY + (m_bottomYOffset + m_stepHeight) * (1.0f - rayCallBack_bottom.m_closestHitFraction)); + float t = rayCallBack_bottom.m_closestHitFraction ; + float clamped = (1.0 - rayCallBack_bottom.m_closestHitFraction); btVector3 vel(m_Rigidbody->getLinearVelocity()); + + if(vel.getY() < 0) // -magic number is to fix bouncing down a slope. + m_Rigidbody->getWorldTransform().getOrigin().setY(previousY - 0.14f + (m_bottomYOffset + m_stepHeight) * (clamped)); + vel.setY(0.0f); m_Rigidbody->setLinearVelocity(vel); IsOnGround = true; + } + + float testOffset = 0.07f; diff --git a/Nuake/src/Core/Physics/CharacterController.h b/Nuake/src/Core/Physics/CharacterController.h index 7584d0b9..3bbf41a6 100644 --- a/Nuake/src/Core/Physics/CharacterController.h +++ b/Nuake/src/Core/Physics/CharacterController.h @@ -13,7 +13,8 @@ namespace Physics public: bool IsOnGround = false; bool m_hittingWall; - float m_stepHeight = .1f; + float m_stepHeight = 0.35f; + float m_MaxSlopeAngle = 45.0f; btTransform* m_Transform; btCollisionShape* m_CollisionShape; diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index d16825a4..1954eb3d 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -2,8 +2,12 @@ #include "Rigibody.h" #include "../Core/Core.h" #include "BulletDebugDrawer.h" +#include +#include + namespace Physics { + DynamicWorld::DynamicWorld() { ///collision configuration contains default setup for memory, collision setup. Advanced users can create their own configuration. btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration(); @@ -52,26 +56,32 @@ namespace Physics // Specify filters manually, otherwise ghost doesn't collide with statics for some reason dynamicsWorld->addCollisionObject(cc->m_GhostObject, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::StaticFilter ); } + RaycastResult DynamicWorld::Raycast(glm::vec3 from, glm::vec3 to) { btVector3 btFrom(from.x, from.y, from.z); btVector3 btTo(to.x, to.y, to.z); - btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo); + ClosestRayResultCallback res(btFrom, btTo); dynamicsWorld->rayTest(btFrom, btTo, res); btVector3 localNormal; if(res.m_collisionObject) { // TODO: Fix the godammn fucked up normal - localNormal = res.m_collisionObject->getWorldTransform().getBasis().inverse() * res.m_hitNormalWorld; + localNormal = res.m_hitNormalWorld; } + + Vector3 localNorm = glm::vec3(localNormal.x(), localNormal.y(), localNormal.z()); + + //Logger::Log("normal: x:" + std::to_string(localNorm.x) + " y:" + std::to_string(localNorm.y )+ "z: " + std::to_string(localNorm.z)); + res.m_closestHitFraction; // Map bullet result to dto. RaycastResult result{ glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()), glm::vec3(res.m_hitPointWorld.x(), res.m_hitPointWorld.y(), res.m_hitPointWorld.z()), - glm::vec3(localNormal.x(), localNormal.y(), localNormal.z()) + localNorm }; return result; diff --git a/Nuake/src/Core/Physics/RaycastResult.h b/Nuake/src/Core/Physics/RaycastResult.h index 2e67ea9a..8e46a155 100644 --- a/Nuake/src/Core/Physics/RaycastResult.h +++ b/Nuake/src/Core/Physics/RaycastResult.h @@ -1,5 +1,64 @@ #pragma once #include +#include "CharacterController.h" + +#include +namespace Physics +{ + struct ClosestRayResultCallback : public btCollisionWorld::RayResultCallback + { + ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld) + { + } + + btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; + + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) + { + //caller already does the filter on the m_closestHitFraction + btAssert(rayResult.m_hitFraction <= m_closestHitFraction); + + m_closestHitFraction = rayResult.m_hitFraction; + m_collisionObject = rayResult.m_collisionObject; + + m_hitNormalWorld = rayResult.m_hitNormalLocal; + + + m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); + return rayResult.m_hitFraction; + } + }; + + class IgnoreBodyAndGhostCast : + public Physics::ClosestRayResultCallback + { + private: + btRigidBody* m_pBody; + btPairCachingGhostObject* m_pGhostObject; + + public: + IgnoreBodyAndGhostCast(btRigidBody* pBody, btPairCachingGhostObject* pGhostObject) + : ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), + m_pBody(pBody), m_pGhostObject(pGhostObject) + { + } + + btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) + { + if (rayResult.m_collisionObject == m_pBody || rayResult.m_collisionObject == m_pGhostObject) + return 1.0f; + + return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); + } + }; +} + // result object from raycast. struct RaycastResult { diff --git a/Nuake/src/Core/Physics/RaycastResults.h b/Nuake/src/Core/Physics/RaycastResults.h new file mode 100644 index 00000000..6f70f09b --- /dev/null +++ b/Nuake/src/Core/Physics/RaycastResults.h @@ -0,0 +1 @@ +#pragma once diff --git a/Nuake/src/Rendering/Framebuffer.cpp b/Nuake/src/Rendering/Framebuffer.cpp index 3bc90757..32ffb10b 100644 --- a/Nuake/src/Rendering/Framebuffer.cpp +++ b/Nuake/src/Rendering/Framebuffer.cpp @@ -77,6 +77,7 @@ void FrameBuffer::QueueResize(Vector2 size) void FrameBuffer::UpdateSize(Vector2 size) { m_Size = size; + ResizeQueued = false; // Delete frame buffer and render buffer. glDeleteFramebuffers(1, &m_FramebufferID); diff --git a/Nuake/src/Rendering/MSAAFramebuffer.cpp b/Nuake/src/Rendering/MSAAFramebuffer.cpp new file mode 100644 index 00000000..71de392a --- /dev/null +++ b/Nuake/src/Rendering/MSAAFramebuffer.cpp @@ -0,0 +1,120 @@ +#include "MSAAFramebuffer.h" +#include +MSAAFrameBuffer::MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size) +{ + m_Textures = std::map>(); + m_Size = size; + + glGenFramebuffers(1, &m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); + + // Create render buffer and attach to frame buffer. + if (hasRenderBuffer) + { + glGenRenderbuffers(1, &m_RenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); + } + else + { + m_RenderBuffer = -1; + } + + // Unbind + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +} + +void MSAAFrameBuffer::SetTexture(Ref texture, GLenum attachment) +{ + m_Textures[attachment] = texture; + // Attach texture to the framebuffer. + Bind(); + texture->AttachToFramebuffer(attachment); + + // Set draw buffer with dynamic amount of render target. + // Surely, this can be optimized. + int size = 0; + std::vector keys = std::vector(); + for (auto s : m_Textures) + { + if (s.first != GL_DEPTH_ATTACHMENT) + { + keys.push_back(s.first); + size += 1; + } + } + + if (size > 0) + glDrawBuffers(size, &keys[0]); + + Unbind(); +} + + +void MSAAFrameBuffer::Bind() +{ + if (ResizeQueued) + UpdateSize(m_Size); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBlitFramebuffer(0, 0, m_Size.x, m_Size.y, 0, 0, m_Size.x, m_Size.y, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glViewport(0, 0, m_Size.x, m_Size.y); +} + +void MSAAFrameBuffer::Unbind() +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void MSAAFrameBuffer::QueueResize(Vector2 size) +{ + ResizeQueued = true; + m_Size = size; +} + +void MSAAFrameBuffer::UpdateSize(Vector2 size) +{ + m_Size = size; + + // Delete frame buffer and render buffer. + glDeleteFramebuffers(1, &m_FramebufferID); + glDeleteRenderbuffers(1, &m_RenderBuffer); + + // Recreate resized texture. + for (auto t : m_Textures) + t.second->Resize(size); + + // New FBO and RBO. + glGenFramebuffers(1, &m_FramebufferID); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FramebufferID); + + // Recreate resized texture. + for (auto t : m_Textures) + t.second->AttachToFramebuffer(t.first); + + // Recreate render buffer + glGenRenderbuffers(1, &m_RenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Size.x, m_Size.y); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_RenderBuffer); + + // Unbind. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +} + +void MSAAFrameBuffer::SetDrawBuffer(GLenum draw) +{ + Bind(); + //glReadBuffer(draw); + Unbind(); +} + +void MSAAFrameBuffer::SetReadBuffer(GLenum read) +{ + Bind(); + //glReadBuffer(read); + Unbind(); +} \ No newline at end of file diff --git a/Nuake/src/Rendering/MSAAFramebuffer.h b/Nuake/src/Rendering/MSAAFramebuffer.h new file mode 100644 index 00000000..5afa9e0e --- /dev/null +++ b/Nuake/src/Rendering/MSAAFramebuffer.h @@ -0,0 +1,38 @@ +#pragma once +#include "../Core/Maths.h" +#include +#include "../Core/Core.h" + +#include +#include +class MSAAFrameBuffer +{ +private: + unsigned int m_FramebufferID; + unsigned int m_RenderBuffer; + + Vector2 m_Size; + bool ResizeQueued = false; + + std::map> m_Textures; + Ref m_Texture; + +public: + MSAAFrameBuffer(bool hasRenderBuffer, Vector2 size); + ~MSAAFrameBuffer() { } + + // 0x8CE0 = color attachment 0. + // TODO: Remove blackbox crap + Ref GetTexture(GLenum attachment = 0x8CE0) { return m_Textures[(int)attachment]; } + void SetTexture(Ref texture, GLenum attachment = 0x8CE0); + + + void Bind(); + void Unbind(); + void QueueResize(Vector2 size); + Vector2 GetSize() const { return m_Size; } + void UpdateSize(Vector2 size); + + void SetDrawBuffer(GLenum draw); + void SetReadBuffer(GLenum read); +}; \ No newline at end of file diff --git a/Nuake/src/Rendering/Renderer.h b/Nuake/src/Rendering/Renderer.h index d2835d72..5b8b1c4b 100644 --- a/Nuake/src/Rendering/Renderer.h +++ b/Nuake/src/Rendering/Renderer.h @@ -1,6 +1,6 @@ #pragma once #include "Shaders/Shader.h" -#include "../Scene/Entities/Components.h" +#include "../Scene/Components/Components.h" #include "../Core/Core.h" // DTO for light data. struct Light { diff --git a/Nuake/src/Rendering/Shaders/Shader.cpp b/Nuake/src/Rendering/Shaders/Shader.cpp index 7ccb8c41..8687c554 100644 --- a/Nuake/src/Rendering/Shaders/Shader.cpp +++ b/Nuake/src/Rendering/Shaders/Shader.cpp @@ -119,7 +119,7 @@ unsigned int Shader::Compile(unsigned int type) // Retrieve uniform address and registers it if not already registered. int Shader::FindUniformLocation(std::string uniform) { - if (UniformCache.find(uniform) == UniformCache.end()) { + if (UniformCache.count(uniform) == 0) { int addr = glGetUniformLocation(ProgramId, uniform.c_str()); if (addr == -1) diff --git a/Nuake/src/Rendering/Textures/MultiSampledTexture.cpp b/Nuake/src/Rendering/Textures/MultiSampledTexture.cpp new file mode 100644 index 00000000..ad314908 --- /dev/null +++ b/Nuake/src/Rendering/Textures/MultiSampledTexture.cpp @@ -0,0 +1,101 @@ +#include "MultiSampledTexture.h" +#include +#include + +MultiSampledTexture::MultiSampledTexture(const std::string& path) { + m_RendererId = 0; + m_FilePath = path; + m_LocalBuffer = nullptr; + m_Width = 0; + m_Height = 0; + m_BPP = 0; + + stbi_set_flip_vertically_on_load(1); + + m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4); + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId); + glGenerateMipmap(GL_TEXTURE_2D); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + 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_LOD_BIAS, -1.0f); + //glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE); + glGenerateMipmap(GL_TEXTURE_2D); + if (m_LocalBuffer) + stbi_image_free(m_LocalBuffer); + else + std::cout << "Error: failed to load texture: " << path << std::endl; +} + +// Empty texture not from file. +MultiSampledTexture::MultiSampledTexture(glm::vec2 size, GLenum format) +{ + m_Format = format; + + m_Width = size.x; + m_Height = size.y; + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_RendererId); + glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, format, size.x, size.y, GL_TRUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); +} + + +MultiSampledTexture::MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t) +{ + m_Width = size.x; + m_Height = size.y; + + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + + auto pixel = bitmap(0, bitmap.height - 0 - 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*)bitmap.pixels); +} + +void MultiSampledTexture::Resize(glm::vec2 size) +{ + glDeleteTextures(1, &m_RendererId); + m_Width = size.x; + m_Height = size.y; + glGenTextures(1, &m_RendererId); + glBindTexture(GL_TEXTURE_2D, m_RendererId); + glTexImage2D(GL_TEXTURE_2D, 0, m_Format, size.x, size.y, 0, m_Format, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + +MultiSampledTexture::~MultiSampledTexture() { + glDeleteTextures(1, &m_RendererId); +} + +void MultiSampledTexture::AttachToFramebuffer(GLenum attachment) +{ + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, m_RendererId, 0); + + //glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_RendererId, 0); +} + + +void MultiSampledTexture::Bind(unsigned int slot) const { + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_2D, m_RendererId); +} + +void MultiSampledTexture::Unbind() const { + glBindTexture(GL_TEXTURE_2D, 0); +} + diff --git a/Nuake/src/Rendering/Textures/MultiSampledTexture.h b/Nuake/src/Rendering/Textures/MultiSampledTexture.h new file mode 100644 index 00000000..0e6e881b --- /dev/null +++ b/Nuake/src/Rendering/Textures/MultiSampledTexture.h @@ -0,0 +1,41 @@ +#pragma once +#include "stb_image/stb_image.h" +#include +#include "glm/vec2.hpp" +#include "msdfgen/core/BitmapRef.hpp" + + +typedef unsigned int GLenum; +class MultiSampledTexture +{ +private: + unsigned int m_RendererId; + std::string m_FilePath; + unsigned char* m_LocalBuffer; + GLenum m_Format; + + int m_Width; + int m_Height; + int m_BPP; // byte per pixel. + +public: + MultiSampledTexture(const std::string& path); + MultiSampledTexture(glm::vec2 size, msdfgen::BitmapConstRef& bitmap, bool t); + MultiSampledTexture(glm::vec2 size, GLenum format); + + ~MultiSampledTexture(); + + void Resize(glm::vec2 size); + void AttachToFramebuffer(GLenum attachment); + + void Bind(unsigned int slot = 0) const; + void Unbind() const; + + unsigned int GetID() const { return m_RendererId; } + + inline int GetWidth() const { return m_Width; } + inline int GetHeight() const { return m_Height; } +}; + + + diff --git a/Nuake/src/Rendering/Textures/Texture.cpp b/Nuake/src/Rendering/Textures/Texture.cpp index abf40efe..f4cc2572 100644 --- a/Nuake/src/Rendering/Textures/Texture.cpp +++ b/Nuake/src/Rendering/Textures/Texture.cpp @@ -19,7 +19,7 @@ Texture::Texture(const std::string& path) { glGenerateMipmap(GL_TEXTURE_2D); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -45,7 +45,7 @@ Texture::Texture(glm::vec2 size, GLenum format) glTexImage2D(GL_TEXTURE_2D, 0, format, size.x, size.y, 0, format, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - + glGenerateMipmap(GL_TEXTURE_2D); } diff --git a/Nuake/src/Scene/Components/BaseComponent.h b/Nuake/src/Scene/Components/BaseComponent.h new file mode 100644 index 00000000..6f70f09b --- /dev/null +++ b/Nuake/src/Scene/Components/BaseComponent.h @@ -0,0 +1 @@ +#pragma once diff --git a/Nuake/src/Scene/Entities/Components/BoxCollider.cpp b/Nuake/src/Scene/Components/BoxCollider.cpp similarity index 100% rename from Nuake/src/Scene/Entities/Components/BoxCollider.cpp rename to Nuake/src/Scene/Components/BoxCollider.cpp diff --git a/Nuake/src/Scene/Entities/Components/BoxCollider.h b/Nuake/src/Scene/Components/BoxCollider.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/BoxCollider.h rename to Nuake/src/Scene/Components/BoxCollider.h diff --git a/Nuake/src/Scene/Entities/Components/CameraComponent.cpp b/Nuake/src/Scene/Components/CameraComponent.cpp similarity index 91% rename from Nuake/src/Scene/Entities/Components/CameraComponent.cpp rename to Nuake/src/Scene/Components/CameraComponent.cpp index 970ab335..a29a7600 100644 --- a/Nuake/src/Scene/Entities/Components/CameraComponent.cpp +++ b/Nuake/src/Scene/Components/CameraComponent.cpp @@ -1,7 +1,7 @@ #pragma once #include "CameraComponent.h" -#include "../ImGuiHelper.h" #include +#include "src/Scene/Entities/ImGuiHelper.h" CameraComponent::CameraComponent() { diff --git a/Nuake/src/Scene/Entities/Components/CameraComponent.h b/Nuake/src/Scene/Components/CameraComponent.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/CameraComponent.h rename to Nuake/src/Scene/Components/CameraComponent.h diff --git a/Nuake/src/Scene/Entities/Components/CharacterControllerComponent.h b/Nuake/src/Scene/Components/CharacterControllerComponent.h similarity index 85% rename from Nuake/src/Scene/Entities/Components/CharacterControllerComponent.h rename to Nuake/src/Scene/Components/CharacterControllerComponent.h index dfd85b18..ea90ddd1 100644 --- a/Nuake/src/Scene/Entities/Components/CharacterControllerComponent.h +++ b/Nuake/src/Scene/Components/CharacterControllerComponent.h @@ -35,8 +35,6 @@ public: btVector3 pos = CharacterController->m_motionTransform.getOrigin(); glm::vec3 finalPos = glm::vec3(pos.x(), pos.y(), pos.z()); - std::string msg = "moved to: " + std::to_string(finalPos.x) + " " + std::to_string(finalPos.y) + "\n"; - printf(msg.c_str()); tc.Translation = finalPos; } }; \ No newline at end of file diff --git a/Nuake/src/Scene/Entities/Components.cpp b/Nuake/src/Scene/Components/Components.cpp similarity index 100% rename from Nuake/src/Scene/Entities/Components.cpp rename to Nuake/src/Scene/Components/Components.cpp diff --git a/Nuake/src/Scene/Components/Components.h b/Nuake/src/Scene/Components/Components.h new file mode 100644 index 00000000..1ef74617 --- /dev/null +++ b/Nuake/src/Scene/Components/Components.h @@ -0,0 +1,24 @@ +#pragma once +#include +#include +#include "BaseComponent.h" +#include "TransformComponent.h" +#include "LightComponent.h" +#include "CameraComponent.h" +#include "MeshComponent.h" +#include "ModelComponent.h" +#include "QuakeMap.h" +#include "RigidbodyComponent.h" +#include "SphereCollider.h" +#include "MeshCollider.h" +#include "NativeScriptComponent.h" +#include "CharacterControllerComponent.h" +#include "ParentComponent.h" +#include "NameComponent.h" +#include +#include "../Entities/Entity.h" + + +// TODO: include components here. + + diff --git a/Nuake/src/Scene/Entities/Components/InterfaceComponent.h b/Nuake/src/Scene/Components/InterfaceComponent.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/InterfaceComponent.h rename to Nuake/src/Scene/Components/InterfaceComponent.h diff --git a/Nuake/src/Scene/Entities/Components/LightComponent.cpp b/Nuake/src/Scene/Components/LightComponent.cpp similarity index 98% rename from Nuake/src/Scene/Entities/Components/LightComponent.cpp rename to Nuake/src/Scene/Components/LightComponent.cpp index 1527b54f..5dff8ed4 100644 --- a/Nuake/src/Scene/Entities/Components/LightComponent.cpp +++ b/Nuake/src/Scene/Components/LightComponent.cpp @@ -2,9 +2,10 @@ //#include #include "LightComponent.h" #include "../../../Rendering/Renderer.h" -#include "../ImGuiHelper.h" + #include #include "../Core/Core.h" +#include LightComponent::LightComponent() { Color = glm::vec3(1, 1, 1); diff --git a/Nuake/src/Scene/Components/LightComponent.h b/Nuake/src/Scene/Components/LightComponent.h new file mode 100644 index 00000000..fa276875 --- /dev/null +++ b/Nuake/src/Scene/Components/LightComponent.h @@ -0,0 +1,196 @@ +#pragma once +#include +#include +#include "TransformComponent.h" +#include "../Rendering/Camera.h" +#include "../Rendering/Framebuffer.h" +#include "BaseComponent.h" +#include "../Resource/Serializable.h" + +enum LightType { + Directional, Point, Spot +}; + +class LightComponent { + +public: + glm::vec2 yes = glm::vec2(2, 2); + + LightType Type = Point; + glm::vec3 Direction = glm::vec3(0, -1, 0); + glm::vec3 Color; + bool IsVolumetric = false; + float Strength; + bool SyncDirectionWithSky = false; + Ref m_Framebuffer; + + bool CastShadows = true; + float Attenuation = 0.0f; + float LinearAttenuation = 0.0f; + float QuadraticAttenuation = 0.0f; + + LightComponent(); + + glm::mat4 GetProjection(); + + glm::mat4 GetLightTransform(); + void SetDirection(glm::vec3 dir); + glm::vec3 GetDirection(); + + void BeginDrawShadow(); + + void EndDrawShadow(); + void DrawShadow(); + + void Draw(TransformComponent transformComponent, Ref cam); + void DrawDeferred(TransformComponent transformComponent, Camera* cam); + void DrawEditor(); + + void SetType(LightType type); + + std::vector mCascadeSplits; + void CalculateViewProjection(glm::mat4& view, const glm::mat4& projection, const glm::vec3& normalizedDirection) + { + glm::mat4 viewProjection = projection * view; + glm::mat4 inverseViewProjection = glm::inverse(viewProjection); + + // TODO: Automate this + const float nearClip = 0.1f; + const float farClip = 1000.0f; + const float clipRange = farClip - nearClip; + + // Calculate the optimal cascade distances + const float minZ = nearClip; + const float maxZ = nearClip + clipRange; + const float range = maxZ - minZ; + const float ratio = maxZ / minZ; + for (int i = 0; i < 4; i++) + { + const float p = (i + 1) / static_cast(4); + const float log = minZ * glm::pow(ratio, p); + const float uniform = minZ + range * p; + //const float d = 0.91f * (log - uniform) + uniform; + //mCascadeSplits[i] = (d - nearClip) / clipRange; + } + + //mCascadeSplits[0] = 0.2f; + //mCascadeSplits[1] = 0.45f; + //mCascadeSplits[2] = 1.0f; + + float lastSplitDist = 0.0f; + // Calculate Orthographic Projection matrix for each cascade + for (int cascade = 0; cascade < 4; cascade++) + { + float splitDist = mCascadeSplits[cascade]; + glm::vec4 frustumCorners[8] = + { + //Near face + { 1.0f, 1.0f, -1.0f, 1.0f }, + { -1.0f, 1.0f, -1.0f, 1.0f }, + { 1.0f, -1.0f, -1.0f, 1.0f }, + { -1.0f, -1.0f, -1.0f, 1.0f }, + + //Far face + { 1.0f, 1.0f, 1.0f, 1.0f }, + { -1.0f, 1.0f, 1.0f, 1.0f }, + { 1.0f, -1.0f, 1.0f, 1.0f }, + { -1.0f, -1.0f, 1.0f, 1.0f }, + }; + + // Project frustum corners into world space from clip space + for (int i = 0; i < 8; i++) + { + glm::vec4 invCorner = inverseViewProjection * frustumCorners[i]; + frustumCorners[i] = invCorner / invCorner.w; + } + for (int i = 0; i < 4; i++) + { + glm::vec4 dist = frustumCorners[i + 4] - frustumCorners[i]; + frustumCorners[i + 4] = frustumCorners[i] + (dist * splitDist); + frustumCorners[i] = frustumCorners[i] + (dist * lastSplitDist); + } + + // Get frustum center + glm::vec3 frustumCenter = glm::vec3(0.0f); + for (int i = 0; i < 8; i++) + frustumCenter += glm::vec3(frustumCorners[i]); + frustumCenter /= 8.0f; + + // Get the minimum and maximum extents + float radius = 0.0f; + for (int i = 0; i < 8; i++) + { + float distance = glm::length(glm::vec3(frustumCorners[i]) - frustumCenter); + radius = glm::max(radius, distance); + } + radius = std::ceil(radius * 16.0f) / 16.0f; + glm::vec3 maxExtents = glm::vec3(radius); + glm::vec3 minExtents = -maxExtents; + + // Calculate the view and projection matrix + glm::vec3 lightDir = -normalizedDirection; + glm::mat4 lightViewMatrix = glm::lookAt(frustumCenter - lightDir * -minExtents.z, frustumCenter, glm::vec3(0.0f, 0.0f, 1.0f)); + //glm::mat4 lightProjectionMatrix = glm::ortho(minExtents.x, maxExtents.x, minExtents.y, maxExtents.y, 0.0f + mCascadeNearPlaneOffset, maxExtents.z - minExtents.z + mCascadeFarPlaneOffset); + + // Offset to texel space to avoid shimmering ->(https://stackoverflow.com/questions/33499053/cascaded-shadow-map-shimmering) + //glm::mat4 shadowMatrix = lightProjectionMatrix * lightViewMatrix; + const float ShadowMapResolution = 4096; + //glm::vec4 shadowOrigin = (shadowMatrix * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)) * ShadowMapResolution / 2.0f; + //glm::vec4 roundedOrigin = glm::round(shadowOrigin); + //glm::vec4 roundOffset = roundedOrigin - shadowOrigin; + //roundOffset = roundOffset * 2.0f / ShadowMapResolution; + //roundOffset.z = 0.0f; + //roundOffset.w = 0.0f; + //lightProjectionMatrix[3] += roundOffset; + + // Store SplitDistance and ViewProjection-Matrix + //mCascadeSplitDepth[cascade] = (nearClip + splitDist * clipRange) * 1.0f; + //mViewProjections[cascade] = lightProjectionMatrix * lightViewMatrix; + lastSplitDist = mCascadeSplits[cascade]; + + // -----------------------Debug only----------------------- + // RendererDebug::BeginScene(viewProjection); + // RendererDebug::SubmitCameraFrustum(frustumCorners, glm::mat4(1.0f), GetColor(cascade)); // Draws the divided camera frustums + // RendererDebug::SubmitLine(glm::vec3(0.0f, 0.0f, 0.0f), frustumCenter, GetColor(cascade)); // Draws the center of the frustum (A line pointing from origin to the center) + // RendererDebug::EndScene(); + } + } + + + json Serialize() + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(Type); + SERIALIZE_VEC3(Direction); + SERIALIZE_VEC3(Color); + SERIALIZE_VAL(IsVolumetric); + SERIALIZE_VAL(Strength); + SERIALIZE_VAL(SyncDirectionWithSky); + SERIALIZE_VAL(CastShadows); + END_SERIALIZE(); + } + + bool Deserialize(std::string str) + { + BEGIN_DESERIALIZE(); + if (j.contains("Type")) + Type = (LightType)j["Type"]; + if (j.contains("IsVolumetric")) + IsVolumetric = j["IsVolumetric"]; + if (j.contains("Strength")) + Strength = j["Strength"]; + if (j.contains("SyncDirectionWithSky")) + SyncDirectionWithSky = j["SyncDirectionWithSky"]; + if (j.contains("CastShadows")) + SyncDirectionWithSky = j["CastShadows"]; + if (j.contains("Direction")) + { + float x = j["Direction"]["x"]; + float y = j["Direction"]["y"]; + float z = j["Direction"]["z"]; + this->Direction = Vector3(x, y, z); + } + + return true; + } +}; \ No newline at end of file diff --git a/Nuake/src/Scene/Entities/Components/LuaScriptComponent.h b/Nuake/src/Scene/Components/LuaScriptComponent.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/LuaScriptComponent.h rename to Nuake/src/Scene/Components/LuaScriptComponent.h diff --git a/Nuake/src/Scene/Entities/Components/MeshCollider.h b/Nuake/src/Scene/Components/MeshCollider.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/MeshCollider.h rename to Nuake/src/Scene/Components/MeshCollider.h diff --git a/Nuake/src/Scene/Entities/Components/MeshComponent.cpp b/Nuake/src/Scene/Components/MeshComponent.cpp similarity index 100% rename from Nuake/src/Scene/Entities/Components/MeshComponent.cpp rename to Nuake/src/Scene/Components/MeshComponent.cpp diff --git a/Nuake/src/Scene/Entities/Components/MeshComponent.h b/Nuake/src/Scene/Components/MeshComponent.h similarity index 90% rename from Nuake/src/Scene/Entities/Components/MeshComponent.h rename to Nuake/src/Scene/Components/MeshComponent.h index e225f923..58586084 100644 --- a/Nuake/src/Scene/Entities/Components/MeshComponent.h +++ b/Nuake/src/Scene/Components/MeshComponent.h @@ -1,5 +1,5 @@ #pragma once -#include "../../../Rendering/Textures/Material.h" +#include "../Rendering/Textures/Material.h" #include #include "BaseComponent.h" diff --git a/Nuake/src/Scene/Entities/Components/ModelComponent.cpp b/Nuake/src/Scene/Components/ModelComponent.cpp similarity index 100% rename from Nuake/src/Scene/Entities/Components/ModelComponent.cpp rename to Nuake/src/Scene/Components/ModelComponent.cpp diff --git a/Nuake/src/Scene/Entities/Components/ModelComponent.h b/Nuake/src/Scene/Components/ModelComponent.h similarity index 93% rename from Nuake/src/Scene/Entities/Components/ModelComponent.h rename to Nuake/src/Scene/Components/ModelComponent.h index 0d1262b6..fbb46e1c 100644 --- a/Nuake/src/Scene/Entities/Components/ModelComponent.h +++ b/Nuake/src/Scene/Components/ModelComponent.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "../../../Rendering/Mesh/Mesh.h" +#include "../Rendering/Mesh/Mesh.h" #include "assimp/Importer.hpp" #include diff --git a/Nuake/src/Scene/Entities/Components/NameComponent.h b/Nuake/src/Scene/Components/NameComponent.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/NameComponent.h rename to Nuake/src/Scene/Components/NameComponent.h diff --git a/Nuake/src/Scene/Entities/Components/NativeScriptComponent.h b/Nuake/src/Scene/Components/NativeScriptComponent.h similarity index 91% rename from Nuake/src/Scene/Entities/Components/NativeScriptComponent.h rename to Nuake/src/Scene/Components/NativeScriptComponent.h index 507b33df..a1fbc8d8 100644 --- a/Nuake/src/Scene/Entities/Components/NativeScriptComponent.h +++ b/Nuake/src/Scene/Components/NativeScriptComponent.h @@ -1,7 +1,7 @@ #pragma once #include #include "../Core/Timestep.h" -#include "../ScriptableEntity.h" +#include "../Entities/ScriptableEntity.h" struct NativeScriptComponent { ScriptableEntity* Instance = nullptr; diff --git a/Nuake/src/Scene/Entities/Components/ParentComponent.h b/Nuake/src/Scene/Components/ParentComponent.h similarity index 91% rename from Nuake/src/Scene/Entities/Components/ParentComponent.h rename to Nuake/src/Scene/Components/ParentComponent.h index 45bbbf87..667588c7 100644 --- a/Nuake/src/Scene/Entities/Components/ParentComponent.h +++ b/Nuake/src/Scene/Components/ParentComponent.h @@ -1,6 +1,6 @@ #pragma once -#include "../Entity.h" +#include "../Entities/Entity.h" struct ParentComponent { diff --git a/Nuake/src/Scene/Entities/Components/QuakeMap.cpp b/Nuake/src/Scene/Components/QuakeMap.cpp similarity index 100% rename from Nuake/src/Scene/Entities/Components/QuakeMap.cpp rename to Nuake/src/Scene/Components/QuakeMap.cpp diff --git a/Nuake/src/Scene/Entities/Components/QuakeMap.h b/Nuake/src/Scene/Components/QuakeMap.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/QuakeMap.h rename to Nuake/src/Scene/Components/QuakeMap.h diff --git a/Nuake/src/Scene/Entities/Components/RigidbodyComponent.cpp b/Nuake/src/Scene/Components/RigidbodyComponent.cpp similarity index 100% rename from Nuake/src/Scene/Entities/Components/RigidbodyComponent.cpp rename to Nuake/src/Scene/Components/RigidbodyComponent.cpp diff --git a/Nuake/src/Scene/Entities/Components/RigidbodyComponent.h b/Nuake/src/Scene/Components/RigidbodyComponent.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/RigidbodyComponent.h rename to Nuake/src/Scene/Components/RigidbodyComponent.h diff --git a/Nuake/src/Scene/Entities/Components/SphereCollider.h b/Nuake/src/Scene/Components/SphereCollider.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/SphereCollider.h rename to Nuake/src/Scene/Components/SphereCollider.h diff --git a/Nuake/src/Scene/Entities/Components/TransformComponent.cpp b/Nuake/src/Scene/Components/TransformComponent.cpp similarity index 100% rename from Nuake/src/Scene/Entities/Components/TransformComponent.cpp rename to Nuake/src/Scene/Components/TransformComponent.cpp diff --git a/Nuake/src/Scene/Entities/Components/TransformComponent.h b/Nuake/src/Scene/Components/TransformComponent.h similarity index 100% rename from Nuake/src/Scene/Entities/Components/TransformComponent.h rename to Nuake/src/Scene/Components/TransformComponent.h diff --git a/Nuake/src/Scene/Entities/Components/WrenScriptComponent.h b/Nuake/src/Scene/Components/WrenScriptComponent.h similarity index 91% rename from Nuake/src/Scene/Entities/Components/WrenScriptComponent.h rename to Nuake/src/Scene/Components/WrenScriptComponent.h index 0dab3666..e5687cbf 100644 --- a/Nuake/src/Scene/Entities/Components/WrenScriptComponent.h +++ b/Nuake/src/Scene/Components/WrenScriptComponent.h @@ -1,5 +1,6 @@ #pragma once #include "../Scripting/WrenScript.h" +#include class WrenScriptComponent { diff --git a/Nuake/src/Scene/Entities/Components.h b/Nuake/src/Scene/Entities/Components.h deleted file mode 100644 index 7608a496..00000000 --- a/Nuake/src/Scene/Entities/Components.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include -#include "Components/BaseComponent.h" -#include "Components/TransformComponent.h" -#include "Components/LightComponent.h" -#include "Components/CameraComponent.h" -#include "Components/MeshComponent.h" -#include "Components/ModelComponent.h" -#include "Components/QuakeMap.h" -#include "Components/RigidbodyComponent.h" -#include "Components/SphereCollider.h" -#include "Components/MeshCollider.h" -#include "Components/NativeScriptComponent.h" -#include "Components/CharacterControllerComponent.h" -#include "Components/ParentComponent.h" -#include "Components/NameComponent.h" -#include -#include "Entity.h" - - -// TODO: include components here. - - diff --git a/Nuake/src/Scene/Entities/Components/BaseComponent.h b/Nuake/src/Scene/Entities/Components/BaseComponent.h deleted file mode 100644 index 4483a1db..00000000 --- a/Nuake/src/Scene/Entities/Components/BaseComponent.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -#include "../Entity.h" diff --git a/Nuake/src/Scene/Entities/Components/LightComponent.h b/Nuake/src/Scene/Entities/Components/LightComponent.h deleted file mode 100644 index 313d5a66..00000000 --- a/Nuake/src/Scene/Entities/Components/LightComponent.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once -#include -#include -#include "TransformComponent.h" -#include "../Rendering/Camera.h" -#include "../../../Rendering/Framebuffer.h" -#include "BaseComponent.h" -#include "../Resource/Serializable.h" - -enum LightType { - Directional, Point, Spot -}; - -class LightComponent { - -public: - glm::vec2 yes = glm::vec2(2, 2); - - LightType Type = Point; - glm::vec3 Direction = glm::vec3(0, -1, 0); - glm::vec3 Color; - bool IsVolumetric = false; - float Strength; - bool SyncDirectionWithSky = false; - Ref m_Framebuffer; - - bool CastShadows = true; - float Attenuation = 0.0f; - float LinearAttenuation = 0.0f; - float QuadraticAttenuation = 0.0f; - - LightComponent(); - - glm::mat4 GetProjection(); - - glm::mat4 GetLightTransform(); - void SetDirection(glm::vec3 dir); - glm::vec3 GetDirection(); - - void BeginDrawShadow(); - - void EndDrawShadow(); - void DrawShadow(); - - void Draw(TransformComponent transformComponent, Ref cam); - void DrawDeferred(TransformComponent transformComponent, Camera* cam); - void DrawEditor(); - - void SetType(LightType type); - - - json Serialize() - { - BEGIN_SERIALIZE(); - SERIALIZE_VAL(Type); - SERIALIZE_VEC3(Direction); - SERIALIZE_VEC3(Color); - SERIALIZE_VAL(IsVolumetric); - SERIALIZE_VAL(Strength); - SERIALIZE_VAL(SyncDirectionWithSky); - SERIALIZE_VAL(CastShadows); - END_SERIALIZE(); - } - - bool Deserialize(std::string str) - { - BEGIN_DESERIALIZE(); - if (j.contains("Type")) - Type = (LightType)j["Type"]; - if (j.contains("IsVolumetric")) - IsVolumetric = j["IsVolumetric"]; - if (j.contains("Strength")) - Strength = j["Strength"]; - if (j.contains("SyncDirectionWithSky")) - SyncDirectionWithSky = j["SyncDirectionWithSky"]; - if (j.contains("CastShadows")) - SyncDirectionWithSky = j["CastShadows"]; - if (j.contains("Direction")) - { - float x = j["Direction"]["x"]; - float y = j["Direction"]["y"]; - float z = j["Direction"]["z"]; - this->Direction = Vector3(x, y, z); - } - - return true; - } -}; \ No newline at end of file diff --git a/Nuake/src/Scene/Entities/Entity.cpp b/Nuake/src/Scene/Entities/Entity.cpp index c93529a2..7719bff2 100644 --- a/Nuake/src/Scene/Entities/Entity.cpp +++ b/Nuake/src/Scene/Entities/Entity.cpp @@ -1,15 +1,15 @@ -#include "Components/ParentComponent.h" +#include "../Components/ParentComponent.h" #include "Entity.h" -#include "Components/NameComponent.h" -#include "Components/TransformComponent.h" -#include "Components/CameraComponent.h" -#include "Components/QuakeMap.h" -#include "Components/LightComponent.h" -#include "Components/QuakeMap.h" -#include -#include +#include "../Components/NameComponent.h" +#include "../Components/TransformComponent.h" +#include "../Components/CameraComponent.h" +#include "../Components/QuakeMap.h" +#include "../Components/LightComponent.h" +#include "../Components/QuakeMap.h" +#include "../Components/WrenScriptComponent.h" +#include "../Components/CharacterControllerComponent.h" void Entity::AddChild(Entity ent) { if ((int)m_EntityHandle != ent.GetHandle()) diff --git a/Nuake/src/Scene/Entities/Entity.h b/Nuake/src/Scene/Entities/Entity.h index 5a621a6f..6b0c9ed9 100644 --- a/Nuake/src/Scene/Entities/Entity.h +++ b/Nuake/src/Scene/Entities/Entity.h @@ -2,7 +2,7 @@ #include #include #include "../Scene.h" -#include "Components/BaseComponent.h" +#include "../Components/BaseComponent.h" #include "../Resource/Serializable.h" class Entity : public ISerializable diff --git a/Nuake/src/Scene/Entities/ScriptableEntity.h b/Nuake/src/Scene/Entities/ScriptableEntity.h index 64df2995..1877740c 100644 --- a/Nuake/src/Scene/Entities/ScriptableEntity.h +++ b/Nuake/src/Scene/Entities/ScriptableEntity.h @@ -1,8 +1,8 @@ #pragma once #include "Entity.h" -#include "../Scene/Entities/Components/ParentComponent.h" -#include "../Scene/Entities/Components/NameComponent.h" +#include "../Components/ParentComponent.h" +#include "../Components/NameComponent.h" class ScriptableEntity { diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index 990749de..608e2eaa 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -1,19 +1,27 @@ #pragma once +#include +#include #include "Scene.h" #include "Entities/Entity.h" -#include "Entities/Components.h" + #include "../Rendering/Renderer.h" #include "../Core/MaterialManager.h" #include "../Core/Physics/PhysicsManager.h" #include "../Core/Core.h" + #include -#include "Entities/Components/BoxCollider.h" + #include "../../Engine.h" #include "../Core/FileSystem.h" -#include "../Scene/Entities/Components/LuaScriptComponent.h" +#include "Components/Components.h" +#include "Components/BoxCollider.h" +#include "Components/LuaScriptComponent.h" +#include "Components/WrenScriptComponent.h" + #include #include -#include "../Scene/Entities/Components/WrenScriptComponent.h" + + Ref Scene::New() { return CreateRef(); @@ -21,9 +29,14 @@ Ref Scene::New() Scene::Scene() { + m_Systems = std::vector>(); m_EditorCamera = CreateRef(); m_Environement = CreateRef(); m_Interfaces = std::vector>(); + + // Adding systems + m_Systems.push_back(CreateRef(this)); + m_Systems.push_back(CreateRef(this)); } Scene::~Scene() {} @@ -37,155 +50,41 @@ bool Scene::SetName(std::string& newName) { if (newName == "") return false; - + this->Name = newName; return true; } void Scene::OnInit() { - ScriptingEngine::Init(); - - // Create physic world. - auto view = m_Registry.view(); - for (auto e : view) - { - auto [transform, rigidbody] = view.get(e); - - Entity ent = Entity({ e, this }); - - if (ent.HasComponent()) - { - float mass = rigidbody.mass; - - BoxColliderComponent& boxComponent = ent.GetComponent(); - Ref boxShape = CreateRef(boxComponent.Size); - - Ref btRigidbody = CreateRef(mass, transform.Translation, boxShape); - rigidbody.m_Rigidbody = btRigidbody; - - btRigidbody->SetKinematic(rigidbody.IsKinematic); - - PhysicsManager::Get()->RegisterBody(btRigidbody); - } - } - - // character controllers - auto ccview = m_Registry.view(); - for (auto e : ccview) - { - auto [transform, cc] = ccview.get(e); - - cc.CharacterController = CreateRef(cc.Height, cc.Radius, cc.Mass, transform.Translation); - Entity ent = Entity({ e, this }); - - PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController); - } - - auto quakeMapview = m_Registry.view(); - for (auto e : quakeMapview) - { - auto [transform, quake] = quakeMapview.get(e); - - if (quake.HasCollisions) - { - for (auto m : quake.m_Meshes) - { - Ref meshShape = CreateRef(m); - Ref btRigidbody = CreateRef(0.0f, transform.Translation, meshShape); - PhysicsManager::Get()->RegisterBody(btRigidbody); - } - } - } - - // Instanciate scripts. - { - auto entities = m_Registry.view(); - for (auto& e : entities) - { - WrenScriptComponent& wren = entities.get(e); - if (wren.Script != "" && wren.Class != "") - wren.WrenScript = CreateRef(wren.Script, wren.Class, true); - - if (wren.WrenScript != nullptr) - { - wren.WrenScript->SetScriptableEntityID((int)e); - wren.WrenScript->CallInit(); - } - } - } + for (auto& system : m_Systems) + system->Init(); } void Scene::OnExit() { - PhysicsManager::Get()->Reset(); - - // destroy scripts. - auto entities = m_Registry.view(); - for (auto& e : entities) - { - WrenScriptComponent& wren = entities.get(e); - - if (wren.WrenScript != nullptr) - { - wren.WrenScript->CallExit(); - - - } - - } - - ScriptingEngine::Close(); + for (auto& system : m_Systems) + system->Exit(); } -// update entities and some components. void Scene::Update(Timestep ts) { - // Update scripts - { - m_Registry.view().each([=](auto entity, auto& nsc) - { - nsc.Instance->OnUpdate(ts); - }); - } - - // destroy scripts. - auto entities = m_Registry.view(); - for (auto& e : entities) - { - WrenScriptComponent& wren = entities.get(e); - - if (wren.WrenScript != nullptr) - wren.WrenScript->CallUpdate(ts); - } - - // Update rigidbodies - PhysicsManager::Get()->Step(ts); - - auto physicGroup = m_Registry.view(); - for (auto e : physicGroup) { - auto [transform, rb] = physicGroup.get(e); - rb.SyncTransformComponent(&m_Registry.get(e)); - } - - auto ccGroup = m_Registry.view(); - for (auto e : ccGroup) { - auto [transform, rb] = ccGroup.get(e); - rb.SyncWithTransform(m_Registry.get(e)); - } - - + for (auto& system : m_Systems) + system->Update(ts); } +void Scene::FixedUpdate(Timestep ts) +{ + for (auto& system : m_Systems) + system->FixedUpdate(ts); +} void Scene::EditorUpdate(Timestep ts) { m_EditorCamera->Update(ts); - + for (auto i : m_Interfaces) - { i->Update(ts); - } } @@ -194,7 +93,7 @@ void Scene::DrawShadows() auto modelView = m_Registry.view(); auto quakeView = m_Registry.view(); auto view = m_Registry.view(); - + Ref cam = nullptr; if (Engine::IsPlayMode) { @@ -209,9 +108,9 @@ void Scene::DrawShadows() { cam = m_EditorCamera; } - + glm::mat4 perspective = cam->GetPerspective(); - + for (auto l : view) { auto [lightTransform, light] = view.get(l); if (light.Type != LightType::Directional) @@ -229,16 +128,16 @@ void Scene::DrawShadows() model.Draw(); } - + for (auto e : quakeView) { auto [transform, model] = quakeView.get(e); - + glm::vec3 pos = lightTransform.Translation; glm::mat4 lightView = glm::lookAt(pos, pos - light.GetDirection(), glm::vec3(0.0f, 1.0f, 0.0f)); - + Renderer::m_ShadowmapShader->SetUniformMat4f("lightSpaceMatrix", light.GetProjection() * lightView); Renderer::m_ShadowmapShader->SetUniformMat4f("model", transform.GetTransform()); - + model.Draw(); } light.EndDrawShadow(); @@ -262,22 +161,22 @@ void Scene::Draw() auto view = m_Registry.view(); for (auto e : view) { auto [transform, camera, parent] = view.get(e); - + TransformComponent copyT = transform; if (parent.HasParent) { Entity currentParent = Entity{ e, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; } - + copyT.Translation = globalOffset; } - + cam = camera.CameraInstance; cam->Translation = copyT.Translation; break; @@ -285,52 +184,52 @@ void Scene::Draw() } glDisable(GL_DEPTH_TEST); Ref env = GetEnvironment(); - + if (env->ProceduralSkybox) { env->ProceduralSkybox->Draw(cam); - + } Renderer::m_Shader->Bind(); env->Push(); glEnable(GL_DEPTH_TEST); - + // Push lights { auto view = m_Registry.view(); for (auto l : view) { auto [transform, light, parent] = view.get(l); - + TransformComponent copyT = transform; if (parent.HasParent) { Entity currentParent = Entity{ l, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; - + } - + copyT.Translation = globalOffset; } - + if (light.SyncDirectionWithSky) light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); - + light.Draw(copyT, m_EditorCamera); } } - + Renderer::m_Shader->Bind(); Renderer::m_Shader->SetUniform3f("u_EyePosition", cam->GetTranslation().x, cam->GetTranslation().y, cam->GetTranslation().z); Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0); if (cam) { Renderer::m_Shader->SetUniform1f("u_Exposure", cam->Exposure); - + auto view = m_Registry.view(); for (auto e : view) { auto [transform, model, parent] = view.get(e); @@ -339,39 +238,39 @@ void Scene::Draw() { Entity currentParent = Entity{ e, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; } - + copyT.Translation = globalOffset; } - + Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform()); Renderer::m_Shader->SetUniformMat4f("u_Projection", cam->GetPerspective()); Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform()); model.Draw(); } - + auto quakeView = m_Registry.view(); for (auto e : quakeView) { auto [transform, model, parent] = quakeView.get(e); - + TransformComponent copyT = transform; if (parent.HasParent) { Entity currentParent = Entity{ e, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; } - + copyT.Translation = globalOffset; } Renderer::m_Shader->SetUniformMat4f("u_View", cam->GetTransform()); @@ -379,12 +278,12 @@ void Scene::Draw() Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform()); model.Draw(); } - + Renderer::m_DebugShader->SetUniformMat4f("u_View", cam->GetTransform()); Renderer::m_DebugShader->SetUniformMat4f("u_Projection", cam->GetPerspective()); PhysicsManager::Get()->DrawDebug(); } - + } @@ -392,16 +291,16 @@ void Scene::EditorDraw() { glDisable(GL_DEPTH_TEST); Ref env = GetEnvironment(); - + if (env->ProceduralSkybox) { env->ProceduralSkybox->Draw(m_EditorCamera); } - + Renderer::m_Shader->Bind(); env->Push(); glEnable(GL_DEPTH_TEST); - + // Push lights { auto view = m_Registry.view(); @@ -413,23 +312,23 @@ void Scene::EditorDraw() { Entity currentParent = Entity{ l, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; } - + copyT.Translation = globalOffset; } - + if (light.SyncDirectionWithSky) light.Direction = GetEnvironment()->ProceduralSkybox->GetSunDirection(); - + light.Draw(copyT, m_EditorCamera); } } - + Renderer::m_Shader->Bind(); Renderer::m_Shader->SetUniform1i("u_ShowNormal", 0); if (m_EditorCamera) @@ -439,74 +338,74 @@ void Scene::EditorDraw() auto view = m_Registry.view(); for (auto e : view) { auto [transform, model, parent] = view.get(e); - + TransformComponent copyT = transform; if (parent.HasParent) { Entity currentParent = Entity{ e, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; } - + copyT.Translation = globalOffset; } - + Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform()); model.Draw(); } - + auto quakeView = m_Registry.view(); for (auto e : quakeView) { auto [transform, model, parent] = quakeView.get(e); - - + + TransformComponent copyT = transform; if (parent.HasParent) { Entity currentParent = Entity{ e, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; } - + copyT.Translation = globalOffset; } Renderer::m_Shader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); Renderer::m_Shader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); - + Renderer::m_Shader->SetUniformMat4f("u_Model", copyT.GetTransform()); model.Draw(); } - + auto boxCollider = m_Registry.view(); for (auto e : boxCollider) { auto [transform, box, parent] = boxCollider.get(e); - + TransformComponent copyT = transform; if (parent.HasParent) { Entity currentParent = Entity{ e, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; - + } - + copyT.Translation = globalOffset; } - + Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); Renderer::m_DebugShader->SetUniformMat4f("u_Model", copyT.GetTransform()); @@ -515,31 +414,31 @@ void Scene::EditorDraw() t.Scale = (box.Size * 2.f) * transform.Scale; Renderer::DrawCube(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f)); } - + auto sphereCollider = m_Registry.view(); for (auto e : sphereCollider) { auto [transform, box, parent] = sphereCollider.get(e); - + TransformComponent copyT = transform; if (parent.HasParent) { Entity currentParent = Entity{ e, this }; glm::vec3 globalOffset = copyT.Translation; - + while (currentParent.GetComponent().HasParent) { currentParent = currentParent.GetComponent().Parent; globalOffset += currentParent.GetComponent().Translation; - + } - + copyT.Translation = globalOffset; } - + Renderer::m_DebugShader->SetUniformMat4f("u_View", m_EditorCamera->GetTransform()); Renderer::m_DebugShader->SetUniformMat4f("u_Projection", m_EditorCamera->GetPerspective()); Renderer::m_DebugShader->SetUniformMat4f("u_Model", transform.GetTransform()); - + TransformComponent t = transform; t.Scale = (box.Radius * 2.f) * transform.Scale; Renderer::DrawSphere(t, glm::vec4(0.0f, 0.0f, 0.9f, 0.2f)); @@ -565,7 +464,7 @@ glm::vec3 Scene::GetGlobalPosition(Entity ent) globalPos += currentParent.GetComponent().Translation; currentParent = currentParent.GetComponent().Parent; } - + return globalPos; } @@ -594,9 +493,9 @@ Entity Scene::CreateEntity(const std::string& name) { NameComponent& nameComponent = entity.AddComponent(); nameComponent.Name = name; - + ParentComponent& parentComponent = entity.AddComponent(); - + Logger::Log("Created entity: " + nameComponent.Name + "\n"); return entity; } @@ -623,7 +522,7 @@ Ref Scene::GetCurrentCamera() cam = m_EditorCamera; return cam; } - + return m_EditorCamera; } @@ -635,7 +534,7 @@ bool Scene::Save() { if (Path == "") Path = FileSystem::AbsoluteToRelative(FileDialog::SaveFile("*.scene") + ".scene"); - + return SaveAs(Path); } @@ -645,7 +544,7 @@ bool Scene::SaveAs(const std::string& path) sceneFile.open(FileSystem::Root + path); sceneFile << Serialize().dump(4); sceneFile.close(); - + Logger::Log("Scene saved successfully"); return true; } @@ -667,12 +566,12 @@ void Scene::AddInterface(Ref interface) json Scene::Serialize() { BEGIN_SERIALIZE(); - SERIALIZE_VAL(Name); - SERIALIZE_OBJECT(m_Environement) + SERIALIZE_VAL(Name); + SERIALIZE_OBJECT(m_Environement) std::vector entities = std::vector(); - for (Entity e : GetAllEntities()) - entities.push_back(e.Serialize()); - SERIALIZE_VAL_LBL("Entities", entities); + for (Entity e : GetAllEntities()) + entities.push_back(e.Serialize()); + SERIALIZE_VAL_LBL("Entities", entities); END_SERIALIZE(); } @@ -681,13 +580,13 @@ bool Scene::Deserialize(const std::string& str) { if (str == "") return false; - + BEGIN_DESERIALIZE(); if (!j.contains("Name")) return false; - + Name = j["Name"]; - + m_Environement = CreateRef(); if (j.contains("m_Environement")) { @@ -695,7 +594,7 @@ bool Scene::Deserialize(const std::string& str) std::string env = j["m_Environement"].dump(); m_Environement->Deserialize(env); } - + // Parse entities { if (j.contains("Entities")) @@ -708,6 +607,6 @@ bool Scene::Deserialize(const std::string& str) } } } - + return true; } diff --git a/Nuake/src/Scene/Scene.h b/Nuake/src/Scene/Scene.h index 83f0bb42..1b8ae0ff 100644 --- a/Nuake/src/Scene/Scene.h +++ b/Nuake/src/Scene/Scene.h @@ -11,7 +11,9 @@ #include "../Resource/Serializable.h" #include "src/UI/UserInterface.h" #include "../Core/Maths.h" +#include class Entity; + class Scene : public ISerializable { friend Entity; @@ -20,12 +22,13 @@ private: std::string Name; bool has_changed = true; + std::vector> m_Systems; - entt::registry m_Registry; Ref m_Environement; Ref m_EditorCamera; public: + entt::registry m_Registry; std::vector> m_Interfaces; std::string Path = ""; static Ref New(); @@ -40,6 +43,7 @@ public: void OnInit(); void OnExit(); void Update(Timestep ts); + void FixedUpdate(Timestep ts); void EditorUpdate(Timestep ts); // TODO: Maybe move this to Renderer::DrawScene() ? diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.cpp b/Nuake/src/Scene/Systems/PhysicsSystem.cpp new file mode 100644 index 00000000..1412f072 --- /dev/null +++ b/Nuake/src/Scene/Systems/PhysicsSystem.cpp @@ -0,0 +1,98 @@ +#include "PhysicsSystem.h" +#include "src/Scene/Scene.h" +#include "src/Scene/Components/BoxCollider.h" + +#include +#include "src/Scene/Entities/Entity.h" +#include +#include +#include +PhysicsSystem::PhysicsSystem(Scene* scene) +{ + m_Scene = scene; +} + +void PhysicsSystem::Init() +{ + // Create physic world. + auto view = m_Scene->m_Registry.view(); + for (auto e : view) + { + auto [transform, rigidbody] = view.get(e); + + Entity ent = Entity({ e, m_Scene }); + + if (ent.HasComponent()) + { + float mass = rigidbody.mass; + + BoxColliderComponent& boxComponent = ent.GetComponent(); + Ref boxShape = CreateRef(boxComponent.Size); + + Ref btRigidbody = CreateRef(mass, transform.Translation, boxShape); + rigidbody.m_Rigidbody = btRigidbody; + + btRigidbody->SetKinematic(rigidbody.IsKinematic); + + PhysicsManager::Get()->RegisterBody(btRigidbody); + } + } + + // character controllers + auto ccview = m_Scene->m_Registry.view(); + for (auto e : ccview) + { + auto [transform, cc] = ccview.get(e); + + cc.CharacterController = CreateRef(cc.Height, cc.Radius, cc.Mass, transform.Translation); + Entity ent = Entity({ e, m_Scene }); + + PhysicsManager::Get()->RegisterCharacterController(cc.CharacterController); + } + + auto quakeMapview = m_Scene->m_Registry.view(); + for (auto e : quakeMapview) + { + auto [transform, quake] = quakeMapview.get(e); + + if (quake.HasCollisions) + { + for (auto m : quake.m_Meshes) + { + Ref meshShape = CreateRef(m); + Ref btRigidbody = CreateRef(0.0f, transform.Translation, meshShape); + PhysicsManager::Get()->RegisterBody(btRigidbody); + } + } + } + +} + +void PhysicsSystem::Update(Timestep ts) +{ + // Update rigidbodies + PhysicsManager::Get()->Step(ts); + + auto physicGroup = m_Scene->m_Registry.view(); + for (auto e : physicGroup) { + auto [transform, rb] = physicGroup.get(e); + rb.SyncTransformComponent(&m_Scene->m_Registry.get(e)); + } + + auto ccGroup = m_Scene->m_Registry.view(); + for (auto e : ccGroup) { + auto [transform, rb] = ccGroup.get(e); + rb.SyncWithTransform(m_Scene->m_Registry.get(e)); + } +} + +void PhysicsSystem::FixedUpdate(Timestep ts) +{ + +} + +void PhysicsSystem::Exit() +{ + PhysicsManager::Get()->Reset(); + +} \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.h b/Nuake/src/Scene/Systems/PhysicsSystem.h new file mode 100644 index 00000000..a76ca83b --- /dev/null +++ b/Nuake/src/Scene/Systems/PhysicsSystem.h @@ -0,0 +1,12 @@ +#pragma once +#include + +class PhysicsSystem : public System { +public: + PhysicsSystem(Scene* scene); + void Init() override; + void Update(Timestep ts) override; + void Draw() override {} + void FixedUpdate(Timestep ts) override; + void Exit() override; +}; \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/ScriptingSystem.cpp b/Nuake/src/Scene/Systems/ScriptingSystem.cpp new file mode 100644 index 00000000..e8f9182d --- /dev/null +++ b/Nuake/src/Scene/Systems/ScriptingSystem.cpp @@ -0,0 +1,69 @@ +#include "ScriptingSystem.h" +#include +#include "src/Scene/Scene.h" + +ScriptingSystem::ScriptingSystem(Scene* scene) +{ + m_Scene = scene; +} + + +void ScriptingSystem::Init() +{ + ScriptingEngine::Init(); + + auto entities = m_Scene->m_Registry.view(); + for (auto& e : entities) + { + WrenScriptComponent& wren = entities.get(e); + if (wren.Script != "" && wren.Class != "") + wren.WrenScript = CreateRef(wren.Script, wren.Class, true); + + if (wren.WrenScript != nullptr) + { + wren.WrenScript->SetScriptableEntityID((int)e); + wren.WrenScript->CallInit(); + } + } +} + + +void ScriptingSystem::Update(Timestep ts) +{ + auto entities = m_Scene->m_Registry.view(); + for (auto& e : entities) + { + WrenScriptComponent& wren = entities.get(e); + + if (wren.WrenScript != nullptr) + wren.WrenScript->CallUpdate(ts); + } +} + + +void ScriptingSystem::FixedUpdate(Timestep ts) +{ + auto entities = m_Scene->m_Registry.view(); + for (auto& e : entities) + { + WrenScriptComponent& wren = entities.get(e); + + if (wren.WrenScript != nullptr) + wren.WrenScript->CallFixedUpdate(ts); + } +} + + +void ScriptingSystem::Exit() +{ + auto entities = m_Scene->m_Registry.view(); + for (auto& e : entities) + { + WrenScriptComponent& wren = entities.get(e); + + if (wren.WrenScript != nullptr) + wren.WrenScript->CallExit(); + } + + ScriptingEngine::Close(); +} \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/ScriptingSystem.h b/Nuake/src/Scene/Systems/ScriptingSystem.h new file mode 100644 index 00000000..07572319 --- /dev/null +++ b/Nuake/src/Scene/Systems/ScriptingSystem.h @@ -0,0 +1,13 @@ +#pragma once +#include "System.h" + +class Scene; +class ScriptingSystem : public System { +public: + ScriptingSystem(Scene* scene); + void Init() override; + void Update(Timestep ts) override; + void Draw() override {} + void FixedUpdate(Timestep ts) override; + void Exit() override; +}; \ No newline at end of file diff --git a/Nuake/src/Scene/Systems/System.cpp b/Nuake/src/Scene/Systems/System.cpp new file mode 100644 index 00000000..c41b4d39 --- /dev/null +++ b/Nuake/src/Scene/Systems/System.cpp @@ -0,0 +1,2 @@ +#include "System.h" + diff --git a/Nuake/src/Scene/Systems/System.h b/Nuake/src/Scene/Systems/System.h new file mode 100644 index 00000000..e9bd56ad --- /dev/null +++ b/Nuake/src/Scene/Systems/System.h @@ -0,0 +1,19 @@ +#pragma once +#include +#include "src/Core/Core.h" + +class Scene; +class System { +public: + Scene* m_Scene; + + virtual void Init() = 0; + + virtual void Draw() = 0; + + virtual void Update(Timestep ts) = 0; + virtual void FixedUpdate(Timestep ts) = 0; + + virtual void Exit() = 0; + +}; \ No newline at end of file diff --git a/Nuake/src/Scripting/Modules/PhysicsModule.h b/Nuake/src/Scripting/Modules/PhysicsModule.h index 7ebeae48..557484bc 100644 --- a/Nuake/src/Scripting/Modules/PhysicsModule.h +++ b/Nuake/src/Scripting/Modules/PhysicsModule.h @@ -45,9 +45,9 @@ namespace ScriptAPI wrenSetSlotDouble(vm, 5, result.WorldPoint.y); wrenSetSlotDouble(vm, 6, result.WorldPoint.z); - wrenSetSlotDouble(vm, 7, result.Normal.x - result.WorldPoint.x); - wrenSetSlotDouble(vm, 8, result.Normal.y - result.WorldPoint.y); - wrenSetSlotDouble(vm, 9, result.Normal.z - result.WorldPoint.z); + wrenSetSlotDouble(vm, 7, result.Normal.x); + wrenSetSlotDouble(vm, 8, result.Normal.y); + wrenSetSlotDouble(vm, 9, result.Normal.z); wrenInsertInList(vm, 0, -1, 1); wrenInsertInList(vm, 0, -1, 2); diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index 527b8712..6f28c308 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -7,12 +7,13 @@ #include #include "Engine.h" #include "../Scene/Entities/Entity.h" -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include namespace ScriptAPI { @@ -30,8 +31,10 @@ namespace ScriptAPI RegisterMethod("GetEntityID(_)", (void*)GetEntity); RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent); RegisterMethod("GetTranslation_(_)", (void*)GetTranslation); + RegisterMethod("SetTranslation_(_,_,_,_)", (void*)SetTranslation); RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity); RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity); + RegisterMethod("GetScript_(_)", (void*)GetScript); RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection); RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection); RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight); @@ -82,6 +85,20 @@ namespace ScriptAPI bool result = ent.HasComponent(); wrenSetSlotBool(vm, 0, result); } + if (name == "Script") { + bool result = ent.HasComponent(); + wrenSetSlotBool(vm, 0, result); + } + } + + static void GetScript(WrenVM* vm) { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + + if (ent.HasComponent()) + { + wrenSetSlotHandle(vm, 0, ent.GetComponent().WrenScript->m_Instance); + } } static void SetLightIntensity(WrenVM* vm) @@ -198,5 +215,17 @@ namespace ScriptAPI wrenInsertInList(vm, 0, 2, 3); } + static void SetTranslation(WrenVM* vm) + { + int handle = wrenGetSlotDouble(vm, 1); + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& transform = ent.GetComponent(); + // set the slots + float x = wrenGetSlotDouble(vm, 2); + float y = wrenGetSlotDouble(vm, 3); + float z = wrenGetSlotDouble(vm, 4); + transform.Translation = Vector3(x, y, z); + } + }; } \ No newline at end of file diff --git a/Nuake/src/Scripting/WrenScript.cpp b/Nuake/src/Scripting/WrenScript.cpp index 1ddcf480..01b369bf 100644 --- a/Nuake/src/Scripting/WrenScript.cpp +++ b/Nuake/src/Scripting/WrenScript.cpp @@ -27,6 +27,7 @@ WrenScript::WrenScript(const std::string& path, const std::string& mod, bool isE // Create handles to the instance methods. this->m_OnInitHandle = wrenMakeCallHandle(vm, "init()"); this->m_OnUpdateHandle = wrenMakeCallHandle(vm, "update(_)"); + this->m_OnFixedUpdateHandle = wrenMakeCallHandle(vm, "fixedUpdate(_)"); this->m_OnExitHandle = wrenMakeCallHandle(vm, "exit()"); if (isEntity) @@ -49,6 +50,15 @@ void WrenScript::CallUpdate(float timestep) WrenInterpretResult result = wrenCall(vm, this->m_OnUpdateHandle); } +void WrenScript::CallFixedUpdate(float timestep) +{ + WrenVM* vm = ScriptingEngine::GetWrenVM(); + wrenEnsureSlots(vm, 2); + wrenSetSlotHandle(vm, 0, this->m_Instance); + wrenSetSlotDouble(vm, 1, timestep); + WrenInterpretResult result = wrenCall(vm, this->m_OnFixedUpdateHandle); +} + void WrenScript::CallExit() { WrenVM* vm = ScriptingEngine::GetWrenVM(); diff --git a/Nuake/src/Scripting/WrenScript.h b/Nuake/src/Scripting/WrenScript.h index 2ddad9b3..87424069 100644 --- a/Nuake/src/Scripting/WrenScript.h +++ b/Nuake/src/Scripting/WrenScript.h @@ -11,6 +11,7 @@ public: WrenHandle* m_Instance; WrenHandle* m_OnInitHandle; WrenHandle* m_OnUpdateHandle; + WrenHandle* m_OnFixedUpdateHandle; WrenHandle* m_OnExitHandle; WrenHandle* m_SetEntityIDHandle; @@ -18,6 +19,7 @@ public: void CallInit(); void CallUpdate(float timestep); + void CallFixedUpdate(float timestep); void CallExit(); void RegisterMethod(const std::string& signature); diff --git a/Nuake/src/Window.cpp b/Nuake/src/Window.cpp index a8f0d58d..18a12b18 100644 --- a/Nuake/src/Window.cpp +++ b/Nuake/src/Window.cpp @@ -223,6 +223,11 @@ void Window::Update(Timestep ts) m_Scene->Update(ts); } +void Window::FixedUpdate(Timestep ts) +{ + m_Scene->FixedUpdate(ts); +} + void Window::Draw() { // Dont render if no scene is loaded. diff --git a/Nuake/src/Window.h b/Nuake/src/Window.h index e8eacaef..4344e4fc 100644 --- a/Nuake/src/Window.h +++ b/Nuake/src/Window.h @@ -3,7 +3,6 @@ #include "Rendering/Framebuffer.h" #include "Scene/Scene.h" #include "Core/Core.h" - struct GLFWwindow; class Window { @@ -31,7 +30,7 @@ public: int Init(); void Update(Timestep ts); - + void FixedUpdate(Timestep ts); void Draw(); void EndDraw();