void mCFileStream::Buffer( MIUInt a_uPosition ) { // Padding: Room for reading before a_uPosition or writing over end of file. enum { EPadding = mEFileBufferSize / 3 }; Flush(); MIBool const bCanRead = ( m_enuOpenMode & mEFileOpenMode_Read ? MITrue : MIFalse ); MIBool const bCanWrite = ( m_enuOpenMode & mEFileOpenMode_Write ? MITrue : MIFalse ); MIUInt const uReadPadding = bCanRead ? EPadding : 0 ; MIUInt const uWritePadding = bCanRead ? ( bCanWrite ? EPadding : 0 ) : mEFileBufferSize; MIUInt const uMinBufferSize = g_min( ( mEFileBufferSize - uWritePadding ), GetSize() ); MIUInt const uMaxBufferedPosition = GetSize() - uMinBufferSize; MIUInt const uOldBufferedPosition = m_uBufferedPosition; if ( a_uPosition <= uReadPadding ) { m_uBufferedPosition = 0; } else { m_uBufferedPosition = g_min( ( a_uPosition - uReadPadding ), uMaxBufferedPosition ); } m_uOffset = a_uPosition - m_uBufferedPosition; if ( !bCanRead ) return; MIUInt const uNewBufferSize = g_min< MIUInt >( mEFileBufferSize, ( GetSize() - m_uBufferedPosition ) ); if ( !m_arrBuffer.GetCount() ) { m_arrBuffer.Resize( uNewBufferSize ); DirectRead( m_arrBuffer.AccessBuffer(), m_uBufferedPosition, uNewBufferSize ); return; } m_arrBuffer.Resize( mEFileBufferSize ); MILPChar const pData = m_arrBuffer.AccessBuffer(); MIInt const iDifference = g_limit< MIInt >( ( m_uBufferedPosition - uOldBufferedPosition ), -mEFileBufferSize, mEFileBufferSize ); if ( iDifference >= 0 ) { MIUInt uSizeRetainable = ( mEFileBufferSize - iDifference ); g_memmove( pData, ( pData + iDifference ), uSizeRetainable ); DirectRead( ( pData + uSizeRetainable ), ( m_uBufferedPosition + uSizeRetainable ), iDifference ); } else { MIUInt uSizeRetainable = ( mEFileBufferSize + iDifference ); g_memmove( ( pData - iDifference ), pData, uSizeRetainable ); DirectRead( pData, m_uBufferedPosition, -iDifference ); } m_arrBuffer.Resize( uNewBufferSize ); }
void mCSkin::LimitNumInfluencingBonesPerVert( MIUInt const a_uMax ) { mTArray< MIUInt > arrVertexIndices( m_arrVertexIndices.GetCount() ); mTArray< MIUInt > arrBoneIndices( m_arrBoneIndices.GetCount() ); mTArray< MIFloat > arrWeights( m_arrWeights.GetCount() ); mTArray< MIUInt > arrVertWeightIndices( 0, 100 ); MIUInt * pVertWeightIndices = arrVertWeightIndices.AccessBuffer(); for ( MIUInt u = 0, ue = GetNumVerts(); u != ue; ++u ) { MIUInt uWeightCount = GetNumInfluencingBones( u ); MIFloat fWeightSum = 0.0f; s_pWeights = &m_arrWeights[ m_arrFirstWeightIndexPerVertex[ u ] ]; for ( MIUInt v = uWeightCount; v--; pVertWeightIndices[ v ] = v ); qsort( pVertWeightIndices, uWeightCount, sizeof( *pVertWeightIndices ), &CompareVretWeightIndices ); uWeightCount = g_min( uWeightCount, a_uMax ); for ( MIUInt v = 0; v != uWeightCount; ++v ) { arrVertexIndices.Add( u ); arrBoneIndices.Add( GetBoneIndex( u, pVertWeightIndices[ v ] ) ); arrWeights.Add( s_pWeights[ pVertWeightIndices[ v ] ] ); fWeightSum += s_pWeights[ pVertWeightIndices[ v ] ]; } for ( MIFloat * pWeights = &arrWeights.Back(), * pEnd = pWeights - uWeightCount; pWeights != pEnd; *pWeights-- /= fWeightSum ); } arrVertexIndices.UnReserve(); arrBoneIndices.UnReserve(); arrWeights.UnReserve(); mCSkin skinResult; skinResult.InitSwapping( GetNumVerts(), m_arrBoneIDs, arrVertexIndices, arrBoneIndices, arrWeights ); Swap( skinResult ); }
mEResult mCFileStream::Read( MILPVoid a_pDest, MIUInt a_uSize ) { if ( m_uOffset + a_uSize <= m_arrBuffer.GetCount() ) { g_memcpy( a_pDest, ( m_arrBuffer.GetBuffer() + m_uOffset ), a_uSize ); m_uOffset += a_uSize; return mEResult_Ok; } if ( !( m_enuOpenMode & mEFileOpenMode_Read ) ) { MI_ERROR( mCStreamError, EFileNotOpen, "File is not open for reading operations." ); return mEResult_False; } if ( ( Tell() + a_uSize ) > GetSize() ) { MI_ERROR( mCStreamError, ESizeExceeded, "File size exceeded when reading binary data." ); return mEResult_False; } MIByte * pDest = static_cast< MIByte * >( a_pDest ); for ( ; ; ) { MIUInt const uSize = g_min( a_uSize, ( m_arrBuffer.GetCount() - m_uOffset ) ); g_memcpy( pDest, ( m_arrBuffer.GetBuffer() + m_uOffset ), uSize ); pDest += uSize; a_uSize -= uSize; m_uOffset += uSize; if ( !a_uSize ) break; Buffer( Tell() ); } return mEResult_Ok; }
mEResult mCFileStream::Write( MILPCVoid a_pSource, MIUInt a_uSize ) { if ( m_bPendingData ) { if ( ( m_uOffset + a_uSize ) <= mEFileBufferSize ) { m_arrBuffer.SetAt( m_uOffset, static_cast< MILPCChar >( a_pSource ), a_uSize ); m_uOffset += a_uSize; return mEResult_Ok; } } if ( !( m_enuOpenMode & mEFileOpenMode_Write ) ) { MI_ERROR( mCStreamError, EFileNotOpen, "File is not open for writing operations." ); return mEResult_False; } MILPCChar pSource = static_cast< MILPCChar >( a_pSource ); for ( ; ; ) { if ( !m_bPendingData ) { m_uOffsetPending = m_uOffset; m_bPendingData = MITrue; } MIUInt const uSize = g_min( a_uSize, ( mEFileBufferSize - m_uOffset ) ); m_arrBuffer.SetAt( m_uOffset, pSource, uSize ); m_uOffset += uSize; pSource += uSize; a_uSize -= uSize; if ( !a_uSize ) break; Buffer( Tell() ); } return mEResult_Ok; }