mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-11 06:34:36 +00:00
Initial implementation of the Scene object for handling scenes/levels in a more consistent and deliberate way.
This commit is contained in:
parent
e0627973fb
commit
1c2f90a190
37 changed files with 509 additions and 140 deletions
236
Engine/source/T3D/Scene.cpp
Normal file
236
Engine/source/T3D/Scene.cpp
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
#include "Scene.h"
|
||||
|
||||
Scene * Scene::smRootScene = nullptr;
|
||||
Vector<Scene*> Scene::smSceneList;
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(Scene);
|
||||
|
||||
Scene::Scene() :
|
||||
mIsSubScene(false),
|
||||
mParentScene(nullptr),
|
||||
mSceneId(-1),
|
||||
mIsEditing(false),
|
||||
mIsDirty(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::initPersistFields()
|
||||
{
|
||||
Parent::initPersistFields();
|
||||
|
||||
addGroup("Internal");
|
||||
addField("isSubscene", TypeBool, Offset(mIsSubScene, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
|
||||
addField("isEditing", TypeBool, Offset(mIsEditing, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
|
||||
addField("isDirty", TypeBool, Offset(mIsDirty, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
|
||||
endGroup("Internal");
|
||||
}
|
||||
|
||||
bool Scene::onAdd()
|
||||
{
|
||||
if (!Parent::onAdd())
|
||||
return false;
|
||||
|
||||
smSceneList.push_back(this);
|
||||
mSceneId = smSceneList.size() - 1;
|
||||
|
||||
/*if (smRootScene == nullptr)
|
||||
{
|
||||
//we're the first scene, so we're the root. woo!
|
||||
smRootScene = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsSubScene = true;
|
||||
smRootScene->mSubScenes.push_back(this);
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scene::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
|
||||
smSceneList.remove(this);
|
||||
mSceneId = -1;
|
||||
|
||||
/*if (smRootScene == this)
|
||||
{
|
||||
for (U32 i = 0; i < mSubScenes.size(); i++)
|
||||
{
|
||||
mSubScenes[i]->deleteObject();
|
||||
}
|
||||
}
|
||||
else if (smRootScene != nullptr)
|
||||
{
|
||||
for (U32 i = 0; i < mSubScenes.size(); i++)
|
||||
{
|
||||
if(mSubScenes[i]->getId() == getId())
|
||||
smRootScene->mSubScenes.erase(i);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void Scene::addObject(SimObject* object)
|
||||
{
|
||||
//Child scene
|
||||
Scene* scene = dynamic_cast<Scene*>(object);
|
||||
if (scene)
|
||||
{
|
||||
//We'll keep these principly separate so they don't get saved into each other
|
||||
mSubScenes.push_back(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
SceneObject* sceneObj = dynamic_cast<SceneObject*>(object);
|
||||
if (sceneObj)
|
||||
{
|
||||
//We'll operate on the presumption that if it's being added via regular parantage means, it's considered permanent
|
||||
mPermanentObjects.push_back(sceneObj);
|
||||
Parent::addObject(object);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
|
||||
Parent::addObject(object);
|
||||
}
|
||||
|
||||
void Scene::removeObject(SimObject* object)
|
||||
{
|
||||
//Child scene
|
||||
Scene* scene = dynamic_cast<Scene*>(object);
|
||||
if (scene)
|
||||
{
|
||||
//We'll keep these principly separate so they don't get saved into each other
|
||||
mSubScenes.remove(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
SceneObject* sceneObj = dynamic_cast<SceneObject*>(object);
|
||||
if (sceneObj)
|
||||
{
|
||||
//We'll operate on the presumption that if it's being added via regular parantage means, it's considered permanent
|
||||
|
||||
mPermanentObjects.remove(sceneObj);
|
||||
Parent::removeObject(object);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Parent::removeObject(object);
|
||||
}
|
||||
|
||||
void Scene::addDynamicObject(SceneObject* object)
|
||||
{
|
||||
mDynamicObjects.push_back(object);
|
||||
|
||||
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
|
||||
Parent::addObject(object);
|
||||
}
|
||||
|
||||
void Scene::removeDynamicObject(SceneObject* object)
|
||||
{
|
||||
mDynamicObjects.remove(object);
|
||||
|
||||
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
|
||||
Parent::removeObject(object);
|
||||
}
|
||||
|
||||
void Scene::interpolateTick(F32 delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::processTick()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::advanceTime(F32 timeDelta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
U32 Scene::packUpdate(NetConnection *conn, U32 mask, BitStream *stream)
|
||||
{
|
||||
bool ret = Parent::packUpdate(conn, mask, stream);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Scene::unpackUpdate(NetConnection *conn, BitStream *stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
Vector<SceneObject*> Scene::getObjectsByClass(String className)
|
||||
{
|
||||
return Vector<SceneObject*>();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getScene, Scene*, (U32 sceneId), (0),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
if (Scene::smSceneList.empty() || sceneId >= Scene::smSceneList.size())
|
||||
return nullptr;
|
||||
|
||||
return Scene::smSceneList[sceneId];
|
||||
}
|
||||
|
||||
DefineEngineFunction(getRootScene, S32, (), ,
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
Scene* root = Scene::getRootScene();
|
||||
|
||||
if (root)
|
||||
return root->getId();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, getRootScene, S32, (),,
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
Scene* root = Scene::getRootScene();
|
||||
|
||||
if (root)
|
||||
return root->getId();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, addDynamicObject, void, (SceneObject* sceneObj), (nullAsType<SceneObject*>()),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
object->addDynamicObject(sceneObj);
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, removeDynamicObject, void, (SceneObject* sceneObj), (nullAsType<SceneObject*>()),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
object->removeDynamicObject(sceneObj);
|
||||
}
|
||||
|
||||
DefineEngineMethod(Scene, getObjectsByClass, String, (String className), (""),
|
||||
"Get the root Scene object that is loaded.\n"
|
||||
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
|
||||
{
|
||||
if (className == String::EmptyString)
|
||||
return "";
|
||||
|
||||
//return object->getObjectsByClass(className);
|
||||
return "";
|
||||
}
|
||||
79
Engine/source/T3D/Scene.h
Normal file
79
Engine/source/T3D/Scene.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#pragma once
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
#ifndef _NETOBJECT_H_
|
||||
#include "sim/netObject.h"
|
||||
#endif
|
||||
|
||||
#ifndef _ITICKABLE_H_
|
||||
#include "core/iTickable.h"
|
||||
#endif
|
||||
|
||||
#include "scene/sceneObject.h"
|
||||
|
||||
/// Scene
|
||||
/// This object is effectively a smart container to hold and manage any relevent scene objects and data
|
||||
/// used to run things.
|
||||
class Scene : public NetObject, public virtual ITickable
|
||||
{
|
||||
typedef NetObject Parent;
|
||||
|
||||
bool mIsSubScene;
|
||||
|
||||
Scene* mParentScene;
|
||||
|
||||
Vector<Scene*> mSubScenes;
|
||||
|
||||
Vector<SceneObject*> mPermanentObjects;
|
||||
|
||||
Vector<SceneObject*> mDynamicObjects;
|
||||
|
||||
S32 mSceneId;
|
||||
|
||||
bool mIsEditing;
|
||||
|
||||
bool mIsDirty;
|
||||
|
||||
protected:
|
||||
static Scene * smRootScene;
|
||||
|
||||
DECLARE_CONOBJECT(Scene);
|
||||
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
|
||||
virtual void interpolateTick(F32 delta);
|
||||
virtual void processTick();
|
||||
virtual void advanceTime(F32 timeDelta);
|
||||
|
||||
virtual void addObject(SimObject* object);
|
||||
virtual void removeObject(SimObject* object);
|
||||
|
||||
void addDynamicObject(SceneObject* object);
|
||||
void removeDynamicObject(SceneObject* object);
|
||||
|
||||
//
|
||||
//Networking
|
||||
U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
|
||||
void unpackUpdate(NetConnection *conn, BitStream *stream);
|
||||
|
||||
//
|
||||
Vector<SceneObject*> getObjectsByClass(String className);
|
||||
|
||||
static Scene *getRootScene()
|
||||
{
|
||||
if (Scene::smSceneList.empty())
|
||||
return nullptr;
|
||||
|
||||
return Scene::smSceneList[0];
|
||||
}
|
||||
|
||||
static Vector<Scene*> smSceneList;
|
||||
};
|
||||
|
|
@ -34,6 +34,8 @@
|
|||
#include "T3D/physics/physicsShape.h"
|
||||
#include "core/util/path.h"
|
||||
|
||||
#include "T3D/Scene.h"
|
||||
|
||||
// We use this locally ( within this file ) to prevent infinite recursion
|
||||
// while loading prefab files that contain other prefabs.
|
||||
static Vector<String> sPrefabFileStack;
|
||||
|
|
@ -269,11 +271,11 @@ void Prefab::setFile( String file )
|
|||
|
||||
SimGroup* Prefab::explode()
|
||||
{
|
||||
SimGroup *missionGroup;
|
||||
Scene* scene = Scene::getRootScene();
|
||||
|
||||
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
|
||||
if ( !scene)
|
||||
{
|
||||
Con::errorf( "Prefab::explode, MissionGroup was not found." );
|
||||
Con::errorf( "Prefab::explode, Scene was not found." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +297,7 @@ SimGroup* Prefab::explode()
|
|||
smChildToPrefabMap.erase( child->getId() );
|
||||
}
|
||||
|
||||
missionGroup->addObject(group);
|
||||
scene->addObject(group);
|
||||
mChildGroup = NULL;
|
||||
mChildMap.clear();
|
||||
|
||||
|
|
@ -468,10 +470,10 @@ Prefab* Prefab::getPrefabByChild( SimObject *child )
|
|||
|
||||
bool Prefab::isValidChild( SimObject *simobj, bool logWarnings )
|
||||
{
|
||||
if ( simobj->getName() && dStricmp(simobj->getName(),"MissionGroup") == 0 )
|
||||
if ( simobj->getName() && simobj == Scene::getRootScene() )
|
||||
{
|
||||
if ( logWarnings )
|
||||
Con::warnf( "MissionGroup is not valid within a Prefab." );
|
||||
Con::warnf( "root Scene is not valid within a Prefab." );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public:
|
|||
void setFile( String file );
|
||||
|
||||
/// Removes all children from this Prefab and puts them into a SimGroup
|
||||
/// which is added to the MissionGroup and returned to the caller.
|
||||
/// which is added to the Scene and returned to the caller.
|
||||
SimGroup* explode();
|
||||
|
||||
bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue