# 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  

seg_remanence_shape.cpp

Go to the documentation of this file.
00001 
00006 /* Copyright, 2000, 2001, 2002 Nevrax Ltd.
00007  *
00008  * This file is part of NEVRAX NEL.
00009  * NEVRAX NEL is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2, or (at your option)
00012  * any later version.
00013 
00014  * NEVRAX NEL is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00017  * General Public License for more details.
00018 
00019  * You should have received a copy of the GNU General Public License
00020  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00021  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00022  * MA 02111-1307, USA.
00023  */
00024 
00025 #include "std3d.h"
00026 
00027 #include "3d/seg_remanence_shape.h"
00028 #include "3d/seg_remanence.h"
00029 #include "3d/driver.h"
00030 #include "3d/scene.h"
00031 
00032 
00033 
00034 
00035 namespace NL3D
00036 {
00037 
00038 
00039 //===========================================================
00040 CSegRemanenceShape::CSegRemanenceShape() : _GeomTouched(true),
00041                                                                                    _MatTouched(true),
00042                                                                                    _TextureShifting(true),
00043                                                                                    _NumSlices(8),
00044                                                                                    _SliceTime(0.05f),
00045                                                                                    _RollUpRatio(1.f),
00046                                                                                    _AnimatedMat(NULL)
00047 {
00048         _BBox.setCenter(NLMISC::CVector::Null);
00049         _BBox.setHalfSize(NLMISC::CVector(3, 3, 3));
00050         setNumCorners(2);
00051 }
00052 
00053 //===========================================================
00054 void CSegRemanenceShape::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00055 {
00056         sint ver = f.serialVersion(1);
00057         f.serial(_NumSlices);
00058         f.serial(_SliceTime);
00059         f.serialCont(_Corners); 
00060         f.serial(_Mat); 
00061         f.serial(_BBox);
00062         f.serial(_TextureShifting);
00063         f.serialPtr(_AnimatedMat);
00064         if (f.isReading())
00065         {       
00066                 _GeomTouched = true;
00067                 _MatTouched  = true;
00068         }
00069         if (ver >= 1)
00070         {
00071                 f.serial(_RollUpRatio);
00072         }
00073 }
00074 
00075 //===========================================================
00076 void CSegRemanenceShape::setSliceTime(float sliceTime)
00077 {
00078         nlassert(sliceTime > 0);
00079         _SliceTime = sliceTime; 
00080 }
00081 
00082 //===========================================================
00083 void CSegRemanenceShape::setCorner(uint corner, const NLMISC::CVector &value)
00084 {
00085         nlassert(corner < _Corners.size());
00086         _Corners[corner] = value;
00087 }
00088 
00089 //===========================================================
00090 void CSegRemanenceShape::setNumSlices(uint32 numSlices)
00091 {
00092         nlassert(numSlices >= 2);
00093         _NumSlices = numSlices; 
00094         _GeomTouched = true;
00095 }
00096 
00097 //===========================================================
00098 NLMISC::CVector CSegRemanenceShape::getCorner(uint corner) const
00099 {
00100         nlassert(corner < _Corners.size());
00101         return _Corners[corner];
00102 }
00103 
00104 //===========================================================
00105 void CSegRemanenceShape::setNumCorners(uint numCorners)
00106 {
00107         nlassert(numCorners >= 2);
00108         _Corners.resize(numCorners);
00109         std::fill(_Corners.begin(), _Corners.end(), NLMISC::CVector::Null);
00110         _GeomTouched = true;
00111 }
00112 
00113 //===========================================================
00114 void CSegRemanenceShape::render(IDriver *drv, CTransformShape *trans, bool opaquePass)
00115 {
00116         if ((!opaquePass && _Mat.getBlend())
00117             || (opaquePass && !_Mat.getBlend())
00118            )
00119         {
00120                 CSegRemanence *sr = NLMISC::safe_cast<CSegRemanence *>(trans);
00121                 if (!sr->isStarted()) return;           
00122                 setupVBnPB();
00123                 setupMaterial();
00124                 // vertices are rendered in world space
00125                 drv->setupModelMatrix(NLMISC::CMatrix::Identity);               
00126                 //              
00127                 sr->render(drv, _VB, _PB, _Mat);                
00128         }
00129 }
00130 
00131 
00132 //===========================================================
00133 void CSegRemanenceShape::flushTextures(IDriver &driver)
00134 {
00135         _Mat.flushTextures(driver);
00136 }
00137 
00138 //===========================================================
00139 CTransformShape *CSegRemanenceShape::createInstance(CScene &scene)
00140 {       
00141         CSegRemanence *sr = NLMISC::safe_cast<CSegRemanence *>(scene.createModel(NL3D::SegRemanenceShapeId) );
00142         sr->Shape = this;
00143         CAnimatedMaterial *aniMat = NULL;
00144         if (_AnimatedMat)
00145         {
00146                 aniMat = new CAnimatedMaterial(_AnimatedMat);
00147                 aniMat->setMaterial(&_Mat);             
00148         }
00149         sr->setAnimatedMaterial(aniMat);
00150         sr->setupFromShape();
00151         // SegRemanence are added to the "Fx" Load Balancing Group.
00152         sr->setLoadBalancingGroup("Fx");
00153         return sr;
00154 }
00155 
00156 
00157 //===========================================================
00158 float CSegRemanenceShape::getNumTriangles(float distance)
00159 {
00160         return (float) (_NumSlices * 2);
00161 }
00162 
00163 
00164 //===========================================================
00165 void CSegRemanenceShape::setupVBnPB()
00166 {
00167         if (!_GeomTouched) return;
00168 
00169         uint numCorners = _Corners.size();
00170         _VB.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag);
00171         _VB.setNumVertices(numCorners * (_NumSlices + 1));
00172         uint k, l;
00173         
00174         // set tex coords
00175         for(l = 0; l < numCorners; ++l)
00176         {               
00177                 for(k = 0; k <= _NumSlices; ++k)
00178                 {
00179                 
00180                         _VB.setTexCoord((_NumSlices + 1) * l + k, 0, (float) k / _NumSlices, (float) l / (numCorners - 1));
00181                 }
00182         }
00183         // create primitive block
00184         _PB.setNumTri(2 * (numCorners - 1) * _NumSlices);
00185         //
00186         for(l = 0; l < numCorners - 1; ++l)
00187         {
00188                 for(k = 0; k < _NumSlices; ++k)
00189                 {
00190                         _PB.setTri(2 * (l * _NumSlices + k), (_NumSlices + 1) * l + k,  (_NumSlices + 1) * (l + 1) + k + 1, (_NumSlices + 1) * (l + 1) + k);
00191                         _PB.setTri(2 * (l * _NumSlices + k) + 1, (_NumSlices + 1) * l + k, (_NumSlices + 1) * l + k + 1, (_NumSlices + 1) * (l + 1) + k + 1);
00192                 }
00193         }
00194         _GeomTouched = false;   
00195 }
00196 
00197 //===========================================================
00198 void CSegRemanenceShape::setBBox(const NLMISC::CAABBox &bbox)
00199 {
00200         _BBox = bbox;
00201 }
00202 
00203 //===========================================================
00204 void CSegRemanenceShape::setMaterial(const CMaterial &mat)
00205 {
00206         _Mat = mat;
00207         _MatTouched = true;
00208 }
00209 
00210 //===========================================================
00211 void CSegRemanenceShape::setTextureShifting(bool on /*=true*/)
00212 {
00213         _TextureShifting = on;
00214         _MatTouched = true;
00215 }
00216 
00217 //===========================================================
00218 void CSegRemanenceShape::setRollupRatio(float ratio)
00219 {
00220         nlassert(ratio > 0);
00221         _RollUpRatio = ratio;
00222 }
00223 
00224 //===========================================================
00225 void CSegRemanenceShape::setupMaterial()
00226 {
00227         if (!_MatTouched) return;       
00228         _Mat.enableUserTexMat(0);
00229         _Mat.getTexture(0)->setWrapS(ITexture::Clamp);  
00230         _Mat.setDoubleSided(true);
00231         _Mat.setLighting(false); // lighting not supported (the vb has no normals anyway..)
00232         _MatTouched = false;
00233 }
00234 
00235 //===========================================================
00236 void CSegRemanenceShape::setAnimatedMaterial(const std::string &name)
00237 {
00238         nlassert(!name.empty());
00239         nlassert(_AnimatedMat == NULL);
00240         _AnimatedMat  = new CMaterialBase;
00241         _AnimatedMat->Name = name;
00242 }
00243 
00244 
00245 
00246 //===========================================================
00247 CSegRemanenceShape::CSegRemanenceShape(const CSegRemanenceShape &other) : IShape(other), _AnimatedMat(NULL)
00248 {
00249         copyFromOther(other);
00250 }
00251 
00252 //===========================================================
00253 CSegRemanenceShape &CSegRemanenceShape::operator = (const CSegRemanenceShape &other)
00254 {
00255         if (&other != this)
00256         {       
00257                 copyFromOther(other);
00258                 (IShape &) *this = (IShape &) other; // copy base part  
00259         }
00260         return *this;
00261 }
00262 
00263 //===========================================================
00264 CSegRemanenceShape::~CSegRemanenceShape()
00265 {
00266         delete _AnimatedMat;
00267 }
00268 
00269 //===========================================================
00270 void CSegRemanenceShape::copyFromOther(const CSegRemanenceShape &other)
00271 {
00272         if (&other == this) return;
00273         CMaterialBase *otherAnimatedMat = other._AnimatedMat != NULL ? new CMaterialBase(*other._AnimatedMat)
00274                                                                                                                                  : NULL;
00275         delete _AnimatedMat;
00276         _AnimatedMat = otherAnimatedMat;
00277 
00278         _GeomTouched     = other._GeomTouched;
00279         _MatTouched      = other._MatTouched; 
00280         _TextureShifting = other._TextureShifting;      
00281         _NumSlices       = other._NumSlices;
00282         _SliceTime       = other._SliceTime;
00283         _Corners                 = other._Corners;      
00284         _Mat             = other._Mat;
00285         _VB              = other._VB;
00286         _PB              = other._PB;
00287         _BBox                    = other._BBox; 
00288         _RollUpRatio     = other._RollUpRatio;  
00289 }
00290         
00291 }
00292