Merge branch 'trunk' of https://github.com/lrre-foss/rnr into trunk
This commit is contained in:
commit
8980f2cb65
|
|
@ -1,3 +1,3 @@
|
||||||
[submodule "Dependencies/Luau"]
|
[submodule "Dependencies/Luau"]
|
||||||
path = Dependencies/Luau
|
path = Dependencies/Luau
|
||||||
url = https://github.com/roblox/luau
|
url = https://github.com/roblox/luau.git
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.6 KiB |
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
material materials/guibase3d
|
material materials/GuiBase3d
|
||||||
{
|
{
|
||||||
technique
|
technique
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
receive_shadows on
|
||||||
|
|
||||||
technique
|
technique
|
||||||
{
|
{
|
||||||
|
shadow_caster_material materials/PartInstanced/shadow_caster
|
||||||
|
|
||||||
pass
|
pass
|
||||||
{
|
{
|
||||||
specular 1 1 1 1 12.5
|
specular 1 1 1 1 12.5
|
||||||
|
|
@ -17,6 +34,7 @@ material materials/partinstanced
|
||||||
rtshader_system
|
rtshader_system
|
||||||
{
|
{
|
||||||
lighting_stage per_pixel
|
lighting_stage per_pixel
|
||||||
|
transform_stage instanced
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Blender 3.5.1 MTL File: 'None'
|
# Blender 3.5.1 MTL File: 'None'
|
||||||
# www.blender.org
|
# www.blender.org
|
||||||
|
|
||||||
newmtl Material
|
newmtl Cube
|
||||||
Ns 250.000000
|
Ns 250.000000
|
||||||
Ka 1.000000 1.000000 1.000000
|
Ka 1.000000 1.000000 1.000000
|
||||||
Kd 0.800000 0.800000 0.800000
|
Kd 0.800000 0.800000 0.800000
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Blender 3.5.1
|
# Blender 3.5.1
|
||||||
# www.blender.org
|
# www.blender.org
|
||||||
mtllib part_mesh.mtl
|
mtllib Cube.mtl
|
||||||
o FormFactor_Brick
|
o FormFactor_Brick
|
||||||
v 1.000000 1.000000 -1.000000
|
v 1.000000 1.000000 -1.000000
|
||||||
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.375000 0.000000
|
||||||
vt 0.125000 0.750000
|
vt 0.125000 0.750000
|
||||||
s 0
|
s 0
|
||||||
usemtl Material
|
usemtl Cube
|
||||||
f 1/1/1 5/5/1 7/9/1 3/3/1
|
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 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
|
f 8/13/3 7/11/3 5/6/3 6/8/3
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- exporter: blender2ogre 0.8.3 -->
|
<!-- exporter: blender2ogre 0.8.3 -->
|
||||||
<!-- export_time: Mon, 17 Jul 2023 06:58:22 +0000 -->
|
<!-- export_time: Thu, 20 Jul 2023 08:20:08 +0000 -->
|
||||||
<!-- previous_export_time: Mon, 17 Jul 2023 06:14:49 +0000 -->
|
<!-- previous_export_time: Mon, 17 Jul 2023 06:58:22 +0000 -->
|
||||||
<scene author="caesium" formatVersion="1.1" >
|
<scene author="caesium" formatVersion="1.1" >
|
||||||
<nodes >
|
<nodes >
|
||||||
<node name="Cube" >
|
<node name="Cube" >
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- exporter: blender2ogre 0.8.3 -->
|
||||||
|
<!-- export_time: Thu, 20 Jul 2023 08:32:47 +0000 -->
|
||||||
|
<!-- previous_export_time: Mon, 17 Jul 2023 06:58:22 +0000 -->
|
||||||
|
<scene author="caesium" formatVersion="1.1" >
|
||||||
|
<nodes >
|
||||||
|
<node name="Cube_Instanced" >
|
||||||
|
<position x="0.000000" y="0.000000" z="0.000000" />
|
||||||
|
<rotation qw="1.000000" qx="0.000000" qy="0.000000" qz="0.000000" />
|
||||||
|
<scale x="1.000000" y="1.000000" z="1.000000" />
|
||||||
|
<entity meshFile="Cube_Instanced.mesh" name="Cube_Instanced" >
|
||||||
|
<userData />
|
||||||
|
</entity>
|
||||||
|
</node>
|
||||||
|
</nodes>
|
||||||
|
<externals >
|
||||||
|
<item type="material" >
|
||||||
|
<file name="InstancedMaterial.material" />
|
||||||
|
</item>
|
||||||
|
</externals>
|
||||||
|
<environment >
|
||||||
|
<colourBackground b="0.050876" g="0.050876" r="0.050876" />
|
||||||
|
</environment>
|
||||||
|
</scene>
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
|
|
@ -93,11 +93,11 @@ namespace RNR
|
||||||
|
|
||||||
Ogre::FontPtr pFont = Ogre::FontManager::getSingletonPtr()->create("ComicSans", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
Ogre::FontPtr pFont = Ogre::FontManager::getSingletonPtr()->create("ComicSans", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||||
pFont->setType(Ogre::FT_TRUETYPE);
|
pFont->setType(Ogre::FT_TRUETYPE);
|
||||||
pFont->setSource("fonts/comic.ttf");
|
pFont->setSource("fonts/ComicSans.ttf");
|
||||||
pFont->setTrueTypeSize(16);
|
pFont->setTrueTypeSize(16);
|
||||||
pFont->load();
|
pFont->load();
|
||||||
|
|
||||||
ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_MODULATIVE);
|
ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE);
|
||||||
ogreSceneManager->setShadowFarDistance(500.f);
|
ogreSceneManager->setShadowFarDistance(500.f);
|
||||||
|
|
||||||
ogreSceneLight = ogreSceneManager->createLight("SunLight");
|
ogreSceneLight = ogreSceneManager->createLight("SunLight");
|
||||||
|
|
@ -127,6 +127,8 @@ namespace RNR
|
||||||
this->render_time += ogreRoot->getTimer()->getMilliseconds() / 1000.0;
|
this->render_time += ogreRoot->getTimer()->getMilliseconds() / 1000.0;
|
||||||
ogreRoot->getTimer()->reset();
|
ogreRoot->getTimer()->reset();
|
||||||
|
|
||||||
|
world->preRender(this->delta);
|
||||||
|
|
||||||
if(world->getWorkspace()->getCurrentCamera())
|
if(world->getWorkspace()->getCurrentCamera())
|
||||||
{
|
{
|
||||||
Camera* cam = world->getWorkspace()->getCurrentCamera();
|
Camera* cam = world->getWorkspace()->getCurrentCamera();
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,9 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
while (window.isVisible())
|
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();
|
app.processEvents();
|
||||||
window.ogreWidget->render();
|
window.ogreWidget->render();
|
||||||
world->preStep();
|
|
||||||
world->step(window.ogreWidget->delta);
|
|
||||||
world->update();
|
world->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,8 @@ add_library(Engine STATIC
|
||||||
Header/Helpers/Strings.hpp
|
Header/Helpers/Strings.hpp
|
||||||
Header/Helpers/XML.hpp
|
Header/Helpers/XML.hpp
|
||||||
Header/Helpers/NormalId.hpp
|
Header/Helpers/NormalId.hpp
|
||||||
|
Header/Helpers/Bullet.hpp
|
||||||
|
Header/Helpers/Lock.hpp
|
||||||
Header/App/Script/ReflectionProperty.hpp
|
Header/App/Script/ReflectionProperty.hpp
|
||||||
Header/App/Script/Script.hpp
|
Header/App/Script/Script.hpp
|
||||||
Header/App/Script/ScriptContext.hpp
|
Header/App/Script/ScriptContext.hpp
|
||||||
|
|
@ -37,6 +39,7 @@ add_library(Engine STATIC
|
||||||
Source/Helpers/Strings.cpp
|
Source/Helpers/Strings.cpp
|
||||||
Source/Helpers/XML.cpp
|
Source/Helpers/XML.cpp
|
||||||
Source/Helpers/NormalId.cpp
|
Source/Helpers/NormalId.cpp
|
||||||
|
Source/Helpers/Bullet.cpp
|
||||||
Source/App/Script/ReflectionProperty.cpp
|
Source/App/Script/ReflectionProperty.cpp
|
||||||
Source/App/Script/Script.cpp
|
Source/App/Script/Script.cpp
|
||||||
Source/App/GUI/GuiBase3d.cpp
|
Source/App/GUI/GuiBase3d.cpp
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace RNR
|
||||||
int m_brickColor;
|
int m_brickColor;
|
||||||
float m_transparency;
|
float m_transparency;
|
||||||
float m_reflectance;
|
float m_reflectance;
|
||||||
|
bool m_anchored;
|
||||||
Ogre::Matrix4 m_matrix;
|
Ogre::Matrix4 m_matrix;
|
||||||
Ogre::Vector3 m_position;
|
Ogre::Vector3 m_position;
|
||||||
Ogre::Vector3 m_size;
|
Ogre::Vector3 m_size;
|
||||||
|
|
@ -34,6 +35,8 @@ namespace RNR
|
||||||
float getReflectance() { return m_reflectance; }
|
float getReflectance() { return m_reflectance; }
|
||||||
void setTransparency(float transparency) { m_transparency = transparency; }
|
void setTransparency(float transparency) { m_transparency = transparency; }
|
||||||
float getTransparency() { return m_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); }
|
Ogre::Vector3 getOgreCenter() { return m_position + (m_size / 2.f); }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <Helpers/Name.hpp>
|
#include <Helpers/Name.hpp>
|
||||||
|
#include <Helpers/Lock.hpp>
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
#include <App/Script/ReflectionProperty.hpp>
|
#include <App/Script/ReflectionProperty.hpp>
|
||||||
|
|
@ -78,5 +79,7 @@ namespace RNR
|
||||||
virtual void onChildRemoved(RNR::Instance* childRemoved);
|
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 onDescendantRemoved(RNR::Instance* descendantRemoved); // make sure this is called in any derived versions of this
|
||||||
virtual void onSetParent(RNR::Instance* newParent);
|
virtual void onSetParent(RNR::Instance* newParent);
|
||||||
|
|
||||||
|
Lock instanceLock;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
namespace RNR
|
namespace RNR
|
||||||
{
|
{
|
||||||
class IInputManager;
|
class IInputManager;
|
||||||
|
class PartInstance;
|
||||||
|
|
||||||
struct WorldUndeserialized
|
struct WorldUndeserialized
|
||||||
{
|
{
|
||||||
|
|
@ -29,6 +30,10 @@ namespace RNR
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
std::thread m_physicsThread;
|
||||||
|
Ogre::Timer* m_physicsTimer;
|
||||||
|
|
||||||
|
bool m_runPhysics;
|
||||||
std::map<std::string, Instance*> m_refs;
|
std::map<std::string, Instance*> m_refs;
|
||||||
std::stack<WorldUndeserialized> m_undeserialized;
|
std::stack<WorldUndeserialized> m_undeserialized;
|
||||||
btDiscreteDynamicsWorld* m_dynamicsWorld;
|
btDiscreteDynamicsWorld* m_dynamicsWorld;
|
||||||
|
|
@ -42,6 +47,8 @@ namespace RNR
|
||||||
InstanceFactory* m_instanceFactory;
|
InstanceFactory* m_instanceFactory;
|
||||||
IInputManager* m_inputManager;
|
IInputManager* m_inputManager;
|
||||||
float m_lastDelta;
|
float m_lastDelta;
|
||||||
|
float m_lastPhysicsDelta;
|
||||||
|
float m_physicsTime;
|
||||||
|
|
||||||
void xmlAddItem(pugi::xml_node node, Instance* parent);
|
void xmlAddItem(pugi::xml_node node, Instance* parent);
|
||||||
public:
|
public:
|
||||||
|
|
@ -52,12 +59,14 @@ namespace RNR
|
||||||
|
|
||||||
void load(char* path);
|
void load(char* path);
|
||||||
|
|
||||||
|
void preRender(float timestep);
|
||||||
void preStep();
|
void preStep();
|
||||||
double step(float timestep);
|
double step(float timestep);
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
btDiscreteDynamicsWorld* getDynamicsWorld() { return m_dynamicsWorld; }
|
btDiscreteDynamicsWorld* getDynamicsWorld() { return m_dynamicsWorld; }
|
||||||
float getLastDelta() { return m_lastDelta; }
|
float getLastDelta() { return m_lastDelta; }
|
||||||
|
float getLastPhysicsDelta() { return m_lastPhysicsDelta; }
|
||||||
DataModel* getDatamodel() { return m_datamodel; }
|
DataModel* getDatamodel() { return m_datamodel; }
|
||||||
void setInputManager(IInputManager* inputManager) { m_inputManager = inputManager; }
|
void setInputManager(IInputManager* inputManager) { m_inputManager = inputManager; }
|
||||||
IInputManager* getInputManager() { return m_inputManager; }
|
IInputManager* getInputManager() { return m_inputManager; }
|
||||||
|
|
@ -68,5 +77,14 @@ namespace RNR
|
||||||
void setRunService(RunService* runService) { m_runService = runService; }
|
void setRunService(RunService* runService) { m_runService = runService; }
|
||||||
Ogre::Root* getOgreRoot() { return m_ogreRoot; }
|
Ogre::Root* getOgreRoot() { return m_ogreRoot; }
|
||||||
Ogre::SceneManager* getOgreSceneManager() { return m_ogreSceneManager; }
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#pragma once
|
||||||
|
#include "LinearMath/btVector3.h"
|
||||||
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
#include <OGRE/Ogre.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
namespace RNR
|
||||||
|
{
|
||||||
|
struct Lock {
|
||||||
|
std::atomic<bool> lock_ = {false};
|
||||||
|
|
||||||
|
void lock() { while(lock_.exchange(true, std::memory_order_acquire)); }
|
||||||
|
|
||||||
|
void unlock() { lock_.store(false, std::memory_order_release); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -100,7 +100,7 @@ namespace RNR
|
||||||
|
|
||||||
bc_prep = true;
|
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));
|
color_material = part_material->clone(Ogre::String("tmp_part/") + Ogre::StringConverter::toString(color_id));
|
||||||
Ogre::RTShader::ShaderGenerator::getSingletonPtr()->cloneShaderBasedTechniques(*part_material, *color_material);
|
Ogre::RTShader::ShaderGenerator::getSingletonPtr()->cloneShaderBasedTechniques(*part_material, *color_material);
|
||||||
Ogre::Technique* mat_tech = color_material->getTechnique(0);
|
Ogre::Technique* mat_tech = color_material->getTechnique(0);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@ namespace RNR
|
||||||
m_transparency = 0.f;
|
m_transparency = 0.f;
|
||||||
m_visible = true;
|
m_visible = true;
|
||||||
|
|
||||||
m_material = Ogre::MaterialManager::getSingletonPtr()->getByName("materials/guibase3d");
|
m_material = Ogre::MaterialManager::getSingletonPtr()->getByName("materials/GuiBase3d");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,11 +128,13 @@ namespace RNR
|
||||||
snprintf(render_debugtext, 255, "using BATCH_STATIC_GEOMETRY\nGeom Regions: %i", workspace->m_geom->getRegions().size());
|
snprintf(render_debugtext, 255, "using BATCH_STATIC_GEOMETRY\nGeom Regions: %i", workspace->m_geom->getRegions().size());
|
||||||
break;
|
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(),
|
m_world->getLastDelta(),
|
||||||
render_debugtext,
|
render_debugtext,
|
||||||
m_world->getOgreSceneManager(),
|
m_world->getLastPhysicsDelta(),
|
||||||
dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints());
|
dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints(),
|
||||||
|
m_world->getRunService()->getRunning() ? "true" : "false",
|
||||||
|
m_world->getRunService()->getPaused() ? "true" : "false");
|
||||||
m_debugText->setCaption(debugtext);
|
m_debugText->setCaption(debugtext);
|
||||||
|
|
||||||
Players* players = (Players*)m_world->getDatamodel()->getService("Players");
|
Players* players = (Players*)m_world->getDatamodel()->getService("Players");
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace RNR
|
||||||
m_reflectance = 0.0;
|
m_reflectance = 0.0;
|
||||||
|
|
||||||
setNode(world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode());
|
setNode(world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode());
|
||||||
setObject(world->getOgreSceneManager()->createEntity("fonts/Cube.mesh"));
|
setObject(world->getOgreSceneManager()->createEntity("meshes/Cube.mesh"));
|
||||||
getNode()->attachObject(getObject());
|
getNode()->attachObject(getObject());
|
||||||
|
|
||||||
updateMatrix();
|
updateMatrix();
|
||||||
|
|
@ -24,16 +24,32 @@ namespace RNR
|
||||||
m_matrix = m_cframe.getMatrix();
|
m_matrix = m_cframe.getMatrix();
|
||||||
m_position = m_cframe.getPosition();
|
m_position = m_cframe.getPosition();
|
||||||
|
|
||||||
getNode()->setOrientation(Ogre::Quaternion(m_cframe.getRotation()));
|
if(getNode())
|
||||||
getNode()->setPosition(m_position);
|
{
|
||||||
getNode()->setScale(m_size);
|
getNode()->setOrientation(Ogre::Quaternion(m_cframe.getRotation()));
|
||||||
|
getNode()->setPosition(m_position);
|
||||||
|
getNode()->setScale(m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getObject() && dynamic_cast<Ogre::InstancedEntity*>(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();
|
Ogre::Entity* entity = (Ogre::Entity*)getObject();
|
||||||
for(auto& subentity : entity->getSubEntities())
|
for(auto& subentity : entity->getSubEntities())
|
||||||
{
|
{
|
||||||
subentity->setMaterial(BrickColor::material(m_brickColor));
|
subentity->setMaterial(BrickColor::material(m_brickColor));
|
||||||
subentity->getMaterial()->setShininess(64);
|
subentity->getMaterial()->setShininess(64);
|
||||||
|
subentity->getMaterial()->setLightingEnabled(true);
|
||||||
}
|
}
|
||||||
|
entity->setCastShadows(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PartInstance::deserializeProperty(char* prop_name, pugi::xml_node node)
|
void PartInstance::deserializeProperty(char* prop_name, pugi::xml_node node)
|
||||||
|
|
@ -58,6 +74,10 @@ namespace RNR
|
||||||
{
|
{
|
||||||
setTransparency(node.text().as_float());
|
setTransparency(node.text().as_float());
|
||||||
}
|
}
|
||||||
|
else if(prop_name == std::string("Anchored"))
|
||||||
|
{
|
||||||
|
setAnchored(node.text().as_bool());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
PVInstance::deserializeProperty(prop_name, node);
|
PVInstance::deserializeProperty(prop_name, node);
|
||||||
updateMatrix();
|
updateMatrix();
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,18 @@ namespace RNR
|
||||||
Workspace::Workspace() : ModelInstance()
|
Workspace::Workspace() : ModelInstance()
|
||||||
{
|
{
|
||||||
setName("Workspace");
|
setName("Workspace");
|
||||||
m_batchMode = BATCH_DONT;
|
m_batchMode = BATCH_INSTANCED;
|
||||||
|
|
||||||
m_worldspawn = world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode();
|
m_worldspawn = world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode();
|
||||||
|
|
||||||
switch(m_batchMode)
|
switch(m_batchMode)
|
||||||
{
|
{
|
||||||
case BATCH_INSTANCED:
|
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;
|
break;
|
||||||
case BATCH_STATIC_GEOMETRY:
|
case BATCH_STATIC_GEOMETRY:
|
||||||
m_geom = world->getOgreSceneManager()->createStaticGeometry("workspaceGeom");
|
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);
|
m_geom->setCastShadows(true);
|
||||||
break;
|
break;
|
||||||
case BATCH_DONT:
|
case BATCH_DONT:
|
||||||
|
|
@ -37,11 +37,13 @@ namespace RNR
|
||||||
{
|
{
|
||||||
case BATCH_INSTANCED:
|
case BATCH_INSTANCED:
|
||||||
{
|
{
|
||||||
Ogre::Entity* childEntity = (Ogre::Entity*)childAdded->getObject();
|
Ogre::InstancedEntity* replica = m_instanceManager->createInstancedEntity(BrickColor::material(part->getBrickColor())->getName());
|
||||||
Ogre::InstancedEntity* replica = m_instanceManager->createInstancedEntity("materials/partinstanced");
|
part->updateMatrix();
|
||||||
replica->setPosition(part->getPosition());
|
replica->setPosition(part->getCFrame().getPosition());
|
||||||
replica->setOrientation(part->getCFrame().getRotation());
|
replica->setOrientation(part->getCFrame().getRotation());
|
||||||
replica->setScale(part->getSize());
|
replica->setScale(part->getSize());
|
||||||
|
replica->setCastShadows(true);
|
||||||
|
m_worldspawn->attachObject(replica);
|
||||||
childAdded->setObject(replica);
|
childAdded->setObject(replica);
|
||||||
child_node->setVisible(false);
|
child_node->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
@ -55,8 +57,10 @@ namespace RNR
|
||||||
m_geomDirty = true;
|
m_geomDirty = true;
|
||||||
break;
|
break;
|
||||||
case BATCH_DONT:
|
case BATCH_DONT:
|
||||||
|
child_node->setVisible(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
world->registerPhysicsPart(part);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,6 +79,9 @@ namespace RNR
|
||||||
|
|
||||||
void Workspace::onDescendantRemoved(Instance* childRemoved)
|
void Workspace::onDescendantRemoved(Instance* childRemoved)
|
||||||
{
|
{
|
||||||
|
PartInstance* part = dynamic_cast<PartInstance*>(childRemoved);
|
||||||
|
if(part)
|
||||||
|
world->deletePhysicsPart(part);
|
||||||
m_geomDirty = true;
|
m_geomDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,25 @@
|
||||||
#include <Network/Player.hpp>
|
#include <Network/Player.hpp>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
#include <Helpers/Bullet.hpp>
|
||||||
|
|
||||||
namespace RNR
|
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)
|
World::World(Ogre::Root* ogre, Ogre::SceneManager* ogreSceneManager)
|
||||||
{
|
{
|
||||||
Instance::setWorld(this);
|
Instance::setWorld(this);
|
||||||
|
|
@ -20,7 +36,7 @@ namespace RNR
|
||||||
btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();
|
btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();
|
||||||
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
|
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
|
||||||
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
|
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;
|
m_inputManager = 0;
|
||||||
|
|
||||||
|
|
@ -45,6 +61,11 @@ namespace RNR
|
||||||
m_runService = (RunService*)m_datamodel->getService("RunService");
|
m_runService = (RunService*)m_datamodel->getService("RunService");
|
||||||
m_players = (Players*)m_datamodel->getService("Players");
|
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);
|
m_tmb = new TopMenuBar(this);
|
||||||
|
|
||||||
Camera* start_cam = new Camera();
|
Camera* start_cam = new Camera();
|
||||||
|
|
@ -54,7 +75,8 @@ namespace RNR
|
||||||
|
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
//
|
m_runPhysics = false;
|
||||||
|
m_physicsThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::xmlAddItem(pugi::xml_node node, Instance* parent)
|
void World::xmlAddItem(pugi::xml_node node, Instance* parent)
|
||||||
|
|
@ -118,7 +140,6 @@ namespace RNR
|
||||||
WorldUndeserialized s = m_undeserialized.top();
|
WorldUndeserialized s = m_undeserialized.top();
|
||||||
m_undeserialized.pop();
|
m_undeserialized.pop();
|
||||||
|
|
||||||
s.instance->setParent(s.parent);
|
|
||||||
|
|
||||||
pugi::xml_node props = s.node.child("Properties");
|
pugi::xml_node props = s.node.child("Properties");
|
||||||
for(pugi::xml_node prop : props.children())
|
for(pugi::xml_node prop : props.children())
|
||||||
|
|
@ -126,6 +147,8 @@ namespace RNR
|
||||||
s.instance->deserializeXmlProperty(prop);
|
s.instance->deserializeXmlProperty(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.instance->setParent(s.parent);
|
||||||
|
|
||||||
if(s.instance->getClassName() == "Model")
|
if(s.instance->getClassName() == "Model")
|
||||||
{
|
{
|
||||||
ModelInstance* m = (ModelInstance*)s.instance;
|
ModelInstance* m = (ModelInstance*)s.instance;
|
||||||
|
|
@ -140,21 +163,66 @@ namespace RNR
|
||||||
m_workspace->build();
|
m_workspace->build();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::preStep()
|
void World::preRender(float timestep)
|
||||||
{
|
{
|
||||||
if(m_inputManager)
|
if(m_inputManager)
|
||||||
m_inputManager->frame();
|
m_inputManager->frame();
|
||||||
m_tmb->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)
|
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_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;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,4 +230,35 @@ namespace RNR
|
||||||
{
|
{
|
||||||
m_workspace->buildGeom();
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include <Helpers/Bullet.hpp>
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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:
|
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/)
|
- [Boost](https://www.boost.org/)
|
||||||
- [OGRE](https://github.com/OGRECave/ogre)
|
- [OGRE](https://github.com/OGRECave/ogre)
|
||||||
|
- [Bullet](https://github.com/bulletphysics/bullet3)
|
||||||
- [pugixml](https://github.com/zeux/pugixml)
|
- [pugixml](https://github.com/zeux/pugixml)
|
||||||
- [Qt 6](https://www.qt.io/product/qt6) (if building the player or studio projects)
|
- [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.
|
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
|
# License
|
||||||
RNR is licensed under two separate licenses:
|
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).
|
- 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).
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue