<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multitheftauto.com/wiki/UpdateAdditionalStreamContent?action=history&amp;feed=atom</id>
	<title>UpdateAdditionalStreamContent - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multitheftauto.com/wiki/UpdateAdditionalStreamContent?action=history&amp;feed=atom"/>
	<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=UpdateAdditionalStreamContent&amp;action=history"/>
	<updated>2026-05-27T19:30:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=UpdateAdditionalStreamContent&amp;diff=50996&amp;oldid=prev</id>
		<title>Xtravax: Created page with &quot;&lt;pageclass subcaption=&quot;C++ Function&quot;&gt;&lt;/pageclass&gt;  This C++ Function is found inside of CAdditionalVertexStreamManager.  It updates additional stream content.  It can be f...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=UpdateAdditionalStreamContent&amp;diff=50996&amp;oldid=prev"/>
		<updated>2017-05-14T13:30:36Z</updated>

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