UpdateAdditionalStreamContent
From Multi Theft Auto: Wiki
This C++ Function is found inside of CAdditionalVertexStreamManager.
It updates additional stream content.
It can be found in Client/Client Core/Sources/CAdditionalVertexStreamManager.cpp in Visual Studio.
Contents
Required Arguments
- state: To be defined.
- pAdditionalInfo: To be defined.
- ReadOffsetStart: To be defined.
- ReadSize: To be defined.
- WriteOffsetStart: To be defined.
- WriteSize: To be defined.
Returns
Returns a boolean whether additional stream content was updated or not.
Code
bool CAdditionalVertexStreamManager::UpdateAdditionalStreamContent ( SCurrentStateInfo& state, SAdditionalStreamInfo* pAdditionalInfo, uint ReadOffsetStart, uint ReadSize, uint WriteOffsetStart, uint WriteSize ) { //HRESULT hr; IDirect3DVertexBuffer9* pStreamDataPT = state.stream1.pStreamData; IDirect3DVertexBuffer9* pStreamDataN = pAdditionalInfo->pStreamData; uint StridePT = 20; uint StrideN = 12; uint NumVerts = ReadSize / StridePT; assert ( NumVerts == WriteSize / StrideN ); // Get the source vertex bytes std::vector < uchar > sourceArray; sourceArray.resize ( ReadSize ); uchar* pSourceArrayBytes = &sourceArray[0]; { void* pVertexBytesPT = NULL; if ( FAILED( pStreamDataPT->Lock ( ReadOffsetStart, ReadSize, &pVertexBytesPT, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY ) ) ) return false; memcpy ( pSourceArrayBytes, pVertexBytesPT, ReadSize ); pStreamDataPT->Unlock (); } // Create dest byte buffer std::vector < uchar > destArray; destArray.resize ( WriteSize ); uchar* pDestArrayBytes = &destArray[0]; // Compute dest bytes { // Get index buffer if ( FAILED( m_pDevice->GetIndices( &state.pIndexData ) ) ) return false; // Get index buffer desc D3DINDEXBUFFER_DESC IndexBufferDesc; state.pIndexData->GetDesc ( &IndexBufferDesc ); uint numIndices = state.args.primCount + 2; uint step = 1; if ( state.args.PrimitiveType == D3DPT_TRIANGLELIST ) { numIndices = state.args.primCount * 3; step = 3; } assert ( IndexBufferDesc.Size >= ( numIndices + state.args.startIndex ) * 2 ); // Get index buffer data std::vector < uchar > indexArray; indexArray.resize ( ReadSize ); uchar* pIndexArrayBytes = &indexArray[0]; { void* pIndexBytes = NULL; if ( FAILED( state.pIndexData->Lock ( state.args.startIndex*2, numIndices*2, &pIndexBytes, D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY ) ) ) return false; memcpy ( pIndexArrayBytes, pIndexBytes, numIndices*2 ); state.pIndexData->Unlock (); } // Calc normals std::vector < CVector > NormalList; NormalList.insert ( NormalList.end (), NumVerts, CVector () ); std::map < long long, CVector > doneTrisMap; // For each triangle for ( uint i = 0 ; i < numIndices - 2 ; i += step ) { // Get triangle vertex indici WORD v0 = ((WORD*)pIndexArrayBytes)[ i ]; WORD v1 = ((WORD*)pIndexArrayBytes)[ i + 1 ]; WORD v2 = ((WORD*)pIndexArrayBytes)[ i + 2 ]; if ( v0 >= NumVerts || v1 >= NumVerts || v2 >= NumVerts ) continue; // vert index out of range if ( v0 == v1 || v0 == v2 || v1 == v2 ) continue; // degenerate tri // Get vertex positions from original stream CVector* pPos0 = (CVector*)( pSourceArrayBytes + v0 * 20 ); CVector* pPos1 = (CVector*)( pSourceArrayBytes + v1 * 20 ); CVector* pPos2 = (CVector*)( pSourceArrayBytes + v2 * 20 ); // Calculate the normal CVector Dir1 = *pPos2 - *pPos1; CVector Dir2 = *pPos0 - *pPos1; CVector Normal = Dir1; Normal.CrossProduct ( &Dir2 ); Normal.Normalize (); // Flip normal if triangle was flipped if ( state.args.PrimitiveType == D3DPT_TRIANGLESTRIP && ( i & 1 ) ) Normal = -Normal; // Try to improve results by ignoring duplicated triangles long long key = getTriKey ( v0, v1, v2 ); if ( CVector* pDoneTriPrevNormal = MapFind ( doneTrisMap, key ) ) { // Already done this tri - Keep prev tri if it has a better 'up' rating if ( pDoneTriPrevNormal->fZ > Normal.fZ ) continue; // Remove effect of prev tri NormalList[ v0 ] -= *pDoneTriPrevNormal; NormalList[ v1 ] -= *pDoneTriPrevNormal; NormalList[ v2 ] -= *pDoneTriPrevNormal; } MapSet ( doneTrisMap, key, Normal ); // Add normal weight to used vertices NormalList[ v0 ] += Normal; NormalList[ v1 ] += Normal; NormalList[ v2 ] += Normal; } // Validate normals and set dest data for ( uint i = 0 ; i < NumVerts ; i++ ) { // Validate CVector& Normal = NormalList[i]; if ( Normal.Normalize () < FLOAT_EPSILON ) Normal = CVector ( 0, 0, 1 ); // Set CVector* pNormal = (CVector*)( pDestArrayBytes + i * 12 ); *pNormal = Normal; } } // Set the dest bytes { void* pVertexBytesN = NULL; if ( FAILED( pStreamDataN->Lock ( WriteOffsetStart, WriteSize, &pVertexBytesN, D3DLOCK_NOSYSLOCK ) ) ) return false; memcpy ( pVertexBytesN, pDestArrayBytes, WriteSize ); pStreamDataN->Unlock (); } return true; }