diff --git a/.gitmodules b/.gitmodules index e9204ba..77c0757 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "Dependencies/Luau"] path = Dependencies/Luau - url = https://github.com/roblox/luau + url = https://github.com/roblox/luau.git \ No newline at end of file diff --git a/Content/RNR/fonts/comic.ttf b/Content/RNR/fonts/ComicSans.ttf similarity index 100% rename from Content/RNR/fonts/comic.ttf rename to Content/RNR/fonts/ComicSans.ttf diff --git a/Content/RNR/fonts/Material.material b/Content/RNR/fonts/Material.material deleted file mode 100644 index 7bf8b4e..0000000 --- a/Content/RNR/fonts/Material.material +++ /dev/null @@ -1,16 +0,0 @@ -// generated by blender2ogre 0.8.3 on 2023-07-11 17:36:32 -material Material { - receive_shadows on - technique { - pass { - diffuse 0.8 0.8 0.8 1.0 - specular 0.512 0.512 0.512 1.0 64.0 - - texture_unit { - texture fonts/brick_tex.PNG - tex_address_mode wrap - colour_op modulate - } - } - } -} diff --git a/Content/RNR/fonts/brick_tex.PNG b/Content/RNR/fonts/brick_tex.PNG deleted file mode 100644 index 0b8a6c5..0000000 Binary files a/Content/RNR/fonts/brick_tex.PNG and /dev/null differ diff --git a/Content/RNR/materials/2008.material b/Content/RNR/materials/2008.material deleted file mode 100644 index 98f9855..0000000 --- a/Content/RNR/materials/2008.material +++ /dev/null @@ -1,137 +0,0 @@ -material sparkle/sparkleMatl -{ - technique - { - pass - { - lighting off - depth_write off - scene_blend add - - texture_unit - { - texture sparkle.png - colour_op modulate - } - } - } -} - -sparkle/sparkle1 -{ - quota 40 - material sparkle/sparkleMatl - particle_width 1 - particle_height 1 - cull_each false - renderer billboard - sorted false - local_space false - iteration_interval 0 - nonvisible_update_timeout 0 - billboard_type point - billboard_origin center - billboard_rotation_type vertex - common_up_vector 0 1 0 - point_rendering false - accurate_facing false - - emitter Point - { - angle 180 - colour 0.3 0.3 0.3 .6 - colour_range_start 0.25 0.25 0.25 1 - colour_range_end 0.5 0.5 0.5 1 - direction 0 -1 0 - emission_rate 160 - position 0 0 0 - velocity_min 5 - velocity_max 10 - duration .2 - time_to_live 1 - } - - affector Rotator - { - rotation_speed_range_end 360 - rotation_range_start 0 - rotation_range_end 360 - } - -} - -material explosion/explosionMatl -{ - technique - { - pass - { - lighting off - depth_write off - scene_blend add - - texture_unit - { - texture explosion.png - colour_op modulate - } - } - } -} - -explosion/explosion1 -{ - quota 400 - material explosion/explosionMatl - particle_width 5 - particle_height 5 - cull_each false - renderer billboard - sorted false - local_space false - iteration_interval 0 - nonvisible_update_timeout 0 - billboard_type point - billboard_origin center - billboard_rotation_type vertex - common_up_vector 0 1 0 - point_rendering false - accurate_facing false - - emitter Point - { - angle 180 - colour 0.3 0.3 0.3 .6 - colour_range_start 0.25 0.25 0.25 1 - colour_range_end 0.5 0.5 0.5 1 - direction 0 -1 0 - emission_rate 20000 - position 0 0 0 - velocity 30 - velocity_min 20 - velocity_max 30 - time_to_live 0.3 - time_to_live_min 0.25 - time_to_live_max 0.35 - duration 1.2 - duration_min 1.2 - duration_max 1.2 - repeat_delay 10000 - repeat_delay_min 10000 - repeat_delay_max 10000 - } - - affector DeflectorPlane - { - plane_point 0 0 0 - plane_normal 0 1 0 - bounce 0 - } - - affector DirectionRandomiser - { - randomness 0 - scope 1 - keep_velocity false - } -} \ No newline at end of file diff --git a/Content/RNR/fonts/BackMaterial.material b/Content/RNR/materials/BackMaterial.material similarity index 100% rename from Content/RNR/fonts/BackMaterial.material rename to Content/RNR/materials/BackMaterial.material diff --git a/Content/RNR/fonts/BottomMaterial.material b/Content/RNR/materials/BottomMaterial.material similarity index 100% rename from Content/RNR/fonts/BottomMaterial.material rename to Content/RNR/materials/BottomMaterial.material diff --git a/Content/RNR/fonts/FrontMaterial.material b/Content/RNR/materials/FrontMaterial.material similarity index 100% rename from Content/RNR/fonts/FrontMaterial.material rename to Content/RNR/materials/FrontMaterial.material diff --git a/Content/RNR/materials/InstancedMaterial.material b/Content/RNR/materials/InstancedMaterial.material new file mode 100644 index 0000000..8d177d2 --- /dev/null +++ b/Content/RNR/materials/InstancedMaterial.material @@ -0,0 +1,16 @@ +// generated by blender2ogre 0.8.3 on 2023-07-20 04:32:47 +material InstancedMaterial { + receive_shadows on + technique { + pass { + diffuse 0.8 0.8 0.8 1.0 + specular 0.5 0.0 0 0 0 + rtshader_system { + lighting_stage metal_roughness + texturing_stage late_add_blend + transform_stage instanced + } + + } + } +} diff --git a/Content/RNR/fonts/LeftMaterial.material b/Content/RNR/materials/LeftMaterial.material similarity index 100% rename from Content/RNR/fonts/LeftMaterial.material rename to Content/RNR/materials/LeftMaterial.material diff --git a/Content/RNR/fonts/RightMaterial.material b/Content/RNR/materials/RightMaterial.material similarity index 100% rename from Content/RNR/fonts/RightMaterial.material rename to Content/RNR/materials/RightMaterial.material diff --git a/Content/RNR/fonts/TopMaterial.material b/Content/RNR/materials/TopMaterial.material similarity index 100% rename from Content/RNR/fonts/TopMaterial.material rename to Content/RNR/materials/TopMaterial.material diff --git a/Content/RNR/materials/guibase3d.material b/Content/RNR/materials/guibase3d.material index 26b4b8c..4ae490c 100644 --- a/Content/RNR/materials/guibase3d.material +++ b/Content/RNR/materials/guibase3d.material @@ -1,4 +1,4 @@ -material materials/guibase3d +material materials/GuiBase3d { technique { diff --git a/Content/RNR/materials/partinstanced.material b/Content/RNR/materials/partinstanced.material index c74c162..1d00859 100644 --- a/Content/RNR/materials/partinstanced.material +++ b/Content/RNR/materials/partinstanced.material @@ -1,9 +1,26 @@ -material materials/partinstanced +material materials/PartInstanced/shadow_caster +{ + technique + { + pass + { + rtshader_system + { + lighting_stage gbuffer depth + transform_stage instanced + } + } + } +} + +material materials/PartInstanced { receive_shadows on technique { + shadow_caster_material materials/PartInstanced/shadow_caster + pass { specular 1 1 1 1 12.5 @@ -17,6 +34,7 @@ material materials/partinstanced rtshader_system { lighting_stage per_pixel + transform_stage instanced } } } diff --git a/Content/RNR/fonts/Cube.mesh b/Content/RNR/meshes/Cube.mesh similarity index 100% rename from Content/RNR/fonts/Cube.mesh rename to Content/RNR/meshes/Cube.mesh diff --git a/Content/RNR/fonts/part_mesh.mtl b/Content/RNR/meshes/Cube.mtl similarity index 93% rename from Content/RNR/fonts/part_mesh.mtl rename to Content/RNR/meshes/Cube.mtl index 2c63179..bc7d9c3 100644 --- a/Content/RNR/fonts/part_mesh.mtl +++ b/Content/RNR/meshes/Cube.mtl @@ -1,7 +1,7 @@ # Blender 3.5.1 MTL File: 'None' # www.blender.org -newmtl Material +newmtl Cube Ns 250.000000 Ka 1.000000 1.000000 1.000000 Kd 0.800000 0.800000 0.800000 diff --git a/Content/RNR/fonts/part_mesh.obj b/Content/RNR/meshes/Cube.obj similarity index 96% rename from Content/RNR/fonts/part_mesh.obj rename to Content/RNR/meshes/Cube.obj index 7ef1677..6456791 100644 --- a/Content/RNR/fonts/part_mesh.obj +++ b/Content/RNR/meshes/Cube.obj @@ -1,6 +1,6 @@ # Blender 3.5.1 # www.blender.org -mtllib part_mesh.mtl +mtllib Cube.mtl o FormFactor_Brick v 1.000000 1.000000 -1.000000 v 1.000000 -1.000000 -1.000000 @@ -31,7 +31,7 @@ vt 0.375000 1.000000 vt 0.375000 0.000000 vt 0.125000 0.750000 s 0 -usemtl Material +usemtl Cube f 1/1/1 5/5/1 7/9/1 3/3/1 f 4/4/2 3/3/2 7/10/2 8/12/2 f 8/13/3 7/11/3 5/6/3 6/8/3 diff --git a/Content/RNR/fonts/part_mesh.scene b/Content/RNR/meshes/Cube.scene similarity index 89% rename from Content/RNR/fonts/part_mesh.scene rename to Content/RNR/meshes/Cube.scene index 9f1cc37..e56d34d 100644 --- a/Content/RNR/fonts/part_mesh.scene +++ b/Content/RNR/meshes/Cube.scene @@ -1,7 +1,7 @@ - - + + diff --git a/Content/RNR/meshes/Cube_Instanced.mesh b/Content/RNR/meshes/Cube_Instanced.mesh new file mode 100644 index 0000000..1ffbcc7 Binary files /dev/null and b/Content/RNR/meshes/Cube_Instanced.mesh differ diff --git a/Content/RNR/meshes/Cube_Instanced.scene b/Content/RNR/meshes/Cube_Instanced.scene new file mode 100644 index 0000000..fca1513 --- /dev/null +++ b/Content/RNR/meshes/Cube_Instanced.scene @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Content/RNR/textures/stud_top.png b/Content/RNR/textures/stud_top.png deleted file mode 100644 index 4909d66..0000000 Binary files a/Content/RNR/textures/stud_top.png and /dev/null differ diff --git a/Content/RNR/textures/surfaces.png b/Content/RNR/textures/surfaces.png deleted file mode 100644 index 2207cbd..0000000 Binary files a/Content/RNR/textures/surfaces.png and /dev/null differ diff --git a/Projects/Client/Common/Source/OgreWidget.cpp b/Projects/Client/Common/Source/OgreWidget.cpp index f98dabe..fed4fde 100644 --- a/Projects/Client/Common/Source/OgreWidget.cpp +++ b/Projects/Client/Common/Source/OgreWidget.cpp @@ -93,11 +93,11 @@ namespace RNR Ogre::FontPtr pFont = Ogre::FontManager::getSingletonPtr()->create("ComicSans", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); pFont->setType(Ogre::FT_TRUETYPE); - pFont->setSource("fonts/comic.ttf"); + pFont->setSource("fonts/ComicSans.ttf"); pFont->setTrueTypeSize(16); pFont->load(); - ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_MODULATIVE); + ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE); ogreSceneManager->setShadowFarDistance(500.f); ogreSceneLight = ogreSceneManager->createLight("SunLight"); @@ -127,6 +127,8 @@ namespace RNR this->render_time += ogreRoot->getTimer()->getMilliseconds() / 1000.0; ogreRoot->getTimer()->reset(); + world->preRender(this->delta); + if(world->getWorkspace()->getCurrentCamera()) { Camera* cam = world->getWorkspace()->getCurrentCamera(); diff --git a/Projects/Client/Studio/Source/main.cpp b/Projects/Client/Studio/Source/main.cpp index 8c4d815..0a1d5d2 100644 --- a/Projects/Client/Studio/Source/main.cpp +++ b/Projects/Client/Studio/Source/main.cpp @@ -32,11 +32,9 @@ int main(int argc, char** argv) while (window.isVisible()) { - window.statusBar()->showMessage(QString::asprintf("Dt=%f, Rt=%f, FPS=%f", window.ogreWidget->delta, window.ogreWidget->render_time, 1 / window.ogreWidget->delta)); + window.statusBar()->showMessage(QString::asprintf("Dt=%f, Rt=%f, Pt=%f, FPS=%f, pFPS=%f", window.ogreWidget->delta, window.ogreWidget->render_time, window.ogreWidget->world->getPhysicsTime(), 1 / window.ogreWidget->delta, 1 / window.ogreWidget->world->getLastPhysicsDelta())); app.processEvents(); window.ogreWidget->render(); - world->preStep(); - world->step(window.ogreWidget->delta); world->update(); } } \ No newline at end of file diff --git a/Projects/Engine/CMakeLists.txt b/Projects/Engine/CMakeLists.txt index f436faa..dddd4cd 100644 --- a/Projects/Engine/CMakeLists.txt +++ b/Projects/Engine/CMakeLists.txt @@ -3,6 +3,8 @@ add_library(Engine STATIC Header/Helpers/Strings.hpp Header/Helpers/XML.hpp Header/Helpers/NormalId.hpp + Header/Helpers/Bullet.hpp + Header/Helpers/Lock.hpp Header/App/Script/ReflectionProperty.hpp Header/App/Script/Script.hpp Header/App/Script/ScriptContext.hpp @@ -37,6 +39,7 @@ add_library(Engine STATIC Source/Helpers/Strings.cpp Source/Helpers/XML.cpp Source/Helpers/NormalId.cpp + Source/Helpers/Bullet.cpp Source/App/Script/ReflectionProperty.cpp Source/App/Script/Script.cpp Source/App/GUI/GuiBase3d.cpp diff --git a/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp b/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp index ca1657d..1d136c0 100644 --- a/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp +++ b/Projects/Engine/Header/App/V8/DataModel/PartInstance.hpp @@ -13,6 +13,7 @@ namespace RNR int m_brickColor; float m_transparency; float m_reflectance; + bool m_anchored; Ogre::Matrix4 m_matrix; Ogre::Vector3 m_position; Ogre::Vector3 m_size; @@ -34,6 +35,8 @@ namespace RNR float getReflectance() { return m_reflectance; } void setTransparency(float transparency) { m_transparency = transparency; } float getTransparency() { return m_transparency; } + void setAnchored(bool anchored) { m_anchored = anchored; } + bool getAnchored() { return m_anchored; } Ogre::Vector3 getOgreCenter() { return m_position + (m_size / 2.f); } diff --git a/Projects/Engine/Header/App/V8/Tree/Instance.hpp b/Projects/Engine/Header/App/V8/Tree/Instance.hpp index f261e40..07f2bec 100644 --- a/Projects/Engine/Header/App/V8/Tree/Instance.hpp +++ b/Projects/Engine/Header/App/V8/Tree/Instance.hpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -78,5 +79,7 @@ namespace RNR virtual void onChildRemoved(RNR::Instance* childRemoved); virtual void onDescendantRemoved(RNR::Instance* descendantRemoved); // make sure this is called in any derived versions of this virtual void onSetParent(RNR::Instance* newParent); + + Lock instanceLock; }; } \ No newline at end of file diff --git a/Projects/Engine/Header/App/V8/World/World.hpp b/Projects/Engine/Header/App/V8/World/World.hpp index 0537c08..3ab28f7 100644 --- a/Projects/Engine/Header/App/V8/World/World.hpp +++ b/Projects/Engine/Header/App/V8/World/World.hpp @@ -18,6 +18,7 @@ namespace RNR { class IInputManager; + class PartInstance; struct WorldUndeserialized { @@ -29,6 +30,10 @@ namespace RNR class World { private: + std::thread m_physicsThread; + Ogre::Timer* m_physicsTimer; + + bool m_runPhysics; std::map m_refs; std::stack m_undeserialized; btDiscreteDynamicsWorld* m_dynamicsWorld; @@ -42,6 +47,8 @@ namespace RNR InstanceFactory* m_instanceFactory; IInputManager* m_inputManager; float m_lastDelta; + float m_lastPhysicsDelta; + float m_physicsTime; void xmlAddItem(pugi::xml_node node, Instance* parent); public: @@ -52,12 +59,14 @@ namespace RNR void load(char* path); + void preRender(float timestep); void preStep(); double step(float timestep); void update(); btDiscreteDynamicsWorld* getDynamicsWorld() { return m_dynamicsWorld; } float getLastDelta() { return m_lastDelta; } + float getLastPhysicsDelta() { return m_lastPhysicsDelta; } DataModel* getDatamodel() { return m_datamodel; } void setInputManager(IInputManager* inputManager) { m_inputManager = inputManager; } IInputManager* getInputManager() { return m_inputManager; } @@ -68,5 +77,14 @@ namespace RNR void setRunService(RunService* runService) { m_runService = runService; } Ogre::Root* getOgreRoot() { return m_ogreRoot; } Ogre::SceneManager* getOgreSceneManager() { return m_ogreSceneManager; } + Ogre::Timer* getPhysicsTimer() { return m_physicsTimer; } + float getPhysicsTime() { return m_physicsTime; } + void setPhysicsTime(float newTime) { m_physicsTime = newTime; } // should only be used by physicsThread + bool getPhysicsShouldBeRunningPleaseStopIfItIsStillRunning() { return m_runPhysics; } + + void registerPhysicsPart(PartInstance* partRegistered); + void deletePhysicsPart(PartInstance* partDelete); + + Lock physicsIterateLock; }; } \ No newline at end of file diff --git a/Projects/Engine/Header/Helpers/Bullet.hpp b/Projects/Engine/Header/Helpers/Bullet.hpp new file mode 100644 index 0000000..d3b6e79 --- /dev/null +++ b/Projects/Engine/Header/Helpers/Bullet.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "LinearMath/btVector3.h" +#include "btBulletDynamicsCommon.h" +#include + +namespace RNR +{ + class Bullet + { + public: + static btVector3 v3ToBullet(Ogre::Vector3 v); + static Ogre::Vector3 v3ToOgre(btVector3 v); + static btQuaternion qtToBullet(Ogre::Quaternion q); + static Ogre::Quaternion qtToOgre(btQuaternion q); + }; +} \ No newline at end of file diff --git a/Projects/Engine/Header/Helpers/Lock.hpp b/Projects/Engine/Header/Helpers/Lock.hpp new file mode 100644 index 0000000..ebd9cf8 --- /dev/null +++ b/Projects/Engine/Header/Helpers/Lock.hpp @@ -0,0 +1,12 @@ +#include + +namespace RNR +{ + struct Lock { + std::atomic lock_ = {false}; + + void lock() { while(lock_.exchange(true, std::memory_order_acquire)); } + + void unlock() { lock_.store(false, std::memory_order_release); } + }; +} \ No newline at end of file diff --git a/Projects/Engine/Source/App/BrickColor.cpp b/Projects/Engine/Source/App/BrickColor.cpp index b8b3b4f..992f0c6 100644 --- a/Projects/Engine/Source/App/BrickColor.cpp +++ b/Projects/Engine/Source/App/BrickColor.cpp @@ -100,7 +100,7 @@ namespace RNR bc_prep = true; } - Ogre::MaterialPtr part_material = Ogre::MaterialManager::getSingletonPtr()->getByName("materials/partinstanced"); + Ogre::MaterialPtr part_material = Ogre::MaterialManager::getSingletonPtr()->getByName("materials/PartInstanced"); color_material = part_material->clone(Ogre::String("tmp_part/") + Ogre::StringConverter::toString(color_id)); Ogre::RTShader::ShaderGenerator::getSingletonPtr()->cloneShaderBasedTechniques(*part_material, *color_material); Ogre::Technique* mat_tech = color_material->getTechnique(0); diff --git a/Projects/Engine/Source/App/GUI/GuiBase3d.cpp b/Projects/Engine/Source/App/GUI/GuiBase3d.cpp index 294d089..9a2ae7c 100644 --- a/Projects/Engine/Source/App/GUI/GuiBase3d.cpp +++ b/Projects/Engine/Source/App/GUI/GuiBase3d.cpp @@ -8,6 +8,6 @@ namespace RNR m_transparency = 0.f; m_visible = true; - m_material = Ogre::MaterialManager::getSingletonPtr()->getByName("materials/guibase3d"); + m_material = Ogre::MaterialManager::getSingletonPtr()->getByName("materials/GuiBase3d"); } } diff --git a/Projects/Engine/Source/App/GUI/TopMenuBar.cpp b/Projects/Engine/Source/App/GUI/TopMenuBar.cpp index 3457d27..f52ef2d 100644 --- a/Projects/Engine/Source/App/GUI/TopMenuBar.cpp +++ b/Projects/Engine/Source/App/GUI/TopMenuBar.cpp @@ -128,11 +128,13 @@ namespace RNR snprintf(render_debugtext, 255, "using BATCH_STATIC_GEOMETRY\nGeom Regions: %i", workspace->m_geom->getRegions().size()); break; } - snprintf(debugtext, 512, "Render\nLast DT = %f\n%s\n\nPhysics\n%i objects, %i constraints", + snprintf(debugtext, 512, "Render\nLast DT = %f\n%s\n\nPhysics\nDT = %f\n%i objects, %i constraints\nRunService: running = %s, paused = %s", m_world->getLastDelta(), render_debugtext, - m_world->getOgreSceneManager(), - dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints()); + m_world->getLastPhysicsDelta(), + dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints(), + m_world->getRunService()->getRunning() ? "true" : "false", + m_world->getRunService()->getPaused() ? "true" : "false"); m_debugText->setCaption(debugtext); Players* players = (Players*)m_world->getDatamodel()->getService("Players"); diff --git a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp index bec7c7c..f8a7cef 100644 --- a/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/PartInstance.cpp @@ -13,7 +13,7 @@ namespace RNR m_reflectance = 0.0; setNode(world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode()); - setObject(world->getOgreSceneManager()->createEntity("fonts/Cube.mesh")); + setObject(world->getOgreSceneManager()->createEntity("meshes/Cube.mesh")); getNode()->attachObject(getObject()); updateMatrix(); @@ -24,16 +24,32 @@ namespace RNR m_matrix = m_cframe.getMatrix(); m_position = m_cframe.getPosition(); - getNode()->setOrientation(Ogre::Quaternion(m_cframe.getRotation())); - getNode()->setPosition(m_position); - getNode()->setScale(m_size); + if(getNode()) + { + getNode()->setOrientation(Ogre::Quaternion(m_cframe.getRotation())); + getNode()->setPosition(m_position); + getNode()->setScale(m_size); + } + + if(getObject() && dynamic_cast(getObject())) + { + Ogre::InstancedEntity* object = (Ogre::InstancedEntity*)getObject(); + + object->setOrientation(Ogre::Quaternion(m_cframe.getRotation())); + object->setPosition(m_position); + object->setScale(m_size); + + object->updateTransforms(); + } Ogre::Entity* entity = (Ogre::Entity*)getObject(); for(auto& subentity : entity->getSubEntities()) { subentity->setMaterial(BrickColor::material(m_brickColor)); subentity->getMaterial()->setShininess(64); + subentity->getMaterial()->setLightingEnabled(true); } + entity->setCastShadows(true); } void PartInstance::deserializeProperty(char* prop_name, pugi::xml_node node) @@ -58,6 +74,10 @@ namespace RNR { setTransparency(node.text().as_float()); } + else if(prop_name == std::string("Anchored")) + { + setAnchored(node.text().as_bool()); + } else PVInstance::deserializeProperty(prop_name, node); updateMatrix(); diff --git a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp index 1ad8055..9e545d5 100644 --- a/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp +++ b/Projects/Engine/Source/App/V8/DataModel/Workspace.cpp @@ -8,18 +8,18 @@ namespace RNR Workspace::Workspace() : ModelInstance() { setName("Workspace"); - m_batchMode = BATCH_DONT; + m_batchMode = BATCH_INSTANCED; m_worldspawn = world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode(); - + switch(m_batchMode) { case BATCH_INSTANCED: - m_instanceManager = world->getOgreSceneManager()->createInstanceManager("workspaceInstanceManager", "fonts/Cube.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::InstanceManager::InstancingTechnique::HWInstancingBasic, 255); + m_instanceManager = world->getOgreSceneManager()->createInstanceManager("workspaceInstanceManager", "meshes/Cube_Instanced.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::InstanceManager::InstancingTechnique::HWInstancingBasic, 255); break; case BATCH_STATIC_GEOMETRY: m_geom = world->getOgreSceneManager()->createStaticGeometry("workspaceGeom"); - m_geom->setRegionDimensions(Ogre::Vector3(2048,2048,2048)); + m_geom->setRegionDimensions(Ogre::Vector3(4096, 4096, 4096)); m_geom->setCastShadows(true); break; case BATCH_DONT: @@ -37,11 +37,13 @@ namespace RNR { case BATCH_INSTANCED: { - Ogre::Entity* childEntity = (Ogre::Entity*)childAdded->getObject(); - Ogre::InstancedEntity* replica = m_instanceManager->createInstancedEntity("materials/partinstanced"); - replica->setPosition(part->getPosition()); + Ogre::InstancedEntity* replica = m_instanceManager->createInstancedEntity(BrickColor::material(part->getBrickColor())->getName()); + part->updateMatrix(); + replica->setPosition(part->getCFrame().getPosition()); replica->setOrientation(part->getCFrame().getRotation()); replica->setScale(part->getSize()); + replica->setCastShadows(true); + m_worldspawn->attachObject(replica); childAdded->setObject(replica); child_node->setVisible(false); } @@ -55,8 +57,10 @@ namespace RNR m_geomDirty = true; break; case BATCH_DONT: + child_node->setVisible(true); break; } + world->registerPhysicsPart(part); } } @@ -75,6 +79,9 @@ namespace RNR void Workspace::onDescendantRemoved(Instance* childRemoved) { + PartInstance* part = dynamic_cast(childRemoved); + if(part) + world->deletePhysicsPart(part); m_geomDirty = true; } diff --git a/Projects/Engine/Source/App/V8/World/World.cpp b/Projects/Engine/Source/App/V8/World/World.cpp index 85b7ee3..547f605 100644 --- a/Projects/Engine/Source/App/V8/World/World.cpp +++ b/Projects/Engine/Source/App/V8/World/World.cpp @@ -8,9 +8,25 @@ #include #include #include +#include namespace RNR { + void physicsThread(World* world) + { + float delta; + float time; + while(world->getPhysicsShouldBeRunningPleaseStopIfItIsStillRunning()) + { + delta = world->getPhysicsTimer()->getMicroseconds() / 1000000.0; + time += world->getPhysicsTimer()->getMilliseconds() / 1000.0; + world->setPhysicsTime(time); + world->getPhysicsTimer()->reset(); + world->preStep(); + world->step(delta); + } + } + World::World(Ogre::Root* ogre, Ogre::SceneManager* ogreSceneManager) { Instance::setWorld(this); @@ -20,7 +36,7 @@ namespace RNR btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase(); btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration); - m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); + m_dynamicsWorld->setGravity(btVector3(0, -64, 0)); m_inputManager = 0; @@ -45,6 +61,11 @@ namespace RNR m_runService = (RunService*)m_datamodel->getService("RunService"); m_players = (Players*)m_datamodel->getService("Players"); + m_runPhysics = true; + m_physicsTimer = new Ogre::Timer(); + m_physicsThread = std::thread(physicsThread, this); + m_physicsTime = 0.0; + m_tmb = new TopMenuBar(this); Camera* start_cam = new Camera(); @@ -54,7 +75,8 @@ namespace RNR World::~World() { - // + m_runPhysics = false; + m_physicsThread.join(); } void World::xmlAddItem(pugi::xml_node node, Instance* parent) @@ -118,7 +140,6 @@ namespace RNR WorldUndeserialized s = m_undeserialized.top(); m_undeserialized.pop(); - s.instance->setParent(s.parent); pugi::xml_node props = s.node.child("Properties"); for(pugi::xml_node prop : props.children()) @@ -126,6 +147,8 @@ namespace RNR s.instance->deserializeXmlProperty(prop); } + s.instance->setParent(s.parent); + if(s.instance->getClassName() == "Model") { ModelInstance* m = (ModelInstance*)s.instance; @@ -140,21 +163,66 @@ namespace RNR m_workspace->build(); } - void World::preStep() + void World::preRender(float timestep) { if(m_inputManager) m_inputManager->frame(); m_tmb->frame(); + m_lastDelta = timestep; + if(m_runService && m_runService->getRunning() && !m_runService->getPaused()) + { + physicsIterateLock.lock(); + for(int j = m_dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[j]; + if(!obj->isActive()) + continue; + PartInstance* part = (PartInstance*)obj->getUserPointer(); + part->updateMatrix(); + } + update(); + physicsIterateLock.unlock(); + } + } + + void World::preStep() + { + } double World::step(float timestep) { - if(m_runService && m_runService->getRunning()) + if(m_runService && m_runService->getRunning() && !m_runService->getPaused()) { m_runService->step(timestep); - m_dynamicsWorld->stepSimulation(timestep); + m_dynamicsWorld->stepSimulation(timestep, 2); + + physicsIterateLock.lock(); + for(int j = m_dynamicsWorld->getNumCollisionObjects() - 1; j >= 0; j--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[j]; + if(!obj->isActive()) + continue; + btRigidBody* body = btRigidBody::upcast(obj); + btTransform trans; + if(body && body->getMotionState()) + { + body->getMotionState()->getWorldTransform(trans); + } + else + { + trans = obj->getWorldTransform(); + } + PartInstance* part = (PartInstance*)obj->getUserPointer(); + part->getCFrame().setPosition(Bullet::v3ToOgre(trans.getOrigin())); + Ogre::Matrix3 partRot; + Ogre::Quaternion transOgre = Bullet::qtToOgre(trans.getRotation()); + transOgre.ToRotationMatrix(partRot); + part->getCFrame().setRotation(partRot); + } + physicsIterateLock.unlock(); } - m_lastDelta = timestep; + m_lastPhysicsDelta = timestep; return 0.0; } @@ -162,4 +230,35 @@ namespace RNR { m_workspace->buildGeom(); } + + void World::registerPhysicsPart(PartInstance* partRegistered) + { + btCollisionShape* partShape = new btBoxShape(Bullet::v3ToBullet(partRegistered->getSize() / 2.f)); + partShape->setUserPointer(partRegistered); + + btTransform partTransform; + partTransform.setIdentity(); + partTransform.setOrigin(Bullet::v3ToBullet(partRegistered->getPosition())); + partTransform.setRotation(Bullet::qtToBullet(partRegistered->getRotation())); + + btScalar mass = partRegistered->getSize().length(); + if(partRegistered->getAnchored()) + mass = 0; + + btVector3 localInertia = btVector3(0,0,0); + if(mass) + partShape->calculateLocalInertia(mass, localInertia); + + btDefaultMotionState* partMotionState = new btDefaultMotionState(partTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, partMotionState, partShape, localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + body->setUserPointer(partRegistered); + + m_dynamicsWorld->addRigidBody(body); + } + + void World::deletePhysicsPart(PartInstance* partDelete) + { + + } } \ No newline at end of file diff --git a/Projects/Engine/Source/Helpers/Bullet.cpp b/Projects/Engine/Source/Helpers/Bullet.cpp new file mode 100644 index 0000000..fb13288 --- /dev/null +++ b/Projects/Engine/Source/Helpers/Bullet.cpp @@ -0,0 +1,24 @@ +#include + +namespace RNR +{ + btVector3 Bullet::v3ToBullet(Ogre::Vector3 v) + { + return btVector3(v.x, v.y, v.z); + } + + Ogre::Vector3 Bullet::v3ToOgre(btVector3 v) + { + return Ogre::Vector3(v.getX(), v.getY(), v.getZ()); + } + + btQuaternion Bullet::qtToBullet(Ogre::Quaternion q) + { + return btQuaternion(q.x, q.y, q.z, q.w); + } + + Ogre::Quaternion Bullet::qtToOgre(btQuaternion q) + { + return Ogre::Quaternion(q.getW(), q.getX(), q.getY(), q.getZ()); + } +} \ No newline at end of file diff --git a/README.md b/README.md index a0872a0..4af4f10 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ There are several goals that RNR seeks to accomplish, them being; RNR uses [CMake](https://cmake.org/) as its build system and [GCC](https://gcc.gnu.org/) as its compiler. To build RNR, you must first have the following packages installed: - [Boost](https://www.boost.org/) - [OGRE](https://github.com/OGRECave/ogre) +- [Bullet](https://github.com/bulletphysics/bullet3) - [pugixml](https://github.com/zeux/pugixml) - [Qt 6](https://www.qt.io/product/qt6) (if building the player or studio projects) @@ -33,6 +34,8 @@ Additionally, you must also acquire the content folder of the Roblox client you Finally, you may run `cmake --build .` in the path of the folder you've cloned the repository to so that you may configure and then finally build RNR. +P.S.: You can check our [GitHub actions page](https://github.com/lrre-foss/rnr/actions) to browse automatic ready-to-run Windows (and soon Linux) builds for each commit. :-) + # License RNR is licensed under two separate licenses: - All of RNR, with the sole exception of the engine, is licensed under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.txt).