#include <mesh_morpher.h>
Nevrax France
Definition at line 66 of file mesh_morpher.h.
Public Member Functions | |
CMeshMorpher () | |
void | init (CVertexBuffer *vbOri, CVertexBuffer *vbDst, IVertexBufferHard *vbDstHrd, bool hasTgSpace) |
void | initSkinned (CVertexBuffer *vbOri, CVertexBuffer *vbDst, IVertexBufferHard *vbDstHrd, bool hasTgSpace, std::vector< CVector > *vVertices, std::vector< CVector > *vNormals, std::vector< CVector > *vTgSpace, bool bSkinApplied) |
void | serial (NLMISC::IStream &f) throw (NLMISC::EStream) |
void | update (std::vector< CAnimatedMorph > *pBSFactor) |
void | updateRawSkin (CVertexBuffer *vbOri, const NLMISC::CObjectVector< CRawSkinVertex *, false > &vertexRemap, std::vector< CAnimatedMorph > *pBSFactor) |
void | updateSkinned (std::vector< CAnimatedMorph > *pBSFactor) |
Data Fields | |
std::vector< CBlendShape > | BlendShapes |
Private Types | |
enum | TState { OriginalAll = 0, OriginalVBDst, Modified } |
Private Attributes | |
std::vector< uint8 > | _Flags |
std::vector< CVector > * | _Normals |
bool | _SkinApplied: 1 |
std::vector< CVector > * | _TgSpace |
bool | _UseTgSpace: 1 |
CVertexBuffer * | _VBDst |
IVertexBufferHard * | _VBDstHrd |
CVertexBuffer * | _VBOri |
std::vector< CVector > * | _Vertices |
|
Definition at line 68 of file mesh_morpher.h.
00069 { 00070 OriginalAll=0, // The vertex is the same as original into VBDst and VBHard 00071 OriginalVBDst, // The vertex is the same as original into VBDst 00072 Modified, // Vertex modified 00073 } TState; |
|
Definition at line 60 of file mesh_morpher.cpp. References _SkinApplied, _TgSpace, _VBDst, _VBDstHrd, _VBOri, and _Vertices.
|
|
Definition at line 73 of file mesh_morpher.cpp. References _UseTgSpace, _VBDst, _VBDstHrd, and _VBOri. Referenced by NL3D::CMeshMRMGeom::render(), and NL3D::CMeshGeom::render().
00074 { 00075 _VBOri = vbOri; 00076 _VBDst = vbDst; 00077 _VBDstHrd = vbDstHrd; 00078 _UseTgSpace = hasTgSpace; 00079 } |
|
Definition at line 82 of file mesh_morpher.cpp. References _SkinApplied, _TgSpace, _UseTgSpace, _VBDst, _VBDstHrd, _VBOri, and _Vertices. Referenced by NL3D::CMeshMRMGeom::render(), NL3D::CMeshGeom::render(), NL3D::CMeshMRMGeom::renderSkin(), and NL3D::CMeshGeom::renderSkin().
00090 { 00091 _VBOri = vbOri; 00092 _VBDst = vbDst; 00093 _VBDstHrd = vbDstHrd; 00094 _UseTgSpace = hasTgSpace; 00095 00096 _Vertices = vVertices; 00097 _Normals = vNormals; 00098 _TgSpace = vTgSpace; 00099 _SkinApplied = bSkinApplied; 00100 } |
|
Definition at line 386 of file mesh_morpher.cpp.
00387 { 00388 (void)f.serialVersion (0); 00389 00390 f.serialCont (BlendShapes); 00391 } |
|
Definition at line 103 of file mesh_morpher.cpp. References _UseTgSpace, _VBDst, _VBDstHrd, _VBOri, NLMISC::CRGBAF::A, NLMISC::CRGBAF::B, NLMISC::clamp(), NL3D::CBlendShape::deltaCol, NL3D::CBlendShape::deltaNorm, NL3D::CBlendShape::deltaPos, NL3D::CBlendShape::deltaTgSpace, NL3D::CBlendShape::deltaUV, NLMISC::CRGBAF::G, NL3D::CVertexBuffer::getColorPointer(), NL3D::CVertexBuffer::getNormalCoordPointer(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), NL3D::IVertexBufferHard::lock(), Modified, nlassert, OriginalAll, OriginalVBDst, NLMISC::CRGBAF::R, uint, uint32, uint8, NL3D::IVertexBufferHard::unlock(), and NL3D::CBlendShape::VertRefs. Referenced by NL3D::CMeshMRMGeom::render(), and NL3D::CMeshGeom::render().
00104 { 00105 uint32 i, j; 00106 00107 if (_VBOri == NULL) 00108 return; 00109 if (BlendShapes.size() == 0) 00110 return; 00111 00112 if (_VBOri->getNumVertices() != _VBDst->getNumVertices()) 00113 { // Because the original vertex buffer is not initialized by default 00114 // we must init it here (if there are some blendshapes) 00115 *_VBOri = *_VBDst; 00116 } 00117 00118 // Does the flags are reserved ? 00119 if (_Flags.size() != _VBOri->getNumVertices()) 00120 { 00121 _Flags.resize (_VBOri->getNumVertices()); 00122 for (i = 0; i < _Flags.size(); ++i) 00123 _Flags[i] = Modified; // Modified to update all 00124 } 00125 00126 nlassert(_VBOri->getVertexFormat() == _VBDst->getVertexFormat()); 00127 00128 // Cleaning with original vertex buffer 00129 uint32 VBVertexSize = _VBOri->getVertexSize(); 00130 uint8 *pOri = (uint8*)_VBOri->getVertexCoordPointer (); 00131 uint8 *pDst = (uint8*)_VBDst->getVertexCoordPointer (); 00132 00133 for (i= 0; i < _Flags.size(); ++i) 00134 if (_Flags[i] >= Modified) 00135 { 00136 _Flags[i] = OriginalVBDst; 00137 00138 for(j = 0; j < VBVertexSize; ++j) 00139 pDst[j+i*VBVertexSize] = pOri[j+i*VBVertexSize]; 00140 } 00141 00142 uint tgSpaceStage = 0; 00143 if (_UseTgSpace) 00144 { 00145 tgSpaceStage = _VBDst->getNumTexCoordUsed() - 1; 00146 } 00147 00148 // Blending with blendshape 00149 for (i = 0; i < BlendShapes.size(); ++i) 00150 { 00151 CBlendShape &rBS = BlendShapes[i]; 00152 float rFactor = pBSFactor->operator[](i).getFactor()/100.0f; 00153 00154 // todo hulud check it works 00155 // if (rFactor > 0.0f) 00156 if (rFactor != 0.0f) 00157 for (j = 0; j < rBS.VertRefs.size(); ++j) 00158 { 00159 uint32 vp = rBS.VertRefs[j]; 00160 00161 // Modify Pos/Norm/TgSpace. 00162 //------------ 00163 if (_VBDst->getVertexFormat() & CVertexBuffer::PositionFlag) 00164 if (rBS.deltaPos.size() > 0) 00165 { 00166 CVector *pV = (CVector*)_VBDst->getVertexCoordPointer (vp); 00167 *pV += rBS.deltaPos[j] * rFactor; 00168 } 00169 00170 if (_VBDst->getVertexFormat() & CVertexBuffer::NormalFlag) 00171 if (rBS.deltaNorm.size() > 0) 00172 { 00173 CVector *pV = (CVector*)_VBDst->getNormalCoordPointer (vp); 00174 *pV += rBS.deltaNorm[j] * rFactor; 00175 } 00176 00177 if (_UseTgSpace) 00178 if (rBS.deltaTgSpace.size() > 0) 00179 { 00180 CVector *pV = (CVector*)_VBDst->getTexCoordPointer (vp, tgSpaceStage); 00181 *pV += rBS.deltaTgSpace[j] * rFactor; 00182 } 00183 00184 // Modify UV0 / Color 00185 //------------ 00186 if (_VBDst->getVertexFormat() & CVertexBuffer::TexCoord0Flag) 00187 if (rBS.deltaUV.size() > 0) 00188 { 00189 CUV *pUV = (CUV*)_VBDst->getTexCoordPointer (vp); 00190 *pUV += rBS.deltaUV[j] * rFactor; 00191 } 00192 00193 if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag) 00194 if (rBS.deltaCol.size() > 0) 00195 { 00196 CRGBA *pRGBA = (CRGBA*)_VBDst->getColorPointer (vp); 00197 CRGBAF rgbf(*pRGBA); 00198 rgbf.R += rBS.deltaCol[j].R * rFactor; 00199 rgbf.G += rBS.deltaCol[j].G * rFactor; 00200 rgbf.B += rBS.deltaCol[j].B * rFactor; 00201 rgbf.A += rBS.deltaCol[j].A * rFactor; 00202 clamp(rgbf.R, 0.0f, 1.0f); 00203 clamp(rgbf.G, 0.0f, 1.0f); 00204 clamp(rgbf.B, 0.0f, 1.0f); 00205 clamp(rgbf.A, 0.0f, 1.0f); 00206 *pRGBA = rgbf; 00207 } 00208 00209 // Modified 00210 _Flags[vp] = Modified; 00211 } 00212 } 00213 00214 // Copying to hardware vertex buffer if some 00215 if (_VBDstHrd != NULL) 00216 { 00217 uint8 *pDstHrd = (uint8*)_VBDstHrd->lock(); 00218 for (i = 0; i < _Flags.size(); ++i) 00219 { 00220 if (_Flags[i] != OriginalAll) // Not OriginalAll ? 00221 { 00222 for(j = 0; j < VBVertexSize; ++j) 00223 pDstHrd[j+i*VBVertexSize] = pDst[j+i*VBVertexSize]; 00224 } 00225 // if this vertex is original in the VBDst 00226 if (_Flags[i] == OriginalVBDst) 00227 // then it is now copied into the VBHard 00228 _Flags[i] = OriginalAll; 00229 } 00230 _VBDstHrd->unlock(); 00231 } 00232 } |
|
Definition at line 399 of file mesh_morpher.cpp. References NL3D::CBlendShape::deltaNorm, NL3D::CBlendShape::deltaPos, NL3D::CBlendShape::deltaUV, NL3D::CVertexBuffer::getNormalOff(), NL3D::CVertexBuffer::getNumVertices(), NLMISC::CObjectVector< T, EnableObjectBehavior >::getPtr(), NL3D::CVertexBuffer::getTexCoordOff(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), NL3D_RAWSKIN_NORMAL_OFF, NL3D_RAWSKIN_UV_OFF, NL3D_RAWSKIN_VERTEX_SIZE, nlassert, NL3D::CRawSkinVertex::Normal, NL3D::CRawSkinVertex::Pos, uint, uint32, uint8, NL3D::CRawSkinVertex::UV, and NL3D::CBlendShape::VertRefs. Referenced by NL3D::CMeshMRMGeom::renderSkinGroupGeom().
00402 { 00403 uint32 i, j; 00404 00405 if (vbOri == NULL) 00406 return; 00407 if (BlendShapes.size() == 0) 00408 return; 00409 00410 nlassert(vbOri->getVertexFormat() == (CVertexBuffer::PositionFlag | CVertexBuffer::NormalFlag |CVertexBuffer::TexCoord0Flag) ); 00411 nlassert(NL3D_RAWSKIN_VERTEX_SIZE == vbOri->getVertexSize()); 00412 nlassert(NL3D_RAWSKIN_NORMAL_OFF == vbOri->getNormalOff()); 00413 nlassert(NL3D_RAWSKIN_UV_OFF == vbOri->getTexCoordOff(0)); 00414 00415 // Cleaning with original vertex buffer 00416 uint8 *pOri = (uint8*)vbOri->getVertexCoordPointer (); 00417 CRawSkinVertex **vRemap= vertexRemap.getPtr(); 00418 uint numVertices= vbOri->getNumVertices(); 00419 00420 // Update only the vertices of this lod 00421 for (i= 0; i < numVertices; ++i) 00422 { 00423 if(*vRemap) 00424 { 00425 (*vRemap)->Pos= *(CVector*)(pOri); 00426 (*vRemap)->Normal= *(CVector*)(pOri + NL3D_RAWSKIN_NORMAL_OFF); 00427 (*vRemap)->UV= *(CUV*)(pOri + NL3D_RAWSKIN_UV_OFF); 00428 } 00429 pOri+= NL3D_RAWSKIN_VERTEX_SIZE; 00430 vRemap++; 00431 } 00432 00433 // Blending with blendshape 00434 for (i = 0; i < BlendShapes.size(); ++i) 00435 { 00436 CBlendShape &rBS = BlendShapes[i]; 00437 float rFactor = pBSFactor->operator[](i).getFactor(); 00438 00439 if (rFactor != 0.0f) 00440 { 00441 rFactor*= 0.01f; 00442 uint32 numVertices= rBS.VertRefs.size(); 00443 // don't know why, but cases happen where deltaNorm not empty while deltaPos is 00444 bool hasPos= rBS.deltaPos.size()>0; 00445 bool hasNorm= rBS.deltaNorm.size()>0; 00446 bool hasUV= rBS.deltaUV.size()>0; 00447 for (j = 0; j < numVertices; ++j) 00448 { 00449 // Get the vertex Index in the VBufferFinal 00450 uint vid= rBS.VertRefs[j]; 00451 // Then get the RawSkin vertex to modify 00452 CRawSkinVertex *rsVert= vertexRemap[vid]; 00453 00454 // If exist in this Lod RawSkin, apply 00455 if(rsVert) 00456 { 00457 if(hasPos) 00458 rsVert->Pos+= rBS.deltaPos[j] * rFactor; 00459 if(hasNorm) 00460 rsVert->Normal+= rBS.deltaNorm[j] * rFactor; 00461 if(hasUV) 00462 rsVert->UV+= rBS.deltaUV[j] * rFactor; 00463 } 00464 } 00465 } 00466 00467 } 00468 00469 } |
|
Definition at line 236 of file mesh_morpher.cpp. References _SkinApplied, _TgSpace, _UseTgSpace, _VBDst, _VBDstHrd, _VBOri, _Vertices, NLMISC::CRGBAF::A, NLMISC::CRGBAF::B, NLMISC::clamp(), NL3D::CBlendShape::deltaCol, NL3D::CBlendShape::deltaNorm, NL3D::CBlendShape::deltaPos, NL3D::CBlendShape::deltaTgSpace, NL3D::CBlendShape::deltaUV, NLMISC::CRGBAF::G, NL3D::CVertexBuffer::getColorPointer(), NL3D::CVertexBuffer::getNumTexCoordUsed(), NL3D::CVertexBuffer::getNumVertices(), NL3D::CVertexBuffer::getTexCoordOff(), NL3D::CVertexBuffer::getTexCoordPointer(), NL3D::CVertexBuffer::getVertexCoordPointer(), NL3D::CVertexBuffer::getVertexFormat(), NL3D::CVertexBuffer::getVertexSize(), NL3D::IVertexBufferHard::lock(), Modified, nlassert, OriginalAll, OriginalVBDst, NLMISC::CRGBAF::R, uint, uint32, uint8, NL3D::IVertexBufferHard::unlock(), and NL3D::CBlendShape::VertRefs. Referenced by NL3D::CMeshMRMGeom::render(), NL3D::CMeshGeom::render(), NL3D::CMeshMRMGeom::renderSkin(), and NL3D::CMeshGeom::renderSkin().
00237 { 00238 uint32 i, j; 00239 00240 if (_VBOri == NULL) 00241 return; 00242 if (BlendShapes.size() == 0) 00243 return; 00244 00245 if (_VBOri->getNumVertices() != _VBDst->getNumVertices()) 00246 { // Because the original vertex buffer is not initialized by default 00247 // we must init it here (if there are some blendshapes) 00248 *_VBOri = *_VBDst; 00249 } 00250 00251 // Does the flags are reserved ? 00252 if (_Flags.size() != _VBOri->getNumVertices()) 00253 { 00254 _Flags.resize (_VBOri->getNumVertices()); 00255 for (i = 0; i < _Flags.size(); ++i) 00256 _Flags[i] = Modified; // Modified to update all 00257 } 00258 00259 nlassert(_VBOri->getVertexFormat() == _VBDst->getVertexFormat()); 00260 00261 uint tgSpaceStage; 00262 uint tgSpaceOff = 0; 00263 if (_UseTgSpace && _TgSpace) 00264 { 00265 tgSpaceStage = _VBDst->getNumTexCoordUsed() - 1; 00266 tgSpaceOff = _VBDst->getTexCoordOff(tgSpaceStage); 00267 } 00268 00269 // Cleaning with original vertex buffer 00270 uint32 VBVertexSize = _VBOri->getVertexSize(); 00271 uint8 *pOri = (uint8*)_VBOri->getVertexCoordPointer (); 00272 uint8 *pDst = (uint8*)_VBDst->getVertexCoordPointer (); 00273 00274 for (i= 0; i < _Flags.size(); ++i) 00275 if (_Flags[i] >= Modified) 00276 { 00277 for(j = 0; j < VBVertexSize; ++j) 00278 pDst[j+i*VBVertexSize] = pOri[j+i*VBVertexSize]; 00279 00280 if (_Vertices != NULL) 00281 _Vertices->operator[](i) = ((CVector*)(pOri+i*VBVertexSize))[0]; 00282 00283 if (_Normals != NULL) 00284 _Normals->operator[](i) = ((CVector*)(pOri+i*VBVertexSize))[1]; 00285 00286 if (_TgSpace != NULL) 00287 (*_TgSpace)[i] = * (CVector*)(pOri + i * VBVertexSize + tgSpaceOff); 00288 00289 _Flags[i] = OriginalVBDst; 00290 } 00291 00292 // Blending with blendshape 00293 for (i = 0; i < BlendShapes.size(); ++i) 00294 { 00295 CBlendShape &rBS = BlendShapes[i]; 00296 float rFactor = pBSFactor->operator[](i).getFactor()/100.0f; 00297 00298 if (rFactor != 0.0f) 00299 for (j = 0; j < rBS.VertRefs.size(); ++j) 00300 { 00301 uint32 vp = rBS.VertRefs[j]; 00302 00303 // Modify Pos/Norm/TgSpace. 00304 //------------ 00305 if (_Vertices != NULL) 00306 if (rBS.deltaPos.size() > 0) 00307 { 00308 CVector *pV = &(_Vertices->operator[](vp)); 00309 *pV += rBS.deltaPos[j] * rFactor; 00310 } 00311 00312 if (_Normals != NULL) 00313 if (rBS.deltaNorm.size() > 0) 00314 { 00315 CVector *pV = &(_Normals->operator[](vp)); 00316 *pV += rBS.deltaNorm[j] * rFactor; 00317 } 00318 00319 if (_UseTgSpace && _TgSpace != NULL) 00320 if (rBS.deltaTgSpace.size() > 0) 00321 { 00322 CVector *pV = &((*_TgSpace)[vp]); 00323 *pV += rBS.deltaTgSpace[j] * rFactor; 00324 } 00325 00326 // Modify UV0 / Color 00327 //------------ 00328 if (_VBDst->getVertexFormat() & CVertexBuffer::TexCoord0Flag) 00329 if (rBS.deltaUV.size() > 0) 00330 { 00331 CUV *pUV = (CUV*)_VBDst->getTexCoordPointer (vp); 00332 *pUV += rBS.deltaUV[j] * rFactor; 00333 } 00334 00335 if (_VBDst->getVertexFormat() & CVertexBuffer::PrimaryColorFlag) 00336 if (rBS.deltaCol.size() > 0) 00337 { 00338 CRGBA *pRGBA = (CRGBA*)_VBDst->getColorPointer (vp); 00339 CRGBAF rgbf(*pRGBA); 00340 rgbf.R += rBS.deltaCol[j].R * rFactor; 00341 rgbf.G += rBS.deltaCol[j].G * rFactor; 00342 rgbf.B += rBS.deltaCol[j].B * rFactor; 00343 rgbf.A += rBS.deltaCol[j].A * rFactor; 00344 clamp(rgbf.R, 0.0f, 1.0f); 00345 clamp(rgbf.G, 0.0f, 1.0f); 00346 clamp(rgbf.B, 0.0f, 1.0f); 00347 clamp(rgbf.A, 0.0f, 1.0f); 00348 *pRGBA = rgbf; 00349 } 00350 00351 // Modified 00352 _Flags[vp] = Modified; 00353 } 00354 } 00355 00356 // Do some transfert to the VBHard if exist. 00357 if (_VBDstHrd != NULL) 00358 { 00359 // lock. 00360 uint8 *pDstHrd = (uint8*)_VBDstHrd->lock(); 00361 00362 // If the skin is applied we have nothing to do 00363 // Because the skinning will transfert ALL the vertices of interest 00364 if (!_SkinApplied) 00365 { 00366 for (i = 0; i < _Flags.size(); ++i) 00367 { 00368 if (_Flags[i] != OriginalAll) // Not OriginalAll ? 00369 { 00370 // We must write the whole vertex because the skinning may not copy 00371 // vertex and normal changes into VBHard 00372 for(j = 0; j < VBVertexSize; ++j) 00373 pDstHrd[j+i*VBVertexSize] = pDst[j+i*VBVertexSize]; 00374 } 00375 if (_Flags[i] == OriginalVBDst) // OriginalVBDst ? 00376 _Flags[i] = OriginalAll; // So OriginalAll ! 00377 } 00378 } 00379 00380 // unlock. 00381 _VBDstHrd->unlock(); 00382 } 00383 } |
|
Definition at line 115 of file mesh_morpher.h. |
|
Definition at line 108 of file mesh_morpher.h. |
|
Definition at line 112 of file mesh_morpher.h. Referenced by CMeshMorpher(), initSkinned(), and updateSkinned(). |
|
Definition at line 109 of file mesh_morpher.h. Referenced by CMeshMorpher(), initSkinned(), and updateSkinned(). |
|
Definition at line 113 of file mesh_morpher.h. Referenced by init(), initSkinned(), update(), and updateSkinned(). |
|
Definition at line 104 of file mesh_morpher.h. Referenced by CMeshMorpher(), init(), initSkinned(), update(), and updateSkinned(). |
|
Definition at line 105 of file mesh_morpher.h. Referenced by CMeshMorpher(), init(), initSkinned(), update(), and updateSkinned(). |
|
Definition at line 103 of file mesh_morpher.h. Referenced by CMeshMorpher(), init(), initSkinned(), update(), and updateSkinned(). |
|
Definition at line 107 of file mesh_morpher.h. Referenced by CMeshMorpher(), initSkinned(), and updateSkinned(). |
|