// *************************************************************** bool CDisplayerVisual::getDisplayFlag(TDisplayFlags flag) const { //H_AUTO(R2_CDisplayerVisual_getDisplayFlag) nlctassert(FlagCount <= 32); nlassert((uint) flag < FlagCount); return (_DisplayFlags & (1 << flag)) != 0; }
// *************************************************************** void CDisplayerVisual::setDisplayFlag(TDisplayFlags flag, bool on) { //H_AUTO(R2_CDisplayerVisual_setDisplayFlag) nlctassert(FlagCount <= 32); nlassert((uint) flag < FlagCount); setFlags(_DisplayFlags, 1 << flag, on); }
void CTuneMrmDlg::applySlider(UINT sliderCur, UINT sliderMax) { nlctassert(NL_TMD_SLIDER_SIZE*NL_TMD_SLIDER_MAX_STEP*NL_TMD_SLIDER_STEP_SIZE < ((uint)1<<31)); // compute actual max polygon uint actualValue= sliderCur*sliderMax*NL_TMD_SLIDER_STEP_SIZE / NL_TMD_SLIDER_SIZE; if(_Scene) { _Scene->setGroupLoadMaxPolygon("Skin", actualValue); } // refresh text views ViewCurrentMaxPoly= NLMISC::toString(actualValue).c_str(); ViewMaxValue= NLMISC::toString(sliderMax*NL_TMD_SLIDER_STEP_SIZE).c_str(); UpdateData(FALSE); }
//******************************************************************************* void CWaterEnvMap::initFlattenVB() { _FlattenVB.setPreferredMemory(CVertexBuffer::AGPPreferred, true); _FlattenVB.setName("Flatten VB"); _FlattenVB.clearValueEx(); _FlattenVB.addValueEx (CVertexBuffer::Position, CVertexBuffer::Float3); _FlattenVB.addValueEx (CVertexBuffer::TexCoord0, CVertexBuffer::Float3); _FlattenVB.initEx(); nlctassert(FVB_NUM_SIDES % 4 == 0); // number of sides must be a multiple of 4 so that sections sides will align with corners _FlattenVB.setNumVertices(FVB_NUM_VERTS); _FlattenIB.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); _FlattenIB.setNumIndexes(3 * FVB_NUM_TRIS); { CVertexBufferReadWrite vbrw; CIndexBufferReadWrite ibrw; _FlattenVB.lock(vbrw); _FlattenIB.lock(ibrw); for(uint l = 0; l < FVB_NUM_SIDES; ++l) { double angle = NLMISC::Pi * 0.25 + 2 * NLMISC::Pi * (double) l / (double) FVB_NUM_SIDES; for(uint k = 0; k < FVB_NUM_SECTIONS + 1; ++k) { double radius = (double) k / (double) (FVB_NUM_SECTIONS - 1); float x = (float) (radius * cos(angle)); float y = (float) (radius * sin(angle)); if (k < FVB_NUM_SECTIONS) { ibrw.setTri(3 * 2 * (k + (l * FVB_NUM_SECTIONS)), getFVBVertex(k, l), getFVBVertex(k + 1, l + 1), getFVBVertex(k + 1, l)); ibrw.setTri(3 * (2 * (k + (l * FVB_NUM_SECTIONS)) + 1), getFVBVertex(k, l), getFVBVertex(k, l + 1), getFVBVertex(k + 1, l + 1)); } else { uint side = l / (FVB_NUM_SIDES / 4); switch(side) { case 0: // top x /= y; y = 1.f; break; case 1: // left y /= -x; x = -1.f; break; case 2: // bottom x /= -y; y = -1.f; break; case 3: // right y /= x; x = 1.f; break; default: nlassert(0); break; } } CVector dir; //dir.sphericToCartesian(1.f, (float) angle, (float) (NLMISC::Pi * 0.5 * acos(std::max(0.f, (1.f - (float) k / (FVB_NUM_SECTIONS - 1)))))); dir.sphericToCartesian(1.f, (float) angle, (float) acos(std::min(1.f, (float) k / (FVB_NUM_SECTIONS - 1)))); vbrw.setValueFloat3Ex(CVertexBuffer::Position, getFVBVertex(k, l), x, 0.5f, y); vbrw.setValueFloat3Ex(CVertexBuffer::TexCoord0, getFVBVertex(k, l), -dir.x, dir.z, -dir.y); } } } }
// *************************************************************************** void CMeshMRMGeom::applyArrayRawSkinNormal1(CRawVertexNormalSkin1 *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(CRawVertexNormalSkin1)); #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.Pos, *(CVector*)(destVertexPtr) ); // Normal. boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Vertex.Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) ); // UV copy. *(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->Vertex.UV; } #else // ASM harcoded for 36 nlctassert(sizeof(CRawVertexNormalSkin1)==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.Pos, *(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.Pos.x // uop: 0/1 fld [esi]src.Vertex.Pos.y // uop: 0/1 fld [esi]src.Vertex.Pos.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->Vertex.Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) ); // load x y z fld [esi]src.Vertex.Normal.x fld [esi]src.Vertex.Normal.y fld [esi]src.Vertex.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->Vertex.UV; mov eax, [esi]src.Vertex.UV.U // uop: 0/1 mov dword ptr[edi+24], eax // uop: 0/0/1/1 mov eax, [esi]src.Vertex.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 CMeshMRMGeom::applyArrayRawSkinNormal2(CRawVertexNormalSkin2 *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(CRawVertexNormalSkin2)); #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.Pos, src->Weights[0], tmpVert); boneMat3x4[ src->MatrixId[1] ].mulAddPoint( src->Vertex.Pos, src->Weights[1], tmpVert); *(CVector*)(destVertexPtr)= tmpVert; // Normal. boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Vertex.Normal, src->Weights[0], tmpVert); boneMat3x4[ src->MatrixId[1] ].mulAddVector( src->Vertex.Normal, src->Weights[1], tmpVert); *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF)= tmpVert; // UV copy. *(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->Vertex.UV; } #else // ASM harcoded for 48 nlctassert(sizeof(CRawVertexNormalSkin2)==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.Pos, *(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.Pos.x // uop: 0/1 fld [esi]src.Vertex.Pos.y // uop: 0/1 fld [esi]src.Vertex.Pos.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->Vertex.Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) ); // load x y z fld [esi]src.Vertex.Normal.x fld [esi]src.Vertex.Normal.y fld [esi]src.Vertex.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->Vertex.UV; mov eax, [esi]src.Vertex.UV.U // uop: 0/1 mov dword ptr[edi+24], eax // uop: 0/0/1/1 mov eax, [esi]src.Vertex.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 CMeshMRMGeom::applyArrayRawSkinNormal3(CRawVertexNormalSkin3 *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(CRawVertexNormalSkin3)); #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.Pos, src->Weights[0], tmpVert); boneMat3x4[ src->MatrixId[1] ].mulAddPoint( src->Vertex.Pos, src->Weights[1], tmpVert); boneMat3x4[ src->MatrixId[2] ].mulAddPoint( src->Vertex.Pos, src->Weights[2], tmpVert); *(CVector*)(destVertexPtr)= tmpVert; // Normal. boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Vertex.Normal, src->Weights[0], tmpVert); boneMat3x4[ src->MatrixId[1] ].mulAddVector( src->Vertex.Normal, src->Weights[1], tmpVert); boneMat3x4[ src->MatrixId[2] ].mulAddVector( src->Vertex.Normal, src->Weights[2], tmpVert); *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF)= tmpVert; // UV copy. *(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->Vertex.UV; } #else // ASM harcoded for 56 nlctassert(sizeof(CRawVertexNormalSkin3)==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.Pos, *(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.Pos.x // uop: 0/1 fld [esi]src.Vertex.Pos.y // uop: 0/1 fld [esi]src.Vertex.Pos.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->Vertex.Normal, *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF) ); // load x y z fld [esi]src.Vertex.Normal.x fld [esi]src.Vertex.Normal.y fld [esi]src.Vertex.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->Vertex.UV; mov eax, [esi]src.Vertex.UV.U // uop: 0/1 mov dword ptr[edi+24], eax // uop: 0/0/1/1 mov eax, [esi]src.Vertex.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 CMeshMRMGeom::applyArrayRawSkinNormal4(CRawVertexNormalSkin4 *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(CRawVertexNormalSkin4)); #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.Pos, src->Weights[0], tmpVert); boneMat3x4[ src->MatrixId[1] ].mulAddPoint( src->Vertex.Pos, src->Weights[1], tmpVert); boneMat3x4[ src->MatrixId[2] ].mulAddPoint( src->Vertex.Pos, src->Weights[2], tmpVert); boneMat3x4[ src->MatrixId[3] ].mulAddPoint( src->Vertex.Pos, src->Weights[3], tmpVert); *(CVector*)(destVertexPtr)= tmpVert; // Normal. boneMat3x4[ src->MatrixId[0] ].mulSetVector( src->Vertex.Normal, src->Weights[0], tmpVert); boneMat3x4[ src->MatrixId[1] ].mulAddVector( src->Vertex.Normal, src->Weights[1], tmpVert); boneMat3x4[ src->MatrixId[2] ].mulAddVector( src->Vertex.Normal, src->Weights[2], tmpVert); boneMat3x4[ src->MatrixId[3] ].mulAddVector( src->Vertex.Normal, src->Weights[3], tmpVert); *(CVector*)(destVertexPtr + NL3D_RAWSKIN_NORMAL_OFF)= tmpVert; // UV copy. *(CUV*)(destVertexPtr + NL3D_RAWSKIN_UV_OFF)= src->Vertex.UV; } // NB: ASM not done for 4 vertices, cause very rare and negligeable ... } } // *************************************************************************** void CMeshMRMGeom::applyRawSkinWithNormal(CLod &lod, CRawSkinNormalCache &rawSkinLod, const CSkeletonModel *skeleton, uint8 *vbHard, float alphaLod) { nlassert(_Skinned); if(_SkinWeights.size()==0) return; // Some assert //=========================== // must have XYZ, Normal and UV only nlassert( _VBufferFinal.getVertexFormat() == (CVertexBuffer::PositionFlag | CVertexBuffer::NormalFlag | CVertexBuffer::TexCoord0Flag) ); nlassert( _VBufferFinal.getValueType(CVertexBuffer::TexCoord0) == CVertexBuffer::Float2 ); nlassert( _VBufferFinal.getVertexSize() ==NL3D_RAWSKIN_VERTEX_SIZE); // HardCoded for normalOff==12 (see applyArrayRawSkinNormal*) nlassert( _VBufferFinal.getNormalOff()==NL3D_RAWSKIN_NORMAL_OFF ); nlassert( _VBufferFinal.getTexCoordOff()==NL3D_RAWSKIN_UV_OFF ); // assert, code below is written especially for 4 per vertex. nlassert( NL3D_MESH_SKINNING_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; } } }
// Remplit les différents informations concernant le craft par un item void FillCraftData( char craft, int eco, int level, bool creature, int bestStat, int worstStat1, int worstStat2, CSString& outStr ) { CSString data; char buf[10]; int index; static CSString carac[] = { "Durability", "Weight", "SapLoad", "DMG", "Speed", "Range", "DodgeModifier", "ParryModifier", "AdversaryDodgeModifier", "AdversaryParryModifier", "ProtectionFactor", "MaxSlashingProtection", "MaxBluntProtection", "MaxPiercingProtection", "ElementalCastingTimeFactor", "ElementalPowerFactor", "OffensiveAfflictionCastingTimeFactor", "OffensiveAfflictionPowerFactor", "HealCastingTimeFactor", "HealPowerFactor", "DefensiveAfflictionCastingTimeFactor", "DefensiveAfflictionPowerFactor", "AcidProtection", "ColdProtection", "FireProtection", "RotProtection", "ShockWaveProtection", "PoisonProtection", "ElectricityProtection", "DesertResistance", "ForestResistance", "LacustreResistance", "JungleResistance", "PrimaryRootResistance", }; nlctassert((sizeof(carac)/sizeof(carac[0]))==NumMPStats); static int mediumStatsByStatQuality[] = { 20, 35, 50, 65, 80 }; int stat, remaining, nbToRaise, ajout; int stats[NumMPStats]; index = craft - 'A'; outStr = " <STRUCT Name=\""; outStr += craftParts[index].Desc; outStr += "\">\n"; nbToRaise = 0; remaining = 0; ajout = 0; currentDocItem.push( DtCraftSlotName, craftParts[index].Desc.splitFrom( "(" ).splitTo( ")" ) ); // enregistrements des stats de chaque // caractèristique for ( int i=0; i<NumMPStats; i++ ) { if ( craftParts[index].Carac[i] ) { if ( !creature ) stat = mediumStatsByStatQuality[ level-1 ]; else stat = mediumStatsByStatQuality[ level ]; // gestion des points forts/faibles de la MP if ( i == bestStat ) { if ( worstStat2 == -1 ) stat += 20; else stat += 40; if ( stat > 100 ) { // si une des stats dépasse 100, les autres // stats sont augmentées remaining = stat - 100; stat = 100; } } else if ( ( i == worstStat1 ) || ( i == worstStat2 ) ) { stat -= 20; // durabilité minimum if ( ( i == 0 ) && ( stat < 1 ) ) stat = 1; } else nbToRaise++; stats[i] = stat; } else stats[i] = -1; } if ( nbToRaise != 0 ) ajout = remaining/nbToRaise; // ajout des informations pour chaque carac for ( int i=0; i<NumMPStats; i++ ) { if ( stats[i] != -1 ) { if ( ( i != bestStat ) && ( i != worstStat1 ) && ( i != worstStat2 ) ) stats[i] += ajout; outStr += " <ATOM Name=\""; outStr += carac[i]; outStr += "\" Value=\""; sprintf( buf, "%d", stats[i] ); outStr += buf; outStr += "\"/>\n"; } } // CraftCivSpec en fonction de l'écosystème outStr += " <ATOM Name=\"CraftCivSpec\" Value=\""; CSString craftCiv; switch ( eco ) { case 'c' : outStr += "common"; craftCiv = "All"; break; case 'd' : outStr += "fyros"; craftCiv = "Fyros"; break; case 'f' : outStr += "matis"; craftCiv = "Matis"; break; case 'j' : outStr += "zorai"; craftCiv = "Zorai"; break; case 'l' : outStr += "tryker"; craftCiv = "Tryker"; break; case 'p' : outStr += "common"; craftCiv = "All"; break; } currentDocItem.push( DtCraftCivSpec, craftCiv ); outStr += "\"/>\n </STRUCT>\n"; }