Need Help With Vertex Buffer

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Need Help With Vertex Buffer

Post by IrrNoob »

I need to get the pointer to the first vertex of a vertex buffer of a IAnimatedMesh, and then place that infomation into a SPEVertex pVertex. This is how I have tried:

Code: Select all

scene::IMeshBuffer* mb = mesh->getMesh(0)->getMeshBuffer(0);
int* mbVertices = (int*)mb->getVertices(); // get pointer to vertices in the mesh buffer
pVertex = new SPEVertex[mbVertices];
But of course, it is not working.

I know my code does not find the first vertex of the vertex buffer, and I've search the forums and looked at the API documents, but I'm struggling to find the solution.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

This is really just a c++ question. If you look at the documentation for IMeshBuffer, you'll see that it returns an untyped pointer to the vertex data.

What you need to do is cast that pointer to a vertex pointer of the correct type. The interface has a method that gives the vertex type so you know the type you need to cast to.

If you only need access to the common vertex data, you can cast to video::S3DVertex and use the stride to find the offset to the next vertex.

You can look at CMeshManipulator.cpp for examples.

Travis
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

vitek wrote: What you need to do is cast that pointer to a vertex pointer of the correct type. The interface has a method that gives the vertex type so you know the type you need to cast to.
...

You can look at CMeshManipulator.cpp for examples.

Travis
I looked through CMeshManipulator.cpp and found

Code: Select all

 void CMeshManipulator::setVertexColors 
with gives me this frame to work with:

Code: Select all

		IMeshBuffer* buffer = mesh->getMeshBuffer(0);
		void* v = buffer->getVertices();  // get pointer to vertices in the mesh buffer
		u32 vb;

       ((video::S3DVertex*)v)[0];
	   vb = (int)v;
       pVertex = new SPEVertex[vb];


		u16* i = buffer->getIndices();  // get pointer to index in the mesh buffer
		int ib;

		switch(buffer->getIndexType())
		{
		case video::EIT_16BIT:
			{

					((u16*)i)[0];
				    ib = (int)i;
                    pIndex = new int[ib]; 
			}
			break;
		case video::EIT_32BIT:
			{
				
					((u32*)i)[0];
                    ib = (int)i;
                    pIndex = new int[ib];
			}
			break;
	
		  }
Which seems to do the trick. Is this correct?
If I'm trying to only produce the address of the first vertex of a vertex buffer for a mesh, is calling

Code: Select all

IMeshBuffer* buffer = mesh->getMeshBuffer(0);
and

Code: Select all

((video::S3DVertex*)v)[0];
the correct way to locate the first vertex?
If you only need access to the common vertex data, you can cast to video::S3DVertex and use the stride to find the offset to the next vertex.
how would I call

Code: Select all

 virtual u32 irr::scene::IVertexBuffer::stride  (   )  const [pure virtual] 
to get the stride size from the vertex buffer? (Sorry for the dumb questions.)
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

IrrNoob wrote:I looked through CMeshManipulator.cpp and found void CMeshManipulator::setVertexColors
Yes, that would be one place to to start. It might be better to look at something like CMeshManipulator::createMeshWith2TCoords().
IrrNoob wrote: with gives me this frame to work with:
Uh. Your code is just silly. See inline comments below...

Code: Select all

IMeshBuffer* buffer = mesh->getMeshBuffer(0);
void* v = buffer->getVertices();  // get pointer to vertices in the mesh buffer
u32 vb;

// What do you think that this does? i.e. What is the net result of this expression
((video::S3DVertex*)v)[0];

// and this line?
vb = (int)v;

// and finally this line... what does it do?
pVertex = new SPEVertex[vb];
IrrNoob wrote:Which seems to do the trick. Is this correct?
Well if it does the trick, it must be correct, right? I mean if it works, why should be asking me if it is wrong or not? I have no idea what trick you want, but if you mean nothing useful, then yes, it does it quite well.
IrrNoob wrote:If I'm trying to only produce the address of the first vertex of a vertex buffer for a mesh, is calling

Code: Select all

IMeshBuffer* buffer = mesh->getMeshBuffer(0);
and

Code: Select all

