1156 lines
31 KiB
C++
1156 lines
31 KiB
C++
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||
|
// 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 <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
#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<CAnimationSetUser *>(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<CPointLightModel*> (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, bool doHrcPass, bool doTrav, bool keepTrav)
|
||
|
{
|
||
|
|
||
|
// 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, doHrcPass, doTrav, keepTrav);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ***************************************************************************
|
||
|
void CSceneUser::endPartRender(bool updateWaitingInstancesFlag, bool restoreMatrixContextAfterRender, bool keepTrav)
|
||
|
{
|
||
|
|
||
|
// render the scene.
|
||
|
{
|
||
|
NL3D_HAUTO_RENDER_SCENE_END
|
||
|
_Scene.endPartRender(keepTrav);
|
||
|
}
|
||
|
|
||
|
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<UInstance*,CTransformShape*>::iterator it = _WaitingInstances.begin();
|
||
|
while( it != _WaitingInstances.end() )
|
||
|
{
|
||
|
if( it->second != NULL )
|
||
|
{
|
||
|
it->first->attach (it->second);
|
||
|
std::map<UInstance*,CTransformShape*>::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<CInstanceGroupUser*>(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<CCamera*>(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<CMeshInstance*>(model)==NULL )
|
||
|
// nlerror("UScene::createInstance(): shape is not a mesh");
|
||
|
|
||
|
// The component is auto added/deleted to _Scene in ctor/dtor.
|
||
|
// return dynamic_cast<UInstance*>( _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<CSkeletonModel*> (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<CInstanceGroupUser*>(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<CVisualCollisionManagerUser*>(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<CVisualCollisionManagerUser*>(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
|