animated_material.cpp

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

Generated on Thu Jan 7 08:26:24 2010 for NeL by  doxygen 1.6.1