00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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 )
00200 {
00201
00202
00203
00204
00205 CRGBA diff= _Diffuse.Value;
00206 sint c= (sint)(_Opacity.Value*255);
00207 clamp(c, 0, 255);
00208 diff.A= c;
00209
00210
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
00221 clearFlag(AmbientValue);
00222 clearFlag(DiffuseValue);
00223 clearFlag(SpecularValue);
00224 clearFlag(ShininessValue);
00225 clearFlag(EmissiveValue);
00226 clearFlag(OpacityValue);
00227
00228
00229
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
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
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:
00294 if (valueId >= TextureMatValues && valueId < AnimValueLast)
00295 {
00296 const uint baseId = valueId - TextureMatValues;
00297 const uint texNum = baseId / NumTexAnimatedValues;
00298 const uint argID = baseId % NumTexAnimatedValues;
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
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:
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
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:
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
00382 nlstop;
00383 return NULL;
00384 }
00385
00386 void CAnimatedMaterial::registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix)
00387 {
00388
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)
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)
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)
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)
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)
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 }