static unsafe BRenderGrannyMesh LoadGR2Internal(granny_file *grannyFile) { try { if (grannyFile != null) { // It's a file Granny can load (but might be just a raw bunch of bits). granny_file_info *file_info = GrannyGetFileInfo((IntPtr)grannyFile); if (file_info != null) { ConvertCoordinateSystem(file_info, true, true); //file has been transformed, load our meshes BRenderGrannyMesh mesh = new BRenderGrannyMesh(); createMeshFromGR2(ref mesh, file_info); return(mesh); } } } catch (Exception e) { Console.WriteLine("Error loading granny file"); } return(null); }
static public unsafe BRenderGrannyMesh LoadGR2FromFile(string filename) { if (!File.Exists(filename)) { // CoreGlobals.getErrorManager().OnSimpleWarning(String.Format("GrannyFile {0} was not found", filename)); return(null); } IntPtr ptr = GrannyReadEntireFile(filename); BRenderGrannyMesh mesh = LoadGR2Internal((granny_file *)ptr); GrannyFreeFile(ptr); return(mesh); }
static private unsafe void createMeshFromGR2(ref BRenderGrannyMesh mesh, granny_file_info *fileInfo) { int NumMeshes = fileInfo->ModelCount; for (int i = 0; i < NumMeshes; i++) { try { if (fileInfo->Models[i]->MeshBindingCount == 0) { // CoreGlobals.getErrorManager().OnSimpleWarning(String.Format("No Mesh Binding for model# {0} out of {1} in {2}", i, NumMeshes, filename)); } else { processMesh(ref mesh, fileInfo->Models[i]->MeshBindings[0].Mesh); } } catch (System.Exception ex) { // CoreGlobals.getErrorManager().OnSimpleWarning(String.Format("Error processing mesh #{0} out of {1} in {2}. {3}", i, NumMeshes, filename, ex.ToString())); } } }
static private unsafe void processMesh(ref BRenderGrannyMesh mesh, granny_mesh *grannyMesh) { BRenderPrimitive prim = new BRenderPrimitive(); //indicies prim.mNumInds = GrannyGetMeshTriangleCount(grannyMesh) * 3; int[] indData = new int[prim.mNumInds]; int indexSize = prim.mNumInds * sizeof(int); IntPtr pMarshaledIndexMem = System.Runtime.InteropServices.Marshal.AllocHGlobal(indexSize); GrannyCopyMeshIndices(grannyMesh, 4, (int *)pMarshaledIndexMem); System.Runtime.InteropServices.Marshal.Copy(pMarshaledIndexMem, indData, 0, prim.mNumInds); System.Runtime.InteropServices.Marshal.FreeHGlobal(pMarshaledIndexMem); //ib's prim.mIB = new IndexBuffer(typeof(int), prim.mNumInds, BRenderDevice.getDevice(), Usage.None, Pool.Managed); GraphicsStream stream = prim.mIB.Lock(0, 0, LockFlags.None); int * outInds = (int *)stream.InternalDataPointer; for (int q = 0; q < prim.mNumInds; q++) { outInds[q] = indData[q]; } prim.mIB.Unlock(); stream.Close(); //verticies prim.mVertexSize = 0; granny_data_type_definition *grnyVertTypeDef = GrannyGetMeshVertexType(grannyMesh); granny_data_type_definition[] grnDTD = null; VertexDeclaration grnVD = null; if (!getVertexTypeFromGranny(grnyVertTypeDef, ref prim.mVertexSize, ref grnDTD, ref grnVD, ref prim.mVDecl)) { //already logged //CoreGlobals.getErrorManager().OnSimpleWarning(String.Format("Error loading {0} getVertexTypeFromGranny failed", filename)); return; } prim.mNumVerts = GrannyGetMeshVertexCount(grannyMesh); { int size = prim.mNumVerts * prim.mVertexSize; IntPtr pMarshaledMem = System.Runtime.InteropServices.Marshal.AllocHGlobal(size); byte[] tGrnVerts = new byte[size]; fixed(granny_data_type_definition *grnPD = grnDTD) GrannyCopyMeshVertices(grannyMesh, grnPD /*grnyVertTypeDef*/, (void *)pMarshaledMem); System.Runtime.InteropServices.Marshal.Copy(pMarshaledMem, tGrnVerts, 0, size); System.Runtime.InteropServices.Marshal.FreeHGlobal(pMarshaledMem); byte[] d3dVerts = new byte[size]; //swizzle the granny verts to be d3d friendly before copying them to the device swzzlGrnyVertsToD3DVerts(tGrnVerts, grnVD, prim.mVertexSize, prim.mNumVerts, ref d3dVerts, prim.mVDecl); prim.mVB = new VertexBuffer(BRenderDevice.getDevice(), (int)prim.mNumVerts * prim.mVertexSize, Usage.None, VertexFormats.None, Pool.Managed); stream = prim.mVB.Lock(0, 0, LockFlags.None); stream.Write(d3dVerts, 0, size); prim.mVB.Unlock(); stream.Close(); tGrnVerts = null; grnVD.Dispose(); grnVD = null; } //SUB GROUPS int groupCount = GrannyGetMeshTriangleGroupCount(grannyMesh); granny_tri_material_group *GrannyMatGroups = GrannyGetMeshTriangleGroups(grannyMesh); //process our material groups for this mesh for (int k = 0; k < groupCount; k++) { BRenderMaterialGroup group = new BRenderMaterialGroup(); group.mStartIndex = GrannyMatGroups[k].TriFirst * 3; group.mPrimCount = GrannyMatGroups[k].TriCount; //load your texture here. prim.mGroups.Add(group); } mesh.addRenderPrimitive(prim); }