((video::S3DVertex*)v)[0];
the correct way to locate the first vertex?
Wait, I thought your code worked? Now you are still trying to find how to get the first vertex? To answer your question, yes, the second expression gets the address of the first video::S3DVertex pointed to by v. I'm almost certain that you still don't know how to use that information though. As I mentioned above, have a look at CMeshManipulator::createMeshWith2TCoords(). There is one line in there that does what you need.

Perhaps you should step back and tell us what you actually want. The code that you keep peddling here does much more than get the address of the first vertex in buffer.

Travis
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

Ok, I was thinking it worked because the compiler wasn't complaining and the program ran without crashing, but I now I see that it doesn't

What I want is to do is feed the pointers pVertex and pIndex into this function:

Code: Select all

    virtual SPERESULT Initialize(BYTE *pVertex, int StrideSize, int *pIndex, int NumTriangles) = 0;
     Create a shape from tri-mesh data. 
 
Parameters
    pVertex
        [in] Pointer to vertex buffer.
    StrideSize
        [in] Stride of one vertex, in bytes.
    pIndex
        [in] Pointer to index buffer, index must be 32BIT.
    NumTriangles
        [in] Number of triangles.
    
Return
        SPE_OK if the method succeeds, else return SPE_FAILED.
    
Remarks 
which requires me to provide a pointer to the first vertex of the vertex buffer of an IAnimatedMesh, and a pointer to the first index of the 32bit index buffer.

I will go look at CMeshManipulator::createMeshWith2TCoords()...

I realized that I could get the vertex and index buffer information using the implementation found in the opengl SPE sample:

Code: Select all

		FILE *fp=0;
		fp=fopen(FileName,"rb");
		if(!fp)
		{
			return false;
		}

		fread(&NumVertices, sizeof(int), 1, fp);
		pVertex=new SPEVertex[NumVertices];
		fread(pVertex, sizeof(SPEVertex)*NumVertices, 1, fp);
		
		int n;
		fread(&n, sizeof(int), 1, fp);
		pIndex=new int[n];
		fread(pIndex, sizeof(int)*n, 1, fp);
		NumFaces=n/3;

		fclose(fp);
And the example feeds the modified pointers pVertex and pIndex into OpenGL to render the meshs:

Code: Select all

void Render()
{
	static DWORD last=0;
	DWORD now=timeGetTime();
	pWorld->Update ((now-last)/1000.0f);
	last=now;

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(Eye.x, Eye.y, Eye.z, At.x, At.y, At.z, 0.0f, 0.0f, 1.0f);

	float LightPosition[]		= { 100.0f, 100.0f, 100.0f, 1.0f };
	glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);

	float mat[16];
	pBox->GetTransformMesh (mat);
	glColor3f(1,1,1);
	BoxMesh.Render (mat);
	
	pCask->GetTransformMesh (mat);
	glColor3f(0.8,0.5,0.5);
	CaskMesh.Render (mat);

	glFlush();
	glutSwapBuffers();
}

Code: Select all

	void Render(float *pmat)
	{
		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_NORMAL_ARRAY);
		glVertexPointer(3, GL_FLOAT, sizeof(SPEVertex), pVertex);
		glNormalPointer(GL_FLOAT, sizeof(SPEVertex), &pVertex[0].n);
		glPushMatrix();
		glMultMatrixf(pmat);
		glDrawElements(GL_TRIANGLES, NumFaces*3, GL_UNSIGNED_INT, pIndex);
		glPopMatrix();
	}
I had the wrong ideals about how to implement this i am thinking now.
I realize what I need to do now is feed pVertex and pIndex into Irrlicht.
Maybe I need to find a way of rendering a IAnimatedMesh without calling the usual

Code: Select all

scene::IAnimatedMesh* lilman = smgr->getMesh("media/file.md2");
Where can I find information on using Irrlicht to make a mesh by manually feeding in pointers to a vertex and index buffers read from a mesh?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

IrrNoob wrote:What I want is to do is feed the pointers pVertex and pIndex into this function:

Code: Select all

    virtual SPERESULT Initialize(BYTE *pVertex, int StrideSize, int *pIndex, int NumTriangles) = 0;
     Create a shape from tri-mesh data. 
Okay, now we're getting somewhere. I still have no idea what library you are using, so I don't know WTF the data behind pVertex is supposed to look like.
IrrNoob wrote:which requires me to provide a pointer to the first vertex of the vertex buffer of an IAnimatedMesh, and a pointer to the first index of the 32bit index buffer.
No, you need a pointer to the vertex buffer as a BYTE*.
IrrNoob wrote:I realized that I could get the vertex and index buffer information using the implementation found in the opengl SPE sample:

