diff --git a/Editor/resources/Scripts/Scene.wren b/Editor/resources/Scripts/Scene.wren index a5f0eb65..64aa3c93 100644 --- a/Editor/resources/Scripts/Scene.wren +++ b/Editor/resources/Scripts/Scene.wren @@ -24,6 +24,8 @@ class Scene { return Light.new(id) } else if (component == "CharacterController") { return CharacterController.new(id) + } else if (component == "RigidBody") { + return RigidBody.new(id) } else if (component == "Camera") { return Camera.new(id) } else if (component == "Transform") { @@ -70,6 +72,9 @@ class Scene { foreign static IsCharacterControllerOnGround_(e) //foreign static IsOnGround_(e) + // RigidBody + foreign static AddForce_(e, x, y, z) + foreign static TriggerGetOverlappingBodyCount_(e) foreign static TriggerGetOverlappingBodies_(e) @@ -159,6 +164,16 @@ class CharacterController { } } +class RigidBody { + construct new(id) { + _entityId = id + } + + AddForce(force) { + Scene.AddForce_(_entityId, force.x, force,y, force.z) + } +} + class Camera { construct new(id) { _entityId = id diff --git a/Editor/src/Windows/EditorInterface.cpp b/Editor/src/Windows/EditorInterface.cpp index 16d21fae..7cea57c6 100644 --- a/Editor/src/Windows/EditorInterface.cpp +++ b/Editor/src/Windows/EditorInterface.cpp @@ -402,8 +402,18 @@ namespace Nuake { { Ref newPrefab = Prefab::CreatePrefabFromEntity(Selection.Entity); std::string savePath = FileDialog::SaveFile("*.prefab"); - newPrefab->SaveAs(savePath); - Selection.Entity.AddComponent().PrefabInstance = newPrefab; + if (!String::EndsWith(savePath, ".prefab")) + { + savePath += ".prefab"; + } + + if (!savePath.empty()) + { + newPrefab->SaveAs(savePath); + Selection.Entity.AddComponent().PrefabInstance = newPrefab; + FileSystem::Scan(); + FileSystemUI::m_CurrentDirectory = FileSystem::RootDirectory; + } } ImGui::EndPopup(); } diff --git a/Editor/src/Windows/FileSystemUI.cpp b/Editor/src/Windows/FileSystemUI.cpp index 1f0f3c4e..bba1f1c7 100644 --- a/Editor/src/Windows/FileSystemUI.cpp +++ b/Editor/src/Windows/FileSystemUI.cpp @@ -144,43 +144,89 @@ namespace Nuake ImGui::OpenPopup(hoverMenuId.c_str()); m_hasClickedOnFile = true; } - + + const std::string openScene = "Open Scene" + std::string("##") + hoverMenuId; + bool shouldOpenScene = false; + + if (ImGui::BeginPopup(hoverMenuId.c_str())) { - if (ImGui::MenuItem("Show in File Explorer")) + if (file->GetExtension() != ".scene") { - OS::ShowInFileExplorer(file->GetAbsolutePath()); - } - - if(file->GetExtension() == ".wren") - { - ImGui::Separator(); - - if(ImGui::MenuItem("Open...")) + if (ImGui::MenuItem("Open in Editor")) { OS::OpenIn(file->GetAbsolutePath()); } } - - if(file->GetExtension() != ".project") + else + { + if (ImGui::MenuItem("Load Scene")) + { + shouldOpenScene = true; + } + } + + ImGui::Separator(); + + if (ImGui::BeginMenu("Copy")) + { + if (ImGui::MenuItem("Full Path")) + { + OS::CopyToClipboard(file->GetAbsolutePath()); + } + + if (ImGui::MenuItem("File Name")) + { + OS::CopyToClipboard(file->GetName()); + } + + ImGui::EndPopup(); + } + + if (file->GetExtension() != ".project") { - ImGui::Separator(); - if (ImGui::MenuItem("Delete")) { - if(FileSystem::RemoveFile(file->GetAbsolutePath()) != 0) + + if (FileSystem::RemoveFile(file->GetAbsolutePath()) != 0) { Logger::Log("Failed to remove file: " + file->GetRelativePath(), "editor", CRITICAL); } RefreshFileBrowser(); } } + else + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 0.2f)); + ImGui::MenuItem("Delete"); + ImGui::PopStyleColor(); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted("The file you're trying to delete is currently loaded by the game engine."); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } + } + + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 0.2f)); + if (ImGui::MenuItem("Rename")) + { + + } + ImGui::PopStyleColor(); + + ImGui::Separator(); + + if (ImGui::MenuItem("Show in File Explorer")) + { + OS::ShowInFileExplorer(file->GetAbsolutePath()); + } ImGui::EndPopup(); } - const std::string openScene = "Open Scene" + std::string("##") + hoverMenuId; - if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(0)) { if (file->GetExtension() == ".scene") @@ -189,7 +235,12 @@ namespace Nuake } } - if (PopupHelper::DefineDialog(openScene, "Open the scene? \n Changes will not be saved.")) + if (shouldOpenScene) + { + PopupHelper::Confirmation(openScene); + } + + if (PopupHelper::DefineDialog(openScene, " Open the scene? \n Changes will not be saved.")) { Ref scene = Scene::New(); const std::string projectPath = file->GetAbsolutePath(); @@ -247,7 +298,7 @@ namespace Nuake path += ".material"; } - if (path != "") + if (!path.empty()) { Ref material = CreateRef(); material->IsEmbedded = false; diff --git a/Nuake/src/Core/OS.cpp b/Nuake/src/Core/OS.cpp index a59ee64c..c2fd29bf 100644 --- a/Nuake/src/Core/OS.cpp +++ b/Nuake/src/Core/OS.cpp @@ -1,11 +1,40 @@ #include "OS.h" +#include "src/Window.h" + +#define GLFW_EXPOSE_NATIVE_WIN32 +#include "GLFW/glfw3.h" +#include "GLFW/glfw3native.h" -#include #include +#include using namespace Nuake; -int OS::GetTime() +void OS::CopyToClipboard(const std::string& value) +{ + auto glob = GlobalAlloc(GMEM_FIXED, 512); + memcpy(glob, value.data(), value.size()); + OpenClipboard(glfwGetWin32Window(Window::Get()->GetHandle())); + EmptyClipboard(); + SetClipboardData(CF_TEXT, glob); + CloseClipboard(); +} + +std::string OS::GetFromClipboard() +{ + OpenClipboard(nullptr); + HANDLE hData = GetClipboardData(CF_TEXT); + + char* pszText = static_cast(GlobalLock(hData)); + std::string text(pszText); + + GlobalUnlock(hData); + CloseClipboard(); + + return text; +} + +int OS::GetTime() { return static_cast(std::chrono::system_clock::now().time_since_epoch().count()); } diff --git a/Nuake/src/Core/OS.h b/Nuake/src/Core/OS.h index 71f80d21..657b1fb5 100644 --- a/Nuake/src/Core/OS.h +++ b/Nuake/src/Core/OS.h @@ -7,6 +7,8 @@ namespace Nuake class OS { public: + static void CopyToClipboard(const std::string& value); + static std::string GetFromClipboard(); static int GetTime(); static void OpenIn(const std::string& filePath); static void ShowInFileExplorer(const std::string& filePath); diff --git a/Nuake/src/Core/Physics/DynamicWorld.cpp b/Nuake/src/Core/Physics/DynamicWorld.cpp index b220bfd5..0cc571e3 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.cpp +++ b/Nuake/src/Core/Physics/DynamicWorld.cpp @@ -419,7 +419,7 @@ namespace Nuake // Do 1 collision step per 1 / 60th of a second (round up). int collisionSteps = 1; constexpr float minStepDuration = 1.0f / 90.0f; - constexpr int maxStepCount = 32; + constexpr int maxStepCount = 16; if(ts > minStepDuration) { collisionSteps = static_cast(ts) / minStepDuration; @@ -461,6 +461,8 @@ namespace Nuake _registeredBodies.clear(); } + + _registeredBodies.clear(); if (!_registeredCharacters.empty()) { @@ -473,7 +475,7 @@ namespace Nuake } } - void DynamicWorld::MoveAndSlideCharacterController(const Entity& entity, const Vector3 velocity) + void DynamicWorld::MoveAndSlideCharacterController(const Entity& entity, const Vector3& velocity) { const uint32_t entityHandle = entity.GetHandle(); if (_registeredCharacters.find(entityHandle) != _registeredCharacters.end()) @@ -497,7 +499,7 @@ namespace Nuake } } - //Logger::Log("Failed to add force to rigidbody. Body not found with id: " + std::to_string(entity.GetHandle()), "physics", WARNING); + Logger::Log("Failed to add force to rigidbody. Body not found with id: " + std::to_string(entity.GetHandle()), "physics", WARNING); } JPH::Ref DynamicWorld::GetJoltShape(const Ref shape) diff --git a/Nuake/src/Core/Physics/DynamicWorld.h b/Nuake/src/Core/Physics/DynamicWorld.h index e9fa74dd..bbb5c05c 100644 --- a/Nuake/src/Core/Physics/DynamicWorld.h +++ b/Nuake/src/Core/Physics/DynamicWorld.h @@ -59,7 +59,7 @@ namespace Nuake void AddCharacterController(Ref cc); bool IsCharacterGrounded(const Entity& entity); // This is going to be ugly. TODO: Find a better way that passing itself as a parameter - void MoveAndSlideCharacterController(const Entity& entity, const Vector3 velocity); + void MoveAndSlideCharacterController(const Entity& entity, const Vector3& velocity); void AddForceToRigidBody(const Entity& entity, const Vector3& force); RaycastResult Raycast(const Vector3& from, const Vector3& to); diff --git a/Nuake/src/Core/Physics/Rigibody.h b/Nuake/src/Core/Physics/Rigibody.h index c579400a..354dd84f 100644 --- a/Nuake/src/Core/Physics/Rigibody.h +++ b/Nuake/src/Core/Physics/Rigibody.h @@ -37,6 +37,7 @@ namespace Nuake void SetShape(Ref shape); Ref GetShape() const { return _collisionShape; } Entity GetEntity() const { return _entity; } + void AddForce(const Vector3& force); }; } } diff --git a/Nuake/src/Core/Physics/Rigidbody.cpp b/Nuake/src/Core/Physics/Rigidbody.cpp index 0a4da02e..464aa7b6 100644 --- a/Nuake/src/Core/Physics/Rigidbody.cpp +++ b/Nuake/src/Core/Physics/Rigidbody.cpp @@ -1,6 +1,8 @@ #include "PhysicsShapes.h" #include "Rigibody.h" -#include "../Core.h" +#include "src/Core/Core.h" +#include "src/Core/Physics/PhysicsManager.h" + #include #include @@ -42,5 +44,10 @@ namespace Nuake { _entity = ent; } + + void RigidBody::AddForce(const Vector3& force) + { + PhysicsManager::Get().GetWorld()->AddForceToRigidBody(_entity, force); + } } } diff --git a/Nuake/src/Rendering/RenderList.h b/Nuake/src/Rendering/RenderList.h index e2f7e7e3..18ab53c1 100644 --- a/Nuake/src/Rendering/RenderList.h +++ b/Nuake/src/Rendering/RenderList.h @@ -36,15 +36,19 @@ namespace Nuake void Flush(Shader* shader, bool depthOnly = false) { shader->Bind(); + const uint32_t entityIdUniformLocation = shader->FindUniformLocation("u_EntityID"); + const uint32_t modelMatrixUniformLocation = shader->FindUniformLocation("u_Model"); for (auto& i : m_RenderList) { - if(!depthOnly) + if (!depthOnly) + { i.first->Bind(shader); + } for (auto& m : i.second) { - shader->SetUniformMat4f("u_Model", m.transform); - shader->SetUniform1i("u_EntityID", m.entityId + 1); + shader->SetUniformMat4f(modelMatrixUniformLocation, m.transform); + shader->SetUniform1i(entityIdUniformLocation, m.entityId + 1); m.Mesh->Draw(shader, false); } } diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index 7d4b2512..486beb1f 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -49,6 +49,9 @@ namespace Nuake mGBuffer->QueueResize(framebuffer.GetSize()); GBufferPass(scene); + mShadingBuffer->QueueResize(framebuffer.GetSize()); + ShadingPass(scene); + const auto& sceneEnv = scene.GetEnvironment(); Ref finalOutput = mShadingBuffer->GetTexture(); if (scene.GetEnvironment()->BloomEnabled) @@ -141,9 +144,6 @@ namespace Nuake - mShadingBuffer->QueueResize(framebuffer.GetSize()); - ShadingPass(scene); - RenderCommand::Enable(RendererEnum::DEPTH_TEST); Renderer::EndDraw(); } @@ -199,8 +199,6 @@ namespace Nuake } Renderer::Flush(shader, true); } - - light.m_Framebuffers[i]->Unbind(); } } } @@ -249,7 +247,6 @@ namespace Nuake } Renderer::Flush(gBufferShader, false); } - mGBuffer->Unbind(); } void SceneRenderer::ShadingPass(Scene& scene) @@ -308,7 +305,6 @@ namespace Nuake Renderer::DrawQuad(Matrix4()); } - mShadingBuffer->Unbind(); } void SceneRenderer::PostProcessPass(const Scene& scene) diff --git a/Nuake/src/Rendering/Shaders/Shader.cpp b/Nuake/src/Rendering/Shaders/Shader.cpp index f4b99993..895eb8c5 100644 --- a/Nuake/src/Rendering/Shaders/Shader.cpp +++ b/Nuake/src/Rendering/Shaders/Shader.cpp @@ -190,7 +190,7 @@ namespace Nuake int addr = glGetUniformLocation(ProgramId, uniform.c_str()); if (addr == -1) - return addr;//std::cout << "Warning: uniform '" << uniform << "' doesn't exists!" << std::endl; + return addr; else UniformCache[uniform] = addr; @@ -250,7 +250,12 @@ namespace Nuake //ASSERT(addr != -1); if (addr != -1) - glUniform1i(addr, v0); + SetUniform1i(addr, v0); + } + + void Shader::SetUniform1i(uint32_t location, int v0) + { + glUniform1i(location, v0); } void Shader::SetUniform1iv(const std::string& name, int size, int* value) @@ -277,12 +282,19 @@ namespace Nuake glUniformMatrix3fv(addr, 1, GL_FALSE, &mat[0][0]); } - void Shader::SetUniformMat4f(const std::string& name, Matrix4 mat) + void Shader::SetUniformMat4f(uint32_t location, const Matrix4& mat) + { + glUniformMatrix4fv(location, 1, GL_FALSE, &mat[0][0]); + } + + void Shader::SetUniformMat4f(const std::string& name, const Matrix4& mat) { int addr = FindUniformLocation(name); if (addr != -1) - glUniformMatrix4fv(addr, 1, GL_FALSE, &mat[0][0]); + { + SetUniformMat4f(addr, std::move(mat)); + } } void Shader::SetUniform1f(const std::string& name, float v0) diff --git a/Nuake/src/Rendering/Shaders/Shader.h b/Nuake/src/Rendering/Shaders/Shader.h index f022f451..6fa41787 100644 --- a/Nuake/src/Rendering/Shaders/Shader.h +++ b/Nuake/src/Rendering/Shaders/Shader.h @@ -42,16 +42,20 @@ namespace Nuake void SetUniform1b(const std::string& name, bool v0); void SetUniformTex(const std::string& name, Texture* texture, unsigned int slot = 0); void SetUniform1i(const std::string& name, int v0); + void SetUniform1i(uint32_t location, int v0); void SetUniform1iv(const std::string& name, int size, int* value); void SetUniform1fv(const std::string& name, int size, float* value); void SetUniformMat3f(const std::string& name, Matrix3 mat); - void SetUniformMat4f(const std::string& name, Matrix4 mat); + + void SetUniformMat4f(uint32_t name, const Matrix4& mat); + void SetUniformMat4f(const std::string& name, const Matrix4& mat); + + int FindUniformLocation(std::string uniform); private: ShaderSource ParseShader(const std::string& filePath); unsigned int CreateProgram(ShaderSource source); unsigned int Compile(unsigned int type, ShaderSource source); - int FindUniformLocation(std::string uniform); }; } diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index 593e3282..6e0241f2 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -71,11 +71,17 @@ namespace Nuake { { for (json e : j["Entities"]) { - Entity entity = Entity { Engine::GetCurrentScene()->m_Registry.create(), Engine::GetCurrentScene().get() }; + Entity entity = Engine::GetCurrentScene()->CreateEntity("-"); + auto& nameComponent = entity.GetComponent(); + + int entityId = nameComponent.ID; entity.Deserialize(e.dump()); + nameComponent.ID = entityId; + this->AddEntity(entity); } + // Set reference to the parent entity to children for (auto& e : Entities) { auto parentC = e.GetComponent(); diff --git a/Nuake/src/Resource/Project.cpp b/Nuake/src/Resource/Project.cpp index 45a9e6be..09709e65 100644 --- a/Nuake/src/Resource/Project.cpp +++ b/Nuake/src/Resource/Project.cpp @@ -43,7 +43,7 @@ namespace Nuake void Project::SaveAs(const std::string& FullPath) { json j = Serialize(); - std::string serialized_string = j.dump(); + std::string serialized_string = j.dump(4); // TODO: Use file interface here... // Write to file. diff --git a/Nuake/src/Scene/Components/RigidbodyComponent.cpp b/Nuake/src/Scene/Components/RigidbodyComponent.cpp index 4dd4c3e7..39862b53 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.cpp +++ b/Nuake/src/Scene/Components/RigidbodyComponent.cpp @@ -13,18 +13,18 @@ namespace Nuake { Ref RigidBodyComponent::GetRigidBody() const { - return m_Rigidbody; + return Rigidbody; } void RigidBodyComponent::SyncTransformComponent(TransformComponent* tc) { - if (!m_Rigidbody) + if (!GetRigidBody()) return; } void RigidBodyComponent::SyncWithTransform(TransformComponent* tc) { - if (!m_Rigidbody) + if (!GetRigidBody()) return; } diff --git a/Nuake/src/Scene/Components/RigidbodyComponent.h b/Nuake/src/Scene/Components/RigidbodyComponent.h index 7fae80fb..508b6597 100644 --- a/Nuake/src/Scene/Components/RigidbodyComponent.h +++ b/Nuake/src/Scene/Components/RigidbodyComponent.h @@ -13,7 +13,7 @@ namespace Nuake { { public: float Mass; - Ref m_Rigidbody; + Ref Rigidbody; RigidBodyComponent(); Ref GetRigidBody() const; @@ -24,6 +24,7 @@ namespace Nuake { void DrawShape(TransformComponent* tc); void DrawEditor(); + json Serialize() { BEGIN_SERIALIZE(); diff --git a/Nuake/src/Scene/Entities/Entity.h b/Nuake/src/Scene/Entities/Entity.h index bbf073d3..2f197050 100644 --- a/Nuake/src/Scene/Entities/Entity.h +++ b/Nuake/src/Scene/Entities/Entity.h @@ -31,7 +31,7 @@ namespace Nuake template T& AddComponent() { - T& component = m_Scene->m_Registry.emplace(m_EntityHandle); + T& component = m_Scene->m_Registry.emplace_or_replace (m_EntityHandle); return component; } diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index fa164531..11f5fd47 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -75,16 +75,25 @@ namespace Nuake { Entity Scene::GetEntityByID(int id) { + if (_EntitiesIDMap.find(id) != _EntitiesIDMap.end()) + { + return _EntitiesIDMap[id]; + } + auto idView = m_Registry.view(); for (auto e : idView) { NameComponent& nameC = idView.get(e); if (nameC.ID == id) { - return Entity{ e, this }; + auto newEntity = Entity{ e, this }; + _EntitiesIDMap[id] = newEntity; + return newEntity; } } + Logger::Log("Entity not found with id: " + std::to_string(id), "scene", CRITICAL); + assert("Entity not found"); } @@ -206,7 +215,7 @@ namespace Nuake { } std::string entityName; - if (GetEntity(name) != Entity()) + if (GetEntity(name) == Entity()) { entityName = name; } @@ -217,7 +226,7 @@ namespace Nuake { { const std::string& entityEnumName = name + std::to_string(i); const auto& entityId = GetEntity(entityEnumName).GetHandle(); - if (entityId != -1) + if (entityId == -1) { entityName = entityEnumName; break; @@ -242,6 +251,8 @@ namespace Nuake { nameComponent.Name = entityName; nameComponent.ID = id; + _EntitiesIDMap[id] = entity; + Logger::Log("Entity created with name: " + nameComponent.Name, "scene", LOG_TYPE::VERBOSE); return entity; } diff --git a/Nuake/src/Scene/Scene.h b/Nuake/src/Scene/Scene.h index 63468d9f..34fe17db 100644 --- a/Nuake/src/Scene/Scene.h +++ b/Nuake/src/Scene/Scene.h @@ -37,9 +37,11 @@ namespace Nuake public: Ref m_EditorCamera; entt::registry m_Registry; + std::map _EntitiesIDMap; std::string Path = ""; SceneRenderer* mSceneRenderer; + static Ref New(); Scene(); ~Scene(); diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.cpp b/Nuake/src/Scene/Systems/PhysicsSystem.cpp index 3f28533d..8f484bfc 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.cpp +++ b/Nuake/src/Scene/Systems/PhysicsSystem.cpp @@ -120,6 +120,8 @@ namespace Nuake if (!Engine::IsPlayMode()) return; + InitializeRigidbodies(); + PhysicsManager::Get().Step(ts); } @@ -227,6 +229,11 @@ namespace Nuake Entity ent = Entity({ e, m_Scene }); Ref rigidBody; + if (rigidBodyComponent.GetRigidBody()) + { + continue; + } + if (ent.HasComponent()) { float mass = rigidBodyComponent.Mass; @@ -276,6 +283,7 @@ namespace Nuake { Logger::Log("Cannot use mesh collider without model component", "physics", WARNING); } + const auto& modelComponent = ent.GetComponent(); const auto& component = ent.GetComponent(); @@ -293,6 +301,8 @@ namespace Nuake PhysicsManager::Get().RegisterBody(rigidBody); } } + + rigidBodyComponent.Rigidbody = rigidBody; } } diff --git a/Nuake/src/Scene/Systems/PhysicsSystem.h b/Nuake/src/Scene/Systems/PhysicsSystem.h index 5c14c303..7b639e65 100644 --- a/Nuake/src/Scene/Systems/PhysicsSystem.h +++ b/Nuake/src/Scene/Systems/PhysicsSystem.h @@ -14,7 +14,6 @@ namespace Nuake void Exit() override; private: - void InitializeShapes(); void InitializeQuakeMap(); void InitializeRigidbodies(); diff --git a/Nuake/src/Scripting/Modules/PhysicsModule.h b/Nuake/src/Scripting/Modules/PhysicsModule.h index ae211dd6..621750bb 100644 --- a/Nuake/src/Scripting/Modules/PhysicsModule.h +++ b/Nuake/src/Scripting/Modules/PhysicsModule.h @@ -8,8 +8,10 @@ #include #include "../Core/Physics/PhysicsManager.h" -namespace Nuake { - namespace ScriptAPI { +namespace Nuake +{ + namespace ScriptAPI + { class PhysicsModule : public ScriptModule { std::string ModuleName = "Engine"; diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index 954126bd..c15f109f 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -57,6 +57,8 @@ namespace Nuake { RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide); RegisterMethod("IsCharacterControllerOnGround_(_)", (void*)IsCharacterControllerOnGround); + RegisterMethod("AddForce_(_,_,_,_)", (void*)AddForce); + RegisterMethod("TriggerGetOverlappingBodyCount_(_)", (void*)TriggerGetOverlappingBodyCount); RegisterMethod("TriggerGetOverlappingBodies_(_)", (void*)TriggerGetOverlappingBodies); @@ -125,6 +127,7 @@ namespace Nuake { if (name == "Transform") result = ent.HasComponent(); if (name == "Light") result = ent.HasComponent(); if (name == "QuakeMap") result = ent.HasComponent(); + if (name == "RigidBody") result = ent.HasComponent(); if (name == "CharacterController") { result = ent.HasComponent(); @@ -258,6 +261,18 @@ namespace Nuake { characterController.CharacterController->MoveAndSlide(Vector3(x, y, z)); } + static void AddForce(WrenVM* vm) + { + double handle = wrenGetSlotDouble(vm, 1); + double x = wrenGetSlotDouble(vm, 2); + double y = wrenGetSlotDouble(vm, 3); + double z = wrenGetSlotDouble(vm, 4); + + Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get()); + auto& rigidBodyComponent = ent.GetComponent(); + rigidBodyComponent.Rigidbody->AddForce(Vector3(x, y, z)); + } + static void GetTranslation(WrenVM* vm) { double handle = wrenGetSlotDouble(vm, 1);