From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/seg__remanence_8cpp-source.html | 529 +++++++++++++++++++++++ 1 file changed, 529 insertions(+) create mode 100644 docs/doxygen/nel/seg__remanence_8cpp-source.html (limited to 'docs/doxygen/nel/seg__remanence_8cpp-source.html') diff --git a/docs/doxygen/nel/seg__remanence_8cpp-source.html b/docs/doxygen/nel/seg__remanence_8cpp-source.html new file mode 100644 index 00000000..fc340689 --- /dev/null +++ b/docs/doxygen/nel/seg__remanence_8cpp-source.html @@ -0,0 +1,529 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# 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.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.h"
+00028 #include "3d/seg_remanence_shape.h"
+00029 #include "3d/vertex_buffer.h"
+00030 #include "3d/driver.h"
+00031 #include "3d/scene.h"
+00032 #include "3d/anim_detail_trav.h"
+00033 #include "3d/skeleton_model.h"
+00034 
+00035 
+00036 
+00037 
+00038 namespace NL3D
+00039 {
+00040 
+00042 static inline void BuildHermiteVector(const NLMISC::CVector &P0,
+00043                                                            const NLMISC::CVector &P1,
+00044                                                            const NLMISC::CVector &T0,
+00045                                                            const NLMISC::CVector &T1,
+00046                                                                          NLMISC::CVector &dest,                                                                  
+00047                                                            float lambda
+00048                                                            )
+00049 {       
+00050         const float lambda2 = lambda * lambda;
+00051         const float lambda3 = lambda2 * lambda;
+00052         const float h1 = 2 * lambda3 - 3 * lambda2 + 1; 
+00053         const float h2 = - 2 * lambda3 + 3 * lambda2; 
+00054         const float h3 = lambda3 - 2 * lambda2 + lambda; 
+00055         const float h4 = lambda3 - lambda2;
+00057         dest.set (h1 * P0.x + h2 * P1.x + h3 * T0.x + h4 * T1.x,
+00058                           h1 * P0.y + h2 * P1.y + h3 * T0.y + h4 * T1.y,
+00059                           h1 * P0.z + h2 * P1.z + h3 * T0.z + h4 * T1.z);
+00060 
+00061 }
+00062 
+00063 //===============================================================
+00064 CSegRemanence::CSegRemanence() : _NumSlice(0),
+00065                                                                  _Started(false),
+00066                                                                  _Stopping(false),
+00067                                                                  _Restarted(false),
+00068                                                                  _UnrollRatio(0),
+00069                                                                  _AniMat(NULL)
+00070 {       
+00071         IAnimatable::resize(AnimValueLast);
+00072 }
+00073 
+00074 //===============================================================
+00075 CSegRemanence::~CSegRemanence()
+00076 {
+00077         delete _AniMat;
+00078         // Auto detach me from skeleton. Must do it here, not in ~CTransform().
+00079         if(_FatherSkeletonModel)
+00080         {
+00081                 // detach me from the skeleton.
+00082                 // Observers hierarchy is modified.
+00083                 _FatherSkeletonModel->detachSkeletonSon(this);
+00084                 nlassert(_FatherSkeletonModel==NULL);
+00085         }
+00086 }
+00087 
+00088 //===============================================================
+00089 CSegRemanence::CSegRemanence(CSegRemanence &other)      : CTransformShape(other), _AniMat(NULL)
+00090 {
+00091         copyFromOther(other);
+00092 }
+00093 
+00094 //===============================================================
+00095 CSegRemanence &CSegRemanence::operator = (CSegRemanence &other)
+00096 {
+00097         if (this != &other)
+00098         {       
+00099                 (CTransformShape &) *this = (CTransformShape &) other; // copy base
+00100                 copyFromOther(other);
+00101         }
+00102         return *this;
+00103 }
+00104 
+00105 //===============================================================
+00106 void CSegRemanence::copyFromOther(CSegRemanence &other)
+00107 {
+00108         if (this == &other) return;
+00109         
+00110         CAnimatedMaterial   *otherMat = other._AniMat != NULL ? new CAnimatedMaterial(*other._AniMat)
+00111                                                                                                                   : NULL;
+00112         delete _AniMat;
+00113         _AniMat = otherMat;
+00114 
+00115         _Ribbons        = other._Ribbons; // sampled positions at each extremities of segment
+00116         _NumSlice       = other._NumSlice;
+00117         _NumCorners = other._NumCorners;
+00118         _Started    = other._Started;
+00119         _Restarted  = other._Restarted;
+00120         _Stopping   = other._Stopping;
+00121         _StartDate  = other._StartDate;
+00122         _CurrDate   = other._CurrDate;
+00123         
+00124 }
+00125 
+00126 //===============================================================
+00127 void CSegRemanence::registerBasic()
+00128 {
+00129         CMOT::registerModel(SegRemanenceShapeId, TransformShapeId, CSegRemanence::creator);     
+00130 //      CMOT::registerObs (HrcTravId, SegRemanenceShapeId, CSegRemanenceHrcObs::creator);
+00131         CMOT::registerObs(AnimDetailTravId, SegRemanenceShapeId, CSegRemanenceAnimDetailObs::creator);
+00132 }
+00133 
+00134 
+00135 //===============================================================
+00136 void CSegRemanence::render(IDriver *drv, CVertexBuffer &vb, CPrimitiveBlock &pb, CMaterial &mat)
+00137 {
+00138         CSegRemanenceShape *srs = NLMISC::safe_cast<CSegRemanenceShape *>((IShape *) Shape);            
+00139         const uint vertexSize = vb.getVertexSize();
+00140         uint8 *datas = (uint8 *) vb.getVertexCoordPointer();
+00141         uint numCorners = _Ribbons.size();
+00142         for(uint k = 0; k < numCorners; ++k)
+00143         {
+00144                 _Ribbons[k].fillVB(datas, vertexSize, srs->getNumSlices(), srs->getSliceTime());
+00145                 datas += (_NumSlice + 1) * vertexSize;
+00146         }       
+00147         
+00148         // roll / unroll using texture matrix
+00149         CMatrix texMat; 
+00150         texMat.setPos(NLMISC::CVector(1.f - _UnrollRatio, 0, 0));
+00151         if (mat.getTexture(0) != NULL)
+00152                 mat.setUserTexMat(0, texMat);
+00153         
+00154         
+00155         
+00156         drv->activeVertexBuffer(vb);    
+00157         drv->render(pb, mat);
+00158 
+00159         CScene *scene = NLMISC::safe_cast<ITravScene *>(_HrcObs->Trav)->Scene;
+00160         // change unroll ratio
+00161         if (!_Stopping)
+00162         {
+00163                 if (_UnrollRatio != 1.f)
+00164                 _UnrollRatio = std::min(1.f, _UnrollRatio + scene->getEllapsedTime() / (srs->getNumSlices() * srs->getSliceTime()));
+00165         }
+00166         else
+00167         {
+00168                 _UnrollRatio = std::max(0.f, _UnrollRatio - srs->getRollupRatio() * scene->getEllapsedTime() / (srs->getNumSlices() * srs->getSliceTime()));
+00169                 if (_UnrollRatio == 0.f)
+00170                 {
+00171                         _Stopping = false;
+00172                         _Started = false;
+00173                 }
+00174         }
+00175 }
+00176 
+00177 //===============================================================
+00178 CSegRemanence::CRibbon::CRibbon() : _LastSamplingDate(0)
+00179 {
+00180 }
+00181 
+00182 //===============================================================
+00183 void CSegRemanence::CRibbon::fillVB(uint8 *dest, uint stride, uint nbSegs, float sliceTime)
+00184 {               
+00185         TSampledPosVect::iterator currIt      = _Ribbon.begin();                        
+00186 
+00187         NLMISC::CVector t0 = (currIt + 1)->Pos - currIt->Pos;
+00188         NLMISC::CVector t1 = 0.5f * ((currIt + 2)->Pos - currIt->Pos);
+00189 
+00190         uint leftToDo = nbSegs + 1;
+00191 
+00192         float lambda = 0.f;
+00193         float lambdaStep = 1.f;
+00194 
+00195 /*      nlinfo("===============================");
+00196         for(uint k = 0; k < _Ribbon.size(); ++k)
+00197         {
+00198                 nlinfo("pos = (%.2f, %.2f, %.2f)", _Ribbon[k].Pos.x, _Ribbon[k].Pos.y, _Ribbon[k].Pos.z);
+00199         }*/
+00200 
+00201         for (;;)
+00202         {               
+00203                 float dt = currIt->SamplingDate - (currIt + 1)->SamplingDate;
+00204 
+00205                 if (dt < 10E-6f) // we reached the start of ribbon
+00206                 {
+00207 
+00208                         do
+00209                         {
+00210                                 (NLMISC::CVector &) *dest = currIt->Pos;
+00211                                 dest  += stride;
+00212                         }
+00213                         while (--leftToDo);                     
+00214                         return;
+00215                 }
+00216 
+00217                 float newLambdaStep = sliceTime / dt;
+00218                 // readapt lambda
+00219                 lambda *= newLambdaStep / lambdaStep;
+00220                 lambdaStep = newLambdaStep;
+00221                 for(;;)
+00222                 {
+00223                         if (lambda >= 1.f) break;
+00225                         BuildHermiteVector(currIt->Pos, (currIt + 1)->Pos, t0, t1, (NLMISC::CVector &) *dest, lambda);
+00226                         dest  += stride;
+00227                         -- leftToDo;
+00228                         if (!leftToDo) return;                                                                                          
+00229                         lambda += lambdaStep;                   
+00230                 }
+00231                 
+00232                 lambda -= 1.f;
+00233 
+00234                 // Start new segment and compute new tangents
+00235                 t0 = t1;
+00236                 ++currIt;               
+00237                 t1 = 0.5f * ((currIt + 2)->Pos - currIt->Pos);
+00238         }        
+00239 }
+00240 
+00241 //===============================================================
+00242 void CSegRemanence::CRibbon::duplicateFirstPos()
+00243 {
+00244         uint ribSize = _Ribbon.size();
+00245         for(uint k = 1; k < ribSize; ++k)
+00246         {
+00247                 _Ribbon[k] = _Ribbon[0];
+00248         }
+00249 }
+00250 
+00251 //===============================================================
+00252 void CSegRemanence::setupFromShape()
+00253 {
+00254         CSegRemanenceShape *srs = NLMISC::safe_cast<CSegRemanenceShape *>((IShape *) Shape);            
+00255         if (srs->getNumCorners() != _NumCorners || srs->getNumSlices() != _NumSlice)
+00256         {
+00257                 _Ribbons.resize(srs->getNumCorners());
+00258                 for(uint k = 0; k < _Ribbons.size(); ++k)
+00259                 {
+00260                         _Ribbons[k].setNumSlices(srs->getNumSlices());
+00261                 }               
+00262                 _NumCorners = srs->getNumCorners();
+00263                 _NumSlice  = srs->getNumSlices();
+00264         }
+00265         updateOpacityFromShape();
+00266 }
+00267 
+00268 
+00269 //===============================================================
+00270 void CSegRemanence::CRibbon::setNumSlices(uint numSegs)
+00271 {       
+00272         _Ribbon.resize(numSegs + 3);
+00273 }
+00274 
+00275 //===============================================================
+00276 void CSegRemanence::CRibbon::samplePos(const NLMISC::CVector &pos, float date, float sliceDuration)
+00277 {
+00278         nlassert(_Ribbon.size() != 0);
+00279         if (date - _LastSamplingDate > sliceDuration)
+00280         {
+00281                 _Ribbon.pop_back();
+00282                 CSampledPos sp(pos, date);
+00283                 _Ribbon.push_front(sp);
+00284                 _LastSamplingDate = date;
+00285         }
+00286         else
+00287         {
+00288                 _Ribbon.front().Pos = pos;
+00289                 _Ribbon.front().SamplingDate = date;
+00290         }
+00291 }
+00292 
+00293 //===============================================================
+00294 void CSegRemanence::samplePos(float date)
+00295 {
+00296         if (_Started)
+00297         {       
+00298                 IBaseHrcObs *bho = (IBaseHrcObs *) getObs(HrcTravId);
+00299                 CSegRemanenceShape *srs = NLMISC::safe_cast<CSegRemanenceShape *>((IShape *) Shape);
+00300                 uint numCorners = _Ribbons.size();
+00301                 for(uint k = 0; k < numCorners; ++k)
+00302                 {               
+00303                         _Ribbons[k].samplePos(bho->WorldMatrix * srs->getCorner(k), date, srs->getSliceTime());
+00304                 }
+00305                 if (_Restarted)
+00306                 {
+00307                         for(uint k = 0; k < numCorners; ++k)
+00308                         {
+00309                                 _Ribbons[k].duplicateFirstPos();
+00310                         }
+00311                         _Restarted = false;
+00312                         _StartDate = date;
+00313                 }
+00314                 _CurrDate = date;
+00315         }
+00316 }
+00317 
+00318 //===============================================================
+00319 /*
+00320 void CSegRemanenceHrcObs::traverse(IObs *caller)
+00321 {
+00322         CTransformHrcObs::traverse (caller);
+00323         CSegRemanence *sr = static_cast<CSegRemanence *>(this->Model);
+00324         if (sr->isStarted())
+00325         {       
+00326                 CScene *scene = NLMISC::safe_cast<ITravScene *>(Trav)->Scene;
+00327                 if (scene->getNumRender() != (_LastSampleFrame + 1))
+00328                 {
+00329                         if (!sr->isStopping())
+00330                         {                       
+00331                                 // if wasn't visible at previous frame, must invalidate position
+00332                                 sr->restart();
+00333                         }
+00334                         else
+00335                         {
+00336                                 // ribbon started unrolling when it disapperaed from screen so simply remove it
+00337                                 sr->stopNoUnroll();
+00338                         }
+00339                 }               
+00340                 _LastSampleFrame = scene->getNumRender();
+00341                 sr->setupFromShape();
+00342                 sr->samplePos((float) scene->getCurrentTime());
+00343         }
+00344 }
+00345 */
+00346 
+00347 /*
+00348 //===============================================================
+00349 CSegRemanenceHrcObs::CSegRemanenceHrcObs() : _LastSampleFrame(0)
+00350 {       
+00351 }
+00352 */
+00353 
+00354 //===============================================================
+00355 void CSegRemanence::start()
+00356 {
+00357         if (_Started && !_Stopping) return;
+00358         restart();              
+00359 }
+00360 
+00361 //===============================================================
+00362 void CSegRemanence::restart()
+00363 {
+00364         CSegRemanenceShape *srs = NLMISC::safe_cast<CSegRemanenceShape *>((IShape *) Shape);    
+00365         if (!srs->getTextureShifting())
+00366         {       
+00367                 _UnrollRatio = 1.f;
+00368         }
+00369         else
+00370         {
+00371                 if (!_Stopping)
+00372                         _UnrollRatio = 0.f;
+00373         }
+00374         _Started = _Restarted = true;
+00375         _Stopping = false;      
+00376 }
+00377 
+00378 //===============================================================
+00379 void CSegRemanence::stop()
+00380 {
+00381         _Stopping = true;
+00382 }
+00383 
+00384 //===============================================================
+00385 void CSegRemanence::stopNoUnroll()
+00386 {
+00387         _Started = _Restarted = _Stopping = false;
+00388 }
+00389 
+00390 //===============================================================
+00391 void CSegRemanence::updateOpacityFromShape()
+00392 {
+00393         CSegRemanenceShape *srs = NLMISC::safe_cast<CSegRemanenceShape *>((IShape *) Shape);
+00394         bool transparent = srs->getMaterial().getBlend();
+00395         setTransparency(transparent);
+00396         setOpacity(!transparent);
+00397 }
+00398 
+00399 //===============================================================
+00400 void CSegRemanence::setAnimatedMaterial(CAnimatedMaterial *mat)
+00401 {
+00402         if (mat == _AniMat) return;
+00403         delete _AniMat;
+00404         _AniMat = mat;
+00405         _AniMat->setFather(this, OwnerBit);
+00406 }
+00407 
+00408 //===============================================================
+00409 void CSegRemanence::registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix)
+00410 {       
+00411         CTransformShape::registerToChannelMixer(chanMixer, prefix);
+00412         if (_AniMat)
+00413         {
+00414                 _AniMat->registerToChannelMixer(chanMixer, prefix + _AniMat->getMaterialName() + ".")   ;
+00415         }
+00416 }
+00417 
+00418 //===============================================================
+00419 void CSegRemanenceAnimDetailObs::traverse(IObs *caller)
+00420 {
+00421         CTransformAnimDetailObs::traverse(caller);
+00422         CSegRemanence *sr = NLMISC::safe_cast<CSegRemanence *>(Model);
+00423         if (sr->isStarted())
+00424         {       
+00427 
+00428                 CScene *scene = NLMISC::safe_cast<ITravScene *>(Trav)->Scene;
+00429                 if (scene->getNumRender() != (_LastSampleFrame + 1))
+00430                 {
+00431                         if (!sr->isStopping())
+00432                         {                       
+00433                                 // if wasn't visible at previous frame, must invalidate position
+00434                                 sr->restart();
+00435                         }
+00436                         else
+00437                         {
+00438                                 // ribbon started unrolling when it disapperaed from screen so simply remove it
+00439                                 sr->stopNoUnroll();
+00440                         }
+00441                 }               
+00442                 _LastSampleFrame = scene->getNumRender();
+00443                 sr->setupFromShape();
+00444                 sr->samplePos((float) scene->getCurrentTime());
+00445 
+00448 
+00449         
+00450                 // test if animated material must be updated.
+00451                 if(sr->IAnimatable::isTouched(CSegRemanence::OwnerBit))
+00452                 {
+00453                         if (sr->getAnimatedMaterial())
+00454                                 sr->getAnimatedMaterial()->update();                    
+00455                         sr->clearAnimatedMatFlag();
+00456                 }
+00457         }
+00458 }
+00459 
+00460 CSegRemanenceAnimDetailObs::CSegRemanenceAnimDetailObs() : _LastSampleFrame(0)
+00461 {       
+00462 }
+00463 
+00464 
+00465 
+00466 }
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1