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/channel__mixer_8cpp-source.html | 769 +++++++++++++++++++++++ 1 file changed, 769 insertions(+) create mode 100644 docs/doxygen/nel/channel__mixer_8cpp-source.html (limited to 'docs/doxygen/nel/channel__mixer_8cpp-source.html') diff --git a/docs/doxygen/nel/channel__mixer_8cpp-source.html b/docs/doxygen/nel/channel__mixer_8cpp-source.html new file mode 100644 index 00000000..fddf125e --- /dev/null +++ b/docs/doxygen/nel/channel__mixer_8cpp-source.html @@ -0,0 +1,769 @@ + + + + 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  
+

channel_mixer.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/channel_mixer.h"
+00029 #include "3d/track.h"
+00030 #include "3d/animatable.h"
+00031 #include "3d/skeleton_weight.h"
+00032 #include "nel/misc/debug.h"
+00033 #include "nel/misc/common.h"
+00034 
+00035 using namespace NLMISC;
+00036 using namespace std;
+00037 
+00038 namespace NL3D 
+00039 {
+00040 
+00041 // ***************************************************************************
+00042 
+00043 CChannelMixer::CChannelMixer()
+00044 {
+00045         // No channel in the list
+00046         _FirstChannelGlobal=NULL;
+00047         _FirstChannelDetail=NULL;
+00048 
+00049         // No animation set
+00050         _AnimationSet=NULL;
+00051 
+00052         // Mixer no dirty
+00053         _Dirt=false;
+00054         _ListToEvalDirt= false;
+00055 
+00056         // never evaluated.
+00057         _LastEvalDetailDate= -1;
+00058 }
+00059 
+00060 // ***************************************************************************
+00061 
+00062 void CChannelMixer::setAnimationSet (const CAnimationSet* animationSet)
+00063 {
+00064         // Set the animationSet Pointer
+00065         _AnimationSet=animationSet;
+00066 
+00067         // clear the channels.
+00068         resetChannels();
+00069 }
+00070 
+00071 // ***************************************************************************
+00072 
+00073 const CAnimationSet* CChannelMixer::getAnimationSet () const
+00074 {
+00075         // Return the animationSet Pointer
+00076         return _AnimationSet;
+00077 }
+00078 
+00079 // ***************************************************************************
+00080 
+00081 void CChannelMixer::eval (bool detail, uint64 evalDetailDate)
+00082 {
+00083         // Setup an array of animation that are not empty and stay
+00084         uint numActive=0;
+00085         uint activeSlot[NumAnimationSlot];
+00086 
+00087         if(detail && (sint64)evalDetailDate== _LastEvalDetailDate)
+00088                 return;
+00089 
+00090         // clean list according to anim setup
+00091         if(_Dirt)
+00092         {
+00093                 refreshList();
+00094                 cleanAll();
+00095         }
+00096 
+00097         // clean eval list, according to channels enabled.
+00098         if(_ListToEvalDirt)
+00099         {
+00100                 refreshListToEval();
+00101                 nlassert(!_ListToEvalDirt);
+00102         }
+00103 
+00104         // Setup it up
+00105         for (uint s=0; s<NumAnimationSlot; s++)
+00106         {
+00107                 // Dirt, not empty and has an influence? (add)
+00108                 if (!_SlotArray[s].isEmpty() && _SlotArray[s]._Weight>0)
+00109                         // Add a dirt slot
+00110                         activeSlot[numActive++]=s;
+00111         }
+00112 
+00113         // no slot enabled at all?? skip
+00114         if(numActive==0)
+00115                 return;
+00116 
+00117         // For each selected channel
+00118         CChannel        **channelArrayPtr = 0;
+00119         uint            numChans;
+00120         if(detail)
+00121         {
+00122                 numChans= _DetailListToEval.size();
+00123                 if(numChans)
+00124                         channelArrayPtr= &_DetailListToEval[0];
+00125                 // eval the animation only one time per scene traversal.
+00126                 _LastEvalDetailDate= evalDetailDate;
+00127         }
+00128         else
+00129         {
+00130                 numChans= _GlobalListToEval.size();
+00131                 if(numChans)
+00132                         channelArrayPtr= &_GlobalListToEval[0];
+00133         }
+00134 
+00135 
+00136         for(;numChans>0; numChans--, channelArrayPtr++)
+00137         {
+00138                 CChannel        *pChannel= *channelArrayPtr;
+00139 
+00140                 // For Quat animated value only.
+00141                 CQuat   firstQuat;
+00142 
+00143                 // First slot found
+00144                 bool bFirst=true;
+00145 
+00146                 // Last blend factor
+00147                 float lastBlend=0.0;
+00148 
+00149                 // Eval each slot
+00150                 for (uint a=0; a<numActive; a++)
+00151                 {
+00152                         // Slot number
+00153                         uint slot=activeSlot[a];
+00154 
+00155                         // Current blend factor
+00156                         float blend=pChannel->_Weights[slot]*_SlotArray[slot]._Weight;
+00157 
+00158                         if(blend!=0.0f)
+00159                         {
+00160                                 // Eval the track at this time
+00161                                 ((ITrack*)pChannel->_Tracks[slot])->eval (_SlotArray[slot]._Time);
+00162 
+00163                                 // First track to be eval ?
+00164                                 if (bFirst)
+00165                                 {
+00166                                         // If channel is a Quaternion animated Value, must store the first Quat.
+00167                                         if (pChannel->_IsQuat)
+00168                                         {
+00169                                                 CAnimatedValueBlendable<NLMISC::CQuat>  *pQuatValue=(CAnimatedValueBlendable<NLMISC::CQuat>*)&pChannel->_Tracks[slot]->getValue();
+00170                                                 firstQuat=pQuatValue->Value;
+00171                                         }
+00172 
+00173                                         // Copy the interpolated value
+00174                                         pChannel->_Value->affect (pChannel->_Tracks[slot]->getValue());
+00175 
+00176                                         // First blend factor
+00177                                         lastBlend=blend;
+00178 
+00179                                         // Not first anymore
+00180                                         bFirst=false;
+00181                                 }
+00182                                 else
+00183                                 {
+00184                                         // If channel is a Quaternion animated Value, must makeClosest the ith result of the track, from firstQuat.
+00185                                         if (pChannel->_IsQuat)
+00186                                         {
+00187                                                 CAnimatedValueBlendable<NLMISC::CQuat>  *pQuatValue=(CAnimatedValueBlendable<NLMISC::CQuat>*)&pChannel->_Tracks[slot]->getValue();
+00188                                                 pQuatValue->Value.makeClosest (firstQuat);
+00189                                         }
+00190 
+00191                                         // Blend with this value and the previous sum
+00192                                         pChannel->_Value->blend (pChannel->_Tracks[slot]->getValue(), lastBlend/(lastBlend+blend));
+00193 
+00194                                         // last blend update
+00195                                         lastBlend+=blend;
+00196                                 }
+00197                         }
+00198 
+00199                         // NB: if all weights are 0, the AnimatedValue is not modified...
+00200                 }
+00201 
+00202                 // Touch the animated value and its owner to recompute them later.
+00203                 pChannel->_Object->touch (pChannel->_ValueId, pChannel->_OwnerValueId);
+00204         }
+00205 }
+00206 
+00207 // ***************************************************************************
+00208 
+00209 sint CChannelMixer::addChannel (const string& channelName, IAnimatable* animatable, IAnimatedValue* value, ITrack* defaultValue, uint32 valueId, uint32 ownerValueId, bool detail)
+00210 {
+00211         // Check the animationSet has been set
+00212         nlassert (_AnimationSet);
+00213 
+00214         // Check args
+00215         nlassert (animatable);
+00216         nlassert (value);
+00217         nlassert (defaultValue);
+00218 
+00219         // Get the channel Id having the same name than the tracks in this animation set.
+00220         uint iDInAnimationSet=_AnimationSet->getChannelIdByName (channelName);
+00221 
+00222         // Tracks exist in this animation set?
+00223         if (iDInAnimationSet!=CAnimationSet::NotFound)
+00224         {
+00225                 // The channel entry
+00226                 CChannel        entry;
+00227 
+00228                 // Set the channel name
+00229                 entry._ChannelName=channelName;
+00230 
+00231                 // Set the object pointer
+00232                 entry._Object=animatable;
+00233 
+00234                 // Set the pointer on the value in the object
+00235                 entry._Value=value;
+00236 
+00237                 // Is this a CQuat animated value???
+00238                 entry._IsQuat= (typeid (*(entry._Value))==typeid (CAnimatedValueBlendable<NLMISC::CQuat>))!=0;
+00239 
+00240 
+00241                 // Set the default track pointer
+00242                 entry._DefaultTracks=defaultValue;
+00243 
+00244                 // Set the value ID in the object
+00245                 entry._ValueId=valueId;
+00246 
+00247                 // Set the First value ID in the object
+00248                 entry._OwnerValueId=ownerValueId;
+00249 
+00250                 // in what mode is the channel?
+00251                 entry._Detail= detail;
+00252 
+00253                 // All weights default to 1. All Tracks default to defaultTrack.
+00254                 for(sint s=0;s<NumAnimationSlot;s++)
+00255                 {
+00256                         entry._Weights[s]= 1.0f;
+00257                         entry._Tracks[s]= entry._DefaultTracks;
+00258                 }
+00259 
+00260                 // add (if not already done) the entry in the map.
+00261                 _Channels[iDInAnimationSet]= entry;
+00262 
+00263                 // Dirt all the slots
+00264                 dirtAll ();
+00265 
+00266                 // Affect the default value in the animated value
+00267                 entry._Value->affect (entry._DefaultTracks->getValue());
+00268 
+00269                 // Touch the animated value and its owner to recompute them later.
+00270                 entry._Object->touch (entry._ValueId, entry._OwnerValueId);
+00271 
+00272                 // return the id.
+00273                 return iDInAnimationSet;
+00274         }
+00275         else
+00276         {
+00277                 // return Not found.
+00278                 return -1;
+00279         }
+00280 }
+00281 
+00282 // ***************************************************************************
+00283 
+00284 void CChannelMixer::resetChannels ()
+00285 {
+00286         _Channels.clear();
+00287         dirtAll ();
+00288 }
+00289 
+00290 
+00291 // ***************************************************************************
+00292 void CChannelMixer::enableChannel (uint channelId, bool enable)
+00293 {
+00294         std::map<uint, CChannel>::iterator      it= _Channels.find(channelId);
+00295         if(it!=_Channels.end())
+00296         {
+00297                 it->second._EnableFlags &= ~CChannel::EnableUserFlag;
+00298                 if(enable)
+00299                         it->second._EnableFlags |= CChannel::EnableUserFlag;
+00300 
+00301                 // Must recompute the channels to animate.
+00302                 _ListToEvalDirt= true;
+00303         }
+00304 }
+00305 
+00306 
+00307 // ***************************************************************************
+00308 bool CChannelMixer::isChannelEnabled (uint channelId) const
+00309 {
+00310         std::map<uint, CChannel>::const_iterator        it= _Channels.find(channelId);
+00311         if(it!=_Channels.end())
+00312         {
+00313                 return (it->second._EnableFlags & CChannel::EnableUserFlag) != 0;
+00314         }
+00315         else
+00316                 return false;
+00317 }
+00318 
+00319 
+00320 // ***************************************************************************
+00321 void CChannelMixer::lodEnableChannel (uint channelId, bool enable)
+00322 {
+00323         std::map<uint, CChannel>::iterator      it= _Channels.find(channelId);
+00324         if(it!=_Channels.end())
+00325         {
+00326                 it->second._EnableFlags &= ~CChannel::EnableLodFlag;
+00327                 if(enable)
+00328                         it->second._EnableFlags |= CChannel::EnableLodFlag;
+00329 
+00330                 // Must recompute the channels to animate.
+00331                 _ListToEvalDirt= true;
+00332         }
+00333 }
+00334 
+00335 
+00336 // ***************************************************************************
+00337 bool CChannelMixer::isChannelLodEnabled (uint channelId) const
+00338 {
+00339         std::map<uint, CChannel>::const_iterator        it= _Channels.find(channelId);
+00340         if(it!=_Channels.end())
+00341         {
+00342                 return (it->second._EnableFlags & CChannel::EnableLodFlag) != 0;
+00343         }
+00344         else
+00345                 return false;
+00346 }
+00347 
+00348 
+00349 
+00350 // ***************************************************************************
+00351 
+00352 void CChannelMixer::setSlotAnimation (uint slot, uint animation)
+00353 {
+00354         // Check alot arg
+00355         nlassert (slot<NumAnimationSlot);
+00356 
+00357         // Check an animationSet as been set.
+00358         nlassert (_AnimationSet);
+00359 
+00360         // Find the animation pointer for this animation
+00361         const CAnimation* pAnimation=_AnimationSet->getAnimation (animation);
+00362 
+00363         // Does this animation change ?
+00364         if (_SlotArray[slot]._Animation!=pAnimation)
+00365         {
+00366                 // Change it
+00367                 _SlotArray[slot]._Animation=pAnimation;
+00368 
+00369                 // Dirt it
+00370                 _SlotArray[slot]._Dirt=true;
+00371 
+00372                 // Dirt the mixer
+00373                 _Dirt=true;
+00374         }
+00375 }
+00376 
+00377 // ***************************************************************************
+00378 
+00379 const CAnimation        *CChannelMixer::getSlotAnimation(uint slot) const
+00380 {
+00381         nlassert(slot < NumAnimationSlot);
+00382         return _SlotArray[slot]._Animation;
+00383 }
+00384 
+00385 
+00386 // ***************************************************************************
+00387 
+00388 void CChannelMixer::emptySlot (uint slot)
+00389 {
+00390         // Check alot arg
+00391         nlassert (slot<NumAnimationSlot);
+00392 
+00393         // Does this animation already empty ?
+00394         if (!_SlotArray[slot].isEmpty ())
+00395         {
+00396                 // Change it
+00397                 _SlotArray[slot].empty ();
+00398 
+00399                 // Dirt it
+00400                 _SlotArray[slot]._Dirt=true;
+00401 
+00402                 // Dirt the mixer
+00403                 _Dirt=true;
+00404         }
+00405 }
+00406 
+00407 // ***************************************************************************
+00408 
+00409 void CChannelMixer::resetSlots ()
+00410 {
+00411         // Empty all slots
+00412         for (uint s=0; s<NumAnimationSlot; s++)
+00413                 // Empty it
+00414                 emptySlot (s);
+00415 }
+00416 
+00417 // ***************************************************************************
+00418 
+00419 void CChannelMixer::applySkeletonWeight (uint slot, uint skeleton, bool invert)
+00420 {
+00421         // Check alot arg
+00422         nlassert (slot<NumAnimationSlot);
+00423 
+00424         // Check the animationSet has been set
+00425         nlassert (_AnimationSet);
+00426 
+00427         // Get the skeleton weight
+00428         const CSkeletonWeight *pSkeleton=_AnimationSet->getSkeletonWeight (skeleton);
+00429 
+00430         // Something to change ?
+00431         if ((pSkeleton!=_SlotArray[slot]._SkeletonWeight)||(invert!=_SlotArray[slot]._InvertedSkeletonWeight))
+00432         {
+00433                 // Set the current skeleton
+00434                 _SlotArray[slot]._SkeletonWeight=pSkeleton;
+00435                 _SlotArray[slot]._InvertedSkeletonWeight=invert;
+00436 
+00437                 // Get number of node in the skeleton weight
+00438                 uint sizeSkel=pSkeleton->getNumNode ();
+00439 
+00440                 // For each entry of the skeleton weight
+00441                 for (uint n=0; n<sizeSkel; n++)
+00442                 {
+00443                         // Get the name of the channel for this node
+00444                         const string& channelName=pSkeleton->getNodeName (n);
+00445 
+00446                         // Get the channel Id having the same name than the tracks in this animation set.
+00447                         uint channelId=_AnimationSet->getChannelIdByName (channelName);
+00448 
+00449                         // Tracks exist in this animation set?
+00450                         if (channelId!=CAnimationSet::NotFound)
+00451                         {
+00452                                 // Get the weight of the channel for this node
+00453                                 float weight=pSkeleton->getNodeWeight (n);
+00454 
+00455                                 // Set the weight of this channel for this slot (only if channel setuped!!)
+00456                                 std::map<uint, CChannel>::iterator ite=_Channels.find(channelId);
+00457                                 if (ite!=_Channels.end())
+00458                                         ite->second._Weights[slot]=invert?1.f-weight:weight;
+00459                         }
+00460                 }
+00461         }
+00462 }
+00463 
+00464 // ***************************************************************************
+00465 
+00466 void CChannelMixer::resetSkeletonWeight (uint slot)
+00467 {
+00468         // Check alot arg
+00469         nlassert (slot<NumAnimationSlot);
+00470 
+00471         // Something to change ?
+00472         if (_SlotArray[slot]._SkeletonWeight!=NULL)
+00473         {
+00474                 // Set skeleton
+00475                 _SlotArray[slot]._SkeletonWeight=NULL;
+00476                 _SlotArray[slot]._InvertedSkeletonWeight=false;
+00477 
+00478                 // For each channels
+00479                 map<uint, CChannel>::iterator           itChannel;
+00480                 for(itChannel= _Channels.begin(); itChannel!=_Channels.end();itChannel++)
+00481                 {
+00482                         // Reset
+00483                         (*itChannel).second._Weights[slot]=1.f;
+00484                 }
+00485         }
+00486 }
+00487 
+00488 // ***************************************************************************
+00489 
+00490 void CChannelMixer::cleanAll ()
+00491 {
+00492         // For each slot
+00493         for (uint s=0; s<NumAnimationSlot; s++)
+00494         {
+00495                 // Clean it
+00496                 _SlotArray[s]._Dirt=false;
+00497         }
+00498 
+00499         // Clean the mixer
+00500         _Dirt=false;
+00501 }
+00502 
+00503 // ***************************************************************************
+00504 
+00505 void CChannelMixer::dirtAll ()
+00506 {
+00507         // For each slot
+00508         for (uint s=0; s<NumAnimationSlot; s++)
+00509         {
+00510                 // Dirt
+00511                 if (!_SlotArray[s].isEmpty())
+00512                 {
+00513                         // Dirt it
+00514                         _SlotArray[s]._Dirt=true;
+00515 
+00516                         // Dirt the mixer
+00517                         _Dirt=true;
+00518                 }
+00519         }
+00520 }
+00521 
+00522 // ***************************************************************************
+00523 
+00524 void CChannelMixer::refreshList ()
+00525 {
+00526         // Setup an array of animation to add
+00527         uint numAdd=0;
+00528         uint addSlot[NumAnimationSlot];
+00529 
+00530         // Setup an array of animation that are not empty and stay
+00531         uint numStay=0;
+00532         uint staySlot[NumAnimationSlot];
+00533 
+00534         // Setup it up
+00535         uint s;
+00536         for (s=0; s<NumAnimationSlot; s++)
+00537         {
+00538                 // Dirt and not empty ? (add)
+00539                 if ((_SlotArray[s]._Dirt)&&(!_SlotArray[s].isEmpty()))
+00540                         // Add a dirt slot
+00541                         addSlot[numAdd++]=s;
+00542 
+00543                 // Not empty and not dirt ? (stay)
+00544                 if ((!_SlotArray[s]._Dirt)&&(!_SlotArray[s].isEmpty()))
+00545                         // Add a dirt slot
+00546                         staySlot[numStay++]=s;
+00547         }
+00548 
+00549         // Last channel pointer
+00550         CChannel **lastPointerGlobal=&_FirstChannelGlobal;
+00551         CChannel **lastPointerDetail=&_FirstChannelDetail;
+00552 
+00553 
+00554         // Now scan each channel
+00555         map<uint, CChannel>::iterator           itChannel;
+00556         for(itChannel= _Channels.begin(); itChannel!=_Channels.end();itChannel++)
+00557         {
+00558                 CChannel        &channel= (*itChannel).second;
+00559 
+00560                 // Add this channel to the list if true
+00561                 bool add=false;
+00562 
+00563                 // For each slot to add
+00564                 for (s=0; s<numAdd; s++)
+00565                 {
+00566                         // Find the index of the channel track in the animation set
+00567                         uint iDTrack=_SlotArray[addSlot[s]]._Animation->getIdTrackByName (channel._ChannelName);
+00568 
+00569                         // If this track exist
+00570                         if (iDTrack!=CAnimation::NotFound)
+00571                         {
+00572                                 // Set the track
+00573                                 channel._Tracks[addSlot[s]]=_SlotArray[addSlot[s]]._Animation->getTrack (iDTrack);
+00574 
+00575                                 // Add this channel to the list
+00576                                 add=true;
+00577                         }
+00578                         else
+00579                         {
+00580                                 // Set the default track
+00581                                 channel._Tracks[addSlot[s]]=channel._DefaultTracks;
+00582                         }
+00583                 }
+00584 
+00585                 // Add this channel to the list ?
+00586                 if (!add)
+00587                 {
+00588                         // Was it in the list ?
+00589                         if (channel._InTheList)
+00590                         {
+00591                                 // Check if this channel is still in use
+00592 
+00593                                 // For each slot in the stay list
+00594                                 for (s=0; s<numStay; s++)
+00595                                 {
+00596                                         // Use anything interesting ?
+00597                                         if (channel._Tracks[staySlot[s]]!=channel._DefaultTracks)
+00598                                         {
+00599                                                 // Ok, add it to the list
+00600                                                 add=true;
+00601 
+00602                                                 // Stop
+00603                                                 break;
+00604                                         }
+00605                                 }
+00606 
+00607                                 // Still in use?
+00608                                 if (!add)
+00609                                 {
+00610                                         // Set it's value to default and touch it's object
+00611                                         channel._Value->affect (channel._DefaultTracks->getValue());
+00612                                         channel._Object->touch (channel._ValueId, channel._OwnerValueId);
+00613                                 }
+00614                         }
+00615                 }
+00616 
+00617                 // Do i have to add the channel to the list
+00618                 if (add)
+00619                 {
+00620                         // It is in the list
+00621                         channel._InTheList=true;
+00622 
+00623                         if(channel._Detail)
+00624                         {
+00625                                 // Set the last pointer value
+00626                                 *lastPointerDetail=&channel;
+00627                                 // Change last pointer
+00628                                 lastPointerDetail=&channel._Next;
+00629                         }
+00630                         else
+00631                         {
+00632                                 // Set the last pointer value
+00633                                 *lastPointerGlobal=&channel;
+00634                                 // Change last pointer
+00635                                 lastPointerGlobal=&channel._Next;
+00636                         }
+00637 
+00638                 }
+00639                 else
+00640                 {
+00641                         // It is not in the list
+00642                         channel._InTheList=false;
+00643                 }
+00644         }
+00645 
+00646         // End of the list
+00647         *lastPointerGlobal=NULL;
+00648         *lastPointerDetail=NULL;
+00649 
+00650         // Must recompute the channels to animate.
+00651         _ListToEvalDirt= true;
+00652 }
+00653 
+00654 
+00655 // ***************************************************************************
+00656 void CChannelMixer::refreshListToEval ()
+00657 {
+00658         CChannel* pChannel;
+00659 
+00660         /* NB: this save if(), especially when Used with Skeleton, and CLod mode
+00661         */
+00662 
+00663         // Global list.
+00664         _GlobalListToEval.clear();
+00665         _GlobalListToEval.reserve(_Channels.size());
+00666         pChannel=_FirstChannelGlobal;
+00667         while(pChannel)
+00668         {
+00669                 // if the channel is enabled (both user and lod), must eval all active slot.
+00670                 if(pChannel->_EnableFlags == CChannel::EnableAllFlag)
+00671                         _GlobalListToEval.push_back(pChannel);
+00672                 // next
+00673                 pChannel= pChannel->_Next;
+00674         }
+00675 
+00676         // Global list.
+00677         _DetailListToEval.clear();
+00678         _DetailListToEval.reserve(_Channels.size());
+00679         pChannel=_FirstChannelDetail;
+00680         while(pChannel)
+00681         {
+00682                 // if the channel is enabled (both user and lod), must eval all active slot.
+00683                 if(pChannel->_EnableFlags == CChannel::EnableAllFlag)
+00684                         _DetailListToEval.push_back(pChannel);
+00685                 // next
+00686                 pChannel= pChannel->_Next;
+00687         }
+00688 
+00689         // done
+00690         _ListToEvalDirt= false;
+00691 }
+00692 
+00693 // ***************************************************************************
+00694 void CChannelMixer::resetEvalDetailDate()
+00695 {
+00696         _LastEvalDetailDate= -1;
+00697 }
+00698 
+00699 
+00700 } // NL3D
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1