337 lines
8.3 KiB
C++
337 lines
8.3 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#ifndef __NSCENE__
|
|
#define __NSCENE__
|
|
|
|
|
|
#include "scene3d/scene_message.h"
|
|
#include "scene3d/scene_event_interface.h"
|
|
#include "scene3d/group.h"
|
|
#include "scene3d/scene_io_flag.h"
|
|
#include "scene3d/scene_profiler.h"
|
|
#include "core/core_profiler.h"
|
|
#include "core/renderer_environment_interface.h"
|
|
#include "core/simple_list_renderable.h"
|
|
#include "core/octree_renderable.h"
|
|
#include "core/tool_mode.h"
|
|
#include "core/clock.h"
|
|
#include "script/script_vm.h"
|
|
#include "timing/profiler.h"
|
|
#include "reflection/c_refl.h"
|
|
|
|
|
|
/// Debug display flags.
|
|
#define SceneDebugDisplayItems (1 << 0)
|
|
#define SceneDebugDisplayBones (1 << 1)
|
|
#define SceneDebugDisplayBoundingVolumes (1 << 2)
|
|
#define SceneDebugDisplayOctreeVolumes (1 << 3)
|
|
#define SceneDebugDisplayMotions (1 << 4)
|
|
|
|
/// Scene update flags.
|
|
#define SceneUpdateNone 0
|
|
#define SceneUpdateMotion (1 << 0)
|
|
#define SceneUpdatePhysic (1 << 1)
|
|
#define SceneUpdateEvent (1 << 2)
|
|
#define SceneUpdateTrigger (1 << 3)
|
|
#define SceneUpdateAll uint(~0)
|
|
|
|
namespace GS {
|
|
|
|
namespace GPU { class TriangleBatch; }
|
|
namespace S2D { class Scene; }
|
|
|
|
namespace S3D {
|
|
struct MLight;
|
|
struct MObject;
|
|
struct MTrigger;
|
|
struct IPhysicWorld;
|
|
class PhysicWorld;
|
|
|
|
using Render::Renderer;
|
|
using Render::RasterFont;
|
|
|
|
/*!
|
|
@short Scene object.
|
|
@author Emmanuel Julien (ejulien@gsworks.fr)
|
|
*/
|
|
class Scene : public SharedObject
|
|
{
|
|
uint current_item_uid;
|
|
|
|
struct RenderData
|
|
{
|
|
Render::sShader skybox_shader;
|
|
Render::sTexture skybox_layer[2];
|
|
Render::sTexture irradiance_probe, radiance_probe;
|
|
};
|
|
|
|
public:
|
|
|
|
/// Scene-wide flag.
|
|
enum SceneFlag
|
|
{
|
|
FlagNone = 0,
|
|
FlagEnd = (1 << 0),
|
|
FlagRenderless = (1 << 1),
|
|
FlagDebugPhysics = (1 << 2)
|
|
};
|
|
|
|
protected:
|
|
|
|
Core::sClock clock;
|
|
|
|
SharedList <MItem *> activation_queue, deactivation_queue;
|
|
SharedList <MItem *> item_list, removal_queue;
|
|
|
|
SharedArrayList <MItem *> active_list; // faster traversal than a shared list
|
|
|
|
SharedList <Group *> group_list;
|
|
|
|
List <MLight *> light_list;
|
|
List <MTrigger *> trigger_list;
|
|
|
|
/// Evaluate item.
|
|
void UpdateItem(float dt, MItem *, Core::Item *, uint eval_flag = SceneUpdateAll);
|
|
|
|
public:
|
|
|
|
String name;
|
|
|
|
BitField flags; ///< Scene flags.
|
|
|
|
AutoPtr <S2D::Scene> ui;
|
|
void Render(Renderer &);
|
|
void RenderUI(Renderer &, GPU::TriangleBatch * = 0);
|
|
|
|
Core::Clock *GetClock() const { return clock; }
|
|
void SetClock(Core::Clock * = 0, bool set_ui = true);
|
|
|
|
/// Dump scene content to log.
|
|
void DumpContentToLog() const;
|
|
|
|
Core::Camera *current_camera;
|
|
|
|
/*!
|
|
@name Core::Item management.
|
|
@{
|
|
*/
|
|
void SetupItemComponents(MItem *);
|
|
void AddItem(MItem *, bool setup_components);
|
|
bool RemoveItem(MItem *);
|
|
|
|
void QueueItemRemoval(MItem *);
|
|
void ProcessItemRemovalQueue();
|
|
|
|
bool ActivateItem(MItem *, bool activate);
|
|
void SetItemStatic(MItem *, bool is_static = true);
|
|
|
|
void QueueItemActivation(MItem *, bool activate = true, bool propagate = false);
|
|
void ProcessItemActivationQueue();
|
|
|
|
MItem *DuplicateItem(MItem *);
|
|
|
|
MItemType LocateItem(const Core::Item *, MItem **entity = 0) const;
|
|
static MItem *LocateManagedItem(Core::Item *);
|
|
|
|
MItem *Item(const char *name, MItem * = 0) const;
|
|
MItem *ItemFromUid(uint uid) const;
|
|
|
|
const List <MLight *> &GetLightList() const { return light_list; }
|
|
|
|
const SharedList <MItem *> &GetItemList() const { return item_list; }
|
|
const SharedArrayList <MItem *> &GetActiveList() const { return active_list; }
|
|
|
|
uint GetItemCountByType(MItemType type) const;
|
|
|
|
// Filter item list and extract items of a give type.
|
|
template <class C> uint GetItemListByType(SharedList <C *> &out) const
|
|
{
|
|
out.Clear();
|
|
ListForeachPtr(MItem *, i, item_list)
|
|
if (i->GetItemType() == C::GetMItemClassType())
|
|
out.Add((C *)i);
|
|
return out.GetCount();
|
|
}
|
|
// Find item by type.
|
|
template <class C> C *FindItemByType(const char *name) const
|
|
{
|
|
ListForeachPtr(MItem *, i, item_list)
|
|
if (i->GetItemType() == C::GetMItemClassType())
|
|
if (i->name == name)
|
|
return (C *)i;
|
|
return 0;
|
|
}
|
|
/*!
|
|
@}
|
|
@name Group management.
|
|
@{
|
|
*/
|
|
Group *AddGroup(Group *);
|
|
bool RemoveGroup(Group *);
|
|
|
|
Group *FindGroup(const char *name) const;
|
|
|
|
uint GetItemGroupList(const MItem *, SharedList <Group *> &) const;
|
|
void UnregisterItemFromGroups(MItem *) const;
|
|
|
|
const SharedList <Group *> &GetGroupList() const { return group_list; }
|
|
|
|
void GroupMembersSetActive(Group *, bool = true);
|
|
void DeleteGroupAndMembers(Group *);
|
|
/*!
|
|
@}
|
|
@name Profiling.
|
|
@{
|
|
*/
|
|
SceneProfiler profiler;
|
|
|
|
/// Display the profiler to screen using the renderer writer.
|
|
void DrawProfilerText(Renderer &, RasterFont *font[2], float &x, float &y);
|
|
/*!
|
|
@}
|
|
@name Culling system.
|
|
@{
|
|
*/
|
|
protected:
|
|
|
|
Core::SimpleCullingSystem simple_culling_system;
|
|
Core::OctreeCullingSystem octree_culling_system;
|
|
|
|
public:
|
|
|
|
void AddRenderable(Core::Renderable *, bool is_static = false);
|
|
void RemoveRenderable(Core::Renderable *);
|
|
|
|
/// Push this scene renderable onto the renderer display queue.
|
|
void PushRenderable(Renderer &);
|
|
/*!
|
|
@}
|
|
@name Environment.
|
|
@{
|
|
*/
|
|
Color background_color, ambient_color;
|
|
float ambient_intensity, target_exposure;
|
|
|
|
float time_of_day;
|
|
String skybox_shader;
|
|
String skybox_layer[2];
|
|
|
|
String irradiance_probe, radiance_probe;
|
|
|
|
float fog_near, fog_far;
|
|
Color fog_color;
|
|
|
|
AutoPtr <Render::IEnvironment> irenderer_environment;
|
|
/*!
|
|
@}
|
|
@name Script system.
|
|
@{
|
|
*/
|
|
protected:
|
|
|
|
Script::sVM vm;
|
|
|
|
public:
|
|
|
|
Script::IVM *GetVM() const { return vm; }
|
|
|
|
AutoPtr <ISceneEvent> scene_event;
|
|
AutoPtr <Script::ScriptedObject> scripted_object;
|
|
|
|
/// Set as the script master global scene.
|
|
void SetAsScriptGlobalScene(Script::IVM * = 0);
|
|
/// @}
|
|
|
|
/*!
|
|
@name Motion system.
|
|
@{
|
|
*/
|
|
Core::SceneMotionContainer motion;
|
|
|
|
/*!
|
|
@short Start a motion on the scene items.
|
|
@note Request an animation source group if you need control on the
|
|
started animation sources.
|
|
*/
|
|
void SetMotion(const char *name, Automation::SourceGroup ** = 0, float blend = Units::Sec(0.1), Automation::Player::AddSourceMode = Automation::Player::SourceSet, float weight = 1);
|
|
/*!
|
|
@}
|
|
@name Physic system.
|
|
@{
|
|
*/
|
|
void SynchronizePhysics();
|
|
|
|
AutoPtr <PhysicWorld> physic_world;
|
|
AutoPtr <IPhysicWorld> iphysic_world;
|
|
|
|
MTrigger *RaytraceTriggerList(Vector4 &s, Vector4 &d, float l = -1.f, Vector4 *i = 0);
|
|
/*
|
|
@}
|
|
@name Scene Management.
|
|
@{
|
|
*/
|
|
bool Create(PhysicWorld *);
|
|
void Reset();
|
|
void Clear(bool keep_script = false);
|
|
|
|
void InstanceSetup();
|
|
void RenderSetup(Core::ResourceFactories *, bool setup_items = true);
|
|
void Setup(ToolMode);
|
|
|
|
void RecordAllItemLocation();
|
|
/// @}
|
|
|
|
void GetMinMax(MinMax &) const;
|
|
|
|
protected:
|
|
|
|
void TestOptimizeGeometry(Render::Geometry *, uint octree_node_size);
|
|
void UpdateItemTransformation(MItem *, const Time &dt);
|
|
|
|
public:
|
|
|
|
void OptimizeForRealtime(uint octree_node_size = 1024);
|
|
|
|
void UpdateTriggers();
|
|
void Update(uint = SceneUpdateAll);
|
|
|
|
/*!
|
|
@name Scene serialization
|
|
@{
|
|
*/
|
|
protected:
|
|
|
|
bool IsItemToBeSaved(MItem *, const Group *, uint flag) const;
|
|
NML::Tag *LinkInfoAsMetaTag(MItem *, const Group * = 0, uint = SceneIOAll) const;
|
|
NML::Tag *SkinInfoAsMetaTag(MObject *o, const Group * = 0, uint = SceneIOAll) const;
|
|
|
|
public:
|
|
|
|
/// Load all scene resources in render cache.
|
|
static bool PreloadResources(Render::ResourceFactory &, const char *uri);
|
|
|
|
/// Load scene from meta file, store content to group.
|
|
bool FromMetaTagStoreGroup(const NML::Tag &, Group ** = 0, uint = SceneIOAll, ToolMode = NoTool, int load_level = 0);
|
|
bool FromMetaFileStoreGroup(const char *, Group ** = 0, uint = SceneIOAll, ToolMode = NoTool, int load_level = 0);
|
|
bool FromMetaTag(const NML::Tag &tag, ToolMode tool = NoTool) { return FromMetaTagStoreGroup(tag, 0, SceneIOAll, tool); }
|
|
|
|
NML::Tag *AsMetaTag(const Group *, uint = SceneIOAll, ToolMode = NoTool) const;
|
|
NML::Tag *AsMetaTag() const { return AsMetaTag(0); }
|
|
/// @}
|
|
|
|
AutoPtr <RenderData> render_data;
|
|
|
|
Scene(Script::IVM *vm = 0);
|
|
virtual ~Scene();
|
|
};
|
|
|
|
} // S3D
|
|
} // GS
|
|
|
|
|
|
#endif // __NSCENE__
|