Jump to content


BSP Tree


18 replies to this topic

#1 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 10 February 2006 - 10:54 AM

I am building up a BSP tree for collision detection. I declared struct for VERTEX, POLYGONS, NODE. Now, I need to generate a linked list which contains list of mesh vertex.
POLYGON *g_polygonList contains Top of polygon linked list.
My addPolygon() function takes a Mesh VERTEX and returns POLYGONS which is added to *g_polygonList. This *g_polygonList can be further used for buildBSPTree() function. PROBLEM IS HOW TO EXTRACT VERTEX INFORMATION FROM LPD3DXMESH CLASS which can be passed to addPolygon() function.


struct VERTEX // Vertex Structure
{
float x; // X Coordinate Component
float y; // Y Coordinate Component
float z; // Z Coordinate Component
D3DCOLOR rgba; // Diffuse Colour Component
float tu; // U Texture Component
float tv; // V Texture Component
};

struct POLYGON // Polygon Structure
{
VERTEX VertexList[10]; // Actual Vertex Data
D3DXVECTOR3 Normal; // Polygon Normal
int nNumberOfVertices; // Number of Vertices
int nNumberOfIndices; // Number of Indices
WORD Indices[30]; // Actual Index Data
POLYGON *Next; // Linked List Next Poly
};



POLYGON *g_polygonList; // Top of polygon linked list
NODE *g_BSPTreeRootNode; // BSP tree root node


// Once we creates the required poly's for the scene
// geometry, we can compile the BSP tree by calling buildBspTree()...
g_BSPTreeRootNode = new NODE;
buildBspTree( g_BSPTreeRootNode, g_polygonList );

//------------------------------------------------------------------------
// Name : addPolygon
// Desc : Takes any convex Polygon and breaks in into multiple Indexed // Triangle Lists and adds the polygon to a Linked list that will be sent
// to the BSP Compiler.
//------------------------------------------------------------------------
POLYGON *addPolygon( POLYGON *Parent, VERTEX *Vertices)
{
POLYGON *Child = new POLYGON;
WORD v0;
WORD v1;
WORD v2;
int i = 0;

Child->nNumberOfVertices = m_pMesh->GetNumVertices();;
Child->nNumberOfIndices = (m_pMesh->GetNumVertices() - 2) * 3;
Child->Next = NULL;

// Copy Vertices
for( i = 0; i < m_pMesh->GetNumVertices(); ++i )
Child->VertexList[i] = Vertices[i]; //

// Calculate indices
for( i = 0; i < Child->nNumberOfIndices / 3; ++i )
{
if( i == 0 )
{
v0 = 0;
v1 = 1;
v2 = 2;
}
else
{
v1 = v2;
++v2;
}

Child->Indices[ i * 3 ] = v0;
Child->Indices[(i * 3) + 1] = v1;
Child->Indices[(i * 3) + 2] = v2;
} // Next Tri


// Generate polygon normal
D3DXVECTOR3 *vec0 = (D3DXVECTOR3*) &Child->VertexList[0];
D3DXVECTOR3 *vec1 = (D3DXVECTOR3*) &Child->VertexList[1];
D3DXVECTOR3 *vec2 = (D3DXVECTOR3*) &Child->VertexList[Child->nNumberOfVertices-1];// the last vert

D3DXVECTOR3 edge1 = (*vec1)-(*vec0);
D3DXVECTOR3 edge2 = (*vec2)-(*vec0);
D3DXVec3Cross(&Child->Normal,&edge1,&edge2);
D3DXVec3Normalize(&Child->Normal,&Child->Normal);

if( Parent != NULL )
Parent->Next=Child;

return Child;
}

#2 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 10 February 2006 - 12:14 PM

Do u wanna extract information about vertex format that particular mesh have or u wanna extract each vertex data one by one? (vertex data: coordinates, color, etc.)

#3 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 13 February 2006 - 05:54 AM

I wanna extract each vertex information from mesh one by one; so that, I can create a linked list of polygons i.e. ( POLYGON *g_polygonList ) which can be further passed to my BuildBSPTree () function. (please, look at the code).


My POLYGON *addPolygon( POLYGON *Parent, VERTEX *Vertices)
function used to create a linked list of polygons i.e ( POLYGON *g_polygonList ) from mesh vertex.

#4 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 13 February 2006 - 01:20 PM

its hard for me to read whats your code is exactly doing.
i'll try to explain how you can acces vertices for single polygon.

array of vertices is stored in vertex buffer.
pointer to it can be obtained by calling LockVertexBuffer() method on
LPD3DXMESH pointer (ID3DXMesh*).

// assuming lpMesh is valid LPD3DXMESH pointer

BYTE* lpbVb;

if( lpMesh->LockVertexBuffer( D3DLOCK_READONLY, (VOID**)&lpbVb ) == D3D_OK ){

	// pointer to VB was obtained correctly, lpbVb contains pointer to array 

	// of vertices

	;

	; // read VB vertices

	;

	lpMesh->UnlockVertexBuffer();		//what was locked must be unlocked or else things ll go bad

}


in most cases mesh also contain index buffer (IB). IB can be accessed
by calling lpMesh->LockIndexBuffer() in similar way as for index buffer or,
lpMesh->GetIndexBuffer then lpD3dxIb->Lock().
also you'll need to know if IB is 16 or 32 bit by calling lpD3dxIb->GetDesc()
then reading Format member of D3DINDEXBUFFER_DESC structure.


if( lpMesh->GetIndexBuffer( &lpD3dxIb ) == D3D_OK ){

	D3DINDEXBUFFER_DESC ibd;

	if( lpD3dxIb->GetDesc( &ibd ) == D3D_OK ){

		if( ibd.Format == D3DFMT_INDEX32 ){

			// IB is 32 bit

		}else{

			// IB is 16 bit

		}

	}

}


IB is an array of values, each value is an index to vertex inside vertex buffer array.
one polygon consist of 3 vertices.
to extract single polygon its needed to get 3 indices from IB then use those 3 values
as indices inside VB.

i.e.
if mesh consist of 4 polygons and its needed to extract polygon with index = 2, then
IB is an array of 4*3=12 elements (4 polygons, 3 vertices per each),
1st vertice of polygon has index = 2*3=6, 2nd index = 7 and 3rd index = 8.
if 'lpIB' points to IB array then:
lpIB[6] - polygons 1st vertex index
lpIB[7] - polygons 2nd vertex index
lpIB[8] - polygons 3rd vertex index

NOTE: now its needed to distinguish between 16 or 32 bit IB, therefore declare
lpIB as DWORD (32 bit) array or as WORD (16 bit) array; use type cast or declare as BYTE*
and multiply index by 2 (for 16bit) or 4 (for 32bit).

after that its needed to use those indices inside VB array

// get number of bytes per vertex

const DWORD nBytesPerVertex = lpMesh->GetNumBytesPerVertex()

// access vertex data

&lpbVb[ lpIB[6] * nBytesPerVertex ]	//points to 1st byte of 1st polygon vertex

&lpbVb[ lpIB[7] * nBytesPerVertex ]	//points to 1st byte of 2nd polygon vertex

&lpbVb[ lpIB[8] * nBytesPerVertex ]	//points to 1st byte of 3rd polygon vertex



#5 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 14 February 2006 - 05:52 AM

My target is to generate linked list of mesh polygons i.e. POLYGON *g_polygonList
which can be further passed to my BuildBSPTree () function. I don't know how to access mesh polygons.

buildBspTree( g_BSPTreeRootNode, g_polygonList ); is the function call


Is the above approach right for collision detection

#6 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 14 February 2006 - 12:54 PM

if u thinking about pointers to polygons, then answer is, u can't have pointers to every polygon inside mesh. meshes are stored inside AGP memory, not inside RAM (random access memory), therefore its needed to perform additional operation to access mesh data, those operations are locking and unlocking.

u goal is propably to loop through all mesh polygons (using i.e for loop).
u can either read polygons in the following ways:
1. extract all polygons, store them as a copy and have easy access to them from RAM while doing collision detection
2. every time its needed to access polygons, lock IB and VB then loop through polygons to do collision detection

in previous post i've showed how to access single polygon using inex buffer and vertex buffer.
u should create loop that walks through IB then use indices inside VB in this way (pseudocode):

[lock VB]

[lock IB]

numIndices = sizeof(IB) / sizeof(INDICE);	//sizeof(INDICE) must be either 2 or 4

numBytesPerVertex = lpMesh->GetNumBytesPerVertex();

for( i=0; i<numIndices; i += 3 ){

	idxVbVert0 = lpIB[ i ];

	idxVbVert1 = lpIB[ i+1 ];

	idxVbVert2 = lpIB[ i+2 ];

	// lpVB is BYTE* and points to previously locked vertex data

	D3DXVECTOR3 v0 = *(D3DXVECTOR3*) &lpVB[ idxVbVert0 * numBytesPerVertex ];

	D3DXVECTOR3 v1 = *(D3DXVECTOR3*) &lpVB[ idxVbVert1 * numBytesPerVertex ];

	D3DXVECTOR3 v2 = *(D3DXVECTOR3*) &lpVB[ idxVbVert2 * numBytesPerVertex ];

	//[ now use vetex coordinates v0, v1, v2 for u own purpose ]

	// do collision detection against polygon or keep extracting them

	;

	;

}

[unlock IB]

[unlock VB]


this is how i see it.
so,

Quote

Is the above approach right for collision detection
yes, u can extract every vertice as well as polygon, when u have polygon u can build planes needed while doing colision detection

if linked list of polygons is needed, i'd do it in one of two ways: 1) storing indices (rather than pointers) to index buffer to know where polygon is stored, or 2) extract/copy polygons and keep them in additional buffer then build linked list out of them

#7 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 15 February 2006 - 12:05 PM

thanks for explaining the concept;

now should I put vetex coordinates v0, v1, v2 into my
struct POLYGONS. how should i do it?
PLEASE see the declaration of struct VERTEX and POLYGONS;
is this declaration correct; do i need all the member of struct POLYGONS AS I DECLARED

#8 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 15 February 2006 - 04:03 PM


struct VERTEX // Vertex Structure

{

	float x; // X Coordinate Component

	float y; // Y Coordinate Component

	float z; // Z Coordinate Component

//	D3DCOLOR rgba; // Diffuse Colour Component

//	float tu; // U Texture Component

//	float tv; // V Texture Component

};

for collision detection u need only vertex coordinates. u dont need color or texture information.

struct POLYGON // Polygon Structure

{

	VERTEX      lpVerts[3];		//polygon vertices

	D3DXVECTOR3 vNormal;		// Polygon Normal

//	int nNumberOfVertices; // Number of Vertices

//	int nNumberOfIndices; // Number of Indices

//	WORD Indices[30]; // Actual Index Data

//	POLYGON *Next; // Linked List Next Poly

};

in mesh, polygon has 3 vertices. normal may be optional bcos it may be calculated out of vertices at any time

#9 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 20 February 2006 - 07:18 AM

I am trying to develop the code this way.this function will generate a g_polygonList of mesh polygons. AddPolygon() function is used for this purpose. Following are the doubts:-

1) what is IB abd INDICE here
numIndices = sizeof(IB) / sizeof(INDICE); //sizeof(INDICE) must be either 2 or 4

2) I’ve put v0, v1, v2 into VERTEX VERTLIST[i] array and passed the array to AddPolygons() function. Is this way right?


code:

HRESULT CMyD3DApplication::InitDeviceObjects()

{

    LPD3DXMESH   pMeshSysMem = NULL;

    LPD3DXBUFFER pAdjacencyBuffer = NULL;


	VERTEX   VERTLIST[3]; 

    POLYGON *child = NULL;


	 g_polygonList = NULL;


   	hr = LoadMeshData(&pMeshSysMem, &pAdjacencyBuffer);

    if (FAILED(hr))

    {

        // ignore load errors, just draw blank screen if mesh is invalid

        hr = S_OK;

        goto End;

    }


	//  array of vertices is stored in vertex buffer.

	//  Lock vertex & index buffer

	//  pMeshSysMem is valid LPD3DXMESH pointer


	BYTE* lpVb, lpIB;

	D3DXVECTOR3 idxVbVert0, idxVbVert1, idxVbVert2;


if( pMeshSysMem->LockVertexBuffer( D3DLOCK_READONLY, (VOID**)&lpVb ) == D3D_OK )


if( pMeshSysMem->LockIndexBuffer ( D3DLOCK_READONLY, (VOID**)&lpIB  ) == D3D_OK  )

	{

		numIndices = sizeof(IB) / sizeof(INDICE);	//sizeof(INDICE) must be either 2 or 4

		numBytesPerVertex = pMeshSysMem->GetNumBytesPerVertex();

		for( i=0; i<numIndices; i += 3 )

		{

			idxVbVert0 = lpIB[ i ];

			idxVbVert1 = lpIB[ i+1 ];

			idxVbVert2 = lpIB[ i+2 ];

	

		// lpVB is BYTE* and points to previously locked vertex data

			D3DXVECTOR3 v0 = *(D3DXVECTOR3*) &lpVB[ idxVbVert0 * numBytesPerVertex ];

			D3DXVECTOR3 v1 = *(D3DXVECTOR3*) &lpVB[ idxVbVert1 * numBytesPerVertex ];

			D3DXVECTOR3 v2 = *(D3DXVECTOR3*) &lpVB[ idxVbVert2 * numBytesPerVertex ];


		//[ now use vetex coordinates v0, v1, v2 for u own purpose ]

		// do collision detection against polygon or keep extracting them

			// Fill array of vertices

			VERTLIST[i++] = v0;

			VERTLIST[i++] = v1;

			VERTLIST[i++] = v2;


			if( g_polygonList == NULL )

              {

                 g_polygonList = addPolygon(NULL,&VERTLIST);

                 child = g_polygonList;

              }

            else

              {

                 child = addPolygon(child,&VERTLIST);

              }

		}


	 pMeshSysMem->UnlockVertexBuffer();		//what was locked must be unlocked or else things i'll go bad

     pMeshSysMem->UnlockIndexBuffer();	

    }


    return hr;

}




//-----------------------------------------------------------------------------

// Name : addPolygon

// Desc : Takes any convex Polygon and breaks in into multiple Indexed Triangle 

//        Lists and adds the polygon to a Linked list that will be sent to 

//        the BSP Compiler.

//-----------------------------------------------------------------------------

POLYGON *addPolygon( POLYGON *Parent, VERTEX *Vertices )

{

    POLYGON *Child = new POLYGON;

	int  i = 0;


    Child->nNumberOfVertices = 3;

   

    // Copy Vertices

    for( i = 0; i < 3; ++i )

        Child->VertexList[i] = Vertices[i];


   

    // Generate polygon normal

    D3DXVECTOR3 *vec0 = (D3DXVECTOR3*) &Child->VertexList[0];

    D3DXVECTOR3 *vec1 = (D3DXVECTOR3*) &Child->VertexList[1];

    D3DXVECTOR3 *vec2 = (D3DXVECTOR3*) &Child->VertexList[Child->nNumberOfVertices-1];// the last vertex


    D3DXVECTOR3 edge1 = (*vec1)-(*vec0);

    D3DXVECTOR3 edge2 = (*vec2)-(*vec0);

    D3DXVec3Cross(&Child->Normal,&edge1,&edge2);

    D3DXVec3Normalize(&Child->Normal,&Child->Normal);


    if( Parent != NULL )

        Parent->Next=Child;


    return Child;

}



#10 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 22 February 2006 - 04:41 PM

Quote

1) what is IB abd INDICE here
numIndices = sizeof(IB) / sizeof(INDICE); //sizeof(INDICE) must be either 2 or 4
IB - index buffer, sizeof(IB) is size of index buffer in bytes
sizeof(INDICE); - just size in bytes of single index value.
those two are only used to calculate number of values (indexes) in index buffer array.
i wrote this in pseudocode, but u should found out yourself how to get number of indexes.

	LPDIRECT3DINDEXBUFFER9 lpIndexBuffer;

	pMeshSysMem->GetIndexBuffer( &lpIndexBuffer );

	D3DINDEXBUFFER_DESC ibdesc;

	lpIndexBuffer->GetDesc( &ibdesc );

	// ibdesc.Size is Size of the index buffer, in bytes

	if( IB is 32 bit )

		numIndices = ibdesc.Size / sizeof(DWORD);

	else

		numIndices = ibdesc.Size / sizeof(WORD);

above sample code is how u can get number of indexes.

Quote

2) I’ve put v0, v1, v2 into VERTEX VERTLIST[i] array and passed the array to AddPolygons() function. Is this way right?

in ur code u should extract indexes from IB this way:

if( /* IB is 32 bit */ ){

	idxVbVert0 = ((DWORD*)lpIB)[ i ];

	idxVbVert1 = ((DWORD*)lpIB)[ i+1 ];

	idxVbVert2 = ((DWORD*)lpIB)[ i+2 ];

}else{

	idxVbVert0 = ((WORD*)lpIB)[ i ];

	idxVbVert1 = ((WORD*)lpIB)[ i+1 ];

	idxVbVert2 = ((WORD*)lpIB)[ i+2 ];

}

then put it into list:

VERTEX VERTEXLIST[3];

VERTEXLIST[ 0 ] = v0;

VERTEXLIST[ 1 ] = v1;

VERTEXLIST[ 2 ] = v2;

u should be checking DirectX documentation more often on functions and methods i mentioned in my previous posts.

EDIT: when ur putting some source code put it inside
[code ] ... [ /code] tags, so it ll be formated

#11 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 23 February 2006 - 11:11 AM

is this right way to assign D3DXVECTOR3 to VERTEX struct?

VERTLIST[0] = v0;

VERTLIST[1] = v1;`

VERTLIST[2] = v2;


this way I am trying to find whether vertex buffer is 16 or 32 bit.

dw32Bit = ibdesc.Size & D3DXMESH_32BIT;	


below is the code for locking vertex & index buffer; and adding polygons to linked list by calling addpolygons() function.

//----------------------------------------------------------------------------------------

// Name: InitDeviceObjects()

// Desc: Initialize scene objects.

//       Builds polygons linked list (g_polygonList) according to what's stored in Mesh  

//----------------------------------------------------------------------------------------

HRESULT CMyD3DApplication::InitDeviceObjects()

{

    HRESULT      hr = S_OK;

    LPD3DXMESH   pMeshSysMem = NULL;

    LPD3DXBUFFER pAdjacencyBuffer = NULL;


   VERTEX   VERTLIST[3]; 

    POLYGON *child = NULL;


	DWORD dw32Bit;

	 g_polygonList = NULL;

	

	hr = LoadMeshData(&pMeshSysMem, &pAdjacencyBuffer);

    if (FAILED(hr))

    {

        // ignore load errors, just draw blank screen if mesh is invalid

        hr = S_OK;

        goto End;

    }


             //  array of vertices is stored in vertex buffer.

	//  Lock vertex & index buffer

	//  pMeshSysMem is valid LPD3DXMESH pointer


	BYTE* lpVB, lpIB;

	DWORD idxVbVert0, idxVbVert1, idxVbVert2;


	if( pMeshSysMem->LockVertexBuffer( D3DLOCK_READONLY, (VOID**)&lpVB ) == D3D_OK )

	if( pMeshSysMem->LockIndexBuffer ( D3DLOCK_READONLY, (VOID**)&lpIB  ) == D3D_OK  )

	{

		LPDIRECT3DINDEXBUFFER9 lpIndexBuffer;

		pMeshSysMem->GetIndexBuffer( &lpIndexBuffer );

		D3DINDEXBUFFER_DESC ibdesc;

		lpIndexBuffer->GetDesc( &ibdesc );

				

		dw32Bit = ibdesc.Size & D3DXMESH_32BIT;	

		

		if( dw32Bit  )

				numIndices = ibdesc.Size / sizeof(DWORD);

			else

				numIndices = ibdesc.Size / sizeof(WORD);

		

	

		numBytesPerVertex = pMeshSysMem->GetNumBytesPerVertex();

		for( i=0; i<numIndices; i += 3 )

		{

			if (dw32Bit  )

			   {

				idxVbVert0 = ((DWORD*)lpIB)[ i ];

				idxVbVert1 = ((DWORD*)lpIB)[ i+1 ];

				idxVbVert2 = ((DWORD*)lpIB)[ i+2 ];

			   }

			else{

				idxVbVert0 = ((WORD*)lpIB)[ i ];

				idxVbVert1 = ((WORD*)lpIB)[ i+1 ];

				idxVbVert2 = ((WORD*)lpIB)[ i+2 ];

				}

	

			// lpVB is BYTE* and points to previously locked vertex data

			D3DXVECTOR3 v0 = *(D3DXVECTOR3*) &lpVB[ idxVbVert0 * numBytesPerVertex ];

			D3DXVECTOR3 v1 = *(D3DXVECTOR3*) &lpVB[ idxVbVert1 * numBytesPerVertex ];

			D3DXVECTOR3 v2 = *(D3DXVECTOR3*) &lpVB[ idxVbVert2 * numBytesPerVertex ];


						// Fill array of vertices

			

			VERTLIST[0] = v0;

			VERTLIST[1] = v1;`

			VERTLIST[2] = v2;



			if( g_polygonList == NULL )

              {

                 g_polygonList = addPolygon(NULL,&VERTLIST);

                 child = g_polygonList;

              }

            else

               {

                 child = addPolygon(child,&VERTLIST);

              }

		}


	 pMeshSysMem->UnlockVertexBuffer();		//what was locked must be unlocked or else things i'll go bad

     pMeshSysMem->UnlockIndexBuffer();	

    }


       return hr;

}





//-----------------------------------------------------------------------------

// Name : addPolygon

// Desc : Takes any convex Polygon and breaks in into multiple Indexed Triangle 

//        Lists and adds the polygon to a Linked list that will be sent to 

//        the BSP Compiler.

//-----------------------------------------------------------------------------

POLYGON *addPolygon( POLYGON *Parent, VERTEX *Vertices )

{

    POLYGON *Child = new POLYGON;

	int  i = 0;


    Child->nNumberOfVertices = 3;

   

    // Copy Vertices

    for( i = 0; i < 3; ++i )

        Child->VertexList[i] = Vertices[i];


   

    // Generate polygon normal

    D3DXVECTOR3 *vec0 = (D3DXVECTOR3*) &Child->VertexList[0];

    D3DXVECTOR3 *vec1 = (D3DXVECTOR3*) &Child->VertexList[1];

    D3DXVECTOR3 *vec2 = (D3DXVECTOR3*) &Child->VertexList[Child->nNumberOfVertices-1];// the last vertex


    D3DXVECTOR3 edge1 = (*vec1)-(*vec0);

    D3DXVECTOR3 edge2 = (*vec2)-(*vec0);

    D3DXVec3Cross(&Child->Normal,&edge1,&edge2);

    D3DXVec3Normalize(&Child->Normal,&Child->Normal);


    if( Parent != NULL )

        Parent->Next=Child;


    return Child;

}



#12 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 23 February 2006 - 11:51 AM

Pushapjit said:

is this right way to assign D3DXVECTOR3 to VERTEX struct?

VERTLIST[0] = v0;

VERTLIST[1] = v1;

VERTLIST[2] = v2;

no, sorry, i forgot how VERTEX struct is declared.
it should be done this way:

VERTLIST[0].x = v0.x;

VERTLIST[0].y = v0.y;

VERTLIST[0].z = v0.z;

VERTLIST[1].x = v1.x;

VERTLIST[1].y = v1.y;

VERTLIST[1].z = v1.z;

VERTLIST[2].x = v2.x;

VERTLIST[2].y = v2.y;

VERTLIST[2].z = v2.z;

instead using your own structure for vertex u could use just D3DXVECTOR3 structure, thus declaring VERTLIST array as:
D3DXVECTOR3 VERTLIST[3];
and writting:
VERTLIST[0] = v0;
VERTLIST[1] = v1;
VERTLIST[2] = v2;
would be correct.

Quote

this way I am trying to find whether vertex buffer is 16 or 32 bit.

dw32Bit = ibdesc.Size & D3DXMESH_32BIT;	

(this about index buffer not vertex buffer, is it 16 or 32 bit)
no, u must check Format member of D3DINDEXBUFFER_DESC structure instead of Size member:

if( ibdesc.Format == D3DFMT_INDEX32 ){

	// index buffer is 32 bit

}else{

	// index buffer is 16 ibt

}



#13 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 03 March 2006 - 07:11 AM

while running the code I am getting An exception 'System.NullReferenceException' on following piece of code.


else{

	idxVbVert0 = ((WORD*)lpIB)[ i ];

	idxVbVert1 = ((WORD*)lpIB)[ i+1 ];

	idxVbVert2 = ((WORD*)lpIB)[ i+2 ];

     }

below is the whole function

HRESULT CMyD3DApplication::InitDeviceObjects()

{

    HRESULT      hr = S_OK;

    LPD3DXMESH   pMeshSysMem = NULL;

    LPD3DXBUFFER pAdjacencyBuffer = NULL;


   VERTEX   VERTLIST[3]; 

    POLYGON *child = NULL;


   g_polygonList = NULL;


  	

	hr = LoadMeshData(&pMeshSysMem, &pAdjacencyBuffer);

    if (FAILED(hr))

    {

        // ignore load errors, just draw blank screen if mesh is invalid

        hr = S_OK;

        goto End;

    }


	//  array of vertices is stored in vertex buffer.

	//  Lock vertex & index buffer

	//  pMeshSysMem is valid LPD3DXMESH pointer


	BYTE* lpVB, lpIB;

	DWORD idxVbVert0, idxVbVert1, idxVbVert2;

	int numIndices;


	if( pMeshSysMem->LockVertexBuffer( D3DLOCK_READONLY, (VOID**)&lpVB ) == D3D_OK )

	if( pMeshSysMem->LockIndexBuffer ( D3DLOCK_READONLY, (VOID**)&lpIB  ) == D3D_OK  )

	{

		LPDIRECT3DINDEXBUFFER9 lpIndexBuffer;

		pMeshSysMem->GetIndexBuffer( &lpIndexBuffer );

		D3DINDEXBUFFER_DESC ibdesc;

		lpIndexBuffer->GetDesc( &ibdesc );

		// ibdesc.Size is Size of the index buffer, in bytes

		// numIndices = sizeof(IB) / sizeof(INDICE);	//sizeof(INDICE) must be either 2 or 4

		  // remember if the mesh is 32 or 16 bit, to be added in on the clones

		

			if( ibdesc.Format == D3DFMT_INDEX32  )

				// index buffer is 32 bit

				numIndices = ibdesc.Size / sizeof(DWORD);


			else

				// index buffer is 16 ibt

				numIndices = ibdesc.Size / sizeof(WORD);

		

	

		DWORD numBytesPerVertex = pMeshSysMem->GetNumBytesPerVertex();

		for( int i=0; i<numIndices; i += 3 )

		{

			if (ibdesc.Format == D3DFMT_INDEX32  )

			   {

				idxVbVert0 = ((DWORD*)lpIB)[ i ];

				idxVbVert1 = ((DWORD*)lpIB)[ i+1 ];

				idxVbVert2 = ((DWORD*)lpIB)[ i+2 ];

			   }

			else{

				idxVbVert0 = ((WORD*)lpIB)[ i ];

				idxVbVert1 = ((WORD*)lpIB)[ i+1 ];

				idxVbVert2 = ((WORD*)lpIB)[ i+2 ];

				}

	

			// lpVB is BYTE* and points to previously locked vertex data

			D3DXVECTOR3 v0 = *(D3DXVECTOR3*) &lpVB[ idxVbVert0 * numBytesPerVertex ];

			D3DXVECTOR3 v1 = *(D3DXVECTOR3*) &lpVB[ idxVbVert1 * numBytesPerVertex ];

			D3DXVECTOR3 v2 = *(D3DXVECTOR3*) &lpVB[ idxVbVert2 * numBytesPerVertex ];


			//[ now use vetex coordinates v0, v1, v2 for u own purpose ]

		    // do collision detection against polygon or keep extracting them

			// Fill array of vertices

			//Should be like this, but requires also a copy operator for the VERTEX class. 


			VERTLIST[0].x = v0.x;

			VERTLIST[0].y = v0.y;

			VERTLIST[0].z = v0.z;

			VERTLIST[1].x = v1.x;

			VERTLIST[1].y = v1.y;

			VERTLIST[1].z = v1.z;

			VERTLIST[2].x = v2.x;

			VERTLIST[2].y = v2.y;

			VERTLIST[2].z = v2.z;



			if( g_polygonList == NULL )

              {

                 g_polygonList = addPolygon(NULL,VERTLIST);

                 child = g_polygonList;

              }

            else

               {

                 child = addPolygon(child,VERTLIST);

              }

		}


	 pMeshSysMem->UnlockVertexBuffer();		//what was locked must be unlocked or else things i'll go bad

     pMeshSysMem->UnlockIndexBuffer();	

    }


  

End:

    SAFE_RELEASE( pMeshSysMem );

    SAFE_RELEASE( pAdjacencyBuffer );

   

    return hr;

}




#14 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 03 March 2006 - 09:58 AM

maybe this, change line:
BYTE* lpVB, lpIB;
to
BYTE *lpVB, *lpIB;

#15 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 06 March 2006 - 11:49 AM

Thanks; things are going fine now. now i am able to generate g_polygonLIst of mesh problem.
when I quit my application after rendering I got system warning that
" D3D object has a non zero reference count (meaning things were not properly cleaning"

my next step is to build BSP tree by passing bSp tree root node & g_polygonList to it. question is where should i call the BuildBspTree (); because it should get g_polygonList generated.
I have put it this way

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )

{

    CMyD3DApplication d3dApp;


    InitCommonControls();

    if( FAILED( d3dApp.Create( hInst ) ) )

        return 0;


	// Once the required poly's for the scene geometry is created with g_polygonList, 

    // we can compile the BSP tree by calling buildBspTree()...

    g_BSPTreeRootNode = new NODE;

    buildBspTree( g_BSPTreeRootNode, g_polygonList );


    return d3dApp.Run();

}



#16 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 08 March 2006 - 11:17 AM

Once I have linked list of polygons, next step is to build BSP tree.

buildBspTree( NODE *CurrentNode,POLYGON *PolyList ); l

this function uses

// Split the poly into two fragments
splitPolygon( polyTest, CurrentNode->Splitter, FrontSplit, BackSplit);

whenever there is need to do all the clipping and Splitting of
polygons. It takes a polygon and a Plane and splits
the polygon into to two seperate polygons.

My problem is locking of vertex & index buffer for memcpy function. There are 3 calls to memcpy() function in splitPolygon().
Should I use Using Dynamic Vertex and Index Buffers? Because there are frequent lock calls?


//-----------------------------------------------------------------------------

// Name : splitPolygon

// Desc : This function is used to do ALL the clipping and Splitting of 

//        polygons. It takes a polygon and a Plane and splits 

//        the polygon into to two seperate polygons. When used for clipping to 

//        a plane, call this function and then simply discard the front or

//        back depending on your needs.

// NOTE : FRONT and BACK MUST be valid pointers to empty Polygon structures as 

//        this function does NOT allocate the memory for them. The reason for

//        this is that this function is used in so many cases and some of them

//        required the Front and Back already be initialized. 

//-----------------------------------------------------------------------------

void CMyD3DApplication::splitPolygon( POLYGON *Poly, POLYGON *Plane, 

                   POLYGON *FrontSplit, POLYGON *BackSplit )

{

    // 50 is used here, as we should never really have more 

    // points on a portal than this.

    VERTEX FrontList[50];

    VERTEX BackList[50];

    int PointLocation[50];

    int CurrentVertex = 0;

    int FrontCounter  = 0;

    int BackCounter   = 0;

    int InFront       = 0;

    int Behind        = 0;

    int OnPlane       = 0;

    int Location      = 0;


    // Determine each points location relative to the plane.

    for( int i = 0; i < Poly->nNumberOfVertices; i++ )  

    {

        Location = classifyPoint((D3DXVECTOR3*)&Poly->VertexList[i], Plane);


        if (Location == POINTPOSITION_FRONT )

            ++InFront;

        else if (Location == POINTPOSITION_BACK )

            ++Behind;

        else

            ++OnPlane;


        PointLocation[i] = Location;

    }

    

    // We set the VertexList[0] location again at the end

    // of the array so that we don't have to check and loop later

    //PointLocation[Poly->nNumberOfVertices] = PointLocation[0];


    if( !InFront ) 

    {

        memcpy(BackList, Poly->VertexList, Poly->nNumberOfVertices * sizeof(VERTEX));

        BackCounter = Poly->nNumberOfVertices;

    }


    if( !Behind ) 

    {

        memcpy(FrontList, Poly->VertexList, Poly->nNumberOfVertices * sizeof(VERTEX));

        FrontCounter = Poly->nNumberOfVertices;

    }


    if( InFront && Behind ) 

    {

        for( i = 0; i < Poly->nNumberOfVertices; ++i) 

        {

            // Store Current vertex remembering to MOD with number of vertices.

            CurrentVertex = (i+1) % Poly->nNumberOfVertices;


            if (PointLocation[i] == POINTPOSITION_ONPLANE ) 

            {

                FrontList[FrontCounter] = Poly->VertexList[i];

                ++FrontCounter;

                BackList[BackCounter] = Poly->VertexList[i];

                ++BackCounter;

                continue; // Skip to next vertex

            }

            if (PointLocation[i] == POINTPOSITION_FRONT ) 

            {

                FrontList[FrontCounter] = Poly->VertexList[i];

                ++FrontCounter;

            } 

            else 

            {

                BackList[BackCounter] = Poly->VertexList[i];

                ++BackCounter;

            }

            

            // If the next vertex is not causing us to span the plane then continue

            //if (PointLocation[i+1] == CP_ONPLANE || PointLocation[i+1] == PointLocation[i]) continue;

            if( PointLocation[CurrentVertex] == POINTPOSITION_ONPLANE || 

                PointLocation[CurrentVertex] == PointLocation[i] ) 

                continue;

            

            // Otherwise create the new vertex

            D3DXVECTOR3 IntersectPoint;

            float       percent;


            getIntersect( (D3DXVECTOR3*)&Poly->VertexList[i], 

                          (D3DXVECTOR3*)&Poly->VertexList[CurrentVertex], 

                          (D3DXVECTOR3*)&Plane->VertexList[0], 

                          &Plane->Normal, &IntersectPoint, &percent );


            // create new vertex  

            VERTEX copy;

           

            copy.x       = IntersectPoint.x;

            copy.y       = IntersectPoint.y;

            copy.z       = IntersectPoint.z;

           


            BackList[BackCounter++]   = copy;

            FrontList[FrontCounter++] = copy;

        }

    }


    //OK THEN LETS BUILD THESE TWO POLYGONAL 


    FrontSplit->nNumberOfVertices = 0;

    BackSplit->nNumberOfVertices  = 0;


    // Copy over the vertices into the new polys

    FrontSplit->nNumberOfVertices = FrontCounter;

    memcpy(FrontSplit->VertexList, FrontList, FrontCounter * sizeof(VERTEX));

    BackSplit->nNumberOfVertices  = BackCounter;

    memcpy(BackSplit->VertexList, BackList, BackCounter * sizeof(VERTEX));


   

    // Copy Extra Values

    FrontSplit->Normal = Poly->Normal;

    BackSplit->Normal  = Poly->Normal;

}




#17 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 28 March 2006 - 09:29 AM

because you're using constant sizes for front and back lists, i assume your application is quite smal, therefore using default options for all directx buffers ll be sufficient.

#18 Pushapjit

    Member

  • Members
  • PipPip
  • 34 posts

Posted 29 March 2006 - 07:22 AM

1)is this ok to have 50 as the limit for points on a portal. how i should i calculate this limit?
2) while memcpy() function call should i lock both vertex as well as index buffer; and with what options?

splitPolygon() function is called from buildbsptree() function whenever there is need for two new polys for the fregment.

#19 ikk

    Member

  • Members
  • PipPip
  • 87 posts

Posted 31 March 2006 - 11:59 PM

1) i don't know is it ok, this may be the case of design, if u want to make your engine/application fully flexible you should use dynamic arrays. but then, having everything dynamic would made your code more complicated.
you should decide yourself if there wont be need for larger arrays, are objects the code work with are small enough.

2) lock buffers with "read only" option if you dont want to modify them. but rather than options used, it is important to ensure that lock was successful.
please refer to directx documentation on functions you're using.
search directx manual for "LockVertexBuffer" function.

also please note that i cant help you with everything, im not fully experienced with terms we're using here.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users