refactor: Make SceneGraph not a singleton

This commit is contained in:
Vsevolod Kremianskii 2020-09-28 18:58:08 +07:00
parent 0819b41a5e
commit 1791b2def6
42 changed files with 105 additions and 82 deletions

View file

@ -66,10 +66,11 @@ static const char kPartyLeaderTag[] = "party-leader";
static const char kPartyMember1Tag[] = "party-member-1";
static const char kPartyMember2Tag[] = "party-member-2";
Area::Area(uint32_t id, GameVersion version, ObjectFactory *objectFactory) :
Area::Area(uint32_t id, GameVersion version, ObjectFactory *objectFactory, SceneGraph *sceneGraph) :
Object(id, ObjectType::Area),
_version(version),
_objectFactory(objectFactory),
_sceneGraph(sceneGraph),
_navMesh(new NavMesh()) {
assert(_objectFactory);
@ -87,17 +88,16 @@ void Area::load(const string &name, const GffStruct &are, const GffStruct &git)
void Area::loadLYT() {
ResourceManager &resources = Resources;
SceneGraph &scene = TheSceneGraph;
LytFile lyt;
lyt.load(wrap(resources.find(_name, ResourceType::AreaLayout)));
for (auto &lytRoom : lyt.rooms()) {
shared_ptr<ModelSceneNode> model(new ModelSceneNode(resources.findModel(lytRoom.name)));
shared_ptr<ModelSceneNode> model(new ModelSceneNode(_sceneGraph, resources.findModel(lytRoom.name)));
model->setLocalTransform(glm::translate(glm::mat4(1.0f), lytRoom.position));
model->animate("animloop1", kAnimationLoop);
scene.addRoot(model);
_sceneGraph->addRoot(model);
shared_ptr<Walkmesh> walkmesh(resources.findWalkmesh(lytRoom.name, ResourceType::Walkmesh));
unique_ptr<Room> room(new Room(lytRoom.name, lytRoom.position, model, walkmesh));
@ -134,10 +134,10 @@ void Area::loadPTH() {
}
pointZ.insert(make_pair(i, z));
shared_ptr<CubeSceneNode> aabb(new CubeSceneNode(0.5f));
shared_ptr<CubeSceneNode> aabb(new CubeSceneNode(_sceneGraph, 0.5f));
aabb->setLocalTransform(glm::translate(glm::mat4(1.0f), glm::vec3(point.x, point.y, z + 0.25f)));
TheSceneGraph.addRoot(aabb);
_sceneGraph->addRoot(aabb);
}
_navMesh->load(paths, pointZ);
@ -167,7 +167,8 @@ void Area::loadAmbientColor(const GffStruct &are) {
(ambientColorValue >> 16) & 0xff);
ambientColor /= 255.0f;
TheSceneGraph.setAmbientLightColor(ambientColor);
_sceneGraph->setAmbientLightColor(ambientColor);
}
void Area::loadScripts(const GffStruct &are) {
@ -248,7 +249,7 @@ void Area::add(const shared_ptr<SpatialObject> &object) {
shared_ptr<ModelSceneNode> sceneNode(object->model());
if (sceneNode) {
TheSceneGraph.addRoot(sceneNode);
_sceneGraph->addRoot(sceneNode);
}
determineObjectRoom(*object);
}
@ -427,7 +428,7 @@ void Area::update(const UpdateContext &updateCtx) {
updateSelection();
TheSceneGraph.prepare(updateCtx.cameraPosition);
_sceneGraph->prepare(updateCtx.cameraPosition);
}
void Area::updateDelayedCommands() {

View file

@ -22,6 +22,7 @@
#include "../gui/types.h"
#include "../net/types.h"
#include "../render/camera/camera.h"
#include "../render/scene/scenegraph.h"
#include "../render/types.h"
#include "../resources/types.h"
#include "../script/variable.h"
@ -47,7 +48,8 @@ public:
Area(
uint32_t id,
resources::GameVersion version,
ObjectFactory *objectFactory);
ObjectFactory *objectFactory,
render::SceneGraph *sceneGraph);
void load(const std::string &name, const resources::GffStruct &are, const resources::GffStruct &git);
void loadParty(const PartyConfiguration &party, const glm::vec3 &position, float heading);
@ -96,6 +98,7 @@ public:
protected:
ObjectFactory *_objectFactory { nullptr };
render::SceneGraph *_sceneGraph { nullptr };
bool _scriptsEnabled { true };
std::function<void()> _onPlayerChanged;

View file

@ -72,7 +72,7 @@ void Game::initGameVersion() {
}
void Game::initObjectFactory() {
_objectFactory = make_unique<ObjectFactory>(_version, _options);
_objectFactory = make_unique<ObjectFactory>(_version, &_sceneGraph, _options);
}
int Game::run() {
@ -157,7 +157,7 @@ void Game::loadNextModule() {
if (_module) {
_module->saveTo(_state);
}
TheSceneGraph.clear();
_sceneGraph.clear();
loadModule(_nextModule, _state.party, _nextEntry);
_nextModule.clear();
@ -221,7 +221,7 @@ void Game::drawWorld() {
case Screen::InGame:
case Screen::Dialog:
case Screen::Container:
TheSceneGraph.render();
_sceneGraph.render();
break;
default:
break;

View file

@ -20,6 +20,7 @@
#include "../audio/soundinstance.h"
#include "../audio/types.h"
#include "../gui/gui.h"
#include "../render/scene/scenegraph.h"
#include "../render/window.h"
#include "../resources/types.h"
@ -87,6 +88,7 @@ protected:
Options _options;
resources::GameVersion _version { resources::GameVersion::KotOR };
std::unique_ptr<ObjectFactory> _objectFactory;
render::SceneGraph _sceneGraph;
std::shared_ptr<Module> _module;
std::string _nextModule;
Screen _screen { Screen::MainMenu };

View file

@ -81,7 +81,7 @@ void MainMenu::load(GameVersion version) {
transform = glm::scale(transform, glm::vec3(scale));
Control::Scene3D scene;
scene.model = make_shared<ModelSceneNode>(Resources.findModel("mainmenu"));
scene.model = make_shared<ModelSceneNode>(nullptr, Resources.findModel("mainmenu"));
scene.transform = move(transform);
control.setScene3D(scene);

View file

@ -34,9 +34,10 @@ MultiplayerArea::MultiplayerArea(
GameVersion version,
MultiplayerMode mode,
ObjectFactory *objectFactory,
SceneGraph *sceneGraph,
IMultiplayerCallbacks *callbacks
) :
Area(id, version, objectFactory), _callbacks(callbacks) {
Area(id, version, objectFactory, sceneGraph), _callbacks(callbacks) {
_scriptsEnabled = mode == MultiplayerMode::Server;
}
@ -75,7 +76,7 @@ void MultiplayerArea::execute(const Command &cmd) {
}
}
void MultiplayerArea::executeLoadCreature(const Command &cmd) {
shared_ptr<Creature> creature(new MultiplayerCreature(cmd.objectId(), _objectFactory, _callbacks));
shared_ptr<Creature> creature(new MultiplayerCreature(cmd.objectId(), _objectFactory, _sceneGraph, _callbacks));
creature->setTag(cmd.tag());
for (auto &item : cmd.equipment()) {

View file

@ -33,6 +33,7 @@ public:
resources::GameVersion version,
MultiplayerMode mode,
ObjectFactory *objectFactory,
render::SceneGraph *sceneGraph,
IMultiplayerCallbacks *callbacks);
void execute(const Command &cmd);

View file

@ -21,12 +21,14 @@
using namespace std;
using namespace reone::render;
namespace reone {
namespace game {
MultiplayerCreature::MultiplayerCreature(uint32_t id, ObjectFactory *objectFactory, IMultiplayerCallbacks *callbacks) :
Creature(id, objectFactory), _callbacks(callbacks) {
MultiplayerCreature::MultiplayerCreature(uint32_t id, ObjectFactory *objectFactory, SceneGraph *sceneGraph, IMultiplayerCallbacks *callbacks) :
Creature(id, objectFactory, sceneGraph), _callbacks(callbacks) {
}
void MultiplayerCreature::setClientTag(const string &clientTag) {

View file

@ -27,7 +27,11 @@ class IMultiplayerCallbacks;
class MultiplayerCreature : public Creature {
public:
MultiplayerCreature(uint32_t id, ObjectFactory *objectFactory, IMultiplayerCallbacks *callbacks);
MultiplayerCreature(
uint32_t id,
ObjectFactory *objectFactory,
render::SceneGraph *sceneGraph,
IMultiplayerCallbacks *callbacks);
void setClientTag(const std::string &clientTag);

View file

@ -21,11 +21,14 @@
using namespace std;
using namespace reone::render;
namespace reone {
namespace game {
MultiplayerDoor::MultiplayerDoor(uint32_t id, IMultiplayerCallbacks *callbacks) : Door(id), _callbacks(callbacks) {
MultiplayerDoor::MultiplayerDoor(uint32_t id, SceneGraph *sceneGraph, IMultiplayerCallbacks *callbacks) :
Door(id, sceneGraph), _callbacks(callbacks) {
}
void MultiplayerDoor::open(const shared_ptr<Object> &trigerrer) {

View file

@ -27,7 +27,7 @@ class IMultiplayerCallbacks;
class MultiplayerDoor : public Door {
public:
MultiplayerDoor(uint32_t id, IMultiplayerCallbacks *callbacks);
MultiplayerDoor(uint32_t id, render::SceneGraph *sceneGraph, IMultiplayerCallbacks *callbacks);
void open(const std::shared_ptr<Object> &trigerrer) override;

View file

@ -42,7 +42,7 @@ MultiplayerGame::MultiplayerGame(MultiplayerMode mode, const fs::path &path, con
}
void MultiplayerGame::initObjectFactory() {
_objectFactory = unique_ptr<ObjectFactory>(new MultiplayerObjectFactory(_version, _mode, this, _options));
_objectFactory = unique_ptr<ObjectFactory>(new MultiplayerObjectFactory(_version, _mode, &_sceneGraph, this, _options));
}
void MultiplayerGame::configure() {

View file

@ -33,22 +33,23 @@ namespace game {
MultiplayerObjectFactory::MultiplayerObjectFactory(
GameVersion version,
MultiplayerMode mode,
render::SceneGraph *sceneGraph,
IMultiplayerCallbacks *callbacks,
const Options &opts
) :
ObjectFactory(version, opts), _mode(mode), _callbacks(callbacks) {
ObjectFactory(version, sceneGraph, opts), _mode(mode), _callbacks(callbacks) {
}
unique_ptr<Area> MultiplayerObjectFactory::newArea() {
return make_unique<MultiplayerArea>(_counter++, _version, _mode, this, _callbacks);
return make_unique<MultiplayerArea>(_counter++, _version, _mode, this, _sceneGraph, _callbacks);
}
unique_ptr<Creature> MultiplayerObjectFactory::newCreature() {
return make_unique<MultiplayerCreature>(_counter++, this, _callbacks);
return make_unique<MultiplayerCreature>(_counter++, this, _sceneGraph, _callbacks);
}
unique_ptr<Door> MultiplayerObjectFactory::newDoor() {
return make_unique<MultiplayerDoor>(_counter++, _callbacks);
return make_unique<MultiplayerDoor>(_counter++, _sceneGraph, _callbacks);
}
} // namespace game

View file

@ -30,6 +30,7 @@ public:
MultiplayerObjectFactory(
resources::GameVersion version,
MultiplayerMode mode,
render::SceneGraph *sceneGraph,
IMultiplayerCallbacks *callbacks,
const Options &opts);

View file

@ -63,8 +63,8 @@ Creature::Action::Action(ActionType type, const shared_ptr<Object> &object, floa
Creature::Action::Action(ActionType type, const ExecutionContext &ctx) : type(type), context(ctx) {
}
Creature::Creature(uint32_t id, ObjectFactory *objectFactory) :
SpatialObject(id, ObjectType::Creature), _objectFactory(objectFactory) {
Creature::Creature(uint32_t id, ObjectFactory *objectFactory, SceneGraph *sceneGraph) :
SpatialObject(id, ObjectType::Creature, sceneGraph), _objectFactory(objectFactory) {
assert(_objectFactory);
_drawDistance = 2048.0f;
@ -130,7 +130,7 @@ void Creature::updateAppearance() {
// Body
if (!_model) {
_model = make_unique<ModelSceneNode>(Resources.findModel(bodyModelName));
_model = make_unique<ModelSceneNode>(_sceneGraph, Resources.findModel(bodyModelName));
_model->setLightingEnabled(true);
} else {
_model->setModel(Resources.findModel(bodyModelName));

View file

@ -71,7 +71,7 @@ public:
int pointIdx { 0 };
};
Creature(uint32_t id, ObjectFactory *objectFactory);
Creature(uint32_t id, ObjectFactory *objectFactory, render::SceneGraph *sceneGraph);
void load(const resources::GffStruct &gffs);
void load(const CreatureConfiguration &config);

View file

@ -34,7 +34,7 @@ namespace reone {
namespace game {
Door::Door(uint32_t id) : SpatialObject(id, ObjectType::Door) {
Door::Door(uint32_t id, SceneGraph *sceneGraph) : SpatialObject(id, ObjectType::Door, sceneGraph) {
_drawDistance = FLT_MAX;
_fadeDistance = 0.25f * _drawDistance;
_selectable = true;
@ -75,7 +75,7 @@ void Door::loadBlueprint(const string &resRef) {
string model(table->getString(_blueprint->genericType(), "modelname"));
boost::to_lower(model);
_model = make_unique<ModelSceneNode>(resources.findModel(model));
_model = make_unique<ModelSceneNode>(_sceneGraph, resources.findModel(model));
_walkmesh = resources.findWalkmesh(model + "0", ResourceType::DoorWalkmesh);
}

View file

@ -29,7 +29,7 @@ namespace game {
class Door : public SpatialObject {
public:
Door(uint32_t id);
Door(uint32_t id, render::SceneGraph *sceneGraph);
void load(const resources::GffStruct &gffs);
virtual void open(const std::shared_ptr<Object> &triggerrer);

View file

@ -19,14 +19,15 @@
using namespace std;
using namespace reone::render;
using namespace reone::resources;
namespace reone {
namespace game {
ObjectFactory::ObjectFactory(GameVersion version, const Options &opts) :
_version(version), _options(opts) {
ObjectFactory::ObjectFactory(GameVersion version, SceneGraph *sceneGraph, const Options &opts) :
_version(version), _sceneGraph(sceneGraph), _options(opts) {
}
unique_ptr<Module> ObjectFactory::newModule() {
@ -34,27 +35,27 @@ unique_ptr<Module> ObjectFactory::newModule() {
}
unique_ptr<Area> ObjectFactory::newArea() {
return make_unique<Area>(_counter++, _version, this);
return make_unique<Area>(_counter++, _version, this, _sceneGraph);
}
unique_ptr<Creature> ObjectFactory::newCreature() {
return make_unique<Creature>(_counter++, this);
return make_unique<Creature>(_counter++, this, _sceneGraph);
}
unique_ptr<Placeable> ObjectFactory::newPlaceable() {
return make_unique<Placeable>(_counter++, this);
return make_unique<Placeable>(_counter++, this, _sceneGraph);
}
unique_ptr<Door> ObjectFactory::newDoor() {
return make_unique<Door>(_counter++);
return make_unique<Door>(_counter++, _sceneGraph);
}
unique_ptr<Waypoint> ObjectFactory::newWaypoint() {
return make_unique<Waypoint>(_counter++);
return make_unique<Waypoint>(_counter++, _sceneGraph);
}
unique_ptr<Trigger> ObjectFactory::newTrigger() {
return make_unique<Trigger>(_counter++);
return make_unique<Trigger>(_counter++, _sceneGraph);
}
unique_ptr<Item> ObjectFactory::newItem() {

View file

@ -20,6 +20,7 @@
#include <cstdint>
#include <memory>
#include "../../render/scene/scenegraph.h"
#include "../../resources/types.h"
#include "../area.h"
@ -38,7 +39,7 @@ namespace game {
class ObjectFactory {
public:
ObjectFactory(resources::GameVersion version, const Options &opts);
ObjectFactory(resources::GameVersion version, render::SceneGraph *sceneGraph, const Options &opts);
virtual std::unique_ptr<Module> newModule();
virtual std::unique_ptr<Area> newArea();
@ -51,6 +52,7 @@ public:
protected:
resources::GameVersion _version { resources::GameVersion::KotOR };
render::SceneGraph *_sceneGraph { nullptr };
Options _options;
uint32_t _counter { 2 }; // ids 0 and 1 are reserved

View file

@ -36,8 +36,8 @@ namespace reone {
namespace game {
Placeable::Placeable(uint32_t id, ObjectFactory *objectFactory) :
SpatialObject(id, ObjectType::Placeable),
Placeable::Placeable(uint32_t id, ObjectFactory *objectFactory, SceneGraph *sceneGraph) :
SpatialObject(id, ObjectType::Placeable, sceneGraph),
_objectFactory(objectFactory) {
assert(_objectFactory);
@ -69,7 +69,7 @@ void Placeable::loadBlueprint(const string &resRef) {
string model(table->getString(_blueprint->appearance(), "modelname"));
boost::to_lower(model);
_model = make_unique<ModelSceneNode>(Resources.findModel(model));
_model = make_unique<ModelSceneNode>(_sceneGraph, Resources.findModel(model));
_model->setLightingEnabled(true);
_walkmesh = Resources.findWalkmesh(model, ResourceType::PlaceableWalkmesh);

View file

@ -33,7 +33,7 @@ class ObjectFactory;
class Placeable : public SpatialObject {
public:
Placeable(uint32_t id, ObjectFactory *objectFactory);
Placeable(uint32_t id, ObjectFactory *objectFactory, render::SceneGraph *sceneGraph);
void load(const resources::GffStruct &gffs);

View file

@ -32,7 +32,8 @@ namespace reone {
namespace game {
SpatialObject::SpatialObject(uint32_t id, ObjectType type) : Object(id, type) {
SpatialObject::SpatialObject(uint32_t id, ObjectType type, SceneGraph *sceneGraph) :
Object(id, type), _sceneGraph(sceneGraph) {
}
float SpatialObject::distanceTo(const glm::vec2 &point) const {

View file

@ -72,6 +72,7 @@ public:
// END Animation
protected:
render::SceneGraph *_sceneGraph { nullptr };
glm::vec3 _position { 0.0f };
float _heading { 0.0f };
glm::mat4 _transform { 1.0f };
@ -83,7 +84,7 @@ protected:
std::vector<std::shared_ptr<Item>> _items;
bool _selectable { false };
SpatialObject(uint32_t id, ObjectType type);
SpatialObject(uint32_t id, ObjectType type, render::SceneGraph *sceneGraph);
virtual void updateTransform();
};

View file

@ -23,13 +23,14 @@
using namespace std;
using namespace reone::render;
using namespace reone::resources;
namespace reone {
namespace game {
Trigger::Trigger(uint32_t id) : SpatialObject(id, ObjectType::Trigger) {
Trigger::Trigger(uint32_t id, SceneGraph *sceneGraph) : SpatialObject(id, ObjectType::Trigger, sceneGraph) {
}
void Trigger::load(const GffStruct &gffs) {

View file

@ -27,7 +27,7 @@ namespace game {
class Trigger : public SpatialObject {
public:
Trigger(uint32_t id);
Trigger(uint32_t id, render::SceneGraph *sceneGraph);
void load(const resources::GffStruct &gffs);

View file

@ -21,13 +21,14 @@
#include "glm/glm.hpp"
using namespace reone::render;
using namespace reone::resources;
namespace reone {
namespace game {
Waypoint::Waypoint(uint32_t id) : SpatialObject(id, ObjectType::Waypoint) {
Waypoint::Waypoint(uint32_t id, SceneGraph *sceneGraph) : SpatialObject(id, ObjectType::Waypoint, sceneGraph) {
}
void Waypoint::load(const GffStruct &gffs) {

View file

@ -27,7 +27,7 @@ namespace game {
class Waypoint : public SpatialObject {
public:
Waypoint(uint32_t id);
Waypoint(uint32_t id, render::SceneGraph *sceneGraph);
void load(const resources::GffStruct &gffs);
};

View file

@ -27,7 +27,7 @@ namespace reone {
namespace render {
AABBSceneNode::AABBSceneNode(const AABB &aabb) : _aabb(aabb) {
AABBSceneNode::AABBSceneNode(SceneGraph *sceneGraph, const AABB &aabb) : SceneNode(sceneGraph), _aabb(aabb) {
}
void AABBSceneNode::render() const {

View file

@ -27,7 +27,7 @@ namespace render {
class AABBSceneNode : public SceneNode {
public:
AABBSceneNode(const AABB &abbb);
AABBSceneNode(SceneGraph *sceneGraph, const AABB &abbb);
void render() const override;

View file

@ -27,7 +27,7 @@ namespace reone {
namespace render {
CubeSceneNode::CubeSceneNode(float size) : _size(size) {
CubeSceneNode::CubeSceneNode(SceneGraph *sceneGraph, float size) : SceneNode(sceneGraph), _size(size) {
}
void CubeSceneNode::render() const {

View file

@ -25,7 +25,7 @@ namespace render {
class CubeSceneNode : public SceneNode {
public:
CubeSceneNode(float size);
CubeSceneNode(SceneGraph *sceneGraph, float size);
void render() const override;

View file

@ -25,12 +25,12 @@ namespace reone {
namespace render {
LightSceneNode::LightSceneNode(const ModelNode *modelNode) : _modelNode(modelNode) {
LightSceneNode::LightSceneNode(SceneGraph *sceneGraph, const ModelNode *modelNode) : SceneNode(sceneGraph), _modelNode(modelNode) {
assert(_modelNode);
}
void LightSceneNode::fillSceneGraph() {
TheSceneGraph.addLight(this);
_sceneGraph->addLight(this);
}
const ModelNode &LightSceneNode::modelNode() const {

View file

@ -27,7 +27,7 @@ class ModelNode;
class LightSceneNode : public SceneNode {
public:
LightSceneNode(const ModelNode *modelNode);
LightSceneNode(SceneGraph *sceneGraph, const ModelNode *modelNode);
void fillSceneGraph() override;

View file

@ -31,16 +31,17 @@ namespace reone {
namespace render {
MeshSceneNode::MeshSceneNode(const ModelSceneNode *model, const ModelNode *modelNode) : _model(model), _modelNode(modelNode) {
MeshSceneNode::MeshSceneNode(SceneGraph *sceneGraph, const ModelSceneNode *model, const ModelNode *modelNode) :
SceneNode(sceneGraph), _model(model), _modelNode(modelNode) {
assert(_model && _modelNode);
}
void MeshSceneNode::fillSceneGraph() {
SceneGraph &scene = TheSceneGraph;
if (isTransparent()) {
scene.addTransparentMesh(this);
_sceneGraph->addTransparentMesh(this);
} else {
scene.addOpaqueMesh(this);
_sceneGraph->addOpaqueMesh(this);
}
SceneNode::fillSceneGraph();
}
@ -128,7 +129,7 @@ void MeshSceneNode::render() const {
shaders.setUniform("lightingEnabled", true);
shaders.setUniform("lightCount", lightCount);
shaders.setUniform("ambientLightColor", TheSceneGraph.ambientLightColor());
shaders.setUniform("ambientLightColor", _sceneGraph->ambientLightColor());
for (int i = 0; i < lightCount; ++i) {
LightSceneNode *light = lights[i];

View file

@ -32,7 +32,7 @@ class ModelSceneNode;
class MeshSceneNode : public SceneNode {
public:
MeshSceneNode(const ModelSceneNode *model, const ModelNode *modelNode);
MeshSceneNode(SceneGraph *sceneGraph, const ModelSceneNode *model, const ModelNode *modelNode);
void fillSceneGraph() override;
void updateDistanceToCamera(const glm::vec3 &cameraPosition);

View file

@ -40,7 +40,7 @@ namespace reone {
namespace render {
ModelSceneNode::ModelSceneNode(const shared_ptr<Model> &model) : _model(model) {
ModelSceneNode::ModelSceneNode(SceneGraph *sceneGraph, const shared_ptr<Model> &model) : SceneNode(sceneGraph), _model(model) {
assert(_model);
initChildren();
}
@ -57,11 +57,11 @@ void ModelSceneNode::initChildren() {
nodes.push(child.get());
}
if (shouldRender(*node)) {
shared_ptr<MeshSceneNode> mesh(new MeshSceneNode(this, node));
shared_ptr<MeshSceneNode> mesh(new MeshSceneNode(_sceneGraph, this, node));
mesh->setParent(this);
mesh->setLocalTransform(node->absoluteTransform());
shared_ptr<AABBSceneNode> aabb(new AABBSceneNode(node->mesh()->aabb()));
shared_ptr<AABBSceneNode> aabb(new AABBSceneNode(_sceneGraph, node->mesh()->aabb()));
mesh->addChild(aabb);
_meshes.insert(make_pair(node->nodeNumber(), mesh));
@ -69,7 +69,7 @@ void ModelSceneNode::initChildren() {
shared_ptr<ModelNode::Light> modelLight(node->light());
if (modelLight) {
shared_ptr<LightSceneNode> light(new LightSceneNode(node));
shared_ptr<LightSceneNode> light(new LightSceneNode(_sceneGraph, node));
light->setParent(this);
light->setLocalTransform(node->absoluteTransform());
@ -144,7 +144,7 @@ void ModelSceneNode::attach(const string &parentNode, const shared_ptr<Model> &m
}
if (model) {
shared_ptr<ModelSceneNode> child(new ModelSceneNode(model));
shared_ptr<ModelSceneNode> child(new ModelSceneNode(_sceneGraph, model));
child->setLocalTransform(parent->absoluteTransform());
child->setLightingEnabled(_lightingEnabled);
addChild(child);
@ -319,7 +319,7 @@ void ModelSceneNode::updateLighting() {
_lightsAffectedBy.clear();
glm::vec3 center(_absoluteTransform * glm::vec4(_model->aabb().center(), 1.0f));
TheSceneGraph.getLightsAt(center, _lightsAffectedBy);
_sceneGraph->getLightsAt(center, _lightsAffectedBy);
_lightingDirty = false;
for (auto &attached : _attachedModels) {

View file

@ -49,7 +49,7 @@ public:
std::unordered_map<uint16_t, glm::mat4> boneTransforms;
};
ModelSceneNode(const std::shared_ptr<Model> &model);
ModelSceneNode(SceneGraph *sceneGraph, const std::shared_ptr<Model> &model);
void attach(const std::string &parentNode, const std::shared_ptr<Model> &model);
void update(float dt);

View file

@ -30,11 +30,6 @@ namespace render {
static const int kMaxLightCount = 8;
SceneGraph &SceneGraph::instance() {
static SceneGraph graph;
return graph;
}
void SceneGraph::clear() {
_opaqueMeshes.clear();
_transparentMeshes.clear();

View file

@ -31,7 +31,7 @@ namespace render {
class SceneGraph {
public:
static SceneGraph &instance();
SceneGraph() = default;
void clear();
void addRoot(const std::shared_ptr<SceneNode> &node);
@ -54,13 +54,10 @@ private:
std::vector<LightSceneNode *> _lights;
glm::vec3 _ambientLightColor { 1.0f };
SceneGraph() = default;
SceneGraph(const SceneGraph &) = delete;
SceneGraph &operator=(const SceneGraph &) = delete;
};
#define TheSceneGraph render::SceneGraph::instance()
} // namespace render
} // namespace reone

View file

@ -29,6 +29,9 @@ namespace reone {
namespace render {
SceneNode::SceneNode(SceneGraph *sceneGraph) : _sceneGraph(sceneGraph) {
}
void SceneNode::addChild(const shared_ptr<SceneNode> &node) {
assert(node);
node->setParent(this);

View file

@ -47,12 +47,13 @@ public:
virtual void setLocalTransform(const glm::mat4 &transform);
protected:
SceneGraph *_sceneGraph { nullptr };
const SceneNode *_parent { nullptr };
glm::mat4 _localTransform { 1.0f };
glm::mat4 _absoluteTransform { 1.0f };
std::vector<std::shared_ptr<SceneNode>> _children;
SceneNode() = default;
SceneNode(SceneGraph *sceneGraph);
virtual void updateAbsoluteTransform();