|
|
@ -30,6 +30,7 @@
|
|
|
|
#include "nel/3d/render_trav.h"
|
|
|
|
#include "nel/3d/render_trav.h"
|
|
|
|
#include "nel/3d/visual_collision_mesh.h"
|
|
|
|
#include "nel/3d/visual_collision_mesh.h"
|
|
|
|
#include "nel/3d/meshvp_wind_tree.h"
|
|
|
|
#include "nel/3d/meshvp_wind_tree.h"
|
|
|
|
|
|
|
|
#include "nel/3d/vertex_stream_manager.h"
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace std;
|
|
|
|
using namespace NLMISC;
|
|
|
|
using namespace NLMISC;
|
|
|
@ -764,9 +765,34 @@ void CMeshGeom::renderSkin(CTransformShape *trans, float alphaMRM)
|
|
|
|
// NB: the skeleton matrix has already been setuped by CSkeletonModel
|
|
|
|
// NB: the skeleton matrix has already been setuped by CSkeletonModel
|
|
|
|
// NB: the normalize flag has already been setuped by CSkeletonModel
|
|
|
|
// NB: the normalize flag has already been setuped by CSkeletonModel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool supportVertexStream = ((_VBuffer.getVertexFormat() & ~(CVertexBuffer::PaletteSkinFlag | CVertexBuffer::WeightFlag))
|
|
|
|
|
|
|
|
== (CVertexBuffer::PositionFlag | CVertexBuffer::NormalFlag | CVertexBuffer::TexCoord0Flag))
|
|
|
|
|
|
|
|
&& (_VBuffer.getValueType(CVertexBuffer::TexCoord0) == CVertexBuffer::Float2)
|
|
|
|
|
|
|
|
&& (_OriginalSkinNormals.size()) && (!_OriginalTGSpace.size());
|
|
|
|
|
|
|
|
CVertexStreamManager *meshSkinManager = renderTrav->getMeshSkinManager();
|
|
|
|
|
|
|
|
|
|
|
|
// apply the skinning: _VBuffer is modified.
|
|
|
|
if (supportVertexStream)
|
|
|
|
applySkin(skeleton);
|
|
|
|
{
|
|
|
|
|
|
|
|
uint maxVertices = meshSkinManager->getMaxVertices();
|
|
|
|
|
|
|
|
uint vertexSize = meshSkinManager->getVertexSize();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (maxVertices >= _OriginalSkinVertices.size() && vertexSize == 32)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// apply the skinning
|
|
|
|
|
|
|
|
uint8 *dstVb = meshSkinManager->lock();
|
|
|
|
|
|
|
|
applySkin(dstVb, skeleton);
|
|
|
|
|
|
|
|
meshSkinManager->unlock(_OriginalSkinVertices.size());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
supportVertexStream = false;
|
|
|
|
|
|
|
|
nlwarning("Unable to animate skinned model, too many vertices, or stream format unsupported");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
nlwarning("Unable to animate skinned model, unsupported vertex format");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Setup meshVertexProgram
|
|
|
|
// Setup meshVertexProgram
|
|
|
@ -786,7 +812,14 @@ void CMeshGeom::renderSkin(CTransformShape *trans, float alphaMRM)
|
|
|
|
// Render the mesh.
|
|
|
|
// Render the mesh.
|
|
|
|
//===========
|
|
|
|
//===========
|
|
|
|
// active VB.
|
|
|
|
// active VB.
|
|
|
|
|
|
|
|
if (supportVertexStream)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
meshSkinManager->activate();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
drv->activeVertexBuffer(_VBuffer);
|
|
|
|
drv->activeVertexBuffer(_VBuffer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// For all _MatrixBlocks
|
|
|
|
// For all _MatrixBlocks
|
|
|
@ -816,6 +849,11 @@ void CMeshGeom::renderSkin(CTransformShape *trans, float alphaMRM)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (supportVertexStream)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
meshSkinManager->swapVBHard();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// End VertexProgram effect
|
|
|
|
// End VertexProgram effect
|
|
|
|
if(useMeshVP)
|
|
|
|
if(useMeshVP)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1787,7 +1825,7 @@ void CMeshGeom::restoreOriginalSkinVertices()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
// ***************************************************************************
|
|
|
|
void CMeshGeom::applySkin(CSkeletonModel *skeleton)
|
|
|
|
void CMeshGeom::applySkin(void *dstVb, CSkeletonModel *skeleton)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// init.
|
|
|
|
// init.
|
|
|
|
//===================
|
|
|
|
//===================
|
|
|
@ -1795,24 +1833,13 @@ void CMeshGeom::applySkin(CSkeletonModel *skeleton)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// Use correct skinning
|
|
|
|
// Use correct skinning
|
|
|
|
TSkinType skinType;
|
|
|
|
nlassert(!_OriginalSkinNormals.empty());
|
|
|
|
if( _OriginalSkinNormals.empty() )
|
|
|
|
nlassert(_OriginalTGSpace.empty());
|
|
|
|
skinType= SkinPosOnly;
|
|
|
|
|
|
|
|
else if( _OriginalTGSpace.empty() )
|
|
|
|
|
|
|
|
skinType= SkinWithNormal;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
skinType= SkinWithTgSpace;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get VB src/dst info/ptrs.
|
|
|
|
// Get VB src/dst info/ptrs.
|
|
|
|
uint numVertices= (uint)_OriginalSkinVertices.size();
|
|
|
|
uint numVertices= (uint)_OriginalSkinVertices.size();
|
|
|
|
uint dstStride= _VBuffer.getVertexSize();
|
|
|
|
static const uint dstStride = 32; // _VBuffer.getVertexSize();
|
|
|
|
// Get dst TgSpace.
|
|
|
|
uint srcStride = _VBuffer.getVertexSize();
|
|
|
|
uint tgSpaceStage = 0;
|
|
|
|
|
|
|
|
if( skinType>= SkinWithTgSpace)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
nlassert(_VBuffer.getNumTexCoordUsed() > 0);
|
|
|
|
|
|
|
|
tgSpaceStage= _VBuffer.getNumTexCoordUsed() - 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Mark all vertices flag to not computed.
|
|
|
|
// Mark all vertices flag to not computed.
|
|
|
|
static vector<uint8> skinFlags;
|
|
|
|
static vector<uint8> skinFlags;
|
|
|
@ -1823,6 +1850,10 @@ void CMeshGeom::applySkin(CSkeletonModel *skeleton)
|
|
|
|
CVertexBufferRead vba;
|
|
|
|
CVertexBufferRead vba;
|
|
|
|
_VBuffer.lock (vba);
|
|
|
|
_VBuffer.lock (vba);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8 *dstVbPos = (uint8 *)dstVb;
|
|
|
|
|
|
|
|
uint8 *dstVbNormal = dstVbPos + 12;
|
|
|
|
|
|
|
|
uint8 *dstVbUV = dstVbPos + 24;
|
|
|
|
|
|
|
|
|
|
|
|
// For all MatrixBlocks
|
|
|
|
// For all MatrixBlocks
|
|
|
|
//===================
|
|
|
|
//===================
|
|
|
|
for(uint mb= 0; mb<_MatrixBlocks.size();mb++)
|
|
|
|
for(uint mb= 0; mb<_MatrixBlocks.size();mb++)
|
|
|
@ -1839,24 +1870,10 @@ void CMeshGeom::applySkin(CSkeletonModel *skeleton)
|
|
|
|
CVector *srcVector= &_OriginalSkinVertices[0];
|
|
|
|
CVector *srcVector= &_OriginalSkinVertices[0];
|
|
|
|
uint8 *srcPal= (uint8*)vba.getPaletteSkinPointer(0);
|
|
|
|
uint8 *srcPal= (uint8*)vba.getPaletteSkinPointer(0);
|
|
|
|
uint8 *srcWgt= (uint8*)vba.getWeightPointer(0);
|
|
|
|
uint8 *srcWgt= (uint8*)vba.getWeightPointer(0);
|
|
|
|
uint8 *dstVector= (uint8*)vba.getVertexCoordPointer(0);
|
|
|
|
uint8 *dstVector = dstVbPos;
|
|
|
|
// Normal.
|
|
|
|
// Normal.
|
|
|
|
CVector *srcNormal= NULL;
|
|
|
|
CVector *srcNormal= &_OriginalSkinNormals[0];
|
|
|
|
uint8 *dstNormal= NULL;
|
|
|
|
uint8 *dstNormal = dstVbNormal;
|
|
|
|
if(skinType>=SkinWithNormal)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
srcNormal= &_OriginalSkinNormals[0];
|
|
|
|
|
|
|
|
dstNormal= (uint8*)vba.getNormalCoordPointer(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// TgSpace.
|
|
|
|
|
|
|
|
CVector *srcTgSpace= NULL;
|
|
|
|
|
|
|
|
uint8 *dstTgSpace= NULL;
|
|
|
|
|
|
|
|
if(skinType>=SkinWithTgSpace)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
srcTgSpace= &_OriginalTGSpace[0];
|
|
|
|
|
|
|
|
dstTgSpace= (uint8*)vba.getTexCoordPointer(0, tgSpaceStage);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// For all vertices that need to be computed.
|
|
|
|
// For all vertices that need to be computed.
|
|
|
|
uint size= numVertices;
|
|
|
|
uint size= numVertices;
|
|
|
@ -1880,12 +1897,7 @@ void CMeshGeom::applySkin(CSkeletonModel *skeleton)
|
|
|
|
computeSoftwarePointSkinning(matrixes, srcVector, psPal, (float*)srcWgt, (CVector*)dstVector);
|
|
|
|
computeSoftwarePointSkinning(matrixes, srcVector, psPal, (float*)srcWgt, (CVector*)dstVector);
|
|
|
|
|
|
|
|
|
|
|
|
// compute normal part.
|
|
|
|
// compute normal part.
|
|
|
|
if(skinType>=SkinWithNormal)
|
|
|
|
|
|
|
|
computeSoftwareVectorSkinning(matrixes, srcNormal, psPal, (float*)srcWgt, (CVector*)dstNormal);
|
|
|
|
computeSoftwareVectorSkinning(matrixes, srcNormal, psPal, (float*)srcWgt, (CVector*)dstNormal);
|
|
|
|
|
|
|
|
|
|
|
|
// compute tg part.
|
|
|
|
|
|
|
|
if(skinType>=SkinWithTgSpace)
|
|
|
|
|
|
|
|
computeSoftwareVectorSkinning(matrixes, srcTgSpace, psPal, (float*)srcWgt, (CVector*)dstTgSpace);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// inc flags.
|
|
|
|
// inc flags.
|
|
|
@ -1893,19 +1905,46 @@ void CMeshGeom::applySkin(CSkeletonModel *skeleton)
|
|
|
|
// inc src (all whatever skin type used...)
|
|
|
|
// inc src (all whatever skin type used...)
|
|
|
|
srcVector++;
|
|
|
|
srcVector++;
|
|
|
|
srcNormal++;
|
|
|
|
srcNormal++;
|
|
|
|
srcTgSpace++;
|
|
|
|
|
|
|
|
// inc paletteSkin and dst (all whatever skin type used...)
|
|
|
|
// inc paletteSkin and dst (all whatever skin type used...)
|
|
|
|
srcPal+= dstStride;
|
|
|
|
srcPal+= srcStride;
|
|
|
|
srcWgt+= dstStride;
|
|
|
|
srcWgt+= srcStride;
|
|
|
|
dstVector+= dstStride;
|
|
|
|
dstVector+= dstStride;
|
|
|
|
dstNormal+= dstStride;
|
|
|
|
dstNormal+= dstStride;
|
|
|
|
dstTgSpace+= dstStride;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Remaining vertices
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint8 *pFlag = &skinFlags[0];
|
|
|
|
|
|
|
|
CVector *srcVector = &_OriginalSkinVertices[0];
|
|
|
|
|
|
|
|
uint8 *dstVector = dstVbPos;
|
|
|
|
|
|
|
|
CVector *srcNormal = &_OriginalSkinNormals[0];
|
|
|
|
|
|
|
|
uint8 *dstNormal = dstVbNormal;
|
|
|
|
|
|
|
|
uint8 *srcUV = (uint8 *)vba.getTexCoordPointer(0, 0);
|
|
|
|
|
|
|
|
uint8 *dstUV = dstVbUV;
|
|
|
|
|
|
|
|
uint srcStride = _VBuffer.getVertexSize();
|
|
|
|
|
|
|
|
|
|
|
|
// dirt
|
|
|
|
for (uint i = 0; i < numVertices; ++i)
|
|
|
|
_OriginalSkinRestored= false;
|
|
|
|
{
|
|
|
|
|
|
|
|
if (*pFlag != NL3D_SOFTSKIN_VCOMPUTED)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
*(CVector *)dstVector = *srcVector;
|
|
|
|
|
|
|
|
*(CVector *)dstNormal = *srcNormal;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
*(CVector2f *)dstUV = *(CVector2f *)srcUV;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// inc flags.
|
|
|
|
|
|
|
|
pFlag++;
|
|
|
|
|
|
|
|
// inc src (all whatever skin type used...)
|
|
|
|
|
|
|
|
srcVector++;
|
|
|
|
|
|
|
|
srcNormal++;
|
|
|
|
|
|
|
|
srcUV += srcStride;
|
|
|
|
|
|
|
|
// inc paletteSkin and dst (all whatever skin type used...)
|
|
|
|
|
|
|
|
dstVector += dstStride;
|
|
|
|
|
|
|
|
dstNormal += dstStride;
|
|
|
|
|
|
|
|
dstUV += dstStride;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|