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/mesh_morpher.h"
00029 #include "3d/vertex_buffer.h"
00030 #include "3d/vertex_buffer_hard.h"
00031
00032
00033 using namespace std;
00034 using namespace NLMISC;
00035
00036
00037 namespace NL3D
00038 {
00039
00040
00041 void CBlendShape::serial (NLMISC::IStream &f) throw(NLMISC::EStream)
00042 {
00043
00044 sint ver = f.serialVersion (1);
00045
00046 f.serial (Name);
00047
00048 f.serialCont (deltaPos);
00049 f.serialCont (deltaNorm);
00050 f.serialCont (deltaUV);
00051 f.serialCont (deltaCol);
00052
00053 if (ver >= 1) f.serialCont(deltaTgSpace);
00054
00055 f.serialCont (VertRefs);
00056 }
00057
00058
00059 CMeshMorpher::CMeshMorpher()
00060 {
00061 _VBOri = NULL;
00062 _VBDst = NULL;
00063 _VBDstHrd = NULL;
00064
00065 _Vertices = NULL;
00066 _Normals = NULL;
00067 _TgSpace= NULL;
00068 _SkinApplied= false;
00069 }
00070
00071
00072 void CMeshMorpher::init (CVertexBuffer *vbOri, CVertexBuffer *vbDst, IVertexBufferHard *vbDstHrd, bool hasTgSpace)
00073 {
00074 _VBOri = vbOri;
00075 _VBDst = vbDst;
00076 _VBDstHrd = vbDstHrd;
00077 _UseTgSpace = hasTgSpace;
00078 }
00079
00080
00081 void CMeshMorpher::initSkinned (CVertexBuffer *vbOri,
00082 CVertexBuffer *vbDst,
00083 IVertexBufferHard *vbDstHrd,
00084 bool hasTgSpace,
00085 std::vector<CVector> *vVertices,
00086 std::vector<CVector> *vNormals,
00087 std::vector<CVector> *vTgSpace,
00088 bool bSkinApplied )
00089 {
00090 _VBOri = vbOri;
00091 _VBDst = vbDst;
00092 _VBDstHrd = vbDstHrd;
00093 _UseTgSpace = hasTgSpace;
00094
00095 _Vertices = vVertices;
00096 _Normals = vNormals;
00097 _TgSpace = vTgSpace;
00098 _SkinApplied = bSkinApplied;
00099 }
00100
00101
00102 void CMeshMorpher::update (std::vector<CAnimatedMorph> *pBSFactor)
00103 {
00104 uint32 i, j;
00105
00106 if (_VBOri == NULL)
00107 return;
00108 if (BlendShapes.size() == 0)
00109 return;
00110
00111 if (_VBOri->getNumVertices() != _VBDst->getNumVertices())
00112 {
00113
00114 *_VBOri = *_VBDst;
00115 }
00116
00117
00118 if (_Flags.size() != _VBOri->getNumVertices())
00119 {
00120 _Flags.resize (_VBOri->getNumVertices());
00121 for (i = 0; i < _Flags.size(); ++i)
00122 _Flags[i] = Modified;
00123 }
00124
00125 nlassert(_VBOri->getVertexFormat() == _VBDst->getVertexFormat());
00126
00127
00128 uint32 VBVertexSize = _VBOri->getVertexSize();
00129 uint8 *pOri = (uint8*)_VBOri->getVertexCoordPointer ();
00130 uint8 *pDst = (uint8*)_VBDst->getVertexCoordPointer ();
00131
00132 for (i= 0; i < _Flags.size(); ++i)
00133 if (_Flags[i] >= Modified)
00134 {
00135 _Flags[i] = OriginalVBDst;
00136
00137 for(j = 0; j < VBVertexSize; ++j)
00138 pDst[j+i*VBVertexSize] = pOri[j+i*VBVertexSize];
00139 }
00140
00141 uint tgSpaceStage = 0;
00142 if (_UseTgSpace)
00143 {
00144 tgSpaceStage = _VBDst->getNumTexCoordUsed() - 1;
00145 }
00146
00147
00148 for (i = 0; i < BlendShapes.size(); ++i)
00149 {
00150 CBlendShape &rBS = BlendShapes[i];
00151 float rFactor = pBSFactor->operator[](i).getFactor()/100.0f;
00152
00153 if (rFactor > 0.0f)
00154 for (j = 0; j < rBS.VertRefs.size(); ++j)
00155 {
00156 uint32 vp = rBS.VertRefs[j];
00157
00158
00159
00160 if (_VBDst->getVertexFormat() & CVertexBuffer::PositionFlag)
00161 if (rBS.deltaPos.size() > 0)
00162 {
00163 CVector *pV = (CVector*)_VBDst->getVertexCoordPointer (vp);
00164 *pV += rBS.deltaPos[j] * rFactor;
00165 }
00166
00167 if (_VBDst->getVertexFormat() & CVertexBuffer::NormalFlag)
00168 if (rBS.deltaNorm.size() > 0)
00169 {
00170 CVector *pV = (CVector*)_VBDst->getNormalCoordPointer (vp);
00171 *pV += rBS.deltaNorm[j] * rFactor;
00172 }
00173
00174 if (_UseTgSpace)
00175 if (rBS.deltaTgSpace.size() > 0)
00176 {
00177 CVector *pV = (CVector*)_VBDst->getTexCoordPointer (vp, tgSpaceStage);
00178 *pV += rBS.deltaTgSpace[j] * rFactor;
00179 }
00180
00181
00182
00183 if (_VBDst->getVertexFormat() & CVertexBuffer::TexCoord0Flag)
00184 if (rBS.deltaUV.size() > 0)
00185 {
00186 CUV *pUV = (CUV*)_VBDst->getTexCoordPointer (vp);
00187 *pUV += rBS.deltaUV[j] * rFactor;
00188 }
00189
00190 if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
00191 if (rBS.deltaCol.size() > 0)
00192 {
00193 CRGBA *pRGBA = (CRGBA*)_VBDst->getColorPointer (vp);
00194 CRGBAF rgbf(*pRGBA);
00195 rgbf.R += rBS.deltaCol[j].R * rFactor;
00196 rgbf.G += rBS.deltaCol[j].G * rFactor;
00197 rgbf.B += rBS.deltaCol[j].B * rFactor;
00198 rgbf.A += rBS.deltaCol[j].A * rFactor;
00199 clamp(rgbf.R, 0.0f, 1.0f);
00200 clamp(rgbf.G, 0.0f, 1.0f);
00201 clamp(rgbf.B, 0.0f, 1.0f);
00202 clamp(rgbf.A, 0.0f, 1.0f);
00203 *pRGBA = rgbf;
00204 }
00205
00206
00207 _Flags[vp] = Modified;
00208 }
00209 }
00210
00211
00212 if (_VBDstHrd != NULL)
00213 {
00214 uint8 *pDstHrd = (uint8*)_VBDstHrd->lock();
00215 for (i = 0; i < _Flags.size(); ++i)
00216 {
00217 if (_Flags[i] != OriginalAll)
00218 {
00219 for(j = 0; j < VBVertexSize; ++j)
00220 pDstHrd[j+i*VBVertexSize] = pDst[j+i*VBVertexSize];
00221 }
00222
00223 if (_Flags[i] == OriginalVBDst)
00224
00225 _Flags[i] = OriginalAll;
00226 }
00227 _VBDstHrd->unlock();
00228 }
00229 }
00230
00231
00232
00233 void CMeshMorpher::updateSkinned (std::vector<CAnimatedMorph> *pBSFactor)
00234 {
00235 uint32 i, j;
00236
00237 if (_VBOri == NULL)
00238 return;
00239 if (BlendShapes.size() == 0)
00240 return;
00241
00242 if (_VBOri->getNumVertices() != _VBDst->getNumVertices())
00243 {
00244
00245 *_VBOri = *_VBDst;
00246 }
00247
00248
00249 if (_Flags.size() != _VBOri->getNumVertices())
00250 {
00251 _Flags.resize (_VBOri->getNumVertices());
00252 for (i = 0; i < _Flags.size(); ++i)
00253 _Flags[i] = Modified;
00254 }
00255
00256 nlassert(_VBOri->getVertexFormat() == _VBDst->getVertexFormat());
00257
00258 uint tgSpaceStage;
00259 uint tgSpaceOff = 0;
00260 if (_UseTgSpace && _TgSpace)
00261 {
00262 tgSpaceStage = _VBDst->getNumTexCoordUsed() - 1;
00263 tgSpaceOff = _VBDst->getTexCoordOff(tgSpaceStage);
00264 }
00265
00266
00267 uint32 VBVertexSize = _VBOri->getVertexSize();
00268 uint8 *pOri = (uint8*)_VBOri->getVertexCoordPointer ();
00269 uint8 *pDst = (uint8*)_VBDst->getVertexCoordPointer ();
00270
00271 for (i= 0; i < _Flags.size(); ++i)
00272 if (_Flags[i] >= Modified)
00273 {
00274 for(j = 0; j < VBVertexSize; ++j)
00275 pDst[j+i*VBVertexSize] = pOri[j+i*VBVertexSize];
00276
00277 if (_Vertices != NULL)
00278 _Vertices->operator[](i) = ((CVector*)(pOri+i*VBVertexSize))[0];
00279
00280 if (_Normals != NULL)
00281 _Normals->operator[](i) = ((CVector*)(pOri+i*VBVertexSize))[1];
00282
00283 if (_TgSpace != NULL)
00284 (*_TgSpace)[i] = * (CVector*)(pOri + i * VBVertexSize + tgSpaceOff);
00285
00286 _Flags[i] = OriginalVBDst;
00287 }
00288
00289
00290 for (i = 0; i < BlendShapes.size(); ++i)
00291 {
00292 CBlendShape &rBS = BlendShapes[i];
00293 float rFactor = pBSFactor->operator[](i).getFactor()/100.0f;
00294
00295 if (rFactor > 0.0f)
00296 for (j = 0; j < rBS.VertRefs.size(); ++j)
00297 {
00298 uint32 vp = rBS.VertRefs[j];
00299
00300
00301
00302 if (_Vertices != NULL)
00303 if (rBS.deltaPos.size() > 0)
00304 {
00305 CVector *pV = &(_Vertices->operator[](vp));
00306 *pV += rBS.deltaPos[j] * rFactor;
00307 }
00308
00309 if (_Normals != NULL)
00310 if (rBS.deltaNorm.size() > 0)
00311 {
00312 CVector *pV = &(_Normals->operator[](vp));
00313 *pV += rBS.deltaNorm[j] * rFactor;
00314 }
00315
00316 if (_UseTgSpace && _TgSpace != NULL)
00317 if (rBS.deltaTgSpace.size() > 0)
00318 {
00319 CVector *pV = &((*_TgSpace)[vp]);
00320 *pV += rBS.deltaTgSpace[j] * rFactor;
00321 }
00322
00323
00324
00325 if (_VBDst->getVertexFormat() & CVertexBuffer::TexCoord0Flag)
00326 if (rBS.deltaUV.size() > 0)
00327 {
00328 CUV *pUV = (CUV*)_VBDst->getTexCoordPointer (vp);
00329 *pUV += rBS.deltaUV[j] * rFactor;
00330 }
00331
00332 if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag)
00333 if (rBS.deltaCol.size() > 0)
00334 {
00335 CRGBA *pRGBA = (CRGBA*)_VBDst->getColorPointer (vp);
00336 CRGBAF rgbf(*pRGBA);
00337 rgbf.R += rBS.deltaCol[j].R * rFactor;
00338 rgbf.G += rBS.deltaCol[j].G * rFactor;
00339 rgbf.B += rBS.deltaCol[j].B * rFactor;
00340 rgbf.A += rBS.deltaCol[j].A * rFactor;
00341 clamp(rgbf.R, 0.0f, 1.0f);
00342 clamp(rgbf.G, 0.0f, 1.0f);
00343 clamp(rgbf.B, 0.0f, 1.0f);
00344 clamp(rgbf.A, 0.0f, 1.0f);
00345 *pRGBA = rgbf;
00346 }
00347
00348
00349 _Flags[vp] = Modified;
00350 }
00351 }
00352
00353
00354 if (_VBDstHrd != NULL)
00355 {
00356
00357 uint8 *pDstHrd = (uint8*)_VBDstHrd->lock();
00358
00359
00360
00361 if (!_SkinApplied)
00362 {
00363 for (i = 0; i < _Flags.size(); ++i)
00364 {
00365 if (_Flags[i] != OriginalAll)
00366 {
00367
00368
00369 for(j = 0; j < VBVertexSize; ++j)
00370 pDstHrd[j+i*VBVertexSize] = pDst[j+i*VBVertexSize];
00371 }
00372 if (_Flags[i] == OriginalVBDst)
00373 _Flags[i] = OriginalAll;
00374 }
00375 }
00376
00377
00378 _VBDstHrd->unlock();
00379 }
00380 }
00381
00382
00383 void CMeshMorpher::serial (NLMISC::IStream &f) throw(NLMISC::EStream)
00384 {
00385 (void)f.serialVersion (0);
00386
00387 f.serialCont (BlendShapes);
00388 }
00389
00390
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401