public SphFile(IntermediateNode root, ILibFile library) { if (root == null) { throw new ArgumentNullException("root"); } if (library == null) { throw new ArgumentNullException("materialLibrary"); } materialsAccessor = new SphMaterials(this); ready = false; this.library = library; sideMaterialNames = new List <string>(); bool sphereSet = false; foreach (Node node in root) { switch (node.Name.ToLowerInvariant()) { case "sphere": if (sphereSet) { throw new Exception("Multiple sphere nodes"); } sphereSet = true; var sphereNode = (IntermediateNode)node; foreach (LeafNode sphereSubNode in sphereNode) { string name = sphereSubNode.Name.ToLowerInvariant(); if (name.StartsWith("m", StringComparison.OrdinalIgnoreCase)) { sideMaterialNames.Add(sphereSubNode.StringData); } else if (name == "radius") { Radius = sphereSubNode.SingleArrayData[0]; } else if (name == "sides") { int count = sphereSubNode.Int32ArrayData[0]; if (count != sideMaterialNames.Count) { throw new Exception("Invalid number of sides in " + node.Name + ": " + count); } } else { throw new Exception("Invalid node in " + node.Name + ": " + sphereSubNode.Name); } } break; case "vmeshlibrary": IntermediateNode vMeshLibraryNode = node as IntermediateNode; if (VMeshLibrary == null) { VMeshLibrary = new VmsFile(vMeshLibraryNode, library); } else { throw new Exception("Multiple vmeshlibrary nodes in 3db root"); } break; case "material library": IntermediateNode materialLibraryNode = node as IntermediateNode; if (MaterialLibrary == null) { MaterialLibrary = new MatFile(materialLibraryNode, library); } else { throw new Exception("Multiple material library nodes in 3db root"); } break; case "texture library": IntermediateNode textureLibraryNode = node as IntermediateNode; if (TextureLibrary == null) { TextureLibrary = new TxmFile(textureLibraryNode); } else { throw new Exception("Multiple texture library nodes in 3db root"); } break; } } }
public static Material FromNode(IntermediateNode node, ILibFile textureLibrary) { if (node == null) { throw new ArgumentNullException("node"); } if (textureLibrary == null) { throw new ArgumentNullException("textureLibrary"); } LeafNode typeNode = node["Type"] as LeafNode; if (typeNode == null) { throw new Exception("Invalid or missing type node in " + node.Name); } string type = typeNode.StringData; type = MaterialMap.Instance.Get(type) ?? type; type = MaterialMap.Instance.Get(node.Name.ToLowerInvariant()) ?? type; if (type == "HighGlassMaterial" || type == "HUDAnimMaterial" || type == "HUDIconMaterial" || type == "PlanetWaterMaterial") { type = "DcDtOcOt"; //HACK: Should do env mapping } if (type == "ExclusionZoneMaterial") { type = "DcDt"; //HACK: This is handled in NebulaRenderer, not in Material.cs } var mat = new Material(node, textureLibrary, type); if (basicMaterials.Contains(type)) { mat.isBasic = true; } else { switch (type) { case "Nebula": case "NebulaTwo": case "AtmosphereMaterial": case "DetailMapMaterial": case "DetailMap2Dm1Msk2PassMaterial": case "IllumDetailMapMaterial": case "Masked2DetailMapMaterial": case "NomadMaterialNoBendy": case "NomadMaterial": break; default: throw new Exception("Invalid material type: " + type); } } return(mat); }
public SphFile(string path, ILibFile materialLibrary) : this(parseFile(path), materialLibrary) { }
public CmpFile(string path, ILibFile additionalLibrary) : this(parseFile(path), additionalLibrary) { Path = path; }
public CmpFile(IntermediateNode rootnode, ILibFile additionalLibrary) { this.additionalLibrary = additionalLibrary; Models = new Dictionary <string, ModelFile>(); Cameras = new Dictionary <string, CmpCameraInfo>(); Constructs = new ConstructCollection(); Parts = new List <Part>(); List <string> modelNames = new List <string>(); foreach (Node node in rootnode) { switch (node.Name.ToLowerInvariant()) { case "exporter version": break; case "vmeshlibrary": IntermediateNode vMeshLibraryNode = node as IntermediateNode; if (VMeshLibrary == null) { VMeshLibrary = new VmsFile(vMeshLibraryNode, this); } else { throw new Exception("Multiple vmeshlibrary nodes in cmp root"); } break; case "animation": IntermediateNode animationNode = node as IntermediateNode; if (Animation == null) { Animation = new AnmFile(animationNode, Constructs); } else { throw new Exception("Multiple animation nodes in cmp root"); } break; case "material library": IntermediateNode materialLibraryNode = node as IntermediateNode; if (MaterialLibrary == null) { MaterialLibrary = new MatFile(materialLibraryNode, this); } else { throw new Exception("Multiple material library nodes in cmp root"); } break; case "texture library": IntermediateNode textureLibraryNode = node as IntermediateNode; if (TextureLibrary == null) { TextureLibrary = new TxmFile(textureLibraryNode); } else { throw new Exception("Multiple texture library nodes in cmp root"); } break; case "cmpnd": IntermediateNode cmpndNode = node as IntermediateNode; foreach (Node SubNode in cmpndNode) { if (SubNode is LeafNode) { continue; } var cmpndSubNode = (IntermediateNode)SubNode; if (cmpndSubNode.Name.Equals("cons", StringComparison.OrdinalIgnoreCase)) { Constructs.AddNode(cmpndSubNode); } else if ( cmpndSubNode.Name.StartsWith("part_", StringComparison.OrdinalIgnoreCase) || cmpndSubNode.Name.Equals("root", StringComparison.OrdinalIgnoreCase) ) { string objectName = string.Empty, fileName = string.Empty; foreach (LeafNode partNode in cmpndSubNode) { switch (partNode.Name.ToLowerInvariant()) { case "object name": objectName = partNode.StringData; break; case "file name": fileName = partNode.StringData; break; case "index": break; default: FLLog.Error("Cmp", "Invalid node in " + cmpndSubNode.Name + ": " + partNode.Name); break; } } Parts.Add(new Part(objectName, fileName, Models, Cameras, Constructs)); } else { throw new Exception("Invalid node in " + cmpndNode.Name + ": " + cmpndSubNode.Name); } } break; case "materialanim": MaterialAnim = new MaterialAnimCollection((IntermediateNode)node); break; default: if (node is IntermediateNode) { var im = (IntermediateNode)node; if (im.Any(x => x.Name.Equals("vmeshpart", StringComparison.OrdinalIgnoreCase) || x.Name.Equals("multilevel", StringComparison.OrdinalIgnoreCase))) { ModelFile m = new ModelFile(im, this); m.Path = node.Name; Models.Add(node.Name, m); modelNames.Add(node.Name); break; } else if (im.Any(x => x.Name.Equals("camera", StringComparison.OrdinalIgnoreCase))) { var cam = new CmpCameraInfo(im); Cameras.Add(im.Name, cam); break; } } FLLog.Error("Cmp", Path ?? "Utf" + ": Invalid Node in cmp root: " + node.Name); break; } } //FL handles cmpnd nodes that point to non-existant models: fix up here List <Part> broken = new List <Part>(); for (int i = 0; i < Parts.Count; i++) { if (Parts[i].IsBroken()) { broken.Add(Parts[i]); } } foreach (var b in broken) { Parts.Remove(b); } }
public MatFile(IntermediateNode materialLibraryNode, ILibFile additionalTextureLibrary) : this(additionalTextureLibrary) { setMaterials(materialLibraryNode); }
public DfmFile(IntermediateNode root, ILibFile additionalLibrary) { this.additionalLibrary = additionalLibrary; Levels = new Dictionary <int, DfmMesh>(); Bones = new Dictionary <string, Bone>(); Parts = new Dictionary <int, DfmPart>(); Constructs = new DfmConstructs(); foreach (Node node in root) { switch (node.Name.ToLowerInvariant()) { case "exporter version": break; case "material library": IntermediateNode materialLibraryNode = node as IntermediateNode; if (MaterialLibrary == null) { MaterialLibrary = new MatFile(materialLibraryNode, this); } else { throw new Exception("Multiple material library nodes in dfm root"); } break; case "texture library": IntermediateNode textureLibraryNode = node as IntermediateNode; if (TextureLibrary == null) { TextureLibrary = new TxmFile(textureLibraryNode); } else { throw new Exception("Multiple texture library nodes in dfm root"); } break; case "multilevel": IntermediateNode multiLevelNode = node as IntermediateNode; foreach (Node multiLevelSubNode in multiLevelNode) { if (multiLevelSubNode.Name.StartsWith("mesh", StringComparison.OrdinalIgnoreCase)) { IntermediateNode meshNode = multiLevelSubNode as IntermediateNode; int level = 0; if (!int.TryParse(meshNode.Name.Substring(4), out level)) { throw new Exception(""); } Levels.Add(level, new DfmMesh(meshNode, this, Parts)); } else if (multiLevelSubNode.Name.Equals("fractions", StringComparison.OrdinalIgnoreCase)) { LeafNode fractionsNode = multiLevelSubNode as LeafNode; if (Fractions == null) { Fractions = fractionsNode.SingleArrayData; } else { throw new Exception("Multiple fractions nodes in multilevel node"); } } else { throw new Exception("Invalid node in " + multiLevelNode.Name + ": " + multiLevelSubNode.Name); } } break; case "skeleton": IntermediateNode skeletonNode = node as IntermediateNode; foreach (LeafNode skeletonSubNode in skeletonNode) { switch (skeletonSubNode.Name.ToLowerInvariant()) { case "name": if (Skeleton == null) { Skeleton = skeletonSubNode.StringData; } else { throw new Exception("Multiple name nodes in skeleton node"); } break; default: throw new Exception("Invalid node in " + skeletonSubNode.Name + ": " + skeletonSubNode.Name); } } break; case "cmpnd": IntermediateNode cmpndNode = node as IntermediateNode; foreach (Node cmpndSubNode in cmpndNode) { if (cmpndSubNode.Name.Equals("scale", StringComparison.OrdinalIgnoreCase)) { if (Scale == null) { Scale = (cmpndSubNode as LeafNode).SingleData; } else { throw new Exception("Multiple scale nodes in cmpnd node"); } } else if (cmpndSubNode.Name.Equals("cons", StringComparison.OrdinalIgnoreCase)) { IntermediateNode consNode = cmpndSubNode as IntermediateNode; Constructs.AddNode(consNode); } else if ( cmpndSubNode.Name.StartsWith("part_", StringComparison.OrdinalIgnoreCase) || cmpndSubNode.Name.Equals("root", StringComparison.OrdinalIgnoreCase) ) { IntermediateNode partsNode = cmpndSubNode as IntermediateNode; string objectName = string.Empty, fileName = string.Empty; int index = -1; foreach (LeafNode partNode in partsNode) { switch (partNode.Name.ToLowerInvariant()) { case "object name": objectName = partNode.StringData; break; case "file name": fileName = partNode.StringData; break; case "index": index = partNode.Int32Data.Value; break; default: throw new Exception("Invalid node in " + cmpndSubNode.Name + ": " + partNode.Name); } } Parts.Add(index, new DfmPart(objectName, fileName, Bones, null)); } else { throw new Exception("Invalid node in " + node.Name + ": " + cmpndSubNode.Name); } } break; default: if (node.Name.EndsWith(".3db", StringComparison.OrdinalIgnoreCase)) { Bone b = new Bone(node as IntermediateNode); Bones.Add(node.Name, b); } else { throw new Exception("Invalid Node in dfm root: " + node.Name); } break; } } }
public DfmMesh(IntermediateNode root, ILibFile materialLibrary, Dictionary <int, DfmPart> parts) { this.parts = parts; FaceGroups = new List <FaceGroup>(); foreach (IntermediateNode node in root) { switch (node.Name.ToLowerInvariant()) { case "face_groups": IntermediateNode faceGroupsNode = node as IntermediateNode; foreach (Node faceGroupNode in faceGroupsNode) { if (faceGroupNode.Name.ToLowerInvariant() == "count") { // ignore } else if (faceGroupNode.Name.StartsWith("group", StringComparison.OrdinalIgnoreCase)) { FaceGroups.Add(new FaceGroup(faceGroupNode as IntermediateNode, materialLibrary)); } else { throw new Exception("Invalid node in " + faceGroupsNode.Name + ": " + faceGroupNode.Name); } } break; case "geometry": foreach (LeafNode geometrySubNode in node) { switch (geometrySubNode.Name.ToLowerInvariant()) { case "point_indices": PointIndices = geometrySubNode.Int32ArrayData; break; case "uv0_indices": UV0Indices = geometrySubNode.Int32ArrayData; break; case "uv1_indices": UV1Indices = geometrySubNode.Int32ArrayData; break; case "points": Points = geometrySubNode.Vector3ArrayData; break; case "point_bone_first": PointBoneFirst = geometrySubNode.Int32ArrayData; break; case "point_bone_count": PointBoneCount = geometrySubNode.Int32ArrayData; break; case "bone_id_chain": BoneIdChain = geometrySubNode.Int32ArrayData; break; case "bone_weight_chain": BoneWeightChain = geometrySubNode.SingleArrayData; break; case "vertex_normals": VertexNormals = geometrySubNode.Vector3ArrayData; break; case "uv0": UV0 = geometrySubNode.Vector2ArrayData; break; case "uv1": UV1 = geometrySubNode.Vector2ArrayData; break; case "uv_bone_id": UVBoneId = geometrySubNode; break; case "uv_vertex_count": UVVertexCount = geometrySubNode; break; case "uv_plane_distance": UVPlaneDistance = geometrySubNode; break; case "bone_x_to_u_scale": BoneXToUScale = geometrySubNode; break; case "bone_y_to_v_scale": BoneYToVScale = geometrySubNode; break; case "min_du": MinDU = geometrySubNode; break; case "max_du": MaxDU = geometrySubNode; break; case "min_dv": MinDV = geometrySubNode; break; case "max_dv": MaxDV = geometrySubNode; break; case "uv_vertex_id": UVVertexId = geometrySubNode; break; case "uv_default_list": UVDefaultList = geometrySubNode; break; default: throw new Exception("Invalid node in " + node.Name + ": " + geometrySubNode.Name); } } break; default: throw new Exception("Invalid node in " + root.Name + ": " + node.Name); } } }
public MatFile(ILibFile additionalTextureLibrary) { this.additionalTextureLibrary = additionalTextureLibrary; Materials = new Dictionary <uint, Material> (); }
public VMeshData(ArraySegment <byte> data, ILibFile materialLibrary, string name) { if (data == null) { throw new ArgumentNullException("data"); } if (materialLibrary == null) { throw new ArgumentNullException("materialLibrary"); } vmsname = name; ready = false; using (BinaryReader reader = new BinaryReader(data.GetReadStream())) { // Read the data header. MeshType = reader.ReadUInt32(); SurfaceType = reader.ReadUInt32(); MeshCount = reader.ReadUInt16(); IndexCount = reader.ReadUInt16(); FlexibleVertexFormat = (D3DFVF)reader.ReadUInt16(); OriginalFVF = FlexibleVertexFormat; VertexCount = reader.ReadUInt16(); // Read the mesh headers. Meshes = new List <TMeshHeader>(); int triangleStartOffset = 0; for (int count = 0; count < MeshCount; count++) { TMeshHeader item = new TMeshHeader(reader, triangleStartOffset, materialLibrary); if (item.NumRefVertices < 3) { FLLog.Warning("Vms", $"{name} mesh {count} references 0 triangles"); } triangleStartOffset += item.NumRefVertices; Meshes.Add(item); } // Read the triangle data Indices = new ushort[IndexCount]; for (int i = 0; i < IndexCount; i++) { Indices[i] = reader.ReadUInt16(); } // Read the vertex data. // The FVF defines what fields are included for each vertex. switch (FlexibleVertexFormat) { case D3DFVF.XYZ: //(D3DFVF)0x0002: verticesVertexPosition = new VertexPosition[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPosition[i] = new VertexPosition(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL: //(D3DFVF)0x0012: verticesVertexPositionNormal = new VertexPositionNormal[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormal[i] = new VertexPositionNormal(reader); } break; case D3DFVF.XYZ | D3DFVF.TEX1: //(D3DFVF)0x0102: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, Vector3.One, textureCoordinate); } FlexibleVertexFormat |= D3DFVF.NORMAL; break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX1: //(D3DFVF)0x0112: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3 normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, normal, textureCoordinate); } break; case D3DFVF.XYZ | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0142: verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount]; Diffuse = new uint[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Diffuse[i] = reader.ReadUInt32(); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, Vector3.One, Diffuse[i], textureCoordinate); } FlexibleVertexFormat |= D3DFVF.NORMAL; break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0152: verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount]; Diffuse = new uint[VertexCount]; for (int i = 0; i < VertexCount; i++) { var position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Diffuse[i] = reader.ReadUInt32(); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, normal, Diffuse[i], textureCoordinate); } break; //TODO: Hacky case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE: verticesVertexPositionNormalDiffuseTexture = new VertexPositionNormalDiffuseTexture[VertexCount]; Diffuse = new uint[VertexCount]; for (int i = 0; i < VertexCount; i++) { var position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Diffuse[i] = reader.ReadUInt32(); verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(position, normal, Diffuse[i], Vector2.Zero); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX2: //(D3DFVF)0x0212: verticesVertexPositionNormalTextureTwo = new VertexPositionNormalTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalTextureTwo[i] = new VertexPositionNormalTextureTwo(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX2: //(D3DFVF)0x0252: verticesVertexPositionNormalDiffuseTextureTwo = new VertexPositionNormalDiffuseTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalDiffuseTextureTwo[i] = new VertexPositionNormalDiffuseTextureTwo(reader); } break; /*case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX4: //(D3DFVF)0x0412: * for (int i = 0; i < VertexCount; i++) vertices[i] = new VertexPositionNormalTextureTangentBinormal(reader); * break;*/ default: throw new FileContentException("UTF:VMeshData", "FVF 0x" + ((int)FlexibleVertexFormat).ToString("X") + " not supported."); } } }
public VmsFile(IntermediateNode vMeshLibrary, ILibFile materialLibrary) : this() { setMeshes(vMeshLibrary, materialLibrary); }
private void load(IntermediateNode root, ILibFile additionalLibrary) { this.additionalLibrary = additionalLibrary; ready = false; Hardpoints = new List <HardpointDefinition>(); var lvls = new Dictionary <int, VMeshRef>(); foreach (Node node in root) { switch (node.Name.ToLowerInvariant()) { case "exporter version": break; case "vmeshlibrary": IntermediateNode vMeshLibraryNode = node as IntermediateNode; if (VMeshLibrary == null) { VMeshLibrary = new VmsFile(vMeshLibraryNode, this); } else { throw new Exception("Multiple vmeshlibrary nodes in 3db root"); } break; case "material library": IntermediateNode materialLibraryNode = node as IntermediateNode; if (MaterialLibrary == null) { MaterialLibrary = new MatFile(materialLibraryNode, this); } else { throw new Exception("Multiple material library nodes in 3db root"); } break; case "texture library": IntermediateNode textureLibraryNode = node as IntermediateNode; if (TextureLibrary == null) { TextureLibrary = new TxmFile(textureLibraryNode); } else { throw new Exception("Multiple texture library nodes in 3db root"); } break; case "hardpoints": IntermediateNode hardpointsNode = node as IntermediateNode; foreach (Node hpn in hardpointsNode) { if (hpn is LeafNode) { continue; //No nodes here } var hardpointTypeNode = (IntermediateNode)hpn; switch (hardpointTypeNode.Name.ToLowerInvariant()) { case "fixed": foreach (IntermediateNode fixedNode in hardpointTypeNode) { Hardpoints.Add(new FixedHardpointDefinition(fixedNode)); } break; case "revolute": foreach (IntermediateNode revoluteNode in hardpointTypeNode) { Hardpoints.Add(new RevoluteHardpointDefinition(revoluteNode)); } break; default: Hardpoints.Add(new FixedHardpointDefinition(hardpointTypeNode)); break; } } break; case "vmeshpart": { IntermediateNode vMeshPartNode = node as IntermediateNode; if (vMeshPartNode.Count == 1) { LeafNode vMeshRefNode = vMeshPartNode[0] as LeafNode; lvls.Add(0, new VMeshRef(vMeshRefNode.DataSegment, this)); } else { throw new Exception("Invalid VMeshPart: More than one child or zero elements"); } } break; case "multilevel": IntermediateNode multiLevelNode = node as IntermediateNode; foreach (Node multiLevelSubNode in multiLevelNode) { if (multiLevelSubNode.Name.StartsWith("level", StringComparison.OrdinalIgnoreCase)) { if (multiLevelSubNode is LeafNode) { continue; } IntermediateNode levelNode = multiLevelSubNode as IntermediateNode; if (levelNode.Count == 1) { int level = 0; if (!int.TryParse(levelNode.Name.Substring(5), out level)) { throw new Exception("Invalid Level: Missing index"); } IntermediateNode vMeshPartNode = levelNode[0] as IntermediateNode; if (vMeshPartNode.Count == 1) { LeafNode vMeshRefNode = vMeshPartNode[0] as LeafNode; if (vMeshRefNode != null && vMeshRefNode.Name.Equals("vmeshref", StringComparison.OrdinalIgnoreCase)) { lvls.Add(level, new VMeshRef(vMeshRefNode.DataSegment, this)); } } else { throw new Exception("Invalid VMeshPart: More than one child or zero elements"); } } //else throw new Exception("Invalid Level: More than one child or zero elements"); } else if (multiLevelSubNode.Name.Equals("switch2", StringComparison.OrdinalIgnoreCase)) { LeafNode switch2Node = multiLevelSubNode as LeafNode; Switch2 = switch2Node.SingleArrayData; } else { throw new Exception("Invalid node in " + multiLevelNode.Name + ": " + multiLevelSubNode.Name); } } break; case "vmeshwire": VMeshWire = new VMeshWire(node as IntermediateNode, this); break; case "mass properties": // TODO 3db Mass Properties break; case "extent tree": // TODO 3db Extent Tree break; case "materialanim": MaterialAnim = new MaterialAnimCollection((IntermediateNode)node); break; default: FLLog.Error("3db", (Path ?? "") + ": Invalid node: " + node.Name); break; } } //Sort levels in order var lvl2 = new List <VMeshRef>(); for (int i = 0; i < 100; i++) { if (lvls.ContainsKey(i)) { lvl2.Add(lvls[i]); } else { break; } } Levels = lvl2.ToArray(); }
public ModelFile(IntermediateNode root, ILibFile additionalLibrary) { Path = root.Name; load(root, additionalLibrary); }
public ModelFile(string path, ILibFile additionalLibrary) { Path = path; load(parseFile(path), additionalLibrary); }
public CmpFile(IntermediateNode rootnode, ILibFile additionalLibrary) { this.additionalLibrary = additionalLibrary; Models = new Dictionary <string, ModelFile>(); Constructs = new ConstructCollection(); Parts = new Dictionary <int, Part>(); foreach (Node node in rootnode) { switch (node.Name.ToLowerInvariant()) { case "exporter version": break; case "vmeshlibrary": IntermediateNode vMeshLibraryNode = node as IntermediateNode; if (VMeshLibrary == null) { VMeshLibrary = new VmsFile(vMeshLibraryNode, this); } else { throw new Exception("Multiple vmeshlibrary nodes in cmp root"); } break; case "animation": IntermediateNode animationNode = node as IntermediateNode; if (Animation == null) { Animation = new AnmFile(animationNode, Constructs); } else { throw new Exception("Multiple animation nodes in cmp root"); } break; case "material library": IntermediateNode materialLibraryNode = node as IntermediateNode; if (MaterialLibrary == null) { MaterialLibrary = new MatFile(materialLibraryNode, this); } else { throw new Exception("Multiple material library nodes in cmp root"); } break; case "texture library": IntermediateNode textureLibraryNode = node as IntermediateNode; if (TextureLibrary == null) { TextureLibrary = new TxmFile(textureLibraryNode); } else { throw new Exception("Multiple texture library nodes in cmp root"); } break; case "cmpnd": IntermediateNode cmpndNode = node as IntermediateNode; int maxIndices = int.MaxValue; foreach (Node SubNode in cmpndNode) { if (SubNode is LeafNode) { continue; } var cmpndSubNode = (IntermediateNode)SubNode; if (cmpndSubNode.Name.Equals("cons", StringComparison.OrdinalIgnoreCase)) { Constructs.AddNode(cmpndSubNode); } else if ( cmpndSubNode.Name.StartsWith("part_", StringComparison.OrdinalIgnoreCase) || cmpndSubNode.Name.Equals("root", StringComparison.OrdinalIgnoreCase) ) { string objectName = string.Empty, fileName = string.Empty; int index = -1; foreach (LeafNode partNode in cmpndSubNode) { switch (partNode.Name.ToLowerInvariant()) { case "object name": objectName = partNode.StringData; break; case "file name": fileName = partNode.StringData; break; case "index": if (partNode.Int32Data != null) { index = partNode.Int32Data.Value; } else { index = partNode.Int32ArrayData [0]; } break; default: throw new Exception("Invalid node in " + cmpndSubNode.Name + ": " + partNode.Name); } } if (Parts.ContainsKey(index)) { FLLog.Error("Cmp", "Duplicate index"); Parts.Add(maxIndices--, new Part(objectName, fileName, Models, Constructs)); } else { Parts.Add(index, new Part(objectName, fileName, Models, Constructs)); } } else { throw new Exception("Invalid node in " + cmpndNode.Name + ": " + cmpndSubNode.Name); } } break; case "materialanim": MaterialAnim = new MaterialAnimCollection((IntermediateNode)node); break; default: if (node.Name.EndsWith(".3db", StringComparison.OrdinalIgnoreCase)) { ModelFile m = new ModelFile(node as IntermediateNode, this); m.Path = node.Name; Models.Add(node.Name, m); } else { FLLog.Error("Cmp", Path ?? "Utf" + ": Invalid Node in cmp root: " + node.Name); } break; } } }
public VMeshData(byte[] data, ILibFile materialLibrary, string name) { if (data == null) { throw new ArgumentNullException("data"); } if (materialLibrary == null) { throw new ArgumentNullException("materialLibrary"); } vmsname = name; ready = false; using (BinaryReader reader = new BinaryReader(new MemoryStream(data))) { // Read the data header. MeshType = reader.ReadUInt32(); SurfaceType = reader.ReadUInt32(); MeshCount = reader.ReadUInt16(); IndexCount = reader.ReadUInt16(); FlexibleVertexFormat = (D3DFVF)reader.ReadUInt16(); VertexCount = reader.ReadUInt16(); // Read the mesh headers. Meshes = new List <TMeshHeader>(); int triangleStartOffset = 0; for (int count = 0; count < MeshCount; count++) { TMeshHeader item = new TMeshHeader(reader, triangleStartOffset, materialLibrary); triangleStartOffset += item.NumRefVertices; Meshes.Add(item); } // Read the triangle data Indices = new ushort[IndexCount]; for (int i = 0; i < IndexCount; i++) { Indices[i] = reader.ReadUInt16(); } // Read the vertex data. // The FVF defines what fields are included for each vertex. switch (FlexibleVertexFormat) { case D3DFVF.XYZ: //(D3DFVF)0x0002: verticesVertexPosition = new VertexPosition[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPosition[i] = new VertexPosition(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL: //(D3DFVF)0x0012: verticesVertexPositionNormal = new VertexPositionNormal[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormal[i] = new VertexPositionNormal(reader); } break; case D3DFVF.XYZ | D3DFVF.TEX1: //(D3DFVF)0x0102: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, Vector3.Zero, textureCoordinate); } CalculateNormals(verticesVertexPositionNormalTexture); FlexibleVertexFormat |= D3DFVF.NORMAL; break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX1: //(D3DFVF)0x0112: verticesVertexPositionNormalTexture = new VertexPositionNormalTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector3 normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalTexture[i] = new VertexPositionNormalTexture(position, normal, textureCoordinate); } break; case D3DFVF.XYZ | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0142: verticesVertexPositionNormalColorTexture = new VertexPositionNormalColorTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { Vector3 position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int r = reader.ReadByte(); int g = reader.ReadByte(); int b = reader.ReadByte(); int a = reader.ReadByte(); Color4 diffuse = new Color4(r / 255f, g / 255f, b / 255f, a / 255f); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalColorTexture[i] = new VertexPositionNormalColorTexture(position, Vector3.Zero, diffuse, textureCoordinate); } FlexibleVertexFormat |= D3DFVF.NORMAL; CalculateNormals(verticesVertexPositionNormalColorTexture); break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX1: //(D3DFVF)0x0152: verticesVertexPositionNormalColorTexture = new VertexPositionNormalColorTexture[VertexCount]; for (int i = 0; i < VertexCount; i++) { //verticesVertexPositionNormalDiffuseTexture[i] = new VertexPositionNormalDiffuseTexture(reader); var position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); var normal = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); int r = reader.ReadByte(); int g = reader.ReadByte(); int b = reader.ReadByte(); int a = reader.ReadByte(); Color4 diffuse = new Color4(r / 255f, g / 255f, b / 255f, a / 255f); Vector2 textureCoordinate = new Vector2(reader.ReadSingle(), 1 - reader.ReadSingle()); verticesVertexPositionNormalColorTexture[i] = new VertexPositionNormalColorTexture(position, normal, diffuse, textureCoordinate); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX2: //(D3DFVF)0x0212: verticesVertexPositionNormalTextureTwo = new VertexPositionNormalTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalTextureTwo[i] = new VertexPositionNormalTextureTwo(reader); } break; case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.DIFFUSE | D3DFVF.TEX2: //(D3DFVF)0x0252: verticesVertexPositionNormalDiffuseTextureTwo = new VertexPositionNormalDiffuseTextureTwo[VertexCount]; for (int i = 0; i < VertexCount; i++) { verticesVertexPositionNormalDiffuseTextureTwo[i] = new VertexPositionNormalDiffuseTextureTwo(reader); } break; /*case D3DFVF.XYZ | D3DFVF.NORMAL | D3DFVF.TEX4: //(D3DFVF)0x0412: * for (int i = 0; i < VertexCount; i++) vertices[i] = new VertexPositionNormalTextureTangentBinormal(reader); * break;*/ default: throw new FileContentException("UTF:VMeshData", "FVF 0x" + FlexibleVertexFormat + " not supported."); } } }