int msXAMLExporter::Execute (msModel *pModel){ if (!pModel) return -1; // // check, if we have something to export // if (msModel_GetMeshCount (pModel) == 0) { ::MessageBox (NULL, "The model is empty! Nothing exported!", "XAML Exporter", MB_OK | MB_ICONWARNING); return 0; } // // choose filename // OPENFILENAME ofn; memset (&ofn, 0, sizeof (OPENFILENAME)); char szFile[MS_MAX_PATH]; char szFileTitle[MS_MAX_PATH]; char szDefExt[32] = "txt"; char szFilter[128] = "XAML Files (*.xaml)\0*.xaml\0All Files (*.*)\0*.*\0\0"; szFile[0] = '\0'; szFileTitle[0] = '\0'; ofn.lStructSize = sizeof (OPENFILENAME); ofn.lpstrDefExt = szDefExt; ofn.lpstrFilter = szFilter; ofn.lpstrFile = szFile; ofn.nMaxFile = MS_MAX_PATH; ofn.lpstrFileTitle = szFileTitle; ofn.nMaxFileTitle = MS_MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; ofn.lpstrTitle = "Export XAML"; if (!::GetSaveFileName (&ofn)) return 0; // // export // FILE *file = fopen (szFile, "wt"); if (!file) return -1; int i, j; char szName[MS_MAX_NAME]; for (i = 0; i < msModel_GetMeshCount (pModel); i++) { msMesh *pMesh = msModel_GetMeshAt (pModel, i); msMesh_GetName (pMesh, szName, MS_MAX_NAME); if (strlen(szName) == 0) strcpy(szName, "myModel"); fprintf( file, "<MeshGeometry3D x:Key='%s'", szName ); // // vertices // fprintf( file, " \r\nPositions='"); for (j = 0; j < msMesh_GetVertexCount (pMesh); j++) { msVertex *pVertex = msMesh_GetVertexAt (pMesh, j); msVec3 Vertex; msVertex_GetVertex (pVertex, Vertex); fprintf (file, "%f,%f,%f ", Vertex[0], Vertex[1], Vertex[2] ); } // // vertex normals // fprintf( file, "' \r\nNormals='"); for (j = 0; j < msMesh_GetVertexNormalCount (pMesh); j++) { msVec3 Normal; msMesh_GetVertexNormalAt (pMesh, j, Normal); fprintf (file, "%f,%f,%f \n", Normal[0], Normal[1], Normal[2]); } // // triangles // fprintf( file, "' \r\nTriangleIndices='"); for (j = 0; j < msMesh_GetTriangleCount (pMesh); j++) { msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, j); word nIndices[3]; msTriangle_GetVertexIndices (pTriangle, nIndices); fprintf (file, "%d %d %d \n", nIndices[0], nIndices[1], nIndices[2] ); } fprintf( file, "'/>\r\n"); } fclose (file); // dont' forget to destroy the model msModel_Destroy (pModel); return 0;}
When you build your DLL, make sure you place it in the installation directory of MilkShape. Not being a simple 'cube' type of guy, I opted to use the terrain generator (Tools->Terrain Generator). After clicking the 'Add Terrain' button, I had to scale the mesh down so the camera in my sample XAML project can view it properly. I used the Scale All tool twice using 10% as the scale value. Once this was done, I clicked on File->Export->XAML Export and saved it to a XAML file. Here's a screenshot of MilkShape and my terrain:
I should note that the exporter itself does not output ready to use XAML (i.e. you can't open it up in XAMLPad). I just had the exporter ouput a MeshGeometry3D element. After I exported the file, I copied the contents of that file and inserted it as a child of the <Application.Resources> element found in the MyApp.xaml file of my XAML project. Next, I noted the name of the 'key' attribute (in this case it was 'terrain') and opened the Windows1.xaml file and looked for the model it was loading. I changed the GeometryModel3D element by using the attribute value "{StaticResource terrain}" defined in the Geometry attribute. The word 'terrain' corresponds to the Key attribute my exporter defined when it output the MeshGeometry3D element. With all that finished, I hit build, ran it and saw the following:
Believe it or not, my exporter worked on the 1st try (that rarely happens). I haven't gotten into any of the material definitions and the lighting that I told Avalon to use was taken directly from the Animate3DRotation demo. If I get bored again one day, I might expand the exporter to export material definitions in the exported XAML file (I think I already know how to do that but I have other fish to fry if you know what I mean).
So there you go. Avalon does 3D but it makes it much easier if you have a 3D modelling tool that will export the XAML code for you. Here's a link to the projects: