public ABScene3D LoadScene(string file) { uint failId; int failPos; lwObject lwobj = lwObject.GetObject5(file, out failId, out failPos); if (lwobj != null) { // convert to AB ABScene3D scene = new ABScene3D(); ABMaterial[] materials = null; int[] clipIndices = null; if (lwobj.surf != null && lwobj.surf.Count > 0) { materials = new ABMaterial[lwobj.surf.Count]; clipIndices = new int[lwobj.surf.Count]; LinkedList <lwSurface> .Enumerator matIter = lwobj.surf.GetEnumerator(); int matIdx = 0; while (matIter.MoveNext()) { lwSurface surface = matIter.Current; ABMaterial mat = materials[matIdx] = new ABMaterial(); mat.Name = surface.name; mat.Ambient = new ABColorARGB(); mat.Ambient.A = 0xFF; mat.Ambient.R = (byte)(surface.color.rgb[0] / 255f); mat.Ambient.G = (byte)(surface.color.rgb[1] / 255f); mat.Ambient.B = (byte)(surface.color.rgb[2] / 255f); mat.Diffuse = new ABColorARGB(); mat.Diffuse.A = 0xFF; mat.Diffuse.R = (byte)((surface.diffuse.val * surface.color.rgb[0]) / 255f); mat.Diffuse.G = (byte)((surface.diffuse.val * surface.color.rgb[1]) / 255f); mat.Diffuse.B = (byte)((surface.diffuse.val * surface.color.rgb[2]) / 255f); if (surface.color.tex != null) { // resolve texture //mat.TextureName clipIndices[matIdx] = surface.color.tex.First.Value.imap.cindex; mat.TextureName = surface.color.tex.First.Value.imap.vmap_name; } else { clipIndices[matIdx] = -1; } matIdx++; } } LinkedList <lwLayer> .Enumerator layIter = lwobj.layer.GetEnumerator(); scene.Models = new ABModel3D[lwobj.layer.Count]; int mdlIdx = 0; while (layIter.MoveNext()) { lwLayer layer = layIter.Current; ABModel3D model = scene.Models[mdlIdx] = new ABModel3D(); model.Geometry = new ABGeometry3D(); model.Geometry.Vertices = new Vector3[layer.point.count]; // break up polygons by surface Dictionary <lwSurface, int> surfGroupCounts = new Dictionary <lwSurface, int>(); for (int i = 0; i < layer.polygon.pol.Length; i++) { lwPolygon polygon = layer.polygon.pol[i]; if (surfGroupCounts.ContainsKey(polygon.surf)) { surfGroupCounts[polygon.surf]++; } else { surfGroupCounts[polygon.surf] = 1; } } int[] groupIndices = new int[surfGroupCounts.Count]; model.MaterialIndices = new ABMaterialIndex[surfGroupCounts.Count]; for (int i = 0; i < layer.polygon.pol.Length; i++) { lwPolygon polygon = layer.polygon.pol[i]; if (surfGroupCounts.ContainsKey(polygon.surf)) { surfGroupCounts[polygon.surf]++; } else { surfGroupCounts[polygon.surf] = 1; } } } // match up clips to materials } return(null); }
public const uint ID_TFP1 = 0x54465031; //ID(('T','F','P','1') #endregion /// <summary> /// Returns the contents of an LWOB, given its filename, or NULL if the /// file couldn't be loaded. On failure, failID and failpos can be used /// to diagnose the cause. /// /// 1. If the file isn't an LWOB, failpos will contain 12 and failID will /// be unchanged. /// /// 2. If an error occurs while reading an LWOB, failID will contain the /// most recently read IFF chunk ID, and failpos will contain the /// value returned by ftell() at the time of the failure. /// /// 3. If the file couldn't be opened, or an error occurs while reading /// the first 12 bytes, both failID and failpos will be unchanged. /// /// If you don't need this information, failID and failpos can be NULL. /// </summary> public static lwObject GetObject5(string filename, out uint failID, out int failpos) { FileStream fp = null; BinaryReader br = null; lwObject obj; lwLayer layer; lwSurface node; uint id, formsize, type, cksize; int flen; /* open the file */ try { br = new BinaryReader(fp = new FileStream(filename, FileMode.Open)); } catch { failID = 0; failpos = 0; return(null); } /* read the first 12 bytes */ flen = 0; id = lwio.getU4(br, ref flen); formsize = lwio.getU4(br, ref flen); type = lwio.getU4(br, ref flen); if (12 != flen) { br.Close(); fp.Close(); failID = 0; failpos = 0; return(null); } /* LWOB? */ if (id != LWID.ID_FORM || type != LWID.ID_LWOB) { br.Close(); fp.Close(); failpos = 12; failID = 0; return(null); } /* allocate an object and a default layer */ obj = new lwObject(); layer = new lwLayer(); obj.layer = new LinkedList <lwLayer>(); obj.layer.AddFirst(layer); obj.nlayers = 1; /* get the first chunk header */ id = lwio.getU4(br, ref flen); cksize = lwio.getU4(br, ref flen); if (0 > flen) { goto Fail; } /* process chunks as they're encountered */ while (true) { cksize += cksize & 1; switch (id) { case LWID.ID_PNTS: if (!lwPointList.GetPoints(fp, (int)cksize, ref layer.point, ref flen)) { goto Fail; } break; case LWID.ID_POLS: if (!layer.polygon.GetPolygons5(fp, cksize, layer.point.offset)) { goto Fail; } break; case ID_SRFS: if (!lwTagList.GetTags(br, (int)cksize, ref obj.taglist, ref flen)) { goto Fail; } break; case LWID.ID_SURF: node = obj.GetSurface5(br, (int)cksize, ref flen); if (node == null) { goto Fail; } obj.surf.AddLast(node); obj.nsurfs++; break; default: fp.Seek(cksize, SeekOrigin.Current); break; } /* end of the file? */ if (formsize <= (uint)fp.Position - 8) { break; } /* get the next chunk header */ flen = 0; id = lwio.getU4(br, ref flen); cksize = lwio.getU4(br, ref flen); if (8 != flen) { goto Fail; } } br.Close(); fp.Close(); fp = null; layer.point.GetBoundingBox(ref layer.bbox); layer.point.GetPolyNormals(ref layer.polygon); if (!layer.point.GetPointPolygons(ref layer.polygon)) { goto Fail; } if (!layer.polygon.ResolvePolySurfaces(ref obj.taglist, ref obj.surf, ref obj.nsurfs)) { goto Fail; } layer.point.GetVertNormals(ref layer.polygon); failID = 0; failpos = 0; return(obj); Fail: failID = id; if (fp != null) { failpos = (int)fp.Position; fp.Close(); } else { failpos = 0; } obj.Dispose(); return(null); }
public const uint ID_TFP1 = 0x54465031;//ID(('T','F','P','1') #endregion /// <summary> /// Returns the contents of an LWOB, given its filename, or NULL if the /// file couldn't be loaded. On failure, failID and failpos can be used /// to diagnose the cause. /// /// 1. If the file isn't an LWOB, failpos will contain 12 and failID will /// be unchanged. /// /// 2. If an error occurs while reading an LWOB, failID will contain the /// most recently read IFF chunk ID, and failpos will contain the /// value returned by ftell() at the time of the failure. /// /// 3. If the file couldn't be opened, or an error occurs while reading /// the first 12 bytes, both failID and failpos will be unchanged. /// /// If you don't need this information, failID and failpos can be NULL. /// </summary> public static lwObject GetObject5(string filename, out uint failID, out int failpos) { FileStream fp = null; BinaryReader br = null; lwObject obj; lwLayer layer; lwSurface node; uint id, formsize, type, cksize; int flen; /* open the file */ try { br = new BinaryReader(fp = new FileStream(filename, FileMode.Open)); } catch { failID = 0; failpos = 0; return null; } /* read the first 12 bytes */ flen = 0; id = lwio.getU4(br, ref flen); formsize = lwio.getU4(br, ref flen); type = lwio.getU4(br, ref flen); if (12 != flen) { br.Close(); fp.Close(); failID = 0; failpos = 0; return null; } /* LWOB? */ if (id != LWID.ID_FORM || type != LWID.ID_LWOB) { br.Close(); fp.Close(); failpos = 12; failID = 0; return null; } /* allocate an object and a default layer */ obj = new lwObject(); layer = new lwLayer(); obj.layer = new LinkedList<lwLayer>(); obj.layer.AddFirst(layer); obj.nlayers = 1; /* get the first chunk header */ id = lwio.getU4(br, ref flen); cksize = lwio.getU4(br, ref flen); if (0 > flen) goto Fail; /* process chunks as they're encountered */ while (true) { cksize += cksize & 1; switch (id) { case LWID.ID_PNTS: if (!lwPointList.GetPoints(fp, (int)cksize, ref layer.point, ref flen)) goto Fail; break; case LWID.ID_POLS: if (!layer.polygon.GetPolygons5(fp, cksize, layer.point.offset)) goto Fail; break; case ID_SRFS: if (!lwTagList.GetTags(br, (int)cksize, ref obj.taglist, ref flen)) goto Fail; break; case LWID.ID_SURF: node = obj.GetSurface5(br, (int)cksize, ref flen); if (node == null) goto Fail; obj.surf.AddLast(node); obj.nsurfs++; break; default: fp.Seek(cksize, SeekOrigin.Current); break; } /* end of the file? */ if (formsize <= (uint)fp.Position - 8) break; /* get the next chunk header */ flen = 0; id = lwio.getU4(br, ref flen); cksize = lwio.getU4(br, ref flen); if (8 != flen) goto Fail; } br.Close(); fp.Close(); fp = null; layer.point.GetBoundingBox(ref layer.bbox); layer.point.GetPolyNormals(ref layer.polygon); if (!layer.point.GetPointPolygons(ref layer.polygon)) goto Fail; if (!layer.polygon.ResolvePolySurfaces(ref obj.taglist, ref obj.surf, ref obj.nsurfs)) goto Fail; layer.point.GetVertNormals(ref layer.polygon); failID = 0; failpos = 0; return obj; Fail: failID = id; if (fp != null) { failpos = (int)fp.Position; fp.Close(); } else failpos = 0; obj.Dispose(); return null; }