# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

particle_system_shape.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2001 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "std3d.h"
00027 
00028 #include "3d/particle_system.h"
00029 #include "3d/particle_system_shape.h"
00030 #include "3d/particle_system_model.h"
00031 #include "3d/scene.h"
00032 #include "3d/driver.h"
00033 #include "nel/misc/file.h"
00034 #include "nel/misc/mem_stream.h"
00035 
00036 
00037 
00038 namespace NL3D {
00039 
00040 using NLMISC::IStream;
00041 using NLMISC::CIFile;
00042 
00043 
00044 
00045 
00046 // private usage : macro to check the memory integrity
00047 #if defined(NL_DEBUG) && defined(NL_OS_WINDOWS)
00048         #include <crtdbg.h>
00049         //#define PARTICLES_CHECK_MEM nlassert(_CrtCheckMemory());
00050         #define PARTICLES_CHECK_MEM 
00051 #else
00052         #define PARTICLES_CHECK_MEM
00053 #endif
00054 
00056 CParticleSystemShape::CParticleSystemShape() : _MaxViewDist(100.f),
00057                                                                                            _DestroyWhenOutOfFrustum(false),
00058                                                                                            _DestroyModelWhenOutOfRange(false),
00059                                                                                            _UsePrecomputedBBox(false),
00060                                                                                            _Sharing(false)
00061 {
00062         for (uint k = 0; k < 4; ++k)
00063         {
00064                 _UserParamDefaultTrack[k].setValue(0);
00065         }
00066         _DefaultPos.setValue(CVector::Null);
00067         _DefaultScale.setValue( CVector(1, 1, 1) );     
00068         _DefaultRotQuat.setValue(CQuat());
00069         _DefaultTriggerTrack.setValue(true); // by default, system start as soon as they are instanciated
00070 
00071 }
00072 
00074 void    CParticleSystemShape::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00075 {
00076         sint ver = f.serialVersion(6);
00078         NLMISC::CVector8 &buf = _ParticleSystemProto.bufferAsVector();
00079         f.serialCont(buf);
00080         if (ver > 1)
00081         {
00082                 // serial default tracks
00083                 for (uint k = 0; k < 4; ++k)
00084                 {
00085                         f.serial(_UserParamDefaultTrack[k]);
00086                 }
00087         }
00088         if ( ver > 2)
00089         {
00090                 f.serial (_DefaultPos);
00091                 f.serial (_DefaultScale);               
00092                 f.serial (_DefaultRotQuat);
00093         }
00094         if ( ver > 3)
00095         {
00096                 f.serial(_MaxViewDist);
00097                 f.serial(_DestroyWhenOutOfFrustum);             
00098                 f.serial(_DestroyModelWhenOutOfRange);
00099         }
00100         if ( ver > 4)
00101         {
00102                 f.serial(_UsePrecomputedBBox);
00103                 if (_UsePrecomputedBBox)
00104                 {
00105                         f.serial(_PrecomputedBBox);
00106                 }
00107         }
00108         if ( ver > 5)
00109         {
00110                 f.serial(_Sharing);
00111         }
00112 }
00113 
00115 void CParticleSystemShape::buildFromPS(const CParticleSystem &ps)
00116 {
00117         // must be sure that we are writting in the stream
00118         if (_ParticleSystemProto.isReading())
00119         {
00120                 _ParticleSystemProto.invert();
00121         }
00122         
00123         // to have const correctness in the prototype, we must do this...
00124         CParticleSystem *myPs = const_cast<CParticleSystem *>(&ps);
00125         nlassert(myPs);
00126         // build the prototype
00127         _ParticleSystemProto.serialPtr(myPs);
00128 
00129         // mirror some system values
00130         _MaxViewDist = myPs->getMaxViewDist();
00131         _DestroyWhenOutOfFrustum = myPs->doesDestroyWhenOutOfFrustum(); 
00132         _DestroyModelWhenOutOfRange    = myPs->getDestroyModelWhenOutOfRange();
00133         if (!myPs->getAutoComputeBBox())
00134         {
00135                 _UsePrecomputedBBox = true;
00136                 myPs->computeBBox(_PrecomputedBBox);
00137         }
00138         else
00139         {
00140                 _UsePrecomputedBBox = false;
00141         }
00142         _Sharing = myPs->isSharingEnabled();
00143 }
00144 
00146 void    CParticleSystemShape::getAABBox(NLMISC::CAABBox &bbox) const
00147 {
00148         if (!_UsePrecomputedBBox)
00149         {
00150                 bbox.setCenter(NLMISC::CVector::Null);
00151                 bbox.setHalfSize(NLMISC::CVector(1, 1, 1));
00152         }
00153         else
00154         {
00155                 bbox = _PrecomputedBBox;
00156         }
00157 }
00158 
00160 CParticleSystem *CParticleSystemShape::instanciatePS(CScene &scene)
00161 {
00162         if (_Sharing && _SharedSystem != NULL) // is sharing enabled, and is a system already instanciated
00163         {
00164                 return _SharedSystem;
00165         }
00166 
00167         // copy the datas
00168         CParticleSystem *myInstance = NULL;
00169 
00170         // serialize from the memory stream     
00171         if (!_ParticleSystemProto.isReading()) // we must be sure that we are reading the stream
00172         {
00173                 _ParticleSystemProto.invert();
00174         }
00175 
00176         _ParticleSystemProto.resetPtrTable();
00177         _ParticleSystemProto.seek(0, IStream::begin);
00178         _ParticleSystemProto.serialPtr(myInstance); // instanciate the system   
00179 
00180 
00181         myInstance->setScene(&scene);
00182 
00183         if (_Sharing)
00184         {
00185                 _SharedSystem = myInstance; // set this as the first shared instance
00186         }
00187 
00188         return myInstance;
00189 }
00190 
00192 CTransformShape         *CParticleSystemShape::createInstance(CScene &scene)
00193 {
00194         CParticleSystemModel *psm = NLMISC::safe_cast<CParticleSystemModel *>(scene.createModel(NL3D::ParticleSystemModelId) );
00195         psm->Shape = this;
00196         psm->_Scene = &scene; // the model needs the scene to recreate the particle system he holds                     
00197         // by default, we don't instanciate the system. It will be instanciated only if visible and triggered
00198         // psm->_ParticleSystem = instanciatePS(scene); 
00199 
00200         // Setup position with the default value
00201         psm->ITransformable::setPos( ((CAnimatedValueVector&)_DefaultPos.getValue()).Value  );
00202         psm->ITransformable::setRotQuat( ((CAnimatedValueQuat&)_DefaultRotQuat.getValue()).Value  );    
00203         psm->ITransformable::setScale( ((CAnimatedValueVector&)_DefaultScale.getValue()).Value  );
00204 
00205         // LoadBalancing backward compatibility: ParticleSystems are added to the "Global" Load Balancing Group.
00206         psm->setLoadBalancingGroup("Global");
00207 
00208         return psm;
00209 }
00210 
00212 void    CParticleSystemShape::render(IDriver *drv, CTransformShape *trans, bool passOpaque)
00213 {
00214         nlassert(dynamic_cast<CParticleSystemModel *>(trans));
00215         nlassert(drv);
00216         CParticleSystemModel *psm = (CParticleSystemModel *) trans;
00217         if (psm->_Invalidated) return;
00218         CParticleSystem *ps = psm->getPS();
00220         if (!ps) return;
00221         
00222         TAnimationTime delay = psm->getEllapsedTime();
00223         nlassert(ps->getScene());       
00224 
00226         // render particles  //
00228 
00230         if (ps->isSharingEnabled())
00231         {
00232                 ps->setSysMat(trans->getWorldMatrix());
00233         }
00234         
00235         // Setup the matrix.
00237 
00238         ps->setDriver(drv);
00239         // draw particle
00240         PARTICLES_CHECK_MEM;
00241         if (passOpaque)
00242         {
00243                 ps->step(CParticleSystem::SolidRender, delay);
00244         }
00245         else
00246         {
00247                 ps->step(CParticleSystem::BlendRender, delay);
00248         }
00249         PARTICLES_CHECK_MEM;
00250         if (psm->isToolDisplayEnabled())
00251         {
00252                 ps->step(CParticleSystem::ToolRender, delay);
00253                 PARTICLES_CHECK_MEM;
00254         }
00255 }
00256 
00257 } // NL3D