Code: Select all

		FILE *fp=0;
		fp=fopen(FileName,"rb");
		if(!fp)
		{
			return false;
		}

		fread(&NumVertices, sizeof(int), 1, fp);
		pVertex=new SPEVertex[NumVertices];
		fread(pVertex, sizeof(SPEVertex)*NumVertices, 1, fp);
This code makes a copy of the vertices it reads from a data file. This is similar to you need to do.

You have a function that takes a pointer to the vertex buffer, a pointer to a 32-bit index buffer, the number of triangles and the stride size (the size of the vertices). What you need to do depends on what the expected vertex format is for that function call. In the worst case you need to translate the Irrlicht vertex data into SPEVertex and copy the index buffer to a 32-bit buffer. In the simple case you just make a function call.

That means asking the Irrlicht mesh buffer for the vertex count. Allocate an array of SPEVertex that is this same size. Then, for every vertex in the mesh buffer, you copy the necessary information into the allocated buffer (you could use core::array<SPEVertex> to make this easier. Then you do something similar for the indexes. The mesh buffer has a function that tells you haw many indices there are. You allocate an array of 32-bit indices (or just use core::array<u32>) and copy the 16-bit indices into the 32-bit indices.

Travis
Frank Dodd
Posts: 208
Joined: Sun Apr 02, 2006 9:20 pm

Post by Frank Dodd »

The following is the code from my IrrlichtWrapper for FreeBasic for getting the mesh verticies from an IAnimatedMesh object and returning them in part to the caller so that they can manipulate them. This is prior to 1.5 so it does not include code to handle 16 or 32 bit vertex counts.

The code travels the verticies in the buffer and copies them into a buffer passed in by the user. I hope this helps.

Frank.

Code: Select all

/* ----------------------------------------------------------------------------
copy the vertices of a mesh into the supplied buffer, the caller must ensure
that the buffer is big enough to store the data
*/
int DLL_EXPORT IrrGetMeshVertices( IAnimatedMesh* mesh, int iFrame, IRR_VERT *verts )
{
    int iLoop;
    S3DVertex *s3d_verts;
    S3DVertex2TCoords *texture_verts;
    S3DVertexTangents *tangent_verts;
    IMeshBuffer *mb = mesh->getMesh(iFrame)->getMeshBuffer(0);
    int iVertexCount = mb->getVertexCount();

    switch ( mb->getVertexType())
    {
    case EVT_STANDARD:
        // Standard vertex type used by the Irrlicht engine, video::S3DVertex
        s3d_verts = (S3DVertex *)mb->getVertices();
        for ( iLoop = 0; iLoop < iVertexCount; iLoop++ )
        {
            verts[iLoop].x = s3d_verts[iLoop].Pos.X;
            verts[iLoop].y = s3d_verts[iLoop].Pos.Y;
            verts[iLoop].z = s3d_verts[iLoop].Pos.Z;

            verts[iLoop].normal_x = s3d_verts[iLoop].Normal.X;
            verts[iLoop].normal_y = s3d_verts[iLoop].Normal.Y;
            verts[iLoop].normal_z = s3d_verts[iLoop].Normal.Z;

            verts[iLoop].vcolor = s3d_verts[iLoop].Color.color;
            verts[iLoop].texture_x = s3d_verts[iLoop].TCoords.X;
            verts[iLoop].texture_y = s3d_verts[iLoop].TCoords.Y;
        }
        break;

    case EVT_2TCOORDS:
        /* Vertex with two texture coordinates, video::S3DVertex2TCoords.
        Usually used for geometry with lightmaps or other special materials. */
        texture_verts = (S3DVertex2TCoords *)mb->getVertices();
        for ( iLoop = 0; iLoop < iVertexCount; iLoop++ )
        {
            verts[iLoop].x = texture_verts[iLoop].Pos.X;
            verts[iLoop].y = texture_verts[iLoop].Pos.Y;
            verts[iLoop].z = texture_verts[iLoop].Pos.Z;

            verts[iLoop].normal_x = texture_verts[iLoop].Normal.X;
            verts[iLoop].normal_y = texture_verts[iLoop].Normal.Y;
            verts[iLoop].normal_z = texture_verts[iLoop].Normal.Z;

            verts[iLoop].vcolor = texture_verts[iLoop].Color.color;
            verts[iLoop].texture_x = texture_verts[iLoop].TCoords.X;
            verts[iLoop].texture_y = texture_verts[iLoop].TCoords.Y;
        }
        break;

    case EVT_TANGENTS:
        /* Vertex with a tangent and binormal vector, video::S3DVertexTangents.
        Usually used for tangent space normal mapping. */
        tangent_verts = (S3DVertexTangents *)mb->getVertices();
        for ( iLoop = 0; iLoop < iVertexCount; iLoop++ )
        {
            verts[iLoop].x = tangent_verts[iLoop].Pos.X;
            verts[iLoop].y = tangent_verts[iLoop].Pos.Y;
            verts[iLoop].z = tangent_verts[iLoop].Pos.Z;

            verts[iLoop].normal_x = tangent_verts[iLoop].Normal.X;
            verts[iLoop].normal_y = tangent_verts[iLoop].Normal.Y;
            verts[iLoop].normal_z = tangent_verts[iLoop].Normal.Z;

            verts[iLoop].vcolor = tangent_verts[iLoop].Color.color;
            verts[iLoop].texture_x = tangent_verts[iLoop].TCoords.X;
            verts[iLoop].texture_y = tangent_verts[iLoop].TCoords.Y;
        }
        break;
    }
}
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Thanks Frank. Now our chances of teaching this guy something useful are nearly zero.

IrrNoob,

It would be beneficial to your understanding of the C++ language if you would answer the questions I previously asked...

Code: Select all

// What do you think that this does? i.e. What is the net result of this expression 
((video::S3DVertex*)v)[0]; 

// and this line? 
vb = (int)v; 

// and finally this line... what does it do? 
pVertex = new SPEVertex[vb]; 
Work through these three answers with me, and I'll get you the code that you are looking for.

Travis
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

Ok, will do:

Code: Select all

((video::S3DVertex*)v)[0];
I thought this would take 'v', which i believe is a pointer to the vertices in the mesh buffer, and convert its value to S3DVertex*, while the '[0]' is to point to the first vertex in the buffer.

Code: Select all

vb = (int)v; 
This code was introduced by myself :oops: to convert the value of 'v' to int, because the compiler was saying I couldn't put S3DVertex v into the last expression:

Code: Select all

pVertex = new SPEVertex[vb];
This is supposed to take the value of that pointer to the vertices in the vertex buffer, and cast it to a new SPEVertex with that data and assign the value to SPEVertex PVertex.

I'm trying to integrate the SPE library (Simple Physics Engine)
http://spehome.com/ into a basic Irrlicht project.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

IrrNoob wrote:Ok, will do
Awesome. Finally we're making some progress. Comments on your response...
IrrNoob wrote:

Code: Select all

((video::S3DVertex*)v)[0];
I thought this would take 'v', which i believe is a pointer to the vertices in the mesh buffer, and convert its value to S3DVertex*, while the '[0]' is to point to the first vertex in the buffer.
You are exactly right what this does. It casts the pointer v to the type video::S3DVertex*, which is essentially an array of vertices. The [0] part indexes into the array to get the 0th element.

Sadly, in the grand scheme of things, this has no net effect. It accesses the first vertex, but it does nothing with it. To be useful you could access or modify the vertex position, like so...

Code: Select all

// read the position
const core::vector3df pos = ((video::S3DVertex*)v)[0].Pos;

// write the position
((video::S3DVertex*)v)[0].Pos = pos;
IrrNoob wrote:

Code: Select all

vb = (int)v; 
This code was introduced by myself :oops: to convert the value of 'v' to int, because the compiler was saying I couldn't put S3DVertex v into the last expression:
If v is a pointer, then vb is the (possibly truncated) pointer value as an integer. It is definitely not the number of vertices in the vertex buffer (there is a IMeshBuffer method that will tell you this). I don't know why you'd write it, but lets move on...
IrrNoob wrote:

Code: Select all

pVertex = new SPEVertex[vb];
This is supposed to take the value of that pointer to the vertices in the vertex buffer, and cast it to a new SPEVertex with that data and assign the value to SPEVertex PVertex.
So you think that this line casts the first vertex vb to a new SPEVertex and assigns that new vertex to pVertex. Well, it doesn't do that.

That line allocates an array of vb default constructed SPEVertex objects. If vb is 1000, you will get 1000 vertex objects. It then assigns pVertex to point to the start of the array.

I think you wanted something more like this (which is still wrong).

Code: Select all

pVertex = new SPEVertex(*vb); // assuming vb is a pointer to S3DVertex
That says allocate a new SPEVertex object and construct it from the S3DVertex object. This would only work if there is some sort of conversion from S3DVertex to SPEVertex, but there isn't one, so that would never work.

What you really want is an array of SPEVertex that has the same number of elements as the mesh buffer has. You can ask the mesh buffer how many vertices it has with mb->getVertexCount(), right? And creating an array of vertices is pretty easy. You declare a core::array<video::SPEVertex> and then resize it. So this gets you an array of the right number of vertices.

Code: Select all

const u32 vertex_count = mb->getVertexCount();
core::array<SPEVertex> vertices;
vertices.set_used(vertex_count);
Now you just have to copy the vertex data. That is pretty easy if you loop through the vertices. The only trick is that you need to be careful about how you index into the Irrlicht vertex array. You need to know the vertex type or the vertex stride to find each vertex after the first...

Code: Select all

u32 stride = 0;
switch (mb->getVertexType())
{
case video::EVT_STANDARD:
  stride = sizeof (video::S3DVertex); break;
case video::EVT_2TCOORDS:
  stride = sizeof (video::S3DVertex2TCoords); break;
case video::EVT_TANGENTS:
  stride = sizeof (video::S3DVertexTangents); break;
}

const u8* pv = (const u8*)mb->getVertices();
for (u32 i = 0; i < vertex_count; ++i)
{
  // this cast gets the address of the ith vertex
  video::S3DVertex* ppv = (video::S3DVertex*)(pv + i * stride);
  vertices [i].x = ppv->Pos.x;
  vertices [i].y = ppv->Pos.y;
  vertices [i].z = ppv->Pos.z;
}
So that gets us a copy of the vertex data.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I don't know what class the Initalize() method is from, but if you only need to use one mesh buffer with it, you don't need to copy the vertex data. You only need to be sure you have a 32-bit index buffer. Assuming you have a 32-bit index buffer, you just need to call

Code: Select all

thing->Initialize((BYTE*)mb->getVertices(),
                  stride, // use stride algorithm above
                  (int*)mb->getIndexBuffer(),
                  mb->getIndexCount() / 3); // assume triangle list
If you don't have a 32-bit index buffer, you have to make one...

Code: Select all

const u32 index_count = mb->getIndexCount();
core::array<int> indices;
indices.set_used (index_count);

const u16* index_data = (const u16*)mb->getIndices();
for (u32 i = 0; i < index_count; ++i)
  indices [i] = index_data[i];

thing->Initialize((BYTE*)mb->getVertices(),
                  stride, // use stride algorithm above
                  indices.pointer(),
                  indices.size() / 3); // assume triangle list
Travis
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

If you need to join multiple mesh buffers to pass to the Initialize() method, the following (untested) code should be close to what you need...

Code: Select all


#if !defined (S32_MAX)
#  define S32_MAX 0x7fffffff
#endif

u32 IMeshBuffer_getStride(video::E_VERTEX_TYPE t)
{
  switch (t) {
  case video::EVT_STANDARD:
    return sizeof (video::S3DVertex);
  case video::EVT_2TCOORDS:
    return sizeof (video::S3DVertex2TCoords);
  case video::EVT_TANGENTS:
    return sizeof (video::S3DVertexTangents);
  }

  return 0;
}


void SPE_Initialize (Thing* thing, const scene::IMesh* mesh)
{
  u32 total_indices  = 0;
  u32 total_vertices = 0;

  // count all of the indices and vertices. be sure we don't
  // have more than 2^32 - 1 vertices

  for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
    const IMeshBuffer* mb = mesh->getMeshBuffer(i);
    if (mb) {
      u32 vertices = mb->getVertexCount();

      if (SINT_MAX - total_vertices < vertices)
        return; // we can't handle all the vertices

      total_indices  += mb->getIndexCount();
      total_vertices += mb->getVertexCount();
    }
  }

  struct MyVertex
  {
    f32 x;
    f32 y;
    f32 z;
  };

  core::array<MyVertex> vb(total_vertices); // vertex buffer
  core::array<s32>      ib(total_indices);  // index buffer

  u32 used_indices  = 0;
  u32 used_vertices = 0;

  for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
    const IMeshBuffer* mb = mesh->getMeshBuffer(i);
    if (mb) {

      const u32 vertex_stride = IMeshBuffer_getStride(mb->getVertexType());
      const u32 vertex_count  = mb->getVertexCount();
      const u32 index_count   = mb->getIndexCount();

      // copy the index data

      // since we are putting all of the vertices into one
      // vertex buffer, we need to offset the index values
      //
      // we know that vertex 0 will only be at index 0 in
      // the vertex buffer if it is the first vertex of the
      // first mesh buffer. if there were 100 vertices in
      // all of the previous mesh buffers, then the first
      // vertex will go at index 101. the loop below deals
      // with this.
      //
      // this _must_ happen before we deal with the vertex
      // data for this mesh buffer.

      const u16* qq = mb->getIndices();
      for (u32 i = 0; i < index_count; ++i) {
        ib [used_indices] = used_vertices + qq[i];

        used_indices += 1;
      }

      // copy the vertex data

      // get a pointer to the start of the first vertex
      const char* pp = (char*)mb->getVertices();
    
      for (u32 v = 0; v < vertex_count; ++v) {
        // cast vertex data to a vertex
        const video::S3DVertex* pv = (video::S3DVertex*)pp;

        vb [used_vertices].x = pv->Pos.x;
        vb [used_vertices].y = pv->Pos.y;
        vb [used_vertices].z = pv->Pos.z;

        used_vertices += 1;

        // step past rest of vertex data to next vertex
        pp += vertex_stride;
      }
    }
  }

  thing->Initialize((BYTE*)vb.pointer(),
                    sizeof (MyVertex),
                    ib.pointer(),
                    ib.size() / 3);
}
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

