# 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  

animated_material.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/animated_material.h"
00029 #include "nel/misc/common.h"
00030 
00031 using namespace NLMISC;
00032 
00033 namespace NL3D
00034 {
00035 
00036 
00037 // ***************************************************************************
00038 // ***************************************************************************
00039 // ***************************************************************************
00040 // ***************************************************************************
00041 
00042 
00043 
00044 // ***************************************************************************
00045 void    CMaterialBase::CAnimatedTexture::serial(NLMISC::IStream &f)
00046 {
00047         ITexture        *text= NULL;
00048         if(f.isReading())
00049         {
00050                 f.serialPolyPtr(text);
00051                 Texture= text;
00052         }
00053         else
00054         {
00055                 text= Texture;
00056                 f.serialPolyPtr(text);
00057         }
00058 }
00059 
00060 
00061 
00062 // ***************************************************************************
00063 CMaterialBase::CMaterialBase()
00064 {
00065         DefaultAmbient.setValue(CRGBA(64,64,64));
00066         DefaultDiffuse.setValue(CRGBA(128,128,128));
00067         DefaultSpecular.setValue(CRGBA(0,0,0));
00068         DefaultShininess.setValue(10);
00069         DefaultEmissive.setValue(CRGBA(128,128,128));
00070         DefaultOpacity.setValue(1);
00071         DefaultTexture.setValue(0x7FFFFFFF);
00072         for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00073         {
00074                 DefaultTexAnimTracks[k].setDefaultValue();
00075         }
00076 }
00077 
00078 
00079 // ***************************************************************************
00080 void    CMaterialBase::serial(NLMISC::IStream &f)
00081 {
00082         sint    ver= f.serialVersion(1);
00083 
00084         f.serial(Name);
00085         f.serial(DefaultAmbient, DefaultDiffuse, DefaultSpecular);
00086         f.serial(DefaultShininess, DefaultEmissive, DefaultOpacity, DefaultTexture);
00087         f.serialCont(_AnimatedTextures);
00088         if (ver > 0)
00089         {
00090                 for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00091                 {
00092                         f.serial(DefaultTexAnimTracks[k]);
00093                 }
00094         }
00095 }
00096 
00097 
00098 // ***************************************************************************
00099 void    CMaterialBase::copyFromMaterial(CMaterial *pMat)
00100 {
00101         DefaultAmbient.setValue(pMat->getAmbient());
00102         DefaultDiffuse.setValue(pMat->getDiffuse());
00103         DefaultSpecular.setValue(pMat->getSpecular());
00104         DefaultShininess.setValue(pMat->getShininess());
00105         DefaultEmissive.setValue(pMat->getEmissive());
00106         DefaultOpacity.setValue(pMat->getDiffuse().A/255.f);
00107 
00109         for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00110         {
00111                 if (pMat->isUserTexMatEnabled(k))
00112                 {
00113                         float uTrans, vTrans, uScale, vScale, wRot;
00114                         pMat->decompUserTexMat(k, uTrans, vTrans, wRot, uScale, vScale);                        
00115                         DefaultTexAnimTracks[k].DefaultUTrans.setValue(uTrans);
00116                         DefaultTexAnimTracks[k].DefaultVTrans.setValue(vTrans);
00117                         DefaultTexAnimTracks[k].DefaultUScale.setValue(uScale);
00118                         DefaultTexAnimTracks[k].DefaultVScale.setValue(vScale);
00119                         DefaultTexAnimTracks[k].DefaultWRot.setValue(wRot);
00120                 }      
00121         }
00122 }
00123 
00124 
00125 // ***************************************************************************
00126 void                    CMaterialBase::setAnimatedTexture(uint32 id, CSmartPtr<ITexture>  pText)
00127 {
00128         // add or replace the texture.
00129         _AnimatedTextures[id].Texture= pText;
00130 }
00131 // ***************************************************************************
00132 bool                    CMaterialBase::validAnimatedTexture(uint32 id)
00133 {
00134         TAnimatedTextureMap::iterator   it;
00135         it= _AnimatedTextures.find(id);
00136         return it!=_AnimatedTextures.end();
00137 }
00138 // ***************************************************************************
00139 ITexture*               CMaterialBase::getAnimatedTexture(uint32 id)
00140 {
00141         TAnimatedTextureMap::iterator   it;
00142         it= _AnimatedTextures.find(id);
00143         if( it!=_AnimatedTextures.end() )
00144                 return it->second.Texture;
00145         else
00146                 return NULL;
00147 }
00148 
00149 
00150 
00151 
00152 // ***************************************************************************
00153 // ***************************************************************************
00154 // ***************************************************************************
00155 // ***************************************************************************
00156 
00157 
00158 // ***************************************************************************
00159 CAnimatedMaterial::CAnimatedMaterial(CMaterialBase *baseMat)
00160 {
00161         nlassert(baseMat);
00162         _MaterialBase= baseMat;
00163 
00164         // IAnimatable.
00165         IAnimatable::resize(AnimValueLast);
00166 
00167         _Ambient.affect(_MaterialBase->DefaultAmbient.getValue());
00168         _Diffuse.affect(_MaterialBase->DefaultDiffuse.getValue());
00169         _Specular.affect(_MaterialBase->DefaultSpecular.getValue());
00170         _Shininess.affect(_MaterialBase->DefaultShininess.getValue());
00171         _Emissive.affect(_MaterialBase->DefaultEmissive.getValue());
00172         _Opacity.affect(_MaterialBase->DefaultOpacity.getValue());
00173 
00174         for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00175         {
00176                 _TexAnimatedMatValues[k].affect(baseMat->DefaultTexAnimTracks[k]);
00177         }
00178 }
00179 
00180 
00181 // ***************************************************************************
00182 void    CAnimatedMaterial::setMaterial(CMaterial *pMat)
00183 {
00184         _Material= pMat;
00185 }
00186 
00187 
00188 // ***************************************************************************
00189 std::string             CAnimatedMaterial::getMaterialName() const
00190 {
00191         nlassert(_MaterialBase);
00192         return _MaterialBase->Name;
00193 }
00194 
00195 
00196 // ***************************************************************************
00197 void    CAnimatedMaterial::update()
00198 {
00199         if(isTouched(OwnerBit) && _Material!=NULL /*&& _Material->isLighted()*/)
00200         {
00201                 
00202                 // well, just update all...  :)
00203 
00204                 // diffuse part.
00205                 CRGBA   diff= _Diffuse.Value;
00206                 sint c= (sint)(_Opacity.Value*255);
00207                 clamp(c, 0, 255);
00208                 diff.A= c;
00209 
00210                 // setup material.
00211                 if (_Material->isLighted())
00212                 {               
00213                         _Material->setLighting(true, _Emissive.Value, _Ambient.Value, diff, _Specular.Value, _Shininess.Value);
00214                 }
00215                 else
00216                 {
00217                         _Material->setColor(diff);
00218                 }
00219 
00220                 // clear flags.
00221                 clearFlag(AmbientValue);
00222                 clearFlag(DiffuseValue);
00223                 clearFlag(SpecularValue);
00224                 clearFlag(ShininessValue);
00225                 clearFlag(EmissiveValue);
00226                 clearFlag(OpacityValue);
00227 
00228 
00229                 // Texture Anim.
00230                 if(isTouched(TextureValue))
00231                 {
00232                         nlassert(_MaterialBase);
00233 
00234                         uint32  id= _Texture.Value;
00235                         if(_MaterialBase->validAnimatedTexture(id))
00236                         {
00237                                 _Material->setTexture(0, _MaterialBase->getAnimatedTexture(id) );
00238                         }
00239                         clearFlag(TextureValue);
00240                 }
00241 
00242                 // Get texture matrix from animated value to setup the material
00243                 uint flagIndex = TextureMatValues;
00244                 for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00245                 {
00246                         if (_Material->isUserTexMatEnabled(k))
00247                         {
00248                                 const CTexAnimatedMatValues &texMatAV = _TexAnimatedMatValues[k];
00249                                 CMatrix texMat; 
00250                                 float fCos, fSin;
00251                                 if (texMatAV._WRot.Value != 0.f)
00252                                 {
00253                                         fCos = ::cosf(- texMatAV._WRot.Value);
00254                                         fSin = ::sinf(- texMatAV._WRot.Value);
00255                                 }
00256                                 else
00257                                 {
00258                                         fCos = 1.f;
00259                                         fSin = 0.f;
00260                                 }
00261                                 NLMISC::CVector I(fCos, fSin, 0);
00262                                 NLMISC::CVector J(-fSin, fCos, 0);                              
00263                                 texMat.setRot(texMatAV._UScale.Value * I, texMatAV._VScale.Value * J, NLMISC::CVector::K);                                                              
00264                                 for (uint l = 0; l < NumTexAnimatedValues; ++l)
00265                                 {
00266                                         clearFlag(flagIndex++);
00267                                 }
00268                                 NLMISC::CVector center(-0.5f, -0.5f, 0.f);
00269                                 NLMISC::CVector t(- texMatAV._UTrans.Value, texMatAV._VTrans.Value, 0);
00270                                 texMat.setPos(t + texMat.mulVector(center) - center);
00271                                 _Material->setUserTexMat(k, texMat);
00272                         }
00273                 }
00274 
00275                 // We are OK!
00276                 IAnimatable::clearFlag(OwnerBit);
00277         }
00278 }
00279 
00280 
00281 // ***************************************************************************
00282 IAnimatedValue* CAnimatedMaterial::getValue (uint valueId)
00283 {
00284         switch(valueId)
00285         {
00286         case AmbientValue: return &_Ambient;
00287         case DiffuseValue: return &_Diffuse;
00288         case SpecularValue: return &_Specular;
00289         case ShininessValue: return &_Shininess;
00290         case EmissiveValue: return &_Emissive;
00291         case OpacityValue: return &_Opacity;
00292         case TextureValue: return &_Texture;
00293         default: // this may be a texture animated value...
00294                 if (valueId >= TextureMatValues && valueId < AnimValueLast)
00295                 {
00296                         const uint baseId = valueId - TextureMatValues;
00297                         const uint texNum =   baseId / NumTexAnimatedValues; // stage index
00298                         const uint argID  =   baseId % NumTexAnimatedValues; // value for this stage
00299                         switch(argID)
00300                         {
00301                                 case 0: return &_TexAnimatedMatValues[texNum]._UTrans;
00302                                 case 1: return &_TexAnimatedMatValues[texNum]._VTrans;
00303                                 case 2: return &_TexAnimatedMatValues[texNum]._UScale;
00304                                 case 3: return &_TexAnimatedMatValues[texNum]._VScale;                          
00305                                 case 4: return &_TexAnimatedMatValues[texNum]._WRot;                            
00306                         }
00307                 }               
00308         break;
00309         };
00310 
00311         // shoudl not be here!!
00312         nlstop;
00313         return NULL;
00314 }
00315 // ***************************************************************************
00316 const char *CAnimatedMaterial::getValueName (uint valueId) const
00317 {
00318         switch(valueId)
00319         {
00320         case AmbientValue: return getAmbientValueName();
00321         case DiffuseValue: return getDiffuseValueName();
00322         case SpecularValue: return getSpecularValueName();
00323         case ShininessValue: return getShininessValueName();
00324         case EmissiveValue: return getEmissiveValueName();
00325         case OpacityValue: return getOpacityValueName();
00326         case TextureValue: return getTextureValueName();
00327         default: // this may be a texture animated value...
00328                 if (valueId >= TextureMatValues && valueId < AnimValueLast)
00329                 {
00330                         const uint baseId = valueId - TextureMatValues;
00331                         const uint texNum =   baseId / NumTexAnimatedValues;
00332                         const uint argID  =   baseId % NumTexAnimatedValues;
00333                         switch(argID)
00334                         {
00335                                 case 0: return getTexMatUTransName      (texNum);
00336                                 case 1: return getTexMatVTransName(texNum);
00337                                 case 2: return getTexMatUScaleName(texNum);
00338                                 case 3: return getTexMatVScaleName(texNum);
00339                                 case 4: return getTexMatWRotName(texNum);
00340                         }
00341                 }               
00342         break;
00343         };
00344 
00345         // shoudl not be here!!
00346         nlstop;
00347         return "";
00348 }
00349 // ***************************************************************************
00350 ITrack* CAnimatedMaterial::getDefaultTrack (uint valueId)
00351 {
00352         nlassert(_MaterialBase);
00353 
00354         switch(valueId)
00355         {
00356         case AmbientValue: return       &_MaterialBase->DefaultAmbient;
00357         case DiffuseValue: return       &_MaterialBase->DefaultDiffuse;
00358         case SpecularValue: return      &_MaterialBase->DefaultSpecular;
00359         case ShininessValue: return     &_MaterialBase->DefaultShininess;
00360         case EmissiveValue: return      &_MaterialBase->DefaultEmissive;
00361         case OpacityValue: return       &_MaterialBase->DefaultOpacity;
00362         case TextureValue: return       &_MaterialBase->DefaultTexture;
00363         default: // this may be a texture animated value...
00364                 if (valueId >= TextureMatValues && valueId < AnimValueLast)
00365                 {
00366                         const uint baseId = valueId - TextureMatValues;
00367                         const uint texNum =   baseId / NumTexAnimatedValues;
00368                         const uint argID  =   baseId % NumTexAnimatedValues;
00369                         switch(argID)
00370                         {
00371                                 case 0: return  &_MaterialBase->DefaultTexAnimTracks[texNum].DefaultUTrans;
00372                                 case 1: return  &_MaterialBase->DefaultTexAnimTracks[texNum].DefaultVTrans;
00373                                 case 2: return  &_MaterialBase->DefaultTexAnimTracks[texNum].DefaultUTrans;
00374                                 case 3: return  &_MaterialBase->DefaultTexAnimTracks[texNum].DefaultVTrans;
00375                                 case 4: return  &_MaterialBase->DefaultTexAnimTracks[texNum].DefaultWRot;
00376                         }
00377                 }               
00378         break;
00379         };
00380 
00381         // shoudl not be here!!
00382         nlstop;
00383         return NULL;
00384 }
00385 // ***************************************************************************
00386 void    CAnimatedMaterial::registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix)
00387 {
00388         // For CAnimatedMaterial, channels are detailled (material rendered after clip)!
00389         addValue(chanMixer, AmbientValue, OwnerBit, prefix, true);
00390         addValue(chanMixer, DiffuseValue, OwnerBit, prefix, true);
00391         addValue(chanMixer, SpecularValue, OwnerBit, prefix, true);
00392         addValue(chanMixer, ShininessValue, OwnerBit, prefix, true);
00393         addValue(chanMixer, EmissiveValue, OwnerBit, prefix, true);
00394         addValue(chanMixer, OpacityValue, OwnerBit, prefix, true);
00395         addValue(chanMixer, TextureValue, OwnerBit, prefix, true);
00396         for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00397         {
00398                 for (uint l = 0; l < NumTexAnimatedValues; ++l)
00399                 {
00400                         addValue(chanMixer, TextureMatValues + l + k * NumTexAnimatedValues, OwnerBit, prefix, true);
00401                 }
00402         }
00403 }
00404 
00405 // ***************************************************************************
00406 const char *CAnimatedMaterial::getTexMatUTransName(uint stage)
00407 {
00408         static char names[IDRV_MAT_MAXTEXTURES][16];
00409         static bool init = false;
00410         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00411         if (!init) // where name initialized ?
00412         {
00413                 for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00414                 {
00415                         sprintf(&names[k][0], "UTrans%d", k);
00416                 }
00417                 init = true;
00418         }
00419         return names[stage];
00420 }
00421 
00422 // ***************************************************************************
00423 const char *CAnimatedMaterial::getTexMatVTransName(uint stage)
00424 {
00425         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00426         static char names[IDRV_MAT_MAXTEXTURES][16];
00427         static bool init = false;
00428         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00429         if (!init) // where name initialized ?
00430         {
00431                 for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00432                 {
00433                         sprintf(&names[k][0], "VTrans%d", k);
00434                 }
00435                 init = true;
00436         }
00437         return names[stage];
00438 }
00439 
00440 
00441 // ***************************************************************************
00442 const char *CAnimatedMaterial::getTexMatUScaleName(uint stage)
00443 {
00444         static char names[IDRV_MAT_MAXTEXTURES][16];
00445         static bool init = false;
00446         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00447         if (!init) // where name initialized ?
00448         {
00449                 for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00450                 {
00451                         sprintf(&names[k][0], "UScale%d", k);
00452                 }
00453                 init = true;
00454         }
00455         return names[stage];
00456 }
00457 
00458 // ***************************************************************************
00459 const char *CAnimatedMaterial::getTexMatVScaleName(uint stage)
00460 {
00461         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00462         static char names[IDRV_MAT_MAXTEXTURES][16];
00463         static bool init = false;
00464         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00465         if (!init) // where name initialized ?
00466         {
00467                 for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00468                 {
00469                         sprintf(&names[k][0], "VScale%d", k);
00470                 }
00471                 init = true;
00472         }
00473         return names[stage];
00474 }
00475 
00476 
00477 // ***************************************************************************
00478 const char *CAnimatedMaterial::getTexMatWRotName(uint stage)
00479 {
00480         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00481         static char names[IDRV_MAT_MAXTEXTURES][16];
00482         static bool init = false;
00483         nlassert(stage < IDRV_MAT_MAXTEXTURES);
00484         if (!init) // where name initialized ?
00485         {
00486                 for (uint k = 0; k < IDRV_MAT_MAXTEXTURES; ++k)
00487                 {
00488                         sprintf(&names[k][0], "WRot%d", k);
00489                 }
00490                 init = true;
00491         }
00492         return names[stage];
00493 }
00494 
00495 
00496 
00497 } // NL3D