1113 lines
30 KiB
C++
1113 lines
30 KiB
C++
/**
|
|
* File not compiled. Included from mesh_mrm_skinned.cpp. It is an "old school" template.
|
|
*/
|
|
|
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include "std3d.h"
|
|
|
|
// ***************************************************************************
|
|
// ***************************************************************************
|
|
// Raw "Vertex/Normal only" ApplySkin methods.
|
|
// ***************************************************************************
|
|
// ***************************************************************************
|
|
|
|
// ace: before including this, #define this define to use it
|
|
// the goal is to be able to compile every .cpp file with no
|
|
// special case (GNU/Linux needs)
|
|
#ifdef ADD_MESH_MRM_SKINNED_TEMPLATE
|
|
|
|
|
|
#define NL3D_RAWSKIN_NORMAL_OFF 12
|
|
#define NL3D_RAWSKIN_UV_OFF 24
|
|
#define NL3D_RAWSKIN_VERTEX_SIZE 32
|
|
|
|
|
|
/* Speed Feature test.
|
|
Don't use precaching for now, cause its seems to be slower on some configs (P4-2.4Ghz),
|
|
but maybe faster on other (P3-800)
|
|
On a P4-2.4Ghz, for 40000 vertices skinned, both no precaching and asm
|
|
saves 27% of execution time in the applyRawSkinNormal*() loop (ie 1 ms)
|
|
*/
|
|
#if defined(NL_OS_WINDOWS) && !defined(NL_NO_ASM)
|
|
//#define NL3D_RAWSKIN_PRECACHE
|
|
#define NL3D_RAWSKIN_ASM
|
|
#endif
|
|
|
|
|
|
// ***************************************************************************
|
|
void CMeshMRMSkinnedGeom::applyArrayRawSkinNormal1(CRawVertexNormalSkinned1 *src, uint8 *destVertexPtr,
|
|
CMatrix3x4 *boneMat3x4, uint nInf)
|
|
{
|
|
// must write contigously in AGP, and ASM is hardcoded...
|
|
nlctassert(NL3D_RAWSKIN_NORMAL_OFF==12);
|
|
nlctassert(NL3D_RAWSKIN_UV_OFF==24);
|
|
|
|
/*extern uint TESTYOYO_NumRawSkinVertices1;
|
|
TESTYOYO_NumRawSkinVertices1+= nInf;
|
|
H_AUTO( TestYoyo_RawSkin1 );*/
|
|
|
|
#ifdef NL3D_RAWSKIN_PRECACHE
|
|
for(;nInf>0;)
|
|
{
|
|
// number of vertices to process for this block.
|
|
uint nBlockInf= min(NumCacheVertexNormal1, nInf);
|
|
// next block.
|
|
nInf-= nBlockInf;
|
|
|
|
// cache the data in L1 cache.
|
|
CFastMem::precache(src, nBlockInf * sizeof(CRawVertexNormalSkinned1));
|
|
#else
|
|
{
|
|
uint nBlockInf= nInf;
|
|
#endif
|
|
|
|
|
|
#ifndef NL3D_RAWSKIN_ASM
|
|
// for all InfluencedVertices only.
|
|
for(;nBlockInf>0;nBlockInf--, src++, destVertexPtr+=NL3D_RAWSKIN_VERTEX_SIZE)
|
|
{
|
|
CVector *dstVertex= (CVector*)(destVertexPtr);
|
|
CVector *dstNormal= (CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF);
|
|
|
|
// For 1 matrix, can write directly to AGP (if destVertexPtr is AGP...)
|
|
// Vertex.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetPoint( src->Vertex, *(CVector*)(destVertexPtr) );
|
|
// Normal.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) );
|
|
// UV copy.
|
|
*(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->UV;
|
|
}
|
|
#else
|
|
// ASM hard coded for 36
|
|
nlctassert(sizeof(CRawVertexNormalSkinned1)==36);
|
|
|
|
/* 116 cycles / loop typical
|
|
58 cycles / loop in theory (no memory problem)
|
|
*/
|
|
__asm
|
|
{
|
|
mov ecx, nBlockInf
|
|
mov esi, src
|
|
mov edi, destVertexPtr
|
|
mov edx, boneMat3x4
|
|
theLoop:
|
|
// Vertex.
|
|
// **** boneMat3x4[ src->MatrixId[0] ].mulSetPoint( src->Vertex, *(CVector*)(destVertexPtr) );
|
|
|
|
// eax= matrix
|
|
mov eax, [esi]src.MatrixId // uop: 0/1
|
|
lea eax, [eax*2+eax]
|
|
shl eax, 4
|
|
add eax, edx // uop: 1/0
|
|
|
|
// load x y z
|
|
fld [esi]src.Vertex.x // uop: 0/1
|
|
fld [esi]src.Vertex.y // uop: 0/1
|
|
fld [esi]src.Vertex.z // uop: 0/1
|
|
// vout.x= (a11*vin.x + a12*vin.y + a13*vin.z + a14);
|
|
fld [eax]CMatrix3x4.a11 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
fld [eax]CMatrix3x4.a12 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a13 // uop: 0/1
|
|
fmul st, st(2) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a14 // uop: 0/1
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fstp dword ptr[edi] // uop: 0/0/1/1
|
|
// vout.y= (a21*vin.x + a22*vin.y + a23*vin.z + a24);
|
|
fld [eax]CMatrix3x4.a21
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a22
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a23
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a24
|
|
faddp st(1), st
|
|
fstp dword ptr[edi+4]
|
|
// vout.z= (a31*vin.x + a32*vin.y + a33*vin.z + a34);
|
|
fld [eax]CMatrix3x4.a31
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a32
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a33
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a34
|
|
faddp st(1), st
|
|
fstp dword ptr[edi+8]
|
|
// free x y z
|
|
fstp st // uop: 1/0
|
|
fstp st // uop: 1/0
|
|
fstp st // uop: 1/0
|
|
|
|
|
|
// Normal
|
|
// **** boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) );
|
|
|
|
// load x y z
|
|
fld [esi]src.Normal.x
|
|
fld [esi]src.Normal.y
|
|
fld [esi]src.Normal.z
|
|
// vout.x= (a11*vin.x + a12*vin.y + a13*vin.z + a14);
|
|
fld [eax]CMatrix3x4.a11 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
fld [eax]CMatrix3x4.a12 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a13 // uop: 0/1
|
|
fmul st, st(2) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fstp dword ptr[edi+12] // uop: 0/0/1/1
|
|
// vout.y= (a21*vin.x + a22*vin.y + a23*vin.z + a24);
|
|
fld [eax]CMatrix3x4.a21
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a22
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a23
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fstp dword ptr[edi+16]
|
|
// vout.z= (a31*vin.x + a32*vin.y + a33*vin.z + a34);
|
|
fld [eax]CMatrix3x4.a31
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a32
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a33
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fstp dword ptr[edi+20]
|
|
// free x y z
|
|
fstp st
|
|
fstp st
|
|
fstp st
|
|
|
|
|
|
// UV copy.
|
|
// **** *(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->UV;
|
|
mov eax, [esi]src.UV.U // uop: 0/1
|
|
mov dword ptr[edi+24], eax // uop: 0/0/1/1
|
|
mov eax, [esi]src.UV.V // uop: 0/1
|
|
mov dword ptr[edi+28], eax // uop: 0/0/1/1
|
|
|
|
|
|
// **** next
|
|
add esi, 36 // uop: 1/0
|
|
add edi, NL3D_RAWSKIN_VERTEX_SIZE // uop: 1/0
|
|
dec ecx // uop: 1/0
|
|
jnz theLoop // uop: 1/1 (p1)
|
|
|
|
mov nBlockInf, ecx
|
|
mov src, esi
|
|
mov destVertexPtr, edi
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CMeshMRMSkinnedGeom::applyArrayRawSkinNormal2(CRawVertexNormalSkinned2 *src, uint8 *destVertexPtr,
|
|
CMatrix3x4 *boneMat3x4, uint nInf)
|
|
{
|
|
// must write contigously in AGP, and ASM is hardcoded...
|
|
nlctassert(NL3D_RAWSKIN_NORMAL_OFF==12);
|
|
nlctassert(NL3D_RAWSKIN_UV_OFF==24);
|
|
|
|
/*extern uint TESTYOYO_NumRawSkinVertices2;
|
|
TESTYOYO_NumRawSkinVertices2+= nInf;
|
|
H_AUTO( TestYoyo_RawSkin2 );*/
|
|
|
|
// Since VertexPtr may be a AGP Ram, MUST NOT read into it! (mulAdd*() do it!)
|
|
CVector tmpVert;
|
|
|
|
#ifdef NL3D_RAWSKIN_PRECACHE
|
|
for(;nInf>0;)
|
|
{
|
|
// number of vertices to process for this block.
|
|
uint nBlockInf= min(NumCacheVertexNormal2, nInf);
|
|
// next block.
|
|
nInf-= nBlockInf;
|
|
|
|
// cache the data in L1 cache.
|
|
CFastMem::precache(src, nBlockInf * sizeof(CRawVertexNormalSkinned2));
|
|
#else
|
|
{
|
|
uint nBlockInf= nInf;
|
|
#endif
|
|
|
|
|
|
#ifndef NL3D_RAWSKIN_ASM
|
|
// for all InfluencedVertices only.
|
|
for(;nBlockInf>0;nBlockInf--, src++, destVertexPtr+=NL3D_RAWSKIN_VERTEX_SIZE)
|
|
{
|
|
// Vertex.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetPoint( src->Vertex, src->Weights[0], tmpVert);
|
|
boneMat3x4[ src->MatrixId[1] ].mulAddPoint( src->Vertex, src->Weights[1], tmpVert);
|
|
*(CVector*)(destVertexPtr)= tmpVert;
|
|
// Normal.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Normal, src->Weights[0], tmpVert);
|
|
boneMat3x4[ src->MatrixId[1] ].mulAddVector( src->Normal, src->Weights[1], tmpVert);
|
|
*(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF)= tmpVert;
|
|
// UV copy.
|
|
*(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->UV;
|
|
}
|
|
#else
|
|
// ASM harcoded for 48
|
|
nlctassert(sizeof(CRawVertexNormalSkinned2)==48);
|
|
|
|
/* 154 cycles / loop typical
|
|
124 cycles / loop in theory (no memory problem)
|
|
*/
|
|
__asm
|
|
{
|
|
mov ecx, nBlockInf
|
|
mov esi, src
|
|
mov edi, destVertexPtr
|
|
mov edx, boneMat3x4
|
|
theLoop:
|
|
// Vertex.
|
|
// **** boneMat3x4[ src->MatrixId[0] ].mulSetPoint( src->Vertex, *(CVector*)(destVertexPtr) );
|
|
|
|
// eax= matrix0
|
|
mov eax, [esi+0]src.MatrixId // uop: 0/1
|
|
lea eax, [eax*2+eax]
|
|
shl eax, 4
|
|
add eax, edx // uop: 1/0
|
|
// ebx= matrix1
|
|
mov ebx, [esi+4]src.MatrixId // uop: 0/1
|
|
lea ebx, [ebx*2+ebx]
|
|
shl ebx, 4
|
|
add ebx, edx // uop: 1/0
|
|
|
|
// load x y z
|
|
fld [esi]src.Vertex.x // uop: 0/1
|
|
fld [esi]src.Vertex.y // uop: 0/1
|
|
fld [esi]src.Vertex.z // uop: 0/1
|
|
|
|
// **** vout.x= (a11*vin.x + a12*vin.y + a13*vin.z + a14);
|
|
// 1st Matrix
|
|
fld [eax]CMatrix3x4.a11 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
fld [eax]CMatrix3x4.a12 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a13 // uop: 0/1
|
|
fmul st, st(2) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a14 // uop: 0/1
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a11
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a12
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a13
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a14
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi] // uop: 0/0/1/1
|
|
|
|
// **** vout.y= (a21*vin.x + a22*vin.y + a23*vin.z + a24);
|
|
fld [eax]CMatrix3x4.a21
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a22
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a23
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a24
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a21
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a22
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a23
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a24
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+4]
|
|
|
|
// **** vout.z= (a31*vin.x + a32*vin.y + a33*vin.z + a34);
|
|
fld [eax]CMatrix3x4.a31
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a32
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a33
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a34
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a31
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a32
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a33
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a34
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+8]
|
|
|
|
// free x y z
|
|
fstp st // uop: 1/0
|
|
fstp st // uop: 1/0
|
|
fstp st // uop: 1/0
|
|
|
|
|
|
// Normal
|
|
// **** boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) );
|
|
|
|
// load x y z
|
|
fld [esi]src.Normal.x
|
|
fld [esi]src.Normal.y
|
|
fld [esi]src.Normal.z
|
|
|
|
// **** vout.x= (a11*vin.x + a12*vin.y + a13*vin.z + a14);
|
|
fld [eax]CMatrix3x4.a11 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
fld [eax]CMatrix3x4.a12 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a13 // uop: 0/1
|
|
fmul st, st(2) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a11
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a12
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a13
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+12] // uop: 0/0/1/1
|
|
|
|
// **** vout.y= (a21*vin.x + a22*vin.y + a23*vin.z + a24);
|
|
fld [eax]CMatrix3x4.a21
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a22
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a23
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a21
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a22
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a23
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+16]
|
|
|
|
// **** vout.z= (a31*vin.x + a32*vin.y + a33*vin.z + a34);
|
|
fld [eax]CMatrix3x4.a31
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a32
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a33
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a31
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a32
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a33
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+20]
|
|
|
|
// free x y z
|
|
fstp st
|
|
fstp st
|
|
fstp st
|
|
|
|
|
|
// UV copy.
|
|
// **** *(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->UV;
|
|
mov eax, [esi]src.UV.U // uop: 0/1
|
|
mov dword ptr[edi+24], eax // uop: 0/0/1/1
|
|
mov eax, [esi]src.UV.V // uop: 0/1
|
|
mov dword ptr[edi+28], eax // uop: 0/0/1/1
|
|
|
|
|
|
// **** next
|
|
add esi, 48 // uop: 1/0
|
|
add edi, NL3D_RAWSKIN_VERTEX_SIZE // uop: 1/0
|
|
dec ecx // uop: 1/0
|
|
jnz theLoop // uop: 1/1 (p1)
|
|
|
|
mov nBlockInf, ecx
|
|
mov src, esi
|
|
mov destVertexPtr, edi
|
|
}
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CMeshMRMSkinnedGeom::applyArrayRawSkinNormal3(CRawVertexNormalSkinned3 *src, uint8 *destVertexPtr,
|
|
CMatrix3x4 *boneMat3x4, uint nInf)
|
|
{
|
|
// must write contigously in AGP, and ASM is hardcoded...
|
|
nlctassert(NL3D_RAWSKIN_NORMAL_OFF==12);
|
|
nlctassert(NL3D_RAWSKIN_UV_OFF==24);
|
|
|
|
/*extern uint TESTYOYO_NumRawSkinVertices3;
|
|
TESTYOYO_NumRawSkinVertices3+= nInf;
|
|
H_AUTO( TestYoyo_RawSkin3 );*/
|
|
|
|
// Since VertexPtr may be a AGP Ram, MUST NOT read into it! (mulAdd*() do it!)
|
|
CVector tmpVert;
|
|
|
|
#ifdef NL3D_RAWSKIN_PRECACHE
|
|
for(;nInf>0;)
|
|
{
|
|
// number of vertices to process for this block.
|
|
uint nBlockInf= min(NumCacheVertexNormal3, nInf);
|
|
// next block.
|
|
nInf-= nBlockInf;
|
|
|
|
// cache the data in L1 cache.
|
|
CFastMem::precache(src, nBlockInf * sizeof(CRawVertexNormalSkinned3));
|
|
#else
|
|
{
|
|
uint nBlockInf= nInf;
|
|
#endif
|
|
|
|
|
|
#ifndef NL3D_RAWSKIN_ASM
|
|
// for all InfluencedVertices only.
|
|
for(;nBlockInf>0;nBlockInf--, src++, destVertexPtr+=NL3D_RAWSKIN_VERTEX_SIZE)
|
|
{
|
|
// Vertex.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetPoint( src->Vertex, src->Weights[0], tmpVert);
|
|
boneMat3x4[ src->MatrixId[1] ].mulAddPoint( src->Vertex, src->Weights[1], tmpVert);
|
|
boneMat3x4[ src->MatrixId[2] ].mulAddPoint( src->Vertex, src->Weights[2], tmpVert);
|
|
*(CVector*)(destVertexPtr)= tmpVert;
|
|
// Normal.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Normal, src->Weights[0], tmpVert);
|
|
boneMat3x4[ src->MatrixId[1] ].mulAddVector( src->Normal, src->Weights[1], tmpVert);
|
|
boneMat3x4[ src->MatrixId[2] ].mulAddVector( src->Normal, src->Weights[2], tmpVert);
|
|
*(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF)= tmpVert;
|
|
// UV copy.
|
|
*(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->UV;
|
|
}
|
|
#else
|
|
// ASM hard coded for 56
|
|
nlctassert(sizeof(CRawVertexNormalSkinned3)==56);
|
|
|
|
|
|
/* 226 cycles / loop typical
|
|
192 cycles / loop in theory (no memory problem)
|
|
148 optimal
|
|
*/
|
|
__asm
|
|
{
|
|
mov ecx, nBlockInf
|
|
mov esi, src
|
|
mov edi, destVertexPtr
|
|
theLoop:
|
|
// Vertex.
|
|
// **** boneMat3x4[ src->MatrixId[0] ].mulSetPoint( src->Vertex, *(CVector*)(destVertexPtr) );
|
|
|
|
// eax= matrix0
|
|
mov eax, [esi+0]src.MatrixId // uop: 0/1
|
|
lea eax, [eax*2+eax]
|
|
shl eax, 4
|
|
add eax, boneMat3x4 // uop: 1/0
|
|
// ebx= matrix1
|
|
mov ebx, [esi+4]src.MatrixId // uop: 0/1
|
|
lea ebx, [ebx*2+ebx]
|
|
shl ebx, 4
|
|
add ebx, boneMat3x4 // uop: 1/0
|
|
// edx= matrix2
|
|
mov edx, [esi+8]src.MatrixId // uop: 0/1
|
|
lea edx, [edx*2+edx]
|
|
shl edx, 4
|
|
add edx, boneMat3x4 // uop: 1/0
|
|
|
|
// load x y z
|
|
fld [esi]src.Vertex.x // uop: 0/1
|
|
fld [esi]src.Vertex.y // uop: 0/1
|
|
fld [esi]src.Vertex.z // uop: 0/1
|
|
|
|
// **** vout.x= (a11*vin.x + a12*vin.y + a13*vin.z + a14);
|
|
// 1st Matrix
|
|
fld [eax]CMatrix3x4.a11 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
fld [eax]CMatrix3x4.a12 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a13 // uop: 0/1
|
|
fmul st, st(2) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a14 // uop: 0/1
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a11
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a12
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a13
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a14
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// 3rd matrix
|
|
fld [edx]CMatrix3x4.a11
|
|
fmul st, st(4)
|
|
fld [edx]CMatrix3x4.a12
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a13
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a14
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+8]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi] // uop: 0/0/1/1
|
|
|
|
// **** vout.y= (a21*vin.x + a22*vin.y + a23*vin.z + a24);
|
|
fld [eax]CMatrix3x4.a21
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a22
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a23
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a24
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a21
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a22
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a23
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a24
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// 3rd matrix
|
|
fld [edx]CMatrix3x4.a21
|
|
fmul st, st(4)
|
|
fld [edx]CMatrix3x4.a22
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a23
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a24
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+8]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+4]
|
|
|
|
// **** vout.z= (a31*vin.x + a32*vin.y + a33*vin.z + a34);
|
|
fld [eax]CMatrix3x4.a31
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a32
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a33
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a34
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a31
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a32
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a33
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a34
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// 3rd matrix
|
|
fld [edx]CMatrix3x4.a31
|
|
fmul st, st(4)
|
|
fld [edx]CMatrix3x4.a32
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a33
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a34
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+8]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+8]
|
|
|
|
// free x y z
|
|
fstp st // uop: 1/0
|
|
fstp st // uop: 1/0
|
|
fstp st // uop: 1/0
|
|
|
|
|
|
// Normal
|
|
// **** boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) );
|
|
|
|
// load x y z
|
|
fld [esi]src.Normal.x
|
|
fld [esi]src.Normal.y
|
|
fld [esi]src.Normal.z
|
|
// **** vout.x= (a11*vin.x + a12*vin.y + a13*vin.z + a14);
|
|
fld [eax]CMatrix3x4.a11 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
fld [eax]CMatrix3x4.a12 // uop: 0/1
|
|
fmul st, st(3) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
fld [eax]CMatrix3x4.a13 // uop: 0/1
|
|
fmul st, st(2) // uop: 1/0 (5)
|
|
faddp st(1), st // uop: 1/0 (3)
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a11
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a12
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a13
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// 3rd matrix
|
|
fld [edx]CMatrix3x4.a11
|
|
fmul st, st(4)
|
|
fld [edx]CMatrix3x4.a12
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a13
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+8]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+12] // uop: 0/0/1/1
|
|
|
|
// **** vout.y= (a21*vin.x + a22*vin.y + a23*vin.z + a24);
|
|
fld [eax]CMatrix3x4.a21
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a22
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a23
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a21
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a22
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a23
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// 3rd matrix
|
|
fld [edx]CMatrix3x4.a21
|
|
fmul st, st(4)
|
|
fld [edx]CMatrix3x4.a22
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a23
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+8]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+16]
|
|
|
|
// **** vout.z= (a31*vin.x + a32*vin.y + a33*vin.z + a34);
|
|
fld [eax]CMatrix3x4.a31
|
|
fmul st, st(3)
|
|
fld [eax]CMatrix3x4.a32
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
fld [eax]CMatrix3x4.a33
|
|
fmul st, st(2)
|
|
faddp st(1), st
|
|
// mul by scale
|
|
fmul [esi+0]src.Weights
|
|
|
|
// 2nd matrix
|
|
fld [ebx]CMatrix3x4.a31
|
|
fmul st, st(4)
|
|
fld [ebx]CMatrix3x4.a32
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [ebx]CMatrix3x4.a33
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+4]src.Weights
|
|
faddp st(1), st
|
|
|
|
// 3rd matrix
|
|
fld [edx]CMatrix3x4.a31
|
|
fmul st, st(4)
|
|
fld [edx]CMatrix3x4.a32
|
|
fmul st, st(4)
|
|
faddp st(1), st
|
|
fld [edx]CMatrix3x4.a33
|
|
fmul st, st(3)
|
|
faddp st(1), st
|
|
// mul by scale, and append
|
|
fmul [esi+8]src.Weights
|
|
faddp st(1), st
|
|
|
|
// store
|
|
fstp dword ptr[edi+20]
|
|
|
|
// free x y z
|
|
fstp st
|
|
fstp st
|
|
fstp st
|
|
|
|
|
|
// UV copy.
|
|
// **** *(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->UV;
|
|
mov eax, [esi]src.UV.U // uop: 0/1
|
|
mov dword ptr[edi+24], eax // uop: 0/0/1/1
|
|
mov eax, [esi]src.UV.V // uop: 0/1
|
|
mov dword ptr[edi+28], eax // uop: 0/0/1/1
|
|
|
|
|
|
// **** next
|
|
add esi, 56 // uop: 1/0
|
|
add edi, NL3D_RAWSKIN_VERTEX_SIZE // uop: 1/0
|
|
dec ecx // uop: 1/0
|
|
jnz theLoop // uop: 1/1 (p1)
|
|
|
|
mov nBlockInf, ecx
|
|
mov src, esi
|
|
mov destVertexPtr, edi
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
// ***************************************************************************
|
|
void CMeshMRMSkinnedGeom::applyArrayRawSkinNormal4(CRawVertexNormalSkinned4 *src, uint8 *destVertexPtr,
|
|
CMatrix3x4 *boneMat3x4, uint nInf)
|
|
{
|
|
// must write contigously in AGP, and ASM is hardcoded...
|
|
nlctassert(NL3D_RAWSKIN_NORMAL_OFF==12);
|
|
nlctassert(NL3D_RAWSKIN_UV_OFF==24);
|
|
|
|
/*extern uint TESTYOYO_NumRawSkinVertices4;
|
|
TESTYOYO_NumRawSkinVertices4+= nInf;
|
|
H_AUTO( TestYoyo_RawSkin4 );*/
|
|
|
|
// Since VertexPtr may be a AGP Ram, MUST NOT read into it! (mulAdd*() do it!)
|
|
CVector tmpVert;
|
|
|
|
#ifdef NL3D_RAWSKIN_PRECACHE
|
|
for(;nInf>0;)
|
|
{
|
|
// number of vertices to process for this block.
|
|
uint nBlockInf= min(NumCacheVertexNormal4, nInf);
|
|
// next block.
|
|
nInf-= nBlockInf;
|
|
|
|
// cache the data in L1 cache.
|
|
CFastMem::precache(src, nBlockInf * sizeof(CRawVertexNormalSkinned4));
|
|
#else
|
|
{
|
|
uint nBlockInf= nInf;
|
|
#endif
|
|
|
|
// for all InfluencedVertices only.
|
|
for(;nBlockInf>0;nBlockInf--, src++, destVertexPtr+=NL3D_RAWSKIN_VERTEX_SIZE)
|
|
{
|
|
// Vertex.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetPoint( src->Vertex, src->Weights[0], tmpVert);
|
|
boneMat3x4[ src->MatrixId[1] ].mulAddPoint( src->Vertex, src->Weights[1], tmpVert);
|
|
boneMat3x4[ src->MatrixId[2] ].mulAddPoint( src->Vertex, src->Weights[2], tmpVert);
|
|
boneMat3x4[ src->MatrixId[3] ].mulAddPoint( src->Vertex, src->Weights[3], tmpVert);
|
|
*(CVector*)(destVertexPtr)= tmpVert;
|
|
// Normal.
|
|
boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Normal, src->Weights[0], tmpVert);
|
|
boneMat3x4[ src->MatrixId[1] ].mulAddVector( src->Normal, src->Weights[1], tmpVert);
|
|
boneMat3x4[ src->MatrixId[2] ].mulAddVector( src->Normal, src->Weights[2], tmpVert);
|
|
boneMat3x4[ src->MatrixId[3] ].mulAddVector( src->Normal, src->Weights[3], tmpVert);
|
|
*(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF)= tmpVert;
|
|
// UV copy.
|
|
*(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->UV;
|
|
}
|
|
|
|
// NB: ASM not done for 4 vertices, cause very rare and negligeable ...
|
|
}
|
|
}
|
|
|
|
|
|
// ***************************************************************************
|
|
void CMeshMRMSkinnedGeom::applyRawSkinWithNormal(CLod &lod, CRawSkinnedNormalCache &rawSkinLod, const CSkeletonModel *skeleton, uint8 *vbHard, float alphaLod)
|
|
{
|
|
// Some assert
|
|
//===========================
|
|
|
|
// assert, code below is written especially for 4 per vertex.
|
|
nlassert( NL3D_MESH_MRM_SKINNED_MAX_MATRIX==4 );
|
|
|
|
|
|
// Compute useful Matrix for this lod.
|
|
//===========================
|
|
// Those arrays map the array of bones in skeleton.
|
|
static vector<CMatrix3x4> boneMat3x4;
|
|
computeBoneMatrixes3x4(boneMat3x4, lod.MatrixInfluences, skeleton);
|
|
|
|
|
|
// TestYoyo
|
|
/*extern uint TESTYOYO_NumRawSkinVertices;
|
|
TESTYOYO_NumRawSkinVertices+= rawSkinLod.Vertices1.size();
|
|
TESTYOYO_NumRawSkinVertices+= rawSkinLod.Vertices2.size();
|
|
TESTYOYO_NumRawSkinVertices+= rawSkinLod.Vertices3.size();
|
|
TESTYOYO_NumRawSkinVertices+= rawSkinLod.Vertices4.size();*/
|
|
|
|
|
|
uint nInf;
|
|
|
|
// Manage "SoftVertices"
|
|
if(rawSkinLod.TotalSoftVertices)
|
|
{
|
|
// apply skinning into Temp RAM for vertices that are Src of Geomorph
|
|
//===========================
|
|
static vector<uint8> tempSkin;
|
|
uint tempVbSize= rawSkinLod.TotalSoftVertices*NL3D_RAWSKIN_VERTEX_SIZE;
|
|
if(tempSkin.size() < tempVbSize)
|
|
tempSkin.resize(tempVbSize);
|
|
uint8 *destVertexPtr= &tempSkin[0];
|
|
|
|
// 1 Matrix
|
|
nInf= rawSkinLod.SoftVertices[0];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal1(&rawSkinLod.Vertices1[0], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
// 2 Matrix
|
|
nInf= rawSkinLod.SoftVertices[1];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal2(&rawSkinLod.Vertices2[0], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
// 3 Matrix
|
|
nInf= rawSkinLod.SoftVertices[2];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal3(&rawSkinLod.Vertices3[0], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
// 4 Matrix
|
|
nInf= rawSkinLod.SoftVertices[3];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal4(&rawSkinLod.Vertices4[0], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
|
|
// Fast Copy this into AGP Ram. NB: done before Geomorphs, because ensure some precaching this way!!
|
|
//===========================
|
|
// Skin geomorphs.
|
|
uint8 *vbHardStart= vbHard + rawSkinLod.Geomorphs.size()*NL3D_RAWSKIN_VERTEX_SIZE;
|
|
|
|
// fast copy
|
|
CFastMem::memcpy(vbHardStart, &tempSkin[0], tempVbSize);
|
|
|
|
// Geomorphs directly into AGP Ram
|
|
//===========================
|
|
clamp(alphaLod, 0.f, 1.f);
|
|
float a= alphaLod;
|
|
float a1= 1 - alphaLod;
|
|
|
|
// Fast Geomorph
|
|
applyGeomorphPosNormalUV0(rawSkinLod.Geomorphs, &tempSkin[0], vbHard, NL3D_RAWSKIN_VERTEX_SIZE, a, a1);
|
|
}
|
|
|
|
// Manage HardVertices
|
|
if(rawSkinLod.TotalHardVertices)
|
|
{
|
|
// apply skinning directly into AGP RAM for vertices that are not Src of Geomorph
|
|
//===========================
|
|
uint startId;
|
|
|
|
// Skip Geomorphs and SoftVertices.
|
|
uint8 *destVertexPtr= vbHard + (rawSkinLod.Geomorphs.size()+rawSkinLod.TotalSoftVertices)*NL3D_RAWSKIN_VERTEX_SIZE;
|
|
|
|
// 1 Matrix
|
|
nInf= rawSkinLod.HardVertices[0];
|
|
startId= rawSkinLod.SoftVertices[0];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal1(&rawSkinLod.Vertices1[startId], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
// 2 Matrix
|
|
nInf= rawSkinLod.HardVertices[1];
|
|
startId= rawSkinLod.SoftVertices[1];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal2(&rawSkinLod.Vertices2[startId], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
// 3 Matrix
|
|
nInf= rawSkinLod.HardVertices[2];
|
|
startId= rawSkinLod.SoftVertices[2];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal3(&rawSkinLod.Vertices3[startId], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
// 4 Matrix
|
|
nInf= rawSkinLod.HardVertices[3];
|
|
startId= rawSkinLod.SoftVertices[3];
|
|
if(nInf>0)
|
|
{
|
|
applyArrayRawSkinNormal4(&rawSkinLod.Vertices4[startId], destVertexPtr, &boneMat3x4[0], nInf);
|
|
destVertexPtr+= nInf * NL3D_RAWSKIN_VERTEX_SIZE;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif // ADD_MESH_MRM_SKINNED_TEMPLATE
|