1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/3d/animated_material.h"
20 #include "nel/misc/common.h"
22 using namespace NLMISC
;
32 // ***************************************************************************
33 // ***************************************************************************
34 // ***************************************************************************
35 // ***************************************************************************
39 // ***************************************************************************
40 void CMaterialBase::CAnimatedTexture::serial(NLMISC::IStream
&f
)
45 f
.serialPolyPtr(text
);
51 f
.serialPolyPtr(text
);
57 // ***************************************************************************
58 CMaterialBase::CMaterialBase()
60 DefaultAmbient
.setDefaultValue(CRGBA(64,64,64));
61 DefaultDiffuse
.setDefaultValue(CRGBA(128,128,128));
62 DefaultSpecular
.setDefaultValue(CRGBA(0,0,0));
63 DefaultShininess
.setDefaultValue(10);
64 DefaultEmissive
.setDefaultValue(CRGBA(128,128,128));
65 DefaultOpacity
.setDefaultValue(1);
66 DefaultTexture
.setDefaultValue(0x7FFFFFFF);
67 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
69 DefaultTexAnimTracks
[k
].setDefaultValue();
74 // ***************************************************************************
75 void CMaterialBase::serial(NLMISC::IStream
&f
)
77 sint ver
= f
.serialVersion(1);
80 f
.serial(DefaultAmbient
, DefaultDiffuse
, DefaultSpecular
);
81 f
.serial(DefaultShininess
, DefaultEmissive
, DefaultOpacity
, DefaultTexture
);
82 f
.serialCont(_AnimatedTextures
);
85 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
87 f
.serial(DefaultTexAnimTracks
[k
]);
93 // ***************************************************************************
94 void CMaterialBase::copyFromMaterial(CMaterial
*pMat
)
96 DefaultAmbient
.setDefaultValue(pMat
->getAmbient());
97 DefaultDiffuse
.setDefaultValue(pMat
->getDiffuse());
98 DefaultSpecular
.setDefaultValue(pMat
->getSpecular());
99 DefaultShininess
.setDefaultValue(pMat
->getShininess());
100 DefaultEmissive
.setDefaultValue(pMat
->getEmissive());
101 DefaultOpacity
.setDefaultValue(pMat
->getDiffuse().A
/255.f
);
103 /// get uv value from material
104 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
106 if (pMat
->isUserTexMatEnabled(k
))
108 float uTrans
, vTrans
, uScale
, vScale
, wRot
;
109 pMat
->decompUserTexMat(k
, uTrans
, vTrans
, wRot
, uScale
, vScale
);
110 DefaultTexAnimTracks
[k
].DefaultUTrans
.setDefaultValue(uTrans
);
111 DefaultTexAnimTracks
[k
].DefaultVTrans
.setDefaultValue(vTrans
);
112 DefaultTexAnimTracks
[k
].DefaultUScale
.setDefaultValue(uScale
);
113 DefaultTexAnimTracks
[k
].DefaultVScale
.setDefaultValue(vScale
);
114 DefaultTexAnimTracks
[k
].DefaultWRot
.setDefaultValue(wRot
);
120 // ***************************************************************************
121 void CMaterialBase::setAnimatedTexture(uint32 id
, CSmartPtr
<ITexture
> pText
)
123 // add or replace the texture.
124 _AnimatedTextures
[id
].Texture
= pText
;
126 // ***************************************************************************
127 bool CMaterialBase::validAnimatedTexture(uint32 id
)
129 TAnimatedTextureMap::iterator it
;
130 it
= _AnimatedTextures
.find(id
);
131 return it
!=_AnimatedTextures
.end();
133 // ***************************************************************************
134 ITexture
* CMaterialBase::getAnimatedTexture(uint32 id
)
136 TAnimatedTextureMap::iterator it
;
137 it
= _AnimatedTextures
.find(id
);
138 if( it
!=_AnimatedTextures
.end() )
139 return it
->second
.Texture
;
147 // ***************************************************************************
148 // ***************************************************************************
149 // ***************************************************************************
150 // ***************************************************************************
153 // ***************************************************************************
154 CAnimatedMaterial::CAnimatedMaterial(CMaterialBase
*baseMat
)
157 _MaterialBase
= baseMat
;
160 IAnimatable::resize(AnimValueLast
);
162 _Ambient
.Value
= _MaterialBase
->DefaultAmbient
.getDefaultValue();
163 _Diffuse
.Value
= _MaterialBase
->DefaultDiffuse
.getDefaultValue();
164 _Specular
.Value
= _MaterialBase
->DefaultSpecular
.getDefaultValue();
165 _Shininess
.Value
= _MaterialBase
->DefaultShininess
.getDefaultValue();
166 _Emissive
.Value
= _MaterialBase
->DefaultEmissive
.getDefaultValue();
167 _Opacity
.Value
= _MaterialBase
->DefaultOpacity
.getDefaultValue();
169 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
171 _TexAnimatedMatValues
[k
].affect(baseMat
->DefaultTexAnimTracks
[k
]);
176 // ***************************************************************************
177 void CAnimatedMaterial::setMaterial(CMaterial
*pMat
)
183 // ***************************************************************************
184 std::string
CAnimatedMaterial::getMaterialName() const
186 nlassert(_MaterialBase
);
187 return _MaterialBase
->Name
;
191 // ***************************************************************************
192 void CAnimatedMaterial::update()
194 if(isTouched(OwnerBit
) && _Material
!=NULL
/*&& _Material->isLighted()*/)
197 // well, just update all... :)
200 CRGBA diff
= _Diffuse
.Value
;
201 sint c
= (sint
)(_Opacity
.Value
*255);
206 if (_Material
->isLighted())
208 _Material
->setLighting(true, _Emissive
.Value
, _Ambient
.Value
, diff
, _Specular
.Value
, _Shininess
.Value
);
212 _Material
->setColor(diff
);
216 clearFlag(AmbientValue
);
217 clearFlag(DiffuseValue
);
218 clearFlag(SpecularValue
);
219 clearFlag(ShininessValue
);
220 clearFlag(EmissiveValue
);
221 clearFlag(OpacityValue
);
225 if(isTouched(TextureValue
))
227 nlassert(_MaterialBase
);
229 uint32 id
= _Texture
.Value
;
230 if(_MaterialBase
->validAnimatedTexture(id
))
232 _Material
->setTexture(0, _MaterialBase
->getAnimatedTexture(id
) );
234 clearFlag(TextureValue
);
237 // Get texture matrix from animated value to setup the material
238 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
240 if (_Material
->isUserTexMatEnabled(k
))
242 const CTexAnimatedMatValues
&texMatAV
= _TexAnimatedMatValues
[k
];
244 CMatrix convMat
; // exported v are already inverted (todo : optim this if needed, this matrix shouldn't be necessary)
245 convMat
.setRot(CVector::I
, -CVector::J
, CVector::K
);
246 convMat
.setPos(CVector::J
);
247 float fCos
= cosf(texMatAV
._WRot
.Value
);
248 float fSin
= sinf(texMatAV
._WRot
.Value
);
250 SR
.setRot(CVector(texMatAV
._UScale
.Value
* fCos
, texMatAV
._VScale
.Value
* fSin
, 0.f
),
251 CVector(- texMatAV
._UScale
.Value
* fSin
, texMatAV
._VScale
.Value
* fCos
, 0.f
),
253 CVector
half(0.5f
, 0.5f
, 0.f
);
254 SR
.setPos(SR
.mulVector(- half
- CVector(texMatAV
._UTrans
.Value
, texMatAV
._VTrans
.Value
, 0.f
)) + half
);
255 _Material
->setUserTexMat(k
, convMat
* SR
* convMat
);
260 IAnimatable::clearFlag(OwnerBit
);
265 // ***************************************************************************
266 IAnimatedValue
* CAnimatedMaterial::getValue (uint valueId
)
270 case AmbientValue
: return &_Ambient
;
271 case DiffuseValue
: return &_Diffuse
;
272 case SpecularValue
: return &_Specular
;
273 case ShininessValue
: return &_Shininess
;
274 case EmissiveValue
: return &_Emissive
;
275 case OpacityValue
: return &_Opacity
;
276 case TextureValue
: return &_Texture
;
277 default: // this may be a texture animated value...
278 if (valueId
>= TextureMatValues
&& valueId
< AnimValueLast
)
280 const uint baseId
= valueId
- TextureMatValues
;
281 const uint texNum
= baseId
/ NumTexAnimatedValues
; // stage index
282 const uint argID
= baseId
% NumTexAnimatedValues
; // value for this stage
285 case 0: return &_TexAnimatedMatValues
[texNum
]._UTrans
;
286 case 1: return &_TexAnimatedMatValues
[texNum
]._VTrans
;
287 case 2: return &_TexAnimatedMatValues
[texNum
]._UScale
;
288 case 3: return &_TexAnimatedMatValues
[texNum
]._VScale
;
289 case 4: return &_TexAnimatedMatValues
[texNum
]._WRot
;
295 // shoudl not be here!!
299 // ***************************************************************************
300 const char *CAnimatedMaterial::getValueName (uint valueId
) const
304 case AmbientValue
: return getAmbientValueName();
305 case DiffuseValue
: return getDiffuseValueName();
306 case SpecularValue
: return getSpecularValueName();
307 case ShininessValue
: return getShininessValueName();
308 case EmissiveValue
: return getEmissiveValueName();
309 case OpacityValue
: return getOpacityValueName();
310 case TextureValue
: return getTextureValueName();
311 default: // this may be a texture animated value...
312 if (valueId
>= TextureMatValues
&& valueId
< AnimValueLast
)
314 const uint baseId
= valueId
- TextureMatValues
;
315 const uint texNum
= baseId
/ NumTexAnimatedValues
;
316 const uint argID
= baseId
% NumTexAnimatedValues
;
319 case 0: return getTexMatUTransName (texNum
);
320 case 1: return getTexMatVTransName(texNum
);
321 case 2: return getTexMatUScaleName(texNum
);
322 case 3: return getTexMatVScaleName(texNum
);
323 case 4: return getTexMatWRotName(texNum
);
329 // shoudl not be here!!
333 // ***************************************************************************
334 ITrack
* CAnimatedMaterial::getDefaultTrack (uint valueId
)
336 nlassert(_MaterialBase
);
340 case AmbientValue
: return &_MaterialBase
->DefaultAmbient
;
341 case DiffuseValue
: return &_MaterialBase
->DefaultDiffuse
;
342 case SpecularValue
: return &_MaterialBase
->DefaultSpecular
;
343 case ShininessValue
: return &_MaterialBase
->DefaultShininess
;
344 case EmissiveValue
: return &_MaterialBase
->DefaultEmissive
;
345 case OpacityValue
: return &_MaterialBase
->DefaultOpacity
;
346 case TextureValue
: return &_MaterialBase
->DefaultTexture
;
347 default: // this may be a texture animated value...
348 if (valueId
>= TextureMatValues
&& valueId
< AnimValueLast
)
350 const uint baseId
= valueId
- TextureMatValues
;
351 const uint texNum
= baseId
/ NumTexAnimatedValues
;
352 const uint argID
= baseId
% NumTexAnimatedValues
;
355 case 0: return &_MaterialBase
->DefaultTexAnimTracks
[texNum
].DefaultUTrans
;
356 case 1: return &_MaterialBase
->DefaultTexAnimTracks
[texNum
].DefaultVTrans
;
357 case 2: return &_MaterialBase
->DefaultTexAnimTracks
[texNum
].DefaultUTrans
;
358 case 3: return &_MaterialBase
->DefaultTexAnimTracks
[texNum
].DefaultVTrans
;
359 case 4: return &_MaterialBase
->DefaultTexAnimTracks
[texNum
].DefaultWRot
;
365 // shoudl not be here!!
369 // ***************************************************************************
370 void CAnimatedMaterial::registerToChannelMixer(CChannelMixer
*chanMixer
, const std::string
&prefix
)
372 // For CAnimatedMaterial, channels are detailled (material rendered after clip)!
373 addValue(chanMixer
, AmbientValue
, OwnerBit
, prefix
, true);
374 addValue(chanMixer
, DiffuseValue
, OwnerBit
, prefix
, true);
375 addValue(chanMixer
, SpecularValue
, OwnerBit
, prefix
, true);
376 addValue(chanMixer
, ShininessValue
, OwnerBit
, prefix
, true);
377 addValue(chanMixer
, EmissiveValue
, OwnerBit
, prefix
, true);
378 addValue(chanMixer
, OpacityValue
, OwnerBit
, prefix
, true);
379 addValue(chanMixer
, TextureValue
, OwnerBit
, prefix
, true);
380 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
382 for (uint l
= 0; l
< NumTexAnimatedValues
; ++l
)
384 addValue(chanMixer
, TextureMatValues
+ l
+ k
* NumTexAnimatedValues
, OwnerBit
, prefix
, true);
389 // ***************************************************************************
390 const char *CAnimatedMaterial::getTexMatUTransName(uint stage
)
392 static char names
[IDRV_MAT_MAXTEXTURES
][16];
393 static bool init
= false;
394 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
395 if (!init
) // where name initialized ?
397 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
399 sprintf(&names
[k
][0], "UTrans%d", k
);
406 // ***************************************************************************
407 const char *CAnimatedMaterial::getTexMatVTransName(uint stage
)
409 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
410 static char names
[IDRV_MAT_MAXTEXTURES
][16];
411 static bool init
= false;
412 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
413 if (!init
) // where name initialized ?
415 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
417 sprintf(&names
[k
][0], "VTrans%d", k
);
425 // ***************************************************************************
426 const char *CAnimatedMaterial::getTexMatUScaleName(uint stage
)
428 static char names
[IDRV_MAT_MAXTEXTURES
][16];
429 static bool init
= false;
430 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
431 if (!init
) // where name initialized ?
433 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
435 sprintf(&names
[k
][0], "UScale%d", k
);
442 // ***************************************************************************
443 const char *CAnimatedMaterial::getTexMatVScaleName(uint stage
)
445 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
446 static char names
[IDRV_MAT_MAXTEXTURES
][16];
447 static bool init
= false;
448 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
449 if (!init
) // where name initialized ?
451 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
453 sprintf(&names
[k
][0], "VScale%d", k
);
461 // ***************************************************************************
462 const char *CAnimatedMaterial::getTexMatWRotName(uint stage
)
464 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
465 static char names
[IDRV_MAT_MAXTEXTURES
][16];
466 static bool init
= false;
467 nlassert(stage
< IDRV_MAT_MAXTEXTURES
);
468 if (!init
) // where name initialized ?
470 for (uint k
= 0; k
< IDRV_MAT_MAXTEXTURES
; ++k
)
472 sprintf(&names
[k
][0], "WRot%d", k
);