00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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 )
00198 {
00199
00200
00201
00202
00203 CRGBA diff= _Diffuse.Value;
00204 sint c= (sint)(_Opacity.Value*255);
00205 clamp(c, 0, 255);
00206 diff.A= c;
00207
00208
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
00219 clearFlag(AmbientValue);
00220 clearFlag(DiffuseValue);
00221 clearFlag(SpecularValue);
00222 clearFlag(ShininessValue);
00223 clearFlag(EmissiveValue);
00224 clearFlag(OpacityValue);
00225
00226
00227
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
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;
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
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:
00281 if (valueId >= TextureMatValues && valueId < AnimValueLast)
00282 {
00283 const uint baseId = valueId - TextureMatValues;
00284 const uint texNum = baseId / NumTexAnimatedValues;
00285 const uint argID = baseId % NumTexAnimatedValues;
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
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:
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
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:
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
00369 nlstop;
00370 return NULL;
00371 }
00372
00373 void CAnimatedMaterial::registerToChannelMixer(CChannelMixer *chanMixer, const std::string &prefix)
00374 {
00375
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)
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)
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)
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)
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)
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 }