// NeL - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
#include "std3d.h"
#include "nel/3d/u_point_light.h"
#include "nel/3d/u_instance.h"
#include "nel/3d/u_camera.h"
#include "nel/3d/u_skeleton.h"
#include "nel/3d/scene_user.h"
#include "nel/3d/skeleton_model.h"
#include "nel/3d/coarse_mesh_manager.h"
#include "nel/3d/point_light_model.h"
#include "nel/3d/lod_character_manager.h"
#include "nel/3d/lod_character_shape.h"
#include "nel/3d/lod_character_shape_bank.h"
#include "nel/misc/hierarchical_timer.h"
#include "nel/3d/async_texture_manager.h"
#include "nel/3d/water_env_map_user.h"
using namespace NLMISC;
namespace NL3D
{
H_AUTO_DECL( NL3D_UI_Scene )
H_AUTO_DECL( NL3D_Misc_Scene_CreateDel_Element )
H_AUTO_DECL( NL3D_CreateOrLoad_Instance )
H_AUTO_DECL( NL3D_CreateOrLoad_Skeleton )
H_AUTO_DECL( NL3D_Load_CLodOrCoarseMesh )
H_AUTO_DECL( NL3D_Load_AsyncIG )
#define NL3D_HAUTO_UI_SCENE H_AUTO_USE( NL3D_UI_Scene )
#define NL3D_HAUTO_ELT_SCENE H_AUTO_USE( NL3D_Misc_Scene_CreateDel_Element )
#define NL3D_HAUTO_CREATE_INSTANCE H_AUTO_USE( NL3D_CreateOrLoad_Instance )
#define NL3D_HAUTO_CREATE_SKELETON H_AUTO_USE( NL3D_CreateOrLoad_Skeleton )
#define NL3D_HAUTO_LOAD_LOD H_AUTO_USE( NL3D_Load_CLodOrCoarseMesh )
#define NL3D_HAUTO_ASYNC_IG H_AUTO_USE( NL3D_Load_AsyncIG )
// Render/Animate.
H_AUTO_DECL( NL3D_Render_Scene )
H_AUTO_DECL( NL3D_Render_Animate_Scene )
H_AUTO_DECL( NL3D_Render_Scene_Begin )
H_AUTO_DECL( NL3D_Render_Scene_Part )
H_AUTO_DECL( NL3D_Render_Scene_End )
#define NL3D_HAUTO_RENDER_SCENE H_AUTO_USE( NL3D_Render_Scene )
#define NL3D_HAUTO_RENDER_SCENE_ANIMATE H_AUTO_USE( NL3D_Render_Animate_Scene )
#define NL3D_HAUTO_RENDER_SCENE_BEGIN H_AUTO_USE( NL3D_Render_Scene_Begin )
#define NL3D_HAUTO_RENDER_SCENE_PART H_AUTO_USE( NL3D_Render_Scene_Part )
#define NL3D_HAUTO_RENDER_SCENE_END H_AUTO_USE( NL3D_Render_Scene_End )
// ***************************************************************************
void CSceneUser::setAutomaticAnimationSet(UAnimationSet *as)
{
NL3D_HAUTO_UI_SCENE;
nlassert(as);
as->build();
CAnimationSetUser *asu = NLMISC::safe_cast(as);
_Scene.setAutomaticAnimationSet(asu->_AnimationSet);
}
// ***************************************************************************
UPlayListManager *CSceneUser::createPlayListManager()
{
NL3D_HAUTO_ELT_SCENE;
return _PlayListManagers.insert(new CPlayListManagerUser());
}
// ***************************************************************************
void CSceneUser::deletePlayListManager(UPlayListManager *playListManager)
{
NL3D_HAUTO_ELT_SCENE;
_PlayListManagers.erase((CPlayListManagerUser*)playListManager, "deletePlayListManager(): Bad PlayListManager ptr");
}
// ***************************************************************************
void CSceneUser::setPolygonBalancingMode(CSceneUser::TPolygonBalancingMode polBalMode)
{
NL3D_HAUTO_UI_SCENE;
nlassert( (uint)CScene::CountPolygonBalancing == (uint)CSceneUser::CountPolygonBalancing );
_Scene.setPolygonBalancingMode((CScene::TPolygonBalancingMode)(uint)(polBalMode));
}
// ***************************************************************************
CSceneUser::TPolygonBalancingMode CSceneUser::getPolygonBalancingMode() const
{
NL3D_HAUTO_UI_SCENE;
nlassert( (uint)CScene::CountPolygonBalancing == (uint)CSceneUser::CountPolygonBalancing );
return (CSceneUser::TPolygonBalancingMode)(uint)_Scene.getPolygonBalancingMode();
}
// ***************************************************************************
float CSceneUser::getNbFaceAsked () const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getNbFaceAsked ();
}
// ***************************************************************************
void CSceneUser::setGroupLoadMaxPolygon(const std::string &group, uint nFaces)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setGroupLoadMaxPolygon(group, nFaces);
}
// ***************************************************************************
uint CSceneUser::getGroupLoadMaxPolygon(const std::string &group)
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getGroupLoadMaxPolygon(group);
}
// ***************************************************************************
float CSceneUser::getGroupNbFaceAsked (const std::string &group) const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getGroupNbFaceAsked (group);
}
// ***************************************************************************
void CSceneUser::setCoarseMeshManagerTexture (const char *sPath)
{
NL3D_HAUTO_LOAD_LOD;
// Get the manager
CCoarseMeshManager *manager=_Scene.getCoarseMeshManager ();
// Does it exist ?
if (manager)
{
// Set the texture
manager->setTextureFile (sPath);
}
}
// ***************************************************************************
void CSceneUser::setCoarseMeshLightingUpdate(uint8 period)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setCoarseMeshLightingUpdate(period);
}
// ***************************************************************************
uint8 CSceneUser::getCoarseMeshLightingUpdate() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getCoarseMeshLightingUpdate();
}
// ***************************************************************************
void CSceneUser::enableLightingSystem(bool enable)
{
NL3D_HAUTO_UI_SCENE;
_Scene.enableLightingSystem(enable);
}
// ***************************************************************************
void CSceneUser::setAmbientGlobal(NLMISC::CRGBA ambient)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setAmbientGlobal(ambient);
}
void CSceneUser::setSunAmbient(NLMISC::CRGBA ambient)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setSunAmbient(ambient);
}
void CSceneUser::setSunDiffuse(NLMISC::CRGBA diffuse)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setSunDiffuse(diffuse);
}
void CSceneUser::setSunSpecular(NLMISC::CRGBA specular)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setSunSpecular(specular);
}
void CSceneUser::setSunDirection(const NLMISC::CVector &direction)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setSunDirection(direction);
}
void CSceneUser::setLightGroupColor(uint lightmapGroup, NLMISC::CRGBA color)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setLightGroupColor(lightmapGroup, color);
}
// ***************************************************************************
NLMISC::CRGBA CSceneUser::getAmbientGlobal() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getAmbientGlobal();
}
NLMISC::CRGBA CSceneUser::getSunAmbient() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getSunAmbient();
}
NLMISC::CRGBA CSceneUser::getSunDiffuse() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getSunDiffuse();
}
NLMISC::CRGBA CSceneUser::getSunSpecular() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getSunSpecular();
}
NLMISC::CVector CSceneUser::getSunDirection() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getSunDirection();
}
// ***************************************************************************
void CSceneUser::setMaxLightContribution(uint nlights)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setMaxLightContribution(nlights);
}
// ***************************************************************************
uint CSceneUser::getMaxLightContribution() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getMaxLightContribution();
}
// ***************************************************************************
void CSceneUser::setLightTransitionThreshold(float lightTransitionThreshold)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setLightTransitionThreshold(lightTransitionThreshold);
}
// ***************************************************************************
float CSceneUser::getLightTransitionThreshold() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getLightTransitionThreshold();
}
// ***************************************************************************
UPointLight CSceneUser::createPointLight()
{
NL3D_HAUTO_ELT_SCENE;
CTransform *model= _Scene.createModel(PointLightModelId);
if (model)
{
CPointLightModel *pointLightModel= safe_cast (model);
// If not found, return NULL.
if(pointLightModel==NULL)
return NULL;
// The component is auto added/deleted to _Scene in ctor/dtor.
return UPointLight (pointLightModel);
}
else
return UPointLight ();
}
// ***************************************************************************
void CSceneUser::deletePointLight(UPointLight &light)
{
NL3D_HAUTO_ELT_SCENE;
// The component is auto added/deleted to _Scene in ctor/dtor.
_Scene.deleteModel (light.getObjectPtr());
light.detach ();
}
// ***************************************************************************
void CSceneUser::setGlobalWindPower(float gwp)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setGlobalWindPower(gwp);
}
// ***************************************************************************
float CSceneUser::getGlobalWindPower() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getGlobalWindPower();
}
// ***************************************************************************
void CSceneUser::setGlobalWindDirection(const CVector &gwd)
{
_Scene.setGlobalWindDirection(gwd);
}
// ***************************************************************************
const CVector &CSceneUser::getGlobalWindDirection() const
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getGlobalWindDirection();
}
// ***************************************************************************
void CSceneUser::updateWaitingIG()
{
for(TWaitingIGList::iterator it = _WaitingIGs.begin(); it != _WaitingIGs.end();)
{
bool erased= false;
if (it->IGToLoad != NULL) // ig loaded ?
{
if (it->IGToLoad != (UInstanceGroup *) -1)
{
switch (it->IGToLoad->getAddToSceneState())
{
case UInstanceGroup::StateNotAdded:
// start loading
if (it->Callback != NULL)
it->Callback->InstanceGroupCreated(it->IGToLoad);
it->IGToLoad->addToSceneAsync(*this, _DriverUser, it->SelectedTexture);
break;
case UInstanceGroup::StateAdded:
it->IGToLoad->setPos(it->Pos);
it->IGToLoad->setRotQuat(it->Rot);
this->setToGlobalInstanceGroup(it->IGToLoad);
*it->CallerPtr = it->IGToLoad;
// remove from list
it = _WaitingIGs.erase(it);
erased= true;
break;
case UInstanceGroup::StateError:
delete it->IGToLoad;
it->IGToLoad = (UInstanceGroup *) -1;
*it->CallerPtr = it->IGToLoad;
// remove from list
it = _WaitingIGs.erase(it);
erased= true;
break;
default:
break;
}
}
else
{
// loading failed
*it->CallerPtr = it->IGToLoad;
it = _WaitingIGs.erase(it);
erased= true;
}
}
// next IG.
if(!erased)
it++;
}
}
// ***************************************************************************
void CSceneUser::resetCLodManager()
{
NL3D_HAUTO_UI_SCENE;
// DriverUser always setup the lod manager
nlassert(_Scene.getLodCharacterManager());
_Scene.getLodCharacterManager()->reset();
}
// ***************************************************************************
uint32 CSceneUser::loadCLodShapeBank(const std::string &fileName)
{
NL3D_HAUTO_LOAD_LOD;
// DriverUser always setup the lod manager
nlassert(_Scene.getLodCharacterManager());
// Open the file
CIFile file(CPath::lookup(fileName));
// create the shape bank
uint32 bankId= _Scene.getLodCharacterManager()->createShapeBank();
// get the bank
CLodCharacterShapeBank *bank= _Scene.getLodCharacterManager()->getShapeBank(bankId);
nlassert(bank);
// read the bank.
file.serial(*bank);
// recompile the shape Map.
_Scene.getLodCharacterManager()->compile();
return bankId;
}
// ***************************************************************************
void CSceneUser::deleteCLodShapeBank(uint32 bankId)
{
NL3D_HAUTO_LOAD_LOD;
// DriverUser always setup the lod manager
nlassert(_Scene.getLodCharacterManager());
// delete the bank
_Scene.getLodCharacterManager()->deleteShapeBank(bankId);
// recompile the shape Map.
_Scene.getLodCharacterManager()->compile();
}
// ***************************************************************************
sint32 CSceneUser::getCLodShapeIdByName(const std::string &name) const
{
NL3D_HAUTO_UI_SCENE;
// DriverUser always setup the lod manager
nlassert(_Scene.getLodCharacterManager());
return _Scene.getLodCharacterManager()->getShapeIdByName(name);
}
// ***************************************************************************
sint32 CSceneUser::getCLodAnimIdByName(uint32 shapeId, const std::string &name) const
{
NL3D_HAUTO_UI_SCENE;
// DriverUser always setup the lod manager
nlassert(_Scene.getLodCharacterManager());
const CLodCharacterShape *shape= _Scene.getLodCharacterManager()->getShape(shapeId);
if(shape)
return shape->getAnimIdByName(name);
else
return -1;
}
// ***************************************************************************
void CSceneUser::render(bool updateWaitingInstancesFlag /*= true*/, bool restoreMatrixContextAfterRender /*= true*/)
{
// render the scene.
{
NL3D_HAUTO_RENDER_SCENE
if(_Scene.getCam() == NULL)
nlerror("render(): try to render with no camera linked (may have been deleted)");
_Scene.render(true);
}
if (updateWaitingInstancesFlag) updateWaitingInstances();
// Must restore the matrix context, so 2D/3D interface not disturbed.
if (restoreMatrixContextAfterRender) _DriverUser->restoreMatrixContext();
}
// ***************************************************************************
void CSceneUser::beginPartRender()
{
// render the scene.
{
NL3D_HAUTO_RENDER_SCENE_BEGIN
_Scene.beginPartRender();
}
}
// ***************************************************************************
void CSceneUser::renderPart(TRenderPart rp)
{
// render the scene.
{
NL3D_HAUTO_RENDER_SCENE_PART
if(_Scene.getCam() == NULL)
nlerror("render(): try to render with no camera linked (may have been deleted)");
_Scene.renderPart(rp, true);
}
}
// ***************************************************************************
void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender)
{
// render the scene.
{
NL3D_HAUTO_RENDER_SCENE_END
_Scene.endPartRender();
}
if (updateWaitingInstancesFlag) updateWaitingInstances();
// Must restore the matrix context, so 2D/3D interface not disturbed.
if (restoreMatrixContextAfterRender) _DriverUser->restoreMatrixContext();
}
// ***************************************************************************
/*virtual*/ void CSceneUser::updateWaitingInstances(double ellapsedTime)
{
_Scene.updateWaitingInstances(ellapsedTime);
updateWaitingInstances();
}
// ***************************************************************************
void CSceneUser::updateWaitingInstances()
{
// Update waiting instances
{
NL3D_HAUTO_ASYNC_IG
// Done after the _Scene.render because in this method the instance are checked for creation
std::map::iterator it = _WaitingInstances.begin();
while( it != _WaitingInstances.end() )
{
if( it->second != NULL )
{
it->first->attach (it->second);
std::map::iterator delIt = it;
++it;
_WaitingInstances.erase(delIt);
}
else
{
++it;
}
}
}
// update waiting instances groups;
{
NL3D_HAUTO_ASYNC_IG
updateWaitingIG();
}
}
void CSceneUser::animate(TGlobalAnimationTime time)
{
NL3D_HAUTO_RENDER_SCENE_ANIMATE;
_Scene.animate(time);
}
// ***************************************************************************
void CSceneUser::setCam(UCamera cam)
{
NL3D_HAUTO_UI_SCENE;
if(cam.empty())
nlerror("setCam(): cannot set a NULL camera");
CCamera *camera = cam.getObjectPtr();
if( camera->getOwnerScene() != &_Scene)
nlerror("setCam(): try to set a current camera not created from this scene");
_Scene.setCam(camera);
}
// ***************************************************************************
UCamera CSceneUser::getCam()
{
NL3D_HAUTO_UI_SCENE;
return UCamera (_Scene.getCam());
}
// ***************************************************************************
void CSceneUser::setViewport(const class CViewport& viewport)
{
NL3D_HAUTO_UI_SCENE;
_Scene.setViewport(viewport);
}
CViewport CSceneUser::getViewport()
{
NL3D_HAUTO_UI_SCENE;
return _Scene.getViewport();
}
UInstanceGroup *CSceneUser::findCameraClusterSystemFromRay(UInstanceGroup *startClusterSystem,
const NLMISC::CVector &startPos, NLMISC::CVector &endPos)
{
NL3D_HAUTO_UI_SCENE;
CInstanceGroupUser *uig= dynamic_cast(startClusterSystem);
CInstanceGroup *pIg= NULL;
if(uig)
pIg= &uig->_InstanceGroup;
CInstanceGroup *resultIg= _Scene.findCameraClusterSystemFromRay(pIg, startPos, endPos);
if(resultIg)
return resultIg->getUserInterface();
else
return NULL;
}
// ***************************************************************************
UCamera CSceneUser::createCamera()
{
NL3D_HAUTO_ELT_SCENE;
CTransform *model= _Scene.createModel(CameraId);
if (model)
{
CCamera *object = NLMISC::safe_cast(model);
object->setFrustum(UCamera::DefLx, UCamera::DefLy, UCamera::DefLzNear, UCamera::DefLzFar);
return UCamera (object);
}
else
return UCamera ();
}
// ***************************************************************************
void CSceneUser::deleteCamera(UCamera &cam)
{
NL3D_HAUTO_ELT_SCENE;
CCamera *object = cam.getObjectPtr();
// The component is auto added/deleted to _Scene in ctor/dtor.
_Scene.deleteModel (object);
cam.detach ();
}
// ***************************************************************************
UInstance CSceneUser::createInstance(const std::string &shapeName)
{
NL3D_HAUTO_CREATE_INSTANCE;
CTransformShape *model= _Scene.createInstance(shapeName);
return UInstance (model);
}
// ***************************************************************************
void CSceneUser::createInstanceAsync(const std::string &shapeName, UInstance *ppInstance, const NLMISC::CVector &position, uint selectedTexture)
{
NL3D_HAUTO_CREATE_INSTANCE;
_WaitingInstances[ppInstance] = NULL;
_Scene.createInstanceAsync(shapeName,&_WaitingInstances[ppInstance], position, selectedTexture);
// CTransform *model= _Scene.createInstance(shapeName);
// If not found, return NULL.
// if(model==NULL)
// return NULL;
// if( dynamic_cast(model)==NULL )
// nlerror("UScene::createInstance(): shape is not a mesh");
// The component is auto added/deleted to _Scene in ctor/dtor.
// return dynamic_cast( _Transforms.insert(new CInstanceUser(&_Scene, model)) );
}
// ***************************************************************************
void CSceneUser::deleteInstance(UInstance &inst)
{
NL3D_HAUTO_ELT_SCENE;
_Scene.deleteInstance (inst.getObjectPtr());
inst.detach ();
}
// ***************************************************************************
void CSceneUser::createInstanceGroupAndAddToSceneAsync (const std::string &instanceGroup, UInstanceGroup **pIG, const NLMISC::CVector &pos, const NLMISC::CQuat &rot,
uint selectedTexture, IAsyncLoadCallback *pCB)
{
NL3D_HAUTO_ASYNC_IG;
_WaitingIGs.push_front(CWaitingIG(pIG, pos, rot, selectedTexture, pCB));
UInstanceGroup::createInstanceGroupAsync(instanceGroup, &(_WaitingIGs.begin()->IGToLoad));
// this list updat will be performed at each render, see updateWaitingIG
}
void CSceneUser::stopCreatingAndAddingIG(UInstanceGroup **pIG)
{
NL3D_HAUTO_ASYNC_IG;
for(TWaitingIGList::iterator it = _WaitingIGs.begin(); it != _WaitingIGs.end(); ++it)
{
CWaitingIG &rWIG = *it;
if (rWIG.CallerPtr == pIG)
{
if (rWIG.IGToLoad == NULL)
{
UInstanceGroup::stopCreateInstanceGroupAsync(pIG);
}
// Ig must be initialized
else if (rWIG.IGToLoad != (UInstanceGroup*)-1)
{
switch(rWIG.IGToLoad->getAddToSceneState())
{
case UInstanceGroup::StateAdding:
rWIG.IGToLoad->stopAddToSceneAsync();
break;
case UInstanceGroup::StateAdded:
rWIG.IGToLoad->removeFromScene(*this);
delete rWIG.IGToLoad;
break;
case UInstanceGroup::StateNotAdded:
delete rWIG.IGToLoad;
break;
default:
break;
}
}
_WaitingIGs.erase(it);
return;
}
}
}
void CSceneUser::deleteInstanceGroup(UInstanceGroup *pIG)
{
delete pIG;
}
// ***************************************************************************
UTransform CSceneUser::createTransform()
{
NL3D_HAUTO_ELT_SCENE;
CTransform *model= _Scene.createModel(TransformId);
return UTransform (model);
}
// ***************************************************************************
void CSceneUser::deleteTransform(UTransform &tr)
{
NL3D_HAUTO_ELT_SCENE;
_Scene.deleteModel (tr.getObjectPtr());
tr.detach ();
}
// ***************************************************************************
USkeleton CSceneUser::createSkeleton(const std::string &shapeName)
{
NL3D_HAUTO_CREATE_SKELETON;
CTransformShape *ts = _Scene.createInstance(shapeName);
if (ts)
{
CSkeletonModel *model= safe_cast (ts);
return USkeleton (model);
}
else
{
return USkeleton ();
}
}
// ***************************************************************************
void CSceneUser::deleteSkeleton(USkeleton &skel)
{
NL3D_HAUTO_ELT_SCENE;
// The component is auto added/deleted to _Scene in ctor/dtor.
_Scene.deleteInstance (skel.getObjectPtr());
skel.detach ();
}
// ***************************************************************************
ULandscape *CSceneUser::createLandscape()
{
NL3D_HAUTO_ELT_SCENE;
// The component is auto added/deleted to _Scene in ctor/dtor.
return _Landscapes.insert(new CLandscapeUser(&_Scene));
}
void CSceneUser::deleteLandscape(ULandscape *land)
{
NL3D_HAUTO_ELT_SCENE;
// The component is auto added/deleted to _Scene in ctor/dtor.
_Landscapes.erase((CLandscapeUser*) land);
}
UCloudScape *CSceneUser::createCloudScape()
{
NL3D_HAUTO_ELT_SCENE;
// The component is auto added/deleted to _Scene in ctor/dtor.
return _CloudScapes.insert(new CCloudScapeUser(&_Scene));
}
void CSceneUser::deleteCloudScape(UCloudScape *cs)
{
// The component is auto added/deleted to _Scene in ctor/dtor.
_CloudScapes.erase((CCloudScapeUser*) cs);
}
/*
UInstanceGroup *CSceneUser::createInstanceGroup (const std::string &instanceGroup)
{
// Create the instance group
CInstanceGroupUser *user=new CInstanceGroupUser;
// Init the class
if (!user->load (instanceGroup))
{
// Prb, erase it
delete user;
// Return error code
return NULL;
}
// Insert the pointer in the pointer list
_InstanceGroups.insert (user);
// return the good value
return user;
}
void CSceneUser::deleteInstanceGroup (UInstanceGroup *group)
{
// The component is auto added/deleted to _Scene in ctor/dtor.
_InstanceGroups.erase (dynamic_cast(group));
}
*/
void CSceneUser::setToGlobalInstanceGroup(UInstanceGroup *pIG)
{
NL3D_HAUTO_UI_SCENE;
CInstanceGroupUser *pIGU = (CInstanceGroupUser*)pIG;
pIGU->_InstanceGroup.setClusterSystemForInstances(_Scene.getGlobalInstanceGroup());
}
// ***************************************************************************
UVisualCollisionManager *CSceneUser::createVisualCollisionManager()
{
NL3D_HAUTO_ELT_SCENE;
return _VisualCollisionManagers.insert(new CVisualCollisionManagerUser);
}
void CSceneUser::deleteVisualCollisionManager(UVisualCollisionManager *mgr)
{
NL3D_HAUTO_ELT_SCENE;
CVisualCollisionManagerUser *vcmUser= dynamic_cast(mgr);
// if it was the one used for shadow receiving in this scene, then set NULL
if(_Scene.getVisualCollisionManagerForShadow()==&vcmUser->getVCM())
_Scene.setVisualCollisionManagerForShadow(NULL);
// and delete it
_VisualCollisionManagers.erase(vcmUser);
}
// ***************************************************************************
CSceneUser::CSceneUser(CDriverUser *drv, bool bSmallScene) : _Scene(bSmallScene)
{
nlassert(drv);
_DriverUser= drv;
// init default Roots.
_Scene.initDefaultRoots();
// Set driver.
_Scene.setDriver(_DriverUser->getDriver());
// Set viewport
_Scene.setViewport (CViewport());
// init QuadGridClipManager
_Scene.initQuadGridClipManager ();
// Create default camera, and active!!
setCam(createCamera());
_WaterEnvMap = NULL;
}
CSceneUser::~CSceneUser()
{
_VisualCollisionManagers.clear();
_Landscapes.clear();
_CloudScapes.clear();
_Scene.release();
_Scene.setDriver(NULL);
_Scene.setCam(NULL);
_DriverUser= NULL;
}
// ***************************************************************************
void CSceneUser::setMaxSkeletonsInNotCLodForm(uint m)
{
_Scene.setMaxSkeletonsInNotCLodForm(m);
}
// ***************************************************************************
uint CSceneUser::getMaxSkeletonsInNotCLodForm() const
{
return _Scene.getMaxSkeletonsInNotCLodForm();
}
// ***************************************************************************
void CSceneUser::enableElementRender(TRenderFilter elt, bool state)
{
_Scene.enableElementRender(elt, state);
}
// ***************************************************************************
void CSceneUser::profileNextRender()
{
_Scene.profileNextRender();
}
// ***************************************************************************
void CSceneUser::getProfileResults(CBenchResults &results)
{
// Fill profile results
results= _Scene.BenchRes;
}
// ***************************************************************************
void CSceneUser::profileQuadGridClipManager()
{
_Scene.getClipTrav().getQuadGridClipManager()->profile();
}
// ***************************************************************************
uint CSceneUser::getNumFlareContexts() const
{
return CScene::MaxNumFlareContexts;
}
// ***************************************************************************
void CSceneUser::setFlareContext(uint context)
{
if (context >= CScene::MaxNumFlareContexts)
{
nlwarning("Invalid flare context");
return;
}
_Scene.setFlareContext(context);
}
// ***************************************************************************
uint CSceneUser::getFlareContext() const
{
return _Scene.getFlareContext();
}
// ***************************************************************************
uint CSceneUser::getShadowMapTextureSize() const
{
return _Scene.getShadowMapTextureSize();
}
// ***************************************************************************
void CSceneUser::setShadowMapTextureSize(uint size)
{
_Scene.setShadowMapTextureSize(size);
}
// ***************************************************************************
uint CSceneUser::getShadowMapBlurSize() const
{
return _Scene.getShadowMapBlurSize();
}
// ***************************************************************************
void CSceneUser::setShadowMapBlurSize(uint bs)
{
_Scene.setShadowMapBlurSize(bs);
}
// ***************************************************************************
void CSceneUser::enableShadowPolySmooth(bool enable)
{
_Scene.enableShadowPolySmooth(enable);
}
// ***************************************************************************
bool CSceneUser::getEnableShadowPolySmooth() const
{
return _Scene.getEnableShadowPolySmooth();
}
// ***************************************************************************
void CSceneUser::setShadowMapDistFadeStart(float dist)
{
_Scene.setShadowMapDistFadeStart(dist);
}
// ***************************************************************************
float CSceneUser::getShadowMapDistFadeStart() const
{
return _Scene.getShadowMapDistFadeStart();
}
// ***************************************************************************
void CSceneUser::setShadowMapDistFadeEnd(float dist)
{
_Scene.setShadowMapDistFadeEnd(dist);
}
// ***************************************************************************
float CSceneUser::getShadowMapDistFadeEnd() const
{
return _Scene.getShadowMapDistFadeEnd();
}
// ***************************************************************************
void CSceneUser::setShadowMapMaxCasterInScreen(uint num)
{
_Scene.setShadowMapMaxCasterInScreen(num);
}
// ***************************************************************************
uint CSceneUser::getShadowMapMaxCasterInScreen() const
{
return _Scene.getShadowMapMaxCasterInScreen();
}
// ***************************************************************************
void CSceneUser::setShadowMapMaxCasterAround(uint num)
{
_Scene.setShadowMapMaxCasterAround(num);
}
// ***************************************************************************
uint CSceneUser::getShadowMapMaxCasterAround() const
{
return _Scene.getShadowMapMaxCasterAround();
}
// ***************************************************************************
void CSceneUser::setVisualCollisionManagerForShadow(UVisualCollisionManager *vcm)
{
if(vcm==NULL)
_Scene.setVisualCollisionManagerForShadow(NULL);
else
{
CVisualCollisionManagerUser *vcmUser= static_cast(vcm);
_Scene.setVisualCollisionManagerForShadow(&vcmUser->getVCM());
}
}
// ***************************************************************************
void CSceneUser::setWaterCallback(IWaterSurfaceAddedCallback *wcb)
{
_Scene.setWaterCallback(wcb);
}
// ***************************************************************************
IWaterSurfaceAddedCallback *CSceneUser::getWaterCallback() const
{
return _Scene.getWaterCallback();
}
// ***************************************************************************
void CSceneUser::setLandscapePolyDrawingCallback(ILandscapePolyDrawingCallback *lpd)
{
_Scene.setLandscapePolyDrawingCallback(lpd);
}
// ***************************************************************************
ILandscapePolyDrawingCallback *CSceneUser::getLandscapePolyDrawingCallback() const
{
return _Scene.getLandscapePolyDrawingCallback();
}
// ***************************************************************************
void CSceneUser::setupTransparencySorting(uint8 maxPriority /*=0*/,uint NbDistanceEntries /*=1024*/)
{
_Scene.getRenderTrav().setupTransparencySorting(maxPriority, NbDistanceEntries);
}
// ***************************************************************************
void CSceneUser::setWaterEnvMap(UWaterEnvMap *waterEnvMap)
{
if (waterEnvMap)
{
if (((CWaterEnvMapUser *) waterEnvMap)->EnvMap.Driver != _DriverUser)
{
nlwarning("Water envmap can only be set in a scene that was created from the same driver");
return;
}
}
_Scene.setWaterEnvMap(&((CWaterEnvMapUser *) waterEnvMap)->EnvMap);
_WaterEnvMap = waterEnvMap;
}
// ***************************************************************************
void CSceneUser::updateWaterEnvMaps(TGlobalAnimationTime time)
{
_Scene.updateWaterEnvMaps(time);
}
} // NL3D