• Welcome to Valhalla Legends Archive.
 

There has got to be a better way to do this

Started by Eibro, February 26, 2004, 11:11 PM

Previous topic - Next topic

Eibro

bool XMesh::buildAABB( AABB3& bb ) const
{
   if ( m_meshObj )  // loaded mesh?     
   {   
      DWORD vertexSize, vertexCount;
      LPDIRECT3DVERTEXBUFFER9 vertexBuffer;

      // Retrieve vertex buffer
      m_meshObj->GetVertexBuffer( &vertexBuffer );
      // retrive vertex size
      vertexSize = m_meshObj->GetNumBytesPerVertex();
      vertexCount = m_meshObj->GetNumVertices();

      void* vertexData;
      void* currentPosition;
      vertexBuffer->Lock( 0, 0, &vertexData, 0 );
      
      // loop through the vertices
      for ( DWORD i = 0; i < vertexCount; ++i )
      {
         // Calculate offset to next vertex
         __int64 address = reinterpret_cast< __int64 >( vertexData ) + vertexSize * i;
         currentPosition = reinterpret_cast< void* >( address );
         // Get a pointer to actual vertex position & add vertex to AABB
         bb.add( *reinterpret_cast< D3DXVECTOR3* >( currentPosition ) );
      }

     vertexBuffer->Unlock();
      return true;
   }

   return false; // not loaded
};
Pay particular attention to the lines:
__int64 address = reinterpret_cast< __int64 >( vertexData ) + vertexSize * i;
currentPosition = reinterpret_cast< void* >( address );
Why do I have to do it this way? The compiler barked at me when I initially had currentPosition = vertexData + vertexSize * i; with the error void*, unknown size. Why would the size of void* need to be known to add vertexSize * i?
Aside from that; how could I do this without casting to __int64? As I doubt that is very portable.
Eibro of Yeti Lovers.

Yoni

You cannot use the + operator (pointer arithmetic) on void*, since sizeof(void) is undefined. The best solution is to temporarily cast to char*, since it's always 1 byte, to do the arithmetic, and then to cast back to void* for the result.
Instead of:
currentPosition = vertexData + vertexSize * i;
Use:
currentPosition = static_cast<char*>(vertexData) + vertexSize * i;
That should work.
(In Windows specific code like yours, you could also replace char* with BYTE* or LPBYTE if you think it's clearer).
Note the cast back to void* is implied.

Adron

Quote from: Eibro on February 26, 2004, 11:11 PM
Why would the size of void* need to be known to add vertexSize * i?

When you add an integer to a pointer, the compiler multiplies by the size of an element. So, if you add 3 to a long*, the compiler will add 12 for you. As "void" has no size, you can't add integers to a void*.

Kp

Addendum:

As a documented extension, gcc defines sizeof(void) = 1, so the original code would have worked in gcc.  However, for portability's sake, it's better to do it as rewritten in this thread.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Eibro

Quote from: Adron on February 27, 2004, 04:59 AM
Quote from: Eibro on February 26, 2004, 11:11 PM
Why would the size of void* need to be known to add vertexSize * i?

When you add an integer to a pointer, the compiler multiplies by the size of an element. So, if you add 3 to a long*, the compiler will add 12 for you. As "void" has no size, you can't add integers to a void*.
Ahh perfect. I don't know how I got this far without knowing that. I suppose it wouldn't make much sense to allow an arbitrary number to be added to a pointer. Casting to a char seems to be the cleanest way.

Thanks everyone.
Eibro of Yeti Lovers.