You're the King Vitek 8) Thanks for the big help.
I'm going to try to read over your posts a couple times more before I try to work with it. I'll let you know how it turns out.

LPSPESHAPE is the class of Initialize(), so I just replace 'thing' with LPSPESHAPE pShape->Initialize().

You are saying that I can pass either one or multiple mesh buffers joined together to Initialize() with your example, but I'm not sure which I'll need; Does it depend on if an animated mesh requires multiple mesh buffers put together? I know in my first sample code I called

Code: Select all

scene::IMeshBuffer* mb = mesh->getMeshBuffer(0);
But I was guessing that Initialize() would only need the first meshbuffer.
I'm really not sure now either, so I will try both ways.

I'm confident your example will be the zen of initializing a Irrlicht mesh for SPE. When I have correctly implemented the code I will then work on
finding out how to provide Irrlicht with the information from these structures to render the mesh after SPE has altered it with physics calculations.
Last edited by IrrNoob on Mon Jan 12, 2009 2:39 am, edited 1 time in total.
IrrNoob
Posts: 110
Joined: Sun Nov 16, 2008 8:01 pm
Location: Fort Collins, Us

Post by IrrNoob »

Okay I'm getting an error with:

Code: Select all

    LPSPESHAPE pShape = pWorld->CreateShape();

	SPE_Initialize (pShape, mesh);
And this message:

Code: Select all

error C2664: 'SPE_Initialize' : cannot convert parameter 1 from 'LPSPESHAPE' to 'LPSPESHAPE *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
So I need to change LPSPESHAPE pShape to LPSPESHAPE* pShape?
No because that causes this error:

Code: Select all

error C2440: 'initializing' : cannot convert from 'ISPEShape *' to 'LPSPESHAPE *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
What do I need to do to satisfy this error?

SPE_Initialize () takes in a IMesh as a parameter, but I'm used to working with IAnimatedMesh instead. Do I need to call IAnimatedMesh to SPE_Initialize? Whats the difference?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I don't know why you would change a working line of code in an attempt to fix a broken line.

Regardless, it looks like you may have declared SPE_Initialize() as

Code: Select all

void SPE_Initialize(LPSPESHAPE*, const video::IMesh*);
I think you should be using...

Code: Select all

void SPE_Initialize(LPSPESHAPE, const video::IMesh*);
FYI, I finally googled the SPE engine, and I found the documentation.

Travis
Post Reply