I can see that in a .x template
template VertexDuplicationIndices {
<b8d65549-d7c9-4995-89cf-53a9a8b031e3>
DWORD nIndices;
DWORD nOriginalVertices;
array DWORD indices[nIndices];
}
There is a duplication of vertices. I believe this was done during the
export when faces sharing a vertex duplicates that vertex. Am I right
to say that
My main problem is how can I get pointers or references back to the original vertices
Can anyone help

.x Model and duplicated vertices issue
C#2006
There is a difference between the actual mesh indices and “VertexDuplicationIndices”.
“VertexDuplicationIndices” doesn’t actually make triangles or whatever type of ordering, its just saying these are the indices used with a few duplicates that have different properties. Also the template might be declared but it doesn’t mean it’s used.
Looks like Etienne is onto something with D3DXWeldVertices, I haven’t used it either, will try later too.
I’m not sure about Maya, I use trueSpace. In the utilities section of the SDK is the source code for the Maya exporter which might be worth checking out, well I’m using the December 2004 version of the SDK which has it, not sure about the latest.
Here’s a small console app to extract the duplication data. Notice the way I’m linking the structures, things end up in a reversed order. I haven’t done any error checking to save space, you can add this.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
// xfile objects
#include <d3dx9xof.h>
// required header for VertexDuplicationIndices template and guid
#include <d3dx9mesh.h>
// Standard xfile templates and guids
#include "rmxfguid.h"
#include "rmxftmpl.h"
#pragma comment (lib, "d3dx9.lib") // D3DX lib
// Declare the structure
struct sDuplicateIndices
{
DWORD nIndices;
DWORD nOriginalVertices;
int *pIndices;
sDuplicateIndices *pNext;
sDuplicateIndices()
{
nIndices = 0;
nOriginalVertices = 0;
pIndices = NULL;
pNext = NULL;
}
~sDuplicateIndices()
{
if(pIndices) delete [] pIndices;
if(pNext) delete pNext;
}
};
BOOL Load(const char *FileName, sDuplicateIndices **ppDupIndices);
BOOL Parse(ID3DXFileData *pData, sDuplicateIndices **ppDupIndices);
int main()
{
sDuplicateIndices *pDupIndices = NULL;
// SDK sample, not to big
Load("airplane 2.x", &pDupIndices);
if(pDupIndices)
{
sDuplicateIndices* ptr = pDupIndices;
while(ptr != NULL)
{
std::cout << "Number of indices: " << ptr->nIndices << std::endl;
std::cout << "Original vertices: " << ptr->nOriginalVertices << std::endl;
std::cout << "The indices : " << std::endl;
for(DWORD i = 0; i < ptr->nIndices; ++i)
{
std::cout << ptr->pIndices[ i ] << ",";
}
std::cout << std::endl << std::endl;
ptr = ptr->pNext;
}
delete pDupIndices;
}
return 0;
}
BOOL Load(const char *FileName, sDuplicateIndices **ppDupIndices)
{
ID3DXFile *pFile = NULL;
ID3DXFileEnumObject *pEnum = NULL;
ID3DXFileData *pData = NULL;
SIZE_T nChildren;
HRESULT hr;
// Create file object
hr = D3DXFileCreate(&pFile);
// Register standard templates
hr = pFile->RegisterTemplates((LPCVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
// Register skin extension templates where VertexDuplicationIndices is defined
// Shouldn't be needed since these are usually defined in the XFiles
//hr = pFile->RegisterTemplates((LPCVOID)XSKINEXP_TEMPLATES, strlen(XSKINEXP_TEMPLATES));
//hr = pFile->RegisterTemplates((LPCVOID)XEXTENSIONS_TEMPLATES, strlen(XEXTENSIONS_TEMPLATES));
// I think there are more templates spread around the place
// Create enumeration object, you’ll get a pass error here for an invalid xfile
hr = pFile->CreateEnumObject((LPCVOID)FileName, D3DXF_FILELOAD_FROMFILE, &pEnum);
// Get the number of top-level objects
hr = pEnum->GetChildren(&nChildren);
// Loop through the top-level objects
for(SIZE_T nChild = 0; nChild < nChildren; ++nChild)
{
// Get the child data
hr = pEnum->GetChild(nChild, &pData);
// Parse data
Parse(pData, ppDupIndices);
pData->Release();
}
pEnum->Release();
pFile->Release();
return TRUE;
}
BOOL Parse(ID3DXFileData *pData, sDuplicateIndices **ppDupIndices)
{
ID3DXFileData *pSubData = NULL;
SIZE_T Size;
GUID Type;
BYTE **Ptr = NULL;
HRESULT hr;
// Get the template type
hr = pData->GetType(&Type);
// Check for a VertexDuplicationIndices type
if(Type == DXFILEOBJ_VertexDuplicationIndices)
{
// Create a new structure
sDuplicateIndices *pDI = new sDuplicateIndices;
// Access the data buffer
hr = pData->Lock(&Size, (LPCVOID*)&Ptr);
// Load the information
pDI->nIndices = ((DWORD*)Ptr)[0];
pDI->nOriginalVertices = ((DWORD*)Ptr)[1];
pDI->pIndices = new int[pDI->nIndices];
memcpy(pDI->pIndices, &((DWORD*)Ptr)[2], sizeof(int) * pDI->nIndices);
// Release the data buffer
hr = pData->Unlock();
// Link into list
pDI->pNext = *ppDupIndices;
*ppDupIndices = pDI;
}
// Scan for embedded templates
hr = pData->GetChildren(&Size);
for(SIZE_T nChild = 0; nChild < Size; ++nChild)
{
hr = pData->GetChild(nChild, &pSubData);
Parse(pSubData, ppDupIndices);
pSubData->Release();
}
return TRUE;
}
Check out a book like Jim Adams “Advanced Animation with DirectX” for more advanced stuff dealing with animation loading.
xeno18274
For a small square in 2 triangles :
the Vertex Buffer 0,1,2,3 so
for the Index Buffer 2 faces/triangle 0,1,2 and 0,2,3 (clock wise)
Your index use the order your vertex was entered...
They are NOT the number of the vertex...just the ORDER they were entered...
I have the same problem to solve...
I have many square to add up and I want to remove their common vertex
for 2 square I have
0,1,2,3 and 3,2,4,5
So I have twice the vertex 2 and 3...
I found the function D3DXWeldvertice...that should merge all vertex that have
the same position and material...it should word for static mesh, I didn't try it yet
It's a mesh function...(not the exact word for the function but it has ''Weld'' in it)
kiwigriff
I was looking on the net, but information on this subject is sparse, I found some good ebooks though.
From what I’ve understood so far some 3D packages write the templates to the xfile so they don’t have to register them, the templates are essentially registered as the file is read. In some of the forums I came across, people were creating simple shapes by writing their own xfiles and trying to load them into their 3D software with little success, they then added the template declarations to their files and the thing would load without a problem.
If you’re parsing the file yourself you can always check for the template’s GUID and extract the information to something separate, then you can play about with it. Maybe you can create a separate vertex buffer and put the vertices into that while ignoring any duplicates to see what will happen.
You can also optimise your mesh using D3DXMESHOPT_ATTRSORT so the faces with the same properties a grouped together. Then you can extract the meshes attribute table and use the attribute’s ID to determine which material and/or texture is being used, also the faces and vertices used. This way you can draw the subsets you want.
Basically we’re going to have to experiment, or maybe someone who knows what he’s talking might come a tell us.
TravelMan
Please correct me or advise me if my understanding is wrong, as I am still pretty new to Direct X.
jefswy
http://msdn.microsoft.com/library/default.asp url=/library/en-us/directx9_c/D3DXWeldVertices.asp frame=true
Giedrius Banaitis
From reading the description of "VertexDuplicationIndices" in the DX documentation this is what I understand.
"nIndices" the number of vertices in the mesh.
"nOriginalVertices" is the number of vertices before duplication, so the number of duplicate vertices must be:
nIndices – nOriginalVertices = number of duplicates
Any indices that are the same in "indices[nIndices]" are the duplicates, so you know where the duplicates are in the vertex buffer.
The thing is the information’s there, but how do you put it together for what you want That’s the question.
If you’ve never passed an xfile before let me know and I’ll put a little example for you.
nidionys
Thanks for the reply, I should have gone to the DirectX SDK files to compile my own exporter that exports the information I need.. how silly of me not to think of this.
I will try out the D3DXMESHOPT_ATTRSORT later on too.. thanks!
Claudia K
I think I am getting what you are driving at.
In the .x file there is the array of indices
eg.
0
1
2
3
2
....
So the second "2" is actually a duplicate right So now all I really need is to parse the .x file and get a handle to this array then remove the duplicates I am not that familar to parsing the .x file, do you have an example to show me
This is another problem, I just realise that directx reads the vertices in a different order then that of Maya. It reads them by the triangle while Maya reads it from bottom up, ie. the DirectX ordering of vertices don't match the Maya one.
Thanks a million!