Merge branch 'trunk' of https://github.com/lrre-foss/rnr into trunk
|
|
@ -17,13 +17,13 @@ jobs:
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- name: Checkout repository
|
||||||
name: Clone repository
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- uses: msys2/setup-msys2@v2
|
- name: Set up MSYS2 and install required packages
|
||||||
name: Set up MSYS2 and install required packages
|
uses: msys2/setup-msys2@v2
|
||||||
with:
|
with:
|
||||||
msystem: ${{ matrix.sys }}
|
msystem: ${{ matrix.sys }}
|
||||||
install: >-
|
install: >-
|
||||||
|
|
@ -34,6 +34,7 @@ jobs:
|
||||||
mingw-w64-${{ matrix.env }}-pugixml
|
mingw-w64-${{ matrix.env }}-pugixml
|
||||||
mingw-w64-${{ matrix.env }}-ogre3d
|
mingw-w64-${{ matrix.env }}-ogre3d
|
||||||
mingw-w64-${{ matrix.env }}-qt6
|
mingw-w64-${{ matrix.env }}-qt6
|
||||||
|
mingw-w64-${{ matrix.env }}-bullet
|
||||||
|
|
||||||
- name: Generate Ninja build files
|
- name: Generate Ninja build files
|
||||||
run: cmake -G Ninja -B build -DCI=ON -DCMAKE_BUILD_TYPE=${{ matrix.configuration == 'Release' && 'MinSizeRel' || matrix.configuration }} .
|
run: cmake -G Ninja -B build -DCI=ON -DCMAKE_BUILD_TYPE=${{ matrix.configuration == 'Release' && 'MinSizeRel' || matrix.configuration }} .
|
||||||
|
|
@ -58,7 +59,7 @@ jobs:
|
||||||
run: mkdir build/dist/shaders && cp -R /${{ matrix.sys }}/share/OGRE/Media/Main/* build/dist/shaders && cp -R /${{ matrix.sys }}/share/OGRE/Media/RTShaderLib/* build/dist/shaders
|
run: mkdir build/dist/shaders && cp -R /${{ matrix.sys }}/share/OGRE/Media/Main/* build/dist/shaders && cp -R /${{ matrix.sys }}/share/OGRE/Media/RTShaderLib/* build/dist/shaders
|
||||||
|
|
||||||
- name: Add additional runtime dependencies
|
- name: Add additional runtime dependencies
|
||||||
run: ldd build/dist/*.exe | grep "=> /" | awk '{print $3}' | grep "clang64" | xargs -I '{}' cp -v '{}' build/dist
|
run: ldd build/dist/*.exe | grep "=> /" | awk '{print $3}' | grep "${{ matrix.sys }}" | xargs -I '{}' cp -v '{}' build/dist
|
||||||
|
|
||||||
- name: Set output variables
|
- name: Set output variables
|
||||||
id: vars
|
id: vars
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,13 @@ add_compile_options(-Wno-attributes -Wno-return-type) # Ignore warnings generate
|
||||||
find_package(Boost REQUIRED)
|
find_package(Boost REQUIRED)
|
||||||
find_package(OGRE REQUIRED COMPONENTS Bites CONFIG)
|
find_package(OGRE REQUIRED COMPONENTS Bites CONFIG)
|
||||||
find_package(pugixml REQUIRED)
|
find_package(pugixml REQUIRED)
|
||||||
|
find_package(Bullet CONFIG REQUIRED)
|
||||||
|
set(RNR_BULLET_LIBRARIES LinearMath Bullet3Common BulletDynamics BulletSoftBody BulletCollision BulletInverseDynamics)
|
||||||
|
|
||||||
add_subdirectory(Projects)
|
add_subdirectory(Projects)
|
||||||
|
|
||||||
if(CI AND UNIX)
|
if(CI AND UNIX)
|
||||||
file(COPY ${OGRE_MEDIA_DIR}/Main/ DESTINATION ${CMAKE_BINARY_DIR}/shaders)
|
file(COPY ${OGRE_MEDIA_DIR}/ShadowVolume/ DESTINATION ${CMAKE_BINARY_DIR}/shaders)
|
||||||
file(COPY ${OGRE_MEDIA_DIR}/RTShaderLib/ DESTINATION ${CMAKE_BINARY_DIR}/shaders)
|
file(COPY ${OGRE_MEDIA_DIR}/RTShaderLib/ DESTINATION ${CMAKE_BINARY_DIR}/shaders)
|
||||||
file(COPY ${OGRE_PLUGIN_DIR}/ DESTINATION ${CMAKE_BINARY_DIR}/plugins)
|
file(COPY ${OGRE_PLUGIN_DIR}/ DESTINATION ${CMAKE_BINARY_DIR}/plugins)
|
||||||
endif()
|
endif()
|
||||||
|
|
@ -16,7 +16,6 @@ material materials/partinstanced
|
||||||
|
|
||||||
rtshader_system
|
rtshader_system
|
||||||
{
|
{
|
||||||
transform_stage instanced
|
|
||||||
lighting_stage per_pixel
|
lighting_stage per_pixel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 6.4 KiB |
|
|
@ -34,6 +34,7 @@ namespace RNR
|
||||||
Ogre::SceneManager* ogreSceneManager;
|
Ogre::SceneManager* ogreSceneManager;
|
||||||
Ogre::Camera* ogreCamera;
|
Ogre::Camera* ogreCamera;
|
||||||
Ogre::Viewport* ogreViewport;
|
Ogre::Viewport* ogreViewport;
|
||||||
|
Ogre::Light* ogreSceneLight;
|
||||||
Ogre::RTShader::ShaderGenerator* ogreShaderGen;
|
Ogre::RTShader::ShaderGenerator* ogreShaderGen;
|
||||||
|
|
||||||
QCursor cursor;
|
QCursor cursor;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
#include <OgreWidget.hpp>
|
#include <OgreWidget.hpp>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include <OGRE/Bites/OgreSGTechniqueResolverListener.h>
|
#include <OGRE/Bites/OgreSGTechniqueResolverListener.h>
|
||||||
#include <OGRE/OgreDefaultDebugDrawer.h>
|
#include <OGRE/OgreDefaultDebugDrawer.h>
|
||||||
#include <OGRE/Overlay/OgreOverlaySystem.h>
|
#include <OGRE/Overlay/OgreOverlaySystem.h>
|
||||||
#include <OGRE/Overlay/OgreOverlayManager.h>
|
#include <OGRE/Overlay/OgreOverlayManager.h>
|
||||||
#include <OGRE/Overlay/OgreFontManager.h>
|
#include <OGRE/Overlay/OgreFontManager.h>
|
||||||
|
#include <App/V8/DataModel/Lighting.hpp>
|
||||||
|
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
|
|
@ -70,6 +72,11 @@ namespace RNR
|
||||||
if(Ogre::RTShader::ShaderGenerator::initialize())
|
if(Ogre::RTShader::ShaderGenerator::initialize())
|
||||||
{
|
{
|
||||||
ogreShaderGen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
ogreShaderGen = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
||||||
|
|
||||||
|
if (!std::filesystem::is_directory("ShaderCache") || !std::filesystem::exists("ShaderCache")) {
|
||||||
|
std::filesystem::create_directory("ShaderCache");
|
||||||
|
}
|
||||||
|
|
||||||
ogreShaderGen->setShaderCachePath("ShaderCache/");
|
ogreShaderGen->setShaderCachePath("ShaderCache/");
|
||||||
ogreShaderGen->addSceneManager(ogreSceneManager);
|
ogreShaderGen->addSceneManager(ogreSceneManager);
|
||||||
|
|
||||||
|
|
@ -90,19 +97,19 @@ namespace RNR
|
||||||
pFont->setTrueTypeSize(16);
|
pFont->setTrueTypeSize(16);
|
||||||
pFont->load();
|
pFont->load();
|
||||||
|
|
||||||
ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_ADDITIVE);
|
ogreSceneManager->setShadowTechnique(Ogre::ShadowTechnique::SHADOWTYPE_STENCIL_MODULATIVE);
|
||||||
ogreSceneManager->setShadowFarDistance(500.f);
|
ogreSceneManager->setShadowFarDistance(500.f);
|
||||||
|
|
||||||
Ogre::Light* light = ogreSceneManager->createLight("SunLight");
|
ogreSceneLight = ogreSceneManager->createLight("SunLight");
|
||||||
Ogre::SceneNode* lightNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode();
|
Ogre::SceneNode* lightNode = ogreSceneManager->getRootSceneNode()->createChildSceneNode();
|
||||||
lightNode->setPosition(0, 10, 15);
|
lightNode->setPosition(0, 10, 15);
|
||||||
lightNode->setDirection(-0.25, -0.5, -0.5);
|
lightNode->setDirection(-0.25, -0.5, -0.5);
|
||||||
lightNode->attachObject(light);
|
lightNode->attachObject(ogreSceneLight);
|
||||||
|
|
||||||
light->setCastShadows(true);
|
ogreSceneLight->setCastShadows(true);
|
||||||
light->setDiffuseColour(0.9, 0.9, 1.0);
|
ogreSceneLight->setDiffuseColour(0.9, 0.9, 1.0);
|
||||||
light->setSpecularColour(1.0, 1.0, 1.0);
|
ogreSceneLight->setSpecularColour(1.0, 1.0, 1.0);
|
||||||
light->setType(Ogre::Light::LT_DIRECTIONAL);
|
ogreSceneLight->setType(Ogre::Light::LT_DIRECTIONAL);
|
||||||
|
|
||||||
Ogre::MaterialManager::getSingletonPtr()->reloadAll();
|
Ogre::MaterialManager::getSingletonPtr()->reloadAll();
|
||||||
Ogre::MaterialManager::getSingletonPtr()->load("sky/null_plainsky512", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
Ogre::MaterialManager::getSingletonPtr()->load("sky/null_plainsky512", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||||
|
|
@ -127,6 +134,21 @@ namespace RNR
|
||||||
ogreCamera->getParentSceneNode()->setOrientation(Ogre::Quaternion(cam->getCFrame().getRotation()));
|
ogreCamera->getParentSceneNode()->setOrientation(Ogre::Quaternion(cam->getCFrame().getRotation()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RNR::Lighting* lighting = (RNR::Lighting*)world->getDatamodel()->getService("Lighting");
|
||||||
|
if(lighting)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 clearColor = lighting->getClearColor();
|
||||||
|
ogreViewport->setBackgroundColour(Ogre::ColourValue(clearColor.x, clearColor.y, clearColor.z));
|
||||||
|
Ogre::Vector3 shadowColor = lighting->getShadowColor();
|
||||||
|
ogreSceneManager->setShadowColour(Ogre::ColourValue(shadowColor.x, shadowColor.y, shadowColor.z));
|
||||||
|
Ogre::Vector3 topAmbient = lighting->getTopAmbient();
|
||||||
|
ogreSceneLight->setDiffuseColour(Ogre::ColourValue(topAmbient.x, topAmbient.y, topAmbient.z));
|
||||||
|
Ogre::Vector3 bottomAmbient = lighting->getBottomAmbient();
|
||||||
|
ogreSceneManager->setAmbientLight(Ogre::ColourValue(bottomAmbient.x, bottomAmbient.y, bottomAmbient.z));
|
||||||
|
Ogre::Vector3 spotLight = lighting->getSpotLight();
|
||||||
|
ogreSceneLight->setSpecularColour(Ogre::ColourValue(spotLight.x, spotLight.y, spotLight.z));
|
||||||
|
}
|
||||||
|
|
||||||
if(isVisible())
|
if(isVisible())
|
||||||
ogreRoot->renderOneFrame(this->delta);
|
ogreRoot->renderOneFrame(this->delta);
|
||||||
}
|
}
|
||||||
|
|
@ -198,7 +220,11 @@ namespace RNR
|
||||||
|
|
||||||
void OgreWidget::closeEvent(QCloseEvent* event)
|
void OgreWidget::closeEvent(QCloseEvent* event)
|
||||||
{
|
{
|
||||||
|
delete world;
|
||||||
|
|
||||||
ogreWindow->destroy();
|
ogreWindow->destroy();
|
||||||
|
ogreRoot->destroySceneManager(ogreSceneManager);
|
||||||
|
ogreRoot->shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPaintEngine* OgreWidget::paintEngine() const
|
QPaintEngine* OgreWidget::paintEngine() const
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,6 @@
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (!std::filesystem::is_directory("ShaderCache") || !std::filesystem::exists("ShaderCache")) {
|
|
||||||
std::filesystem::create_directory("ShaderCache");
|
|
||||||
}
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
MainWindow window = MainWindow();
|
MainWindow window = MainWindow();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ void MainWindow::widgetItemPrepare(QTreeWidgetItem* item, RNR::Instance* instanc
|
||||||
{
|
{
|
||||||
QString icon_path;
|
QString icon_path;
|
||||||
icon_path = "content/textures/studio/icons/";
|
icon_path = "content/textures/studio/icons/";
|
||||||
icon_path += instance->getClassName();
|
icon_path += instance->getExplorerIcon();
|
||||||
icon_path += ".png";
|
icon_path += ".png";
|
||||||
QIcon icon;
|
QIcon icon;
|
||||||
if(QFile::exists(icon_path))
|
if(QFile::exists(icon_path))
|
||||||
|
|
@ -138,7 +138,10 @@ void MainWindow::playSolo()
|
||||||
|
|
||||||
RNR::Players* players = (RNR::Players*)this->ogreWidget->world->getDatamodel()->getService("Players");
|
RNR::Players* players = (RNR::Players*)this->ogreWidget->world->getDatamodel()->getService("Players");
|
||||||
RNR::Player* player = players->createLocalPlayer(0);
|
RNR::Player* player = players->createLocalPlayer(0);
|
||||||
|
if(!player)
|
||||||
|
return;
|
||||||
player->setName(QInputDialog::getText(this, "Player Name", "Enter your player name").toLocal8Bit().data());
|
player->setName(QInputDialog::getText(this, "Player Name", "Enter your player name").toLocal8Bit().data());
|
||||||
|
player->loadCharacter();
|
||||||
|
|
||||||
updateTree(ogreWidget->world->getDatamodel());
|
updateTree(ogreWidget->world->getDatamodel());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ void PropertyViewer::view(RNR::Instance* instance)
|
||||||
QImage image;
|
QImage image;
|
||||||
QString icon_path;
|
QString icon_path;
|
||||||
icon_path = "content/textures/studio/icons/";
|
icon_path = "content/textures/studio/icons/";
|
||||||
icon_path += instance_ref->getClassName();
|
icon_path += instance_ref->getExplorerIcon();
|
||||||
icon_path += ".png";
|
icon_path += ".png";
|
||||||
if(QFile::exists(icon_path))
|
if(QFile::exists(icon_path))
|
||||||
image = QImage(icon_path);
|
image = QImage(icon_path);
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,6 @@
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (!std::filesystem::is_directory("ShaderCache") || !std::filesystem::exists("ShaderCache")) {
|
|
||||||
std::filesystem::create_directory("ShaderCache");
|
|
||||||
}
|
|
||||||
|
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
|
format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ add_library(Engine STATIC
|
||||||
Header/App/V8/DataModel/ForceField.hpp
|
Header/App/V8/DataModel/ForceField.hpp
|
||||||
Header/App/V8/DataModel/PartInstance.hpp
|
Header/App/V8/DataModel/PartInstance.hpp
|
||||||
Header/App/V8/DataModel/Light.hpp
|
Header/App/V8/DataModel/Light.hpp
|
||||||
|
Header/App/V8/DataModel/Lighting.hpp
|
||||||
Header/App/V8/DataModel/FaceInstance.hpp
|
Header/App/V8/DataModel/FaceInstance.hpp
|
||||||
Header/App/V8/DataModel/RunService.hpp
|
Header/App/V8/DataModel/RunService.hpp
|
||||||
Header/App/V8/DataModel/Workspace.hpp
|
Header/App/V8/DataModel/Workspace.hpp
|
||||||
|
|
@ -48,6 +49,7 @@ add_library(Engine STATIC
|
||||||
Source/App/V8/DataModel/ForceField.cpp
|
Source/App/V8/DataModel/ForceField.cpp
|
||||||
Source/App/V8/DataModel/PartInstance.cpp
|
Source/App/V8/DataModel/PartInstance.cpp
|
||||||
Source/App/V8/DataModel/Light.cpp
|
Source/App/V8/DataModel/Light.cpp
|
||||||
|
Source/App/V8/DataModel/Lighting.cpp
|
||||||
Source/App/V8/DataModel/FaceInstance.cpp
|
Source/App/V8/DataModel/FaceInstance.cpp
|
||||||
Source/App/V8/DataModel/RunService.cpp
|
Source/App/V8/DataModel/RunService.cpp
|
||||||
Source/App/V8/DataModel/Workspace.cpp
|
Source/App/V8/DataModel/Workspace.cpp
|
||||||
|
|
@ -65,5 +67,7 @@ add_library(Engine STATIC
|
||||||
Source/Rendering/Adorn.cpp
|
Source/Rendering/Adorn.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(Engine PUBLIC ${BOOST_INCLUDE_DIRS} Header/)
|
target_include_directories(Engine PUBLIC ${Boost_INCLUDE_DIRS} ${BULLET_ROOT_DIR}/${BULLET_INCLUDE_DIR} Header/)
|
||||||
target_link_libraries(Engine PUBLIC ${BOOST_LIBRARIES} pugixml OgreBites Luau.Analysis Luau.Ast Luau.Compiler Luau.VM)
|
target_compile_definitions(Engine PUBLIC ${BULLET_DEFINITIONS})
|
||||||
|
target_link_directories(Engine PUBLIC ${Bullet_DIR}/${BULLET_ROOT_DIR}/${BULLET_LIBRARY_DIRS})
|
||||||
|
target_link_libraries(Engine PUBLIC ${Boost_LIBRARIES} ${RNR_BULLET_LIBRARIES} pugixml OgreBites Luau.Analysis Luau.Ast Luau.Compiler Luau.VM)
|
||||||
|
|
@ -20,6 +20,7 @@ namespace RNR
|
||||||
PartInstance* getTorso();
|
PartInstance* getTorso();
|
||||||
PartInstance* getHead();
|
PartInstance* getHead();
|
||||||
|
|
||||||
|
void inputFrame(float dx, float dy);
|
||||||
void createHealthBar();
|
void createHealthBar();
|
||||||
|
|
||||||
float getHealth() { return m_health; };
|
float getHealth() { return m_health; };
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ namespace RNR
|
||||||
{
|
{
|
||||||
World* m_world;
|
World* m_world;
|
||||||
std::vector<int> scancodes_down;
|
std::vector<int> scancodes_down;
|
||||||
|
float m_mouseDX;
|
||||||
|
float m_mouseDY;
|
||||||
protected:
|
protected:
|
||||||
MouseState state;
|
MouseState state;
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace RNR
|
||||||
private:
|
private:
|
||||||
CoordinateFrame m_cframe;
|
CoordinateFrame m_cframe;
|
||||||
CoordinateFrame m_focus;
|
CoordinateFrame m_focus;
|
||||||
|
Ogre::Radian m_yaw;
|
||||||
virtual void deserializeProperty(char* prop_name, pugi::xml_node prop);
|
virtual void deserializeProperty(char* prop_name, pugi::xml_node prop);
|
||||||
virtual void addProperties(std::vector<ReflectionProperty>& properties);
|
virtual void addProperties(std::vector<ReflectionProperty>& properties);
|
||||||
public:
|
public:
|
||||||
|
|
@ -24,6 +25,7 @@ namespace RNR
|
||||||
virtual std::string getClassName() { return "Camera"; }
|
virtual std::string getClassName() { return "Camera"; }
|
||||||
CoordinateFrame& getCFrame() { return m_cframe; };
|
CoordinateFrame& getCFrame() { return m_cframe; };
|
||||||
CoordinateFrame& getFocus() { return m_focus; }
|
CoordinateFrame& getFocus() { return m_focus; }
|
||||||
|
Ogre::Radian getYaw() { return m_yaw; }
|
||||||
void setCFrame(CoordinateFrame cframe) { m_cframe = cframe; };
|
void setCFrame(CoordinateFrame cframe) { m_cframe = cframe; };
|
||||||
void setFocus(CoordinateFrame focus) { m_focus = focus; }
|
void setFocus(CoordinateFrame focus) { m_focus = focus; }
|
||||||
bool zoom(float distance);
|
bool zoom(float distance);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
#pragma once
|
||||||
|
#include <App/V8/Tree/Instance.hpp>
|
||||||
|
|
||||||
|
namespace RNR
|
||||||
|
{
|
||||||
|
class Lighting : public Instance
|
||||||
|
{
|
||||||
|
float m_brightness;
|
||||||
|
float m_geographicLatitude;
|
||||||
|
|
||||||
|
Ogre::Vector3 m_bottomAmbient;
|
||||||
|
Ogre::Vector3 m_topAmbient;
|
||||||
|
Ogre::Vector3 m_spotLight;
|
||||||
|
Ogre::Vector3 m_shadowColor;
|
||||||
|
Ogre::Vector3 m_clearColor;
|
||||||
|
|
||||||
|
virtual void addProperties(std::vector<ReflectionProperty>& properties);
|
||||||
|
virtual void deserializeProperty(char* prop_name, pugi::xml_node prop);
|
||||||
|
public:
|
||||||
|
Lighting();
|
||||||
|
|
||||||
|
void setBottomAmbient(Ogre::Vector3 color) { m_bottomAmbient = color; }
|
||||||
|
Ogre::Vector3 getBottomAmbient() { return m_bottomAmbient; }
|
||||||
|
void setTopAmbient(Ogre::Vector3 color) { m_topAmbient = color; }
|
||||||
|
Ogre::Vector3 getTopAmbient() { return m_topAmbient; }
|
||||||
|
void setSpotLight(Ogre::Vector3 color) { m_spotLight = color; }
|
||||||
|
Ogre::Vector3 getSpotLight() { return m_spotLight; }
|
||||||
|
void setShadowColor(Ogre::Vector3 color) { m_shadowColor = color; }
|
||||||
|
Ogre::Vector3 getShadowColor() { return m_shadowColor; }
|
||||||
|
void setClearColor(Ogre::Vector3 color) { m_clearColor = color; }
|
||||||
|
Ogre::Vector3 getClearColor() { return m_clearColor; }
|
||||||
|
|
||||||
|
virtual std::string getClassName() { return "Lighting"; }
|
||||||
|
virtual std::string getExplorerIcon() { return "PointLight"; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -13,8 +13,10 @@ namespace RNR
|
||||||
|
|
||||||
enum WorkspaceBatchingMode
|
enum WorkspaceBatchingMode
|
||||||
{
|
{
|
||||||
|
BATCH_DONT,
|
||||||
BATCH_INSTANCED,
|
BATCH_INSTANCED,
|
||||||
BATCH_STATIC_GEOMETRY,
|
BATCH_STATIC_GEOMETRY,
|
||||||
|
BATCH_DYNAMIC_RENDERABLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Workspace : public ModelInstance
|
class Workspace : public ModelInstance
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#include <OGRE/Ogre.h>
|
#include <OGRE/Ogre.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
@ -36,7 +37,7 @@ namespace RNR
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Instance();
|
Instance();
|
||||||
~Instance();
|
virtual ~Instance();
|
||||||
|
|
||||||
virtual std::vector<ReflectionProperty> getProperties();
|
virtual std::vector<ReflectionProperty> getProperties();
|
||||||
void deserializeXmlProperty(pugi::xml_node prop); // TODO: eventually replace this with a method that uses getProperties
|
void deserializeXmlProperty(pugi::xml_node prop); // TODO: eventually replace this with a method that uses getProperties
|
||||||
|
|
@ -61,6 +62,7 @@ namespace RNR
|
||||||
RNR::Instance* getParent() { return this->m_parent; };
|
RNR::Instance* getParent() { return this->m_parent; };
|
||||||
std::string getName() { return this->m_name; };
|
std::string getName() { return this->m_name; };
|
||||||
virtual std::string getClassName() { return "Instance"; }
|
virtual std::string getClassName() { return "Instance"; }
|
||||||
|
virtual std::string getExplorerIcon() { return getClassName(); }
|
||||||
|
|
||||||
void setParent(RNR::Instance* newParent);
|
void setParent(RNR::Instance* newParent);
|
||||||
void setName(std::string name);
|
void setName(std::string name);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ namespace RNR
|
||||||
|
|
||||||
CoordinateFrame& getCFrame() { return m_cframe; };
|
CoordinateFrame& getCFrame() { return m_cframe; };
|
||||||
void setCFrame(CoordinateFrame cframe) { m_cframe = cframe; };
|
void setCFrame(CoordinateFrame cframe) { m_cframe = cframe; };
|
||||||
|
Ogre::Vector3 relativePositionTo(PVInstance* point);
|
||||||
virtual std::string getClassName() { return "PVInstance"; }
|
virtual std::string getClassName() { return "PVInstance"; }
|
||||||
|
|
||||||
Ogre::Vector3 getPosition() { return m_cframe.getPosition(); }
|
Ogre::Vector3 getPosition() { return m_cframe.getPosition(); }
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@
|
||||||
#include <OGRE/Ogre.h>
|
#include <OGRE/Ogre.h>
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include "LinearMath/btVector3.h"
|
||||||
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
|
||||||
|
|
||||||
namespace RNR
|
namespace RNR
|
||||||
{
|
{
|
||||||
|
|
@ -28,6 +31,7 @@ namespace RNR
|
||||||
private:
|
private:
|
||||||
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;
|
||||||
DataModel* m_datamodel;
|
DataModel* m_datamodel;
|
||||||
Workspace* m_workspace;
|
Workspace* m_workspace;
|
||||||
RunService* m_runService;
|
RunService* m_runService;
|
||||||
|
|
@ -52,6 +56,7 @@ namespace RNR
|
||||||
double step(float timestep);
|
double step(float timestep);
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
btDiscreteDynamicsWorld* getDynamicsWorld() { return m_dynamicsWorld; }
|
||||||
float getLastDelta() { return m_lastDelta; }
|
float getLastDelta() { return m_lastDelta; }
|
||||||
DataModel* getDatamodel() { return m_datamodel; }
|
DataModel* getDatamodel() { return m_datamodel; }
|
||||||
void setInputManager(IInputManager* inputManager) { m_inputManager = inputManager; }
|
void setInputManager(IInputManager* inputManager) { m_inputManager = inputManager; }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace RNR
|
namespace RNR
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ namespace RNR
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Ogre::Vector3 getVector3(pugi::xml_node node);
|
static Ogre::Vector3 getVector3(pugi::xml_node node);
|
||||||
|
static Ogre::Vector3 getColor(pugi::xml_node node);
|
||||||
static CoordinateFrame getCFrame(pugi::xml_node node);
|
static CoordinateFrame getCFrame(pugi::xml_node node);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -11,6 +11,9 @@ namespace RNR
|
||||||
public:
|
public:
|
||||||
Player();
|
Player();
|
||||||
|
|
||||||
|
void initLocalPlayer();
|
||||||
|
void loadCharacter();
|
||||||
|
|
||||||
ModelInstance* getCharacter() { return m_character; }
|
ModelInstance* getCharacter() { return m_character; }
|
||||||
void setCharacter(ModelInstance* model) { m_character = model; }
|
void setCharacter(ModelInstance* model) { m_character = model; }
|
||||||
virtual std::string getClassName() { return "Player"; }
|
virtual std::string getClassName() { return "Player"; }
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ namespace RNR
|
||||||
void TopMenuBar::frame()
|
void TopMenuBar::frame()
|
||||||
{
|
{
|
||||||
Workspace* workspace = m_world->getWorkspace();
|
Workspace* workspace = m_world->getWorkspace();
|
||||||
|
btDiscreteDynamicsWorld* dynamicsWorld = m_world->getDynamicsWorld();
|
||||||
|
|
||||||
char debugtext[512];
|
char debugtext[512];
|
||||||
char render_debugtext[255];
|
char render_debugtext[255];
|
||||||
|
|
@ -127,7 +128,11 @@ 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",m_world->getLastDelta(),render_debugtext,m_world->getOgreSceneManager());
|
snprintf(debugtext, 512, "Render\nLast DT = %f\n%s\n\nPhysics\n%i objects, %i constraints",
|
||||||
|
m_world->getLastDelta(),
|
||||||
|
render_debugtext,
|
||||||
|
m_world->getOgreSceneManager(),
|
||||||
|
dynamicsWorld->getNumCollisionObjects(), dynamicsWorld->getNumConstraints());
|
||||||
m_debugText->setCaption(debugtext);
|
m_debugText->setCaption(debugtext);
|
||||||
|
|
||||||
Players* players = (Players*)m_world->getDatamodel()->getService("Players");
|
Players* players = (Players*)m_world->getDatamodel()->getService("Players");
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
#include <App/Humanoid/Humanoid.hpp>
|
#include <App/Humanoid/Humanoid.hpp>
|
||||||
#include <App/V8/World/World.hpp>
|
#include <App/V8/World/World.hpp>
|
||||||
|
#include <App/InputManager.hpp>
|
||||||
|
|
||||||
namespace RNR
|
namespace RNR
|
||||||
{
|
{
|
||||||
Humanoid::Humanoid()
|
Humanoid::Humanoid()
|
||||||
{
|
{
|
||||||
//
|
setName("Humanoid");
|
||||||
|
|
||||||
|
m_maxHealth = 100.f;
|
||||||
|
m_health = 100.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Humanoid::~Humanoid()
|
Humanoid::~Humanoid()
|
||||||
|
|
@ -42,13 +46,38 @@ namespace RNR
|
||||||
}
|
}
|
||||||
if(getNode())
|
if(getNode())
|
||||||
world->getOgreSceneManager()->destroySceneNode(getNode());
|
world->getOgreSceneManager()->destroySceneNode(getNode());
|
||||||
|
|
||||||
setNode(world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode());
|
setNode(world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode());
|
||||||
Ogre::BillboardSet* healthBarSet = world->getOgreSceneManager()->createBillboardSet("HumanoidHealth" + getParent()->getName());
|
Ogre::BillboardSet* healthBarSet = world->getOgreSceneManager()->createBillboardSet("HumanoidHealth" + getParent()->getName());
|
||||||
Ogre::Billboard* healthBarBillboard = healthBarSet->createBillboard(Ogre::Vector3(100, 0, 200));
|
healthBarSet->setBillboardType(Ogre::BillboardType::BBT_PERPENDICULAR_COMMON);
|
||||||
getNode()->attachObject(healthBarSet);
|
healthBarSet->setDebugDisplayEnabled(true);
|
||||||
getNode()->setPosition(getHead()->getPosition());
|
//Ogre::Billboard* healthBarBillboard = healthBarSet->createBillboard(Ogre::Vector3(0, 2, 0), Ogre::ColourValue(1, 0, 0, 1));
|
||||||
|
Ogre::Billboard* healthBarBillboardFilled = healthBarSet->createBillboard(Ogre::Vector3(0, 2, 0), Ogre::ColourValue(0, 1, 0, 1));
|
||||||
|
float healthBarScale = 0.5f;
|
||||||
|
//healthBarBillboard->setDimensions(5 * healthBarScale, 1 * healthBarScale);
|
||||||
|
healthBarBillboardFilled->setDimensions((m_health / m_maxHealth) * 5.f * healthBarScale, 1 * healthBarScale);
|
||||||
|
healthBarSet->setCastShadows(true);
|
||||||
|
|
||||||
printf("Humanoid::createHealthBar: WIP");
|
Ogre::BillboardSet* nameBarSet = world->getOgreSceneManager()->createBillboardSet("HumanoidName" + getParent()->getName());
|
||||||
|
nameBarSet->setDebugDisplayEnabled(true);
|
||||||
|
Ogre::FontPtr comic = Ogre::FontManager::getSingletonPtr()->getByName("ComicSans");
|
||||||
|
if(!comic)
|
||||||
|
printf("Humanoid::createHealthBar: comic == NULL\n");
|
||||||
|
comic->putText(nameBarSet, getParent()->getName(), 1);
|
||||||
|
int num_billboards = nameBarSet->getNumBillboards();
|
||||||
|
for(int i = 0; i < num_billboards; i++)
|
||||||
|
{
|
||||||
|
Ogre::Billboard* chara = nameBarSet->getBillboard(i);
|
||||||
|
Ogre::Vector3 chara_pos = chara->getPosition();
|
||||||
|
chara_pos.y += 2 + healthBarScale;
|
||||||
|
chara->setPosition(chara_pos);
|
||||||
|
}
|
||||||
|
getNode()->attachObject(healthBarSet);
|
||||||
|
getNode()->attachObject(nameBarSet);
|
||||||
|
getNode()->setPosition(getHead()->getPosition());
|
||||||
|
getNode()->setOrientation(getHead()->getRotation());
|
||||||
|
|
||||||
|
printf("Humanoid::createHealthBar: WIP\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Humanoid::deserializeProperty(char* prop_name, pugi::xml_node prop)
|
void Humanoid::deserializeProperty(char* prop_name, pugi::xml_node prop)
|
||||||
|
|
@ -63,6 +92,58 @@ namespace RNR
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Humanoid::inputFrame(float dx, float dy)
|
||||||
|
{
|
||||||
|
IInputManager* inputManager = world->getInputManager();
|
||||||
|
PartInstance* torso = getTorso();
|
||||||
|
Camera* camera = world->getWorkspace()->getCurrentCamera();
|
||||||
|
if(!torso)
|
||||||
|
{
|
||||||
|
printf("Humanoid::inputFrame: no torso\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(inputManager)
|
||||||
|
{
|
||||||
|
Ogre::Matrix3 camera_rotation;
|
||||||
|
camera_rotation.FromEulerAnglesYXZ(camera->getYaw(), Ogre::Radian(0), Ogre::Radian(0)); // we only want yaw because otherwise the movement target will go through the ground/in the air
|
||||||
|
Ogre::Quaternion direction = torso->getRotation();
|
||||||
|
Ogre::Quaternion new_direction = Ogre::Quaternion::nlerp(0.5f, direction, camera_rotation);
|
||||||
|
float forward = 0;
|
||||||
|
|
||||||
|
if(inputManager->isKeyDown('W'))
|
||||||
|
forward = 16;
|
||||||
|
|
||||||
|
Ogre::Vector3 move = Ogre::Vector3(0, 0, -forward);
|
||||||
|
move = direction * move;
|
||||||
|
move *= world->getLastDelta();
|
||||||
|
|
||||||
|
bool move_valid = true;
|
||||||
|
|
||||||
|
// TODO: collision checking
|
||||||
|
|
||||||
|
if(!move_valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(auto& child : *getParent()->getChildren())
|
||||||
|
{
|
||||||
|
PartInstance* bp = dynamic_cast<PartInstance*>(child);
|
||||||
|
if(bp)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 bp_p = bp->getPosition();
|
||||||
|
bp_p += move;
|
||||||
|
bp->getCFrame().setPosition(bp_p);
|
||||||
|
Ogre::Matrix3 new_rotation_matrix;
|
||||||
|
new_direction.ToRotationMatrix(new_rotation_matrix);
|
||||||
|
bp->getCFrame().setRotation(new_rotation_matrix);
|
||||||
|
bp->updateMatrix();
|
||||||
|
world->getWorkspace()->setDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
camera->getCFrame().setPosition(camera->getCFrame().getPosition() + move);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Humanoid::addProperties(std::vector<ReflectionProperty>& properties)
|
void Humanoid::addProperties(std::vector<ReflectionProperty>& properties)
|
||||||
{
|
{
|
||||||
ReflectionProperty _properties[] = {
|
ReflectionProperty _properties[] = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <App/InputManager.hpp>
|
#include <App/InputManager.hpp>
|
||||||
#include <App/V8/DataModel/Camera.hpp>
|
#include <App/V8/DataModel/Camera.hpp>
|
||||||
|
#include <App/Humanoid/Humanoid.hpp>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace RNR
|
namespace RNR
|
||||||
|
|
@ -9,8 +10,7 @@ namespace RNR
|
||||||
state.mouse_primary = false;
|
state.mouse_primary = false;
|
||||||
state.mouse_secondary = false;
|
state.mouse_secondary = false;
|
||||||
state.mouse_middle = false;
|
state.mouse_middle = false;
|
||||||
state.mouse_scroll = 0;
|
state.mouse_scroll = 0; }
|
||||||
}
|
|
||||||
|
|
||||||
void IInputManager::keyDown(int scancode)
|
void IInputManager::keyDown(int scancode)
|
||||||
{
|
{
|
||||||
|
|
@ -43,14 +43,14 @@ namespace RNR
|
||||||
{
|
{
|
||||||
if(m_world)
|
if(m_world)
|
||||||
{
|
{
|
||||||
float xd = x * m_world->getLastDelta();
|
m_mouseDX = x * m_world->getLastDelta();
|
||||||
float yd = y * m_world->getLastDelta();
|
m_mouseDY = y * m_world->getLastDelta();
|
||||||
|
|
||||||
Workspace* workspace = m_world->getWorkspace();
|
Workspace* workspace = m_world->getWorkspace();
|
||||||
Camera* camera = workspace->getCurrentCamera();
|
Camera* camera = workspace->getCurrentCamera();
|
||||||
if(camera && state.mouse_secondary)
|
if(camera && state.mouse_secondary)
|
||||||
{
|
{
|
||||||
camera->cameraFrame(xd, yd);
|
camera->cameraFrame(m_mouseDX, m_mouseDY);
|
||||||
|
|
||||||
resetMouse();
|
resetMouse();
|
||||||
}
|
}
|
||||||
|
|
@ -59,10 +59,29 @@ namespace RNR
|
||||||
|
|
||||||
void IInputManager::frame()
|
void IInputManager::frame()
|
||||||
{
|
{
|
||||||
Workspace* workspace = m_world->getWorkspace();
|
Players* players = (Players*)m_world->getDatamodel()->getService("Players");
|
||||||
Camera* camera = workspace->getCurrentCamera();
|
Player* localPlayer = players->getLocalPlayer();
|
||||||
if(camera)
|
if(localPlayer)
|
||||||
camera->cameraFrame(0, 0, false); // update camera position
|
{
|
||||||
|
ModelInstance* character = localPlayer->getCharacter();
|
||||||
|
if(character)
|
||||||
|
{
|
||||||
|
Humanoid* humanoid = (Humanoid*)character->findFirstChildOfType("Humanoid");
|
||||||
|
if(humanoid)
|
||||||
|
{
|
||||||
|
humanoid->inputFrame(m_mouseDX, m_mouseDY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Workspace* workspace = m_world->getWorkspace();
|
||||||
|
Camera* camera = workspace->getCurrentCamera();
|
||||||
|
if(camera)
|
||||||
|
camera->cameraFrame(0, 0, false); // update camera position
|
||||||
|
}
|
||||||
|
m_mouseDX = 0;
|
||||||
|
m_mouseDY = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IInputManager::mousePrimaryState(bool down)
|
void IInputManager::mousePrimaryState(bool down)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include <App/CoordinateFrame.hpp>
|
#include <App/CoordinateFrame.hpp>
|
||||||
#include <App/BrickColor.hpp>
|
#include <App/BrickColor.hpp>
|
||||||
#include <Helpers/Strings.hpp>
|
#include <Helpers/Strings.hpp>
|
||||||
#include <format>
|
|
||||||
|
|
||||||
namespace RNR
|
namespace RNR
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <App/V8/DataModel/Camera.hpp>
|
#include <App/V8/DataModel/Camera.hpp>
|
||||||
#include <App/V8/World/World.hpp>
|
#include <App/V8/World/World.hpp>
|
||||||
#include <App/InputManager.hpp>
|
#include <App/InputManager.hpp>
|
||||||
|
#include <Network/Players.hpp>
|
||||||
#include <Helpers/XML.hpp>
|
#include <Helpers/XML.hpp>
|
||||||
|
|
||||||
namespace RNR
|
namespace RNR
|
||||||
|
|
@ -40,6 +41,7 @@ namespace RNR
|
||||||
|
|
||||||
pitch = old_pitch + pitch;
|
pitch = old_pitch + pitch;
|
||||||
yaw = old_yaw - yaw;
|
yaw = old_yaw - yaw;
|
||||||
|
m_yaw = yaw;
|
||||||
|
|
||||||
Ogre::Matrix3 rotation;
|
Ogre::Matrix3 rotation;
|
||||||
rotation.FromEulerAnglesYXZ(yaw, pitch, Ogre::Radian(0));
|
rotation.FromEulerAnglesYXZ(yaw, pitch, Ogre::Radian(0));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include <App/V8/DataModel/Lighting.hpp>
|
||||||
|
#include <Helpers/XML.hpp>
|
||||||
|
|
||||||
|
namespace RNR
|
||||||
|
{
|
||||||
|
Lighting::Lighting()
|
||||||
|
{
|
||||||
|
setName("Lighting");
|
||||||
|
setClearColor(Ogre::Vector3(255.f/255.f,255.f/255.f,255.f/255.f));
|
||||||
|
setShadowColor(Ogre::Vector3(127.f/255.f,127.f/255.f,127.f/255.f));
|
||||||
|
setBottomAmbient(Ogre::Vector3(122.f/255.f,134.f/255.f,120.f/255.f));
|
||||||
|
setTopAmbient(Ogre::Vector3(209.f/255.f,208.f/255.f,217.f/255.f));
|
||||||
|
setSpotLight(Ogre::Vector3(191.f/255.f,191.f/255.f,191.f/255.f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lighting::deserializeProperty(char* prop_name, pugi::xml_node node)
|
||||||
|
{
|
||||||
|
if(prop_name == std::string("ClearColor"))
|
||||||
|
{
|
||||||
|
setClearColor(XML::getColor(node));
|
||||||
|
}
|
||||||
|
else if(prop_name == std::string("ShadowColor"))
|
||||||
|
{
|
||||||
|
setShadowColor(XML::getColor(node));
|
||||||
|
}
|
||||||
|
else if(prop_name == std::string("SpotLightV9"))
|
||||||
|
{
|
||||||
|
setSpotLight(XML::getColor(node));
|
||||||
|
}
|
||||||
|
else if(prop_name == std::string("BottomAmbientV9"))
|
||||||
|
{
|
||||||
|
setBottomAmbient(XML::getColor(node));
|
||||||
|
}
|
||||||
|
else if(prop_name == std::string("TopAmbientV9"))
|
||||||
|
{
|
||||||
|
setTopAmbient(XML::getColor(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lighting::addProperties(std::vector<ReflectionProperty>& properties)
|
||||||
|
{
|
||||||
|
ReflectionProperty _properties[] = {
|
||||||
|
{ this, std::string("BottomAmbientV9"), std::string(""),
|
||||||
|
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_VECTOR3,
|
||||||
|
REFLECTION_GETTER(Lighting* instance = (Lighting*)object; return &instance->m_bottomAmbient; ),
|
||||||
|
REFLECTION_SETTER(Lighting* instance = (Lighting*)object; instance->setBottomAmbient(*(Ogre::Vector3*)value); ) },
|
||||||
|
{ this, std::string("TopAmbientV9"), std::string(""),
|
||||||
|
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_VECTOR3,
|
||||||
|
REFLECTION_GETTER(Lighting* instance = (Lighting*)object; return &instance->m_topAmbient; ),
|
||||||
|
REFLECTION_SETTER(Lighting* instance = (Lighting*)object; instance->setTopAmbient(*(Ogre::Vector3*)value); ) },
|
||||||
|
{ this, std::string("ClearColor"), std::string(""),
|
||||||
|
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_VECTOR3,
|
||||||
|
REFLECTION_GETTER(Lighting* instance = (Lighting*)object; return &instance->m_clearColor; ),
|
||||||
|
REFLECTION_SETTER(Lighting* instance = (Lighting*)object; instance->setClearColor(*(Ogre::Vector3*)value); ) },
|
||||||
|
{ this, std::string("ShadowColor"), std::string(""),
|
||||||
|
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_VECTOR3,
|
||||||
|
REFLECTION_GETTER(Lighting* instance = (Lighting*)object; return &instance->m_shadowColor; ),
|
||||||
|
REFLECTION_SETTER(Lighting* instance = (Lighting*)object; instance->setShadowColor(*(Ogre::Vector3*)value); ) },
|
||||||
|
{ this, std::string("SpotLightV9"), std::string(""),
|
||||||
|
ACCESS_NONE, OPERATION_READWRITE, PROPERTY_VECTOR3,
|
||||||
|
REFLECTION_GETTER(Lighting* instance = (Lighting*)object; return &instance->m_spotLight; ),
|
||||||
|
REFLECTION_SETTER(Lighting* instance = (Lighting*)object; instance->setSpotLight(*(Ogre::Vector3*)value); ) },
|
||||||
|
};
|
||||||
|
|
||||||
|
properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ namespace RNR
|
||||||
Workspace::Workspace() : ModelInstance()
|
Workspace::Workspace() : ModelInstance()
|
||||||
{
|
{
|
||||||
setName("Workspace");
|
setName("Workspace");
|
||||||
m_batchMode = BATCH_STATIC_GEOMETRY;
|
m_batchMode = BATCH_DONT;
|
||||||
|
|
||||||
m_worldspawn = world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode();
|
m_worldspawn = world->getOgreSceneManager()->getRootSceneNode()->createChildSceneNode();
|
||||||
|
|
||||||
|
|
@ -19,9 +19,11 @@ namespace RNR
|
||||||
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(512,512,512));
|
m_geom->setRegionDimensions(Ogre::Vector3(2048,2048,2048));
|
||||||
m_geom->setCastShadows(true);
|
m_geom->setCastShadows(true);
|
||||||
break;
|
break;
|
||||||
|
case BATCH_DONT:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,11 +38,12 @@ namespace RNR
|
||||||
case BATCH_INSTANCED:
|
case BATCH_INSTANCED:
|
||||||
{
|
{
|
||||||
Ogre::Entity* childEntity = (Ogre::Entity*)childAdded->getObject();
|
Ogre::Entity* childEntity = (Ogre::Entity*)childAdded->getObject();
|
||||||
Ogre::InstancedEntity* replica = m_instanceManager->createInstancedEntity(childEntity->getSubEntity(0)->getMaterialName());
|
Ogre::InstancedEntity* replica = m_instanceManager->createInstancedEntity("materials/partinstanced");
|
||||||
replica->setPosition(part->getPosition());
|
replica->setPosition(part->getPosition());
|
||||||
replica->setOrientation(part->getCFrame().getRotation());
|
replica->setOrientation(part->getCFrame().getRotation());
|
||||||
replica->setScale(part->getSize());
|
replica->setScale(part->getSize());
|
||||||
childAdded->setObject(replica);
|
childAdded->setObject(replica);
|
||||||
|
child_node->setVisible(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BATCH_STATIC_GEOMETRY:
|
case BATCH_STATIC_GEOMETRY:
|
||||||
|
|
@ -48,10 +51,12 @@ namespace RNR
|
||||||
part->getPosition(),
|
part->getPosition(),
|
||||||
part->getCFrame().getRotation(),
|
part->getCFrame().getRotation(),
|
||||||
part->getSize());
|
part->getSize());
|
||||||
|
child_node->setVisible(false);
|
||||||
|
m_geomDirty = true;
|
||||||
|
break;
|
||||||
|
case BATCH_DONT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
child_node->setVisible(false);
|
|
||||||
m_geomDirty = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,17 @@ namespace RNR
|
||||||
Instance::~Instance()
|
Instance::~Instance()
|
||||||
{
|
{
|
||||||
setParent(NULL);
|
setParent(NULL);
|
||||||
|
if(getNode())
|
||||||
|
{
|
||||||
|
getNode()->removeAndDestroyAllChildren();
|
||||||
|
delete getNode();
|
||||||
|
}
|
||||||
|
if(getObject())
|
||||||
|
{
|
||||||
|
if(getObject()->getParentNode() != 0)
|
||||||
|
getObject()->detachFromParent();
|
||||||
|
delete getObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ReflectionProperty> Instance::getProperties()
|
std::vector<ReflectionProperty> Instance::getProperties()
|
||||||
|
|
@ -47,6 +58,8 @@ namespace RNR
|
||||||
pugi::xml_attribute prop_name = prop.attribute("name");
|
pugi::xml_attribute prop_name = prop.attribute("name");
|
||||||
if(prop_name.as_string() == std::string("Name"))
|
if(prop_name.as_string() == std::string("Name"))
|
||||||
setName(prop.text().as_string());
|
setName(prop.text().as_string());
|
||||||
|
else if(prop_name.as_string() == std::string("archivable"))
|
||||||
|
m_archivable = prop.text().as_bool();
|
||||||
else
|
else
|
||||||
deserializeProperty((char*)prop_name.as_string(), prop);
|
deserializeProperty((char*)prop_name.as_string(), prop);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,9 @@ namespace RNR
|
||||||
|
|
||||||
properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty)));
|
properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 PVInstance::relativePositionTo(PVInstance* point)
|
||||||
|
{
|
||||||
|
return point->getPosition() - getPosition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include <App/V8/World/World.hpp>
|
#include <App/V8/World/World.hpp>
|
||||||
#include <App/V8/Tree/InstanceFactory.hpp>
|
#include <App/V8/Tree/InstanceFactory.hpp>
|
||||||
#include <App/V8/DataModel/PartInstance.hpp>
|
#include <App/V8/DataModel/PartInstance.hpp>
|
||||||
|
#include <App/V8/DataModel/Lighting.hpp>
|
||||||
#include <App/GUI/SelectionBox.hpp>
|
#include <App/GUI/SelectionBox.hpp>
|
||||||
#include <App/Humanoid/Humanoid.hpp>
|
#include <App/Humanoid/Humanoid.hpp>
|
||||||
#include <App/InputManager.hpp>
|
#include <App/InputManager.hpp>
|
||||||
|
|
@ -14,6 +15,13 @@ namespace RNR
|
||||||
{
|
{
|
||||||
Instance::setWorld(this);
|
Instance::setWorld(this);
|
||||||
|
|
||||||
|
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||||
|
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
|
||||||
|
btBroadphaseInterface* overlappingPairCache = new btDbvtBroadphase();
|
||||||
|
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
|
||||||
|
m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
|
||||||
|
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
|
||||||
|
|
||||||
m_inputManager = 0;
|
m_inputManager = 0;
|
||||||
|
|
||||||
m_instanceFactory = new InstanceFactory();
|
m_instanceFactory = new InstanceFactory();
|
||||||
|
|
@ -27,6 +35,7 @@ namespace RNR
|
||||||
m_instanceFactory->registerInstance("RunService", InstanceFactory::instanceBuilder<RunService>);
|
m_instanceFactory->registerInstance("RunService", InstanceFactory::instanceBuilder<RunService>);
|
||||||
m_instanceFactory->registerInstance("Players", InstanceFactory::instanceBuilder<Players>);
|
m_instanceFactory->registerInstance("Players", InstanceFactory::instanceBuilder<Players>);
|
||||||
m_instanceFactory->registerInstance("Player", InstanceFactory::instanceBuilder<Player>);
|
m_instanceFactory->registerInstance("Player", InstanceFactory::instanceBuilder<Player>);
|
||||||
|
m_instanceFactory->registerInstance("Lighting", InstanceFactory::instanceBuilder<Lighting>);
|
||||||
|
|
||||||
m_ogreRoot = ogre;
|
m_ogreRoot = ogre;
|
||||||
m_ogreSceneManager = ogreSceneManager;
|
m_ogreSceneManager = ogreSceneManager;
|
||||||
|
|
@ -109,13 +118,14 @@ 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())
|
||||||
{
|
{
|
||||||
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,7 +150,10 @@ namespace RNR
|
||||||
double World::step(float timestep)
|
double World::step(float timestep)
|
||||||
{
|
{
|
||||||
if(m_runService && m_runService->getRunning())
|
if(m_runService && m_runService->getRunning())
|
||||||
|
{
|
||||||
m_runService->step(timestep);
|
m_runService->step(timestep);
|
||||||
|
m_dynamicsWorld->stepSimulation(timestep);
|
||||||
|
}
|
||||||
m_lastDelta = timestep;
|
m_lastDelta = timestep;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,16 @@ namespace RNR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ogre::Vector3 XML::getColor(pugi::xml_node node)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 rgb;
|
||||||
|
unsigned int hex = node.text().as_uint();
|
||||||
|
rgb.x = ((hex >> 16) & 0xff) / 255.0;
|
||||||
|
rgb.y = ((hex >> 8) & 0xff) / 255.0;
|
||||||
|
rgb.z = ((hex) & 0xff) / 255.0;
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
CoordinateFrame XML::getCFrame(pugi::xml_node node)
|
CoordinateFrame XML::getCFrame(pugi::xml_node node)
|
||||||
{
|
{
|
||||||
CoordinateFrame cframe;
|
CoordinateFrame cframe;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#include <Network/Player.hpp>
|
#include <Network/Player.hpp>
|
||||||
|
#include <App/Humanoid/Humanoid.hpp>
|
||||||
#include <App/V8/World/World.hpp>
|
#include <App/V8/World/World.hpp>
|
||||||
|
|
||||||
namespace RNR
|
namespace RNR
|
||||||
|
|
@ -22,4 +23,38 @@ namespace RNR
|
||||||
|
|
||||||
properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty)));
|
properties.insert(properties.end(), _properties, _properties+(sizeof(_properties)/sizeof(ReflectionProperty)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::initLocalPlayer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::loadCharacter()
|
||||||
|
{
|
||||||
|
m_character = new ModelInstance();
|
||||||
|
m_character->setName(getName());
|
||||||
|
|
||||||
|
PartInstance* head = new PartInstance();
|
||||||
|
head->setName("Head");
|
||||||
|
head->setSize(Ogre::Vector3(2, 1, 1));
|
||||||
|
head->setBrickColor(24);
|
||||||
|
head->getCFrame().setPosition(Ogre::Vector3(0, 1.5, 0));
|
||||||
|
head->updateMatrix();
|
||||||
|
head->setParent(m_character);
|
||||||
|
|
||||||
|
PartInstance* torso = new PartInstance();
|
||||||
|
torso->setName("Torso");
|
||||||
|
torso->setSize(Ogre::Vector3(2, 2, 1));
|
||||||
|
torso->setBrickColor(23);
|
||||||
|
torso->getCFrame().setPosition(Ogre::Vector3(0, 0, 0));
|
||||||
|
torso->updateMatrix();
|
||||||
|
torso->setParent(m_character);
|
||||||
|
|
||||||
|
Humanoid* character_humanoid = new Humanoid();
|
||||||
|
character_humanoid->setParent(m_character);
|
||||||
|
m_character->setParent(world->getWorkspace());
|
||||||
|
|
||||||
|
Camera* player_camera = world->getWorkspace()->getCurrentCamera();
|
||||||
|
player_camera->setCFrame(CoordinateFrame());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,12 @@ namespace RNR
|
||||||
{
|
{
|
||||||
if(m_localPlayer)
|
if(m_localPlayer)
|
||||||
{
|
{
|
||||||
printf("Players::createLocalPlayer: attempt to create another local player\n", userId);
|
printf("Players::createLocalPlayer: attempt to create another local player %i\n", userId);
|
||||||
return m_localPlayer;
|
return 0;
|
||||||
}
|
}
|
||||||
printf("Players::createLocalPlayer: created player %i\n", userId);
|
printf("Players::createLocalPlayer: created player %i\n", userId);
|
||||||
m_localPlayer = new Player();
|
m_localPlayer = new Player();
|
||||||
|
m_localPlayer->initLocalPlayer();
|
||||||
return m_localPlayer;
|
return m_localPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
# RNR
|
# RNR
|
||||||
[](https://github.com/lrre-foss/rnr/actions)
|
[](https://github.com/lrre-foss/rnr/actions)
|
||||||
|
[](https://discord.gg/2tj4TREby3)
|
||||||
[](https://github.com/lrre-foss/RNR/stargazers)
|
[](https://github.com/lrre-foss/RNR/stargazers)
|
||||||
[Discord](https://discord.gg/89WagAUr)
|
|
||||||
|
|
||||||
RNR (**R**NR's **N**ot **R**oblox) is a project that aims to recreate the look and feel of classic Roblox with new features while remaining partially compatible with clients from that era. It is built upon an engine that closely resembles Roblox's own at the time, referencing disassemblies of legacy client binaries.
|
RNR (**R**NR's **N**ot **R**oblox) is a project that aims to recreate the look and feel of classic Roblox with new features while remaining fully compatible with clients from that era. It is built upon an engine that closely resembles Roblox's own at the time, referencing disassemblies of legacy client binaries.
|
||||||
|
|
||||||
Interested in contributing? [Feel free to make a pull request!](https://github.com/lrre-foss/RNR/pulls)
|
Interested in contributing? [Feel free to make a pull request!](https://github.com/lrre-foss/RNR/pulls)
|
||||||
|
|
||||||
|
|
@ -13,6 +13,7 @@ There are several goals that RNR seeks to accomplish, them being;
|
||||||
- Easy-to-use (simple CLI options to launch and host games, as well as a level editor with a modern UI)
|
- Easy-to-use (simple CLI options to launch and host games, as well as a level editor with a modern UI)
|
||||||
- Fully compatible with Roblox versions up to 0.3.744.0 (dated April 2008) in areas such as hosting, joining, levels, etc.
|
- Fully compatible with Roblox versions up to 0.3.744.0 (dated April 2008) in areas such as hosting, joining, levels, etc.
|
||||||
- Incorporates all the various facets of the Roblox engine, plus a little bit extra (e.g. a network replication whitelist, fancy shader support, etc.)
|
- Incorporates all the various facets of the Roblox engine, plus a little bit extra (e.g. a network replication whitelist, fancy shader support, etc.)
|
||||||
|
- Made using clean-room reverse engineering
|
||||||
- Uses Roblox's [Luau](https://luau-lang.org/) as its scripting language while remaining fully compatible with classic Roblox scripts written using Lua 5.1
|
- Uses Roblox's [Luau](https://luau-lang.org/) as its scripting language while remaining fully compatible with classic Roblox scripts written using Lua 5.1
|
||||||
- As free and open-source as possible (with client code licensed under the GPL and the engine itself being released into the public domain, void of any copyright)
|
- As free and open-source as possible (with client code licensed under the GPL and the engine itself being released into the public domain, void of any copyright)
|
||||||
- Patching all the security vulnerabilities and fixing bugs/inefficiencies that legacy Roblox clients had
|
- Patching all the security vulnerabilities and fixing bugs/inefficiencies that legacy Roblox clients had
|
||||||
|
|
|
||||||