public SurPart ToSurHierarchy(out Dictionary <Part, SurPart> surParts) { surParts = new Dictionary <Part, SurPart>(); foreach (var part in Parts) { var sp = new SurPart() { Children = new List <SurPart>(), Hash = CrcTool.FLModelCrc(part.ObjectName) }; surParts.Add(part, sp); } foreach (var part in Parts) { if (part.Construct != null) { var p = Parts.FirstOrDefault((x) => x.ObjectName.Equals(part.Construct.ParentName, StringComparison.OrdinalIgnoreCase)); if (p != null) { surParts[p].Children.Add(surParts[part]); } } } return(surParts[GetRootPart()]); }
public byte[] VMeshRef(string nodename) { using (var stream = new MemoryStream()) { var writer = new BinaryWriter(stream); writer.Write((uint)60); //HeaderSize writer.Write(CrcTool.FLModelCrc(nodename)); //Fields used for referencing sections of VMeshData writer.Write((ushort)0); //StartVertex - BaseVertex in drawcall writer.Write((ushort)Vertices.Length); //VertexCount (idk?) writer.Write((ushort)0); //StartIndex writer.Write((ushort)Indices.Length); //IndexCount writer.Write((ushort)0); //StartMesh writer.Write((ushort)Drawcalls.Length); //MeshCount //Write rendering things writer.Write(Max.X); writer.Write(Min.X); writer.Write(Max.Y); writer.Write(Min.Y); writer.Write(Max.Z); writer.Write(Min.Z); writer.Write(Center.X); writer.Write(Center.Y); writer.Write(Center.Z); writer.Write(Radius); return(stream.ToArray()); } }
public RigidModel CreateRigidModel(bool drawable) { var model = new RigidModel(); var part = new RigidModelPart(); var dcs = new List <MeshDrawcall>(); var scale = Matrix4x4.CreateScale(Radius); if (drawable && SideMaterials.Length >= 6) { for (int i = 0; i < 6; i++) { int start, count; Vector3 pos; sphere.GetDrawParameters(faces[i], out start, out count, out pos); var dc = new MeshDrawcall(); dc.Buffer = sphere.VertexBuffer; dc.MaterialCrc = CrcTool.FLModelCrc(sideMaterialNames[i]); dc.BaseVertex = 0; dc.StartIndex = start; dc.PrimitiveCount = count; dc.HasScale = true; dc.Scale = scale; dcs.Add(dc); } if (SideMaterials.Length > 6) { var crc = CrcTool.FLModelCrc(sideMaterialNames[6]); for (int i = 0; i < 6; i++) { int start, count; Vector3 pos; sphere.GetDrawParameters(faces[i], out start, out count, out pos); var dc = new MeshDrawcall(); dc.Buffer = sphere.VertexBuffer; dc.MaterialCrc = crc; dc.BaseVertex = 0; dc.StartIndex = start; dc.PrimitiveCount = count; dc.HasScale = true; dc.Scale = scale; dcs.Add(dc); } } } var vmesh = new VisualMesh(); vmesh.Radius = Radius; vmesh.BoundingBox = BoundingBox.CreateFromSphere(new BoundingSphere(Vector3.Zero, Radius)); vmesh.Levels = new[] { dcs.ToArray() }; part.Hardpoints = new List <Hardpoint>(); part.Mesh = vmesh; model.Root = part; model.AllParts = new[] { part }; return(model); }
void ProcessSur(LibreLancer.Physics.Sur.SurFile surfile) { if (surs != null) { foreach (var mdl in surs) { mdl.Vertices.Dispose(); mdl.Elements.Dispose(); } } surs = new List <SurModel>(); if ((drawable is ModelFile)) { surs.Add(GetSurModel(surfile.GetMesh(0, false), null, surPart)); foreach (var hpid in surfile.HardpointIds) { surs.Add(GetSurModel(surfile.GetMesh(hpid, true), null, surHardpoint)); } } else { Dictionary <Part, SurPart> surParts; var surHierarchy = ((CmpFile)drawable).ToSurHierarchy(out surParts); surfile.FillMeshHierarchy(surHierarchy); foreach (var kv in surParts) { var mdl = new SurModel() { Part = kv.Key }; foreach (var hp in kv.Key.Model.Hardpoints) { var crc = CrcTool.FLModelCrc(hp.Name); if (surfile.HardpointIds.Contains(crc)) { surs.Add(GetSurModel(surfile.GetMesh(crc, true), kv.Key, surHardpoint)); } } if (kv.Value.DisplayMeshes != null) { foreach (var msh in kv.Value.DisplayMeshes) { AddVertices(mdl, msh); } } mdl.Vertices = new VertexBuffer(typeof(VertexPositionColor), mdl.BuildVertices.Count); mdl.Vertices.SetData(mdl.BuildVertices.ToArray()); mdl.BuildVertices = null; mdl.Elements = new ElementBuffer(mdl.BuildIndices.Count); mdl.Elements.SetData(mdl.BuildIndices.ToArray()); mdl.Vertices.SetElementBuffer(mdl.Elements); mdl.BuildIndices = null; surs.Add(mdl); } } }
void CheckNullArray() { if (sph.sideMaterials == null) { sph.sideMaterials = new Material[sph.sideMaterialNames.Count]; for (int i = 0; i < sph.sideMaterialNames.Count; i++) { sph.sideMaterials[i] = sph.library.FindMaterial(CrcTool.FLModelCrc(sph.sideMaterialNames[i])); } } }
private void setMeshes(IntermediateNode vMeshLibrary, ILibFile materialLibrary) { foreach (IntermediateNode vmsNode in vMeshLibrary) { if (vmsNode.Count != 1) { throw new Exception("Invalid VMeshLibrary: More than one child or zero elements: " + vmsNode.Name); } LeafNode vMeshDataNode = vmsNode[0] as LeafNode; Meshes.Add(CrcTool.FLModelCrc(vmsNode.Name), new VMeshData(vMeshDataNode.ByteArrayData, materialLibrary, vmsNode.Name)); } }
public Material this[int i] { get { CheckNullArray(); if (sph.sideMaterials[i] == null) { var crc = CrcTool.FLModelCrc(sph.sideMaterialNames[i]); sph.sideMaterials[i] = sph.library.FindMaterial(CrcTool.FLModelCrc(sph.sideMaterialNames[i])); } return(sph.sideMaterials[i]); } set { CheckNullArray(); sph.sideMaterials[i] = value; } }
private void setMaterials(IntermediateNode materialLibraryNode) { //TODO: int count = 0; foreach (Node materialNode in materialLibraryNode) { if (materialNode is IntermediateNode) { uint materialId = CrcTool.FLModelCrc(materialNode.Name); if (!Materials.ContainsKey(materialId)) { Materials.Add(materialId, Material.FromNode(materialNode as IntermediateNode, this)); } } //else if (subNode.Name.Equals("material count", StringComparison.OrdinalIgnoreCase)) //count = (subNode as LeafNode).getIntegerBlaBLubb; } //if (count != materials.Count) //throw new Exception("Invalid material count: " + count + " != " + materials.Count); }
public static void DetectDrawable(string name, IDrawable drawable, ResourceManager res, List <MissingReference> missing, List <uint> matrefs, List <string> texrefs) { if (drawable is CmpFile) { var cmp = (CmpFile)drawable; foreach (var part in cmp.ModelParts()) { DetectResourcesModel(part.Model, name + ", " + part.Model.Path, res, missing, matrefs, texrefs); } } if (drawable is ModelFile) { DetectResourcesModel((ModelFile)drawable, name, res, missing, matrefs, texrefs); } if (drawable is SphFile) { var sph = (SphFile)drawable; for (int i = 0; i < sph.SideMaterials.Length; i++) { if (sph.SideMaterials[i] != null && !sph.SideMaterials[i].Loaded) { sph.SideMaterials[i] = null; } if (sph.SideMaterials[i] == null) { var str = "Material: " + sph.SideMaterialNames[i]; if (!HasMissing(missing, str)) { missing.Add(new MissingReference(str, string.Format("{0} M{1}", name, i))); } } else { var crc = CrcTool.FLModelCrc(sph.SideMaterialNames[i]); if (!matrefs.Contains(crc)) { matrefs.Add(crc); } DoMaterialRefs(sph.SideMaterials[i], res, missing, texrefs, string.Format(" - {0} M{1}", name, i)); } } } }
private void setMeshes(IntermediateNode vMeshLibrary, ILibFile materialLibrary) { foreach (IntermediateNode vmsNode in vMeshLibrary) { var vMeshDataNode = vmsNode.FirstOrDefault(x => x.Name.Equals("VMeshData", StringComparison.OrdinalIgnoreCase)); if (vMeshDataNode == null) { FLLog.Error("VMS", "Invalid VMeshLibrary: No VMeshData: " + vmsNode.Name); continue; } LeafNode vmsdat = vmsNode[0] as LeafNode; if (vmsdat == null) { FLLog.Error("VMS", "Invalid VMeshLibrary: VMeshData has no bytes: " + vmsNode.Name); } else { Meshes.Add(CrcTool.FLModelCrc(vmsNode.Name), new VMeshData(vmsdat.DataSegment, materialLibrary, vmsNode.Name)); } } }
public byte[] VMeshData() { using (var stream = new MemoryStream()) { var writer = new BinaryWriter(stream); writer.Write((uint)0x01); //MeshType writer.Write((uint)0x04); //SurfaceType writer.Write((ushort)(Drawcalls.Length)); //MeshCount writer.Write((ushort)(Indices.Length)); //IndexCount writer.Write((ushort)FVF); //FVF writer.Write((ushort)Vertices.Length); //VertexCount int startTri = 0; foreach (var dc in Drawcalls) { //drawcalls must be sequential (start index isn't in VMeshData) //this error shouldn't ever throw if (startTri != dc.StartIndex) { throw new Exception("Invalid start index"); } //write TMeshHeader var crc = dc.Material != null?CrcTool.FLModelCrc(dc.Material.Name) : 0; writer.Write(crc); writer.Write((ushort)dc.StartVertex); writer.Write((ushort)dc.EndVertex); writer.Write((ushort)(dc.TriCount * 3)); //NumRefVertices writer.Write((ushort)0); //Padding //validation startTri += dc.TriCount * 3; } foreach (var idx in Indices) { writer.Write(idx); } foreach (var v in Vertices) { writer.Write(v.Position.X); writer.Write(v.Position.Y); writer.Write(v.Position.Z); if ((FVF & D3DFVF.NORMAL) == D3DFVF.NORMAL) { writer.Write(v.Normal.X); writer.Write(v.Normal.Y); writer.Write(v.Normal.Z); } if ((FVF & D3DFVF.DIFFUSE) == D3DFVF.DIFFUSE) { writer.Write(v.Diffuse); } //Librelancer stores texture coordinates flipped internally if ((FVF & D3DFVF.TEX2) == D3DFVF.TEX2) { writer.Write(v.TextureCoordinate.X); writer.Write(1 - v.TextureCoordinate.Y); writer.Write(v.TextureCoordinateTwo.X); writer.Write(1 - v.TextureCoordinateTwo.Y); } else if ((FVF & D3DFVF.TEX1) == D3DFVF.TEX1) { writer.Write(v.TextureCoordinate.X); writer.Write(1 - v.TextureCoordinate.Y); } } return(stream.ToArray()); } }
void DoNodeMenu(string id, LUtfNode node, LUtfNode parent) { if (ImGui.BeginPopupContextItem(id)) { ImGui.MenuItem(node.Name, false); ImGui.MenuItem(string.Format("CRC: 0x{0:X}", CrcTool.FLModelCrc(node.Name)), false); ImGui.Separator(); if (Theme.IconMenuItem(Icons.Edit, "Rename", node != Utf.Root)) { text.SetText(node.Name); renameNode = node; popups.OpenPopup("Rename Node"); } if (Theme.IconMenuItem(Icons.TrashAlt, "Delete", node != Utf.Root)) { deleteParent = parent; deleteNode = node; Confirm("Are you sure you want to delete: '" + node.Name + "'?", () => { if (selectedNode == deleteNode) { selectedNode = null; } deleteParent.Children.Remove(deleteNode); }); } if (Theme.IconMenuItem(Icons.Eraser, "Clear", node.Children != null || node.Data != null)) { clearNode = node; Confirm("Clearing this node will delete all data and children. Continue?", () => { clearNode.Data = null; if (clearNode == Utf.Root) { clearNode.Children = new List <LUtfNode>(); } else { clearNode.Children = null; } }); } ImGui.Separator(); if (Theme.BeginIconMenu(Icons.PlusCircle, "Add")) { if (ImGui.MenuItem("Child")) { text.SetText(""); addParent = null; addNode = node; if (node.Data != null) { Confirm("Adding a node will clear data. Continue?", () => { popups.OpenPopup("New Node"); }); } else { popups.OpenPopup("New Node"); } } if (ImGui.MenuItem("Before", node != Utf.Root)) { text.SetText(""); addParent = parent; addNode = node; addOffset = 0; popups.OpenPopup("New Node"); } if (ImGui.MenuItem("After", node != Utf.Root)) { text.SetText(""); addParent = parent; addNode = node; addOffset = 1; popups.OpenPopup("New Node"); } ImGui.EndMenu(); } ImGui.Separator(); if (Theme.IconMenuItem(Icons.Cut, "Cut", node != Utf.Root)) { parent.Children.Remove(node); main.ClipboardCopy = false; main.Clipboard = node; } if (Theme.IconMenuItem(Icons.Copy, "Copy", node != Utf.Root)) { main.ClipboardCopy = true; main.Clipboard = node.MakeCopy(); } if (main.Clipboard != null) { if (Theme.BeginIconMenu(Icons.Paste, "Paste")) { if (ImGui.MenuItem("Before", node != Utf.Root)) { if (main.ClipboardCopy) { var cpy = main.Clipboard.MakeCopy(); cpy.Parent = parent; parent.Children.Insert(parent.Children.IndexOf(node), cpy); } else { main.Clipboard.Parent = parent; parent.Children.Insert(parent.Children.IndexOf(node), main.Clipboard); main.Clipboard = null; } } if (ImGui.MenuItem("After", node != Utf.Root)) { if (main.ClipboardCopy) { var cpy = main.Clipboard.MakeCopy(); cpy.Parent = parent; parent.Children.Insert(parent.Children.IndexOf(node) + 1, cpy); } else { main.Clipboard.Parent = parent; parent.Children.Insert(parent.Children.IndexOf(node) + 1, main.Clipboard); main.Clipboard = null; } } if (ImGui.MenuItem("Into")) { if (node.Data == null) { if (node.Children == null) { node.Children = new List <LUtfNode>(); } if (main.ClipboardCopy) { var cpy = main.Clipboard.MakeCopy(); cpy.Parent = node; node.Children.Add(cpy); } else { main.Clipboard.Parent = node; node.Children.Add(main.Clipboard); main.Clipboard = null; } } else { pasteInto = node; Confirm("Adding children will delete this node's data. Continue?", () => { pasteInto.Data = null; pasteInto.Children = new List <LUtfNode>(); if (main.ClipboardCopy) { var cpy = main.Clipboard.MakeCopy(); cpy.Parent = pasteInto; pasteInto.Children.Add(cpy); } else { main.Clipboard.Parent = pasteInto; pasteInto.Children.Add(main.Clipboard); main.Clipboard = null; } }); } } ImGui.EndMenu(); } } else { Theme.IconMenuItem(Icons.Paste, "Paste", false); } ImGui.EndPopup(); } }
public void DrawBuffer(CommandBuffer buffer, Matrix4 world, ref Lighting lighting, Material overrideMat = null) { if (SideMaterials.Length < 6) { return; } if (ready) { for (int i = 0; i < SideMaterials.Length; i++) { if (SideMaterials[i] != null && !SideMaterials[i].Loaded) { SideMaterials[i].Loaded = false; } } for (int i = 0; i < 6; i++) { int start, count; Vector3 pos; sphere.GetDrawParameters(faces[i], out start, out count, out pos); if (SideMaterials[i] == null) { SideMaterials[i] = library.FindMaterial(CrcTool.FLModelCrc(sideMaterialNames[i])); } var mat = SideMaterials[i] ?? defaultMaterial; mat = overrideMat ?? mat; mat.Render.Camera = _camera; var transform = Matrix4.CreateScale(Radius) * world; buffer.AddCommand( mat.Render, null, transform, lighting, sphere.VertexBuffer, PrimitiveTypes.TriangleList, 0, start, count, SortLayers.OBJECT ); } //Draw atmosphere if (SideMaterials.Length > 6 && overrideMat == null) { if (SideMaterials[6] == null) { SideMaterials[6] = library.FindMaterial(CrcTool.FLModelCrc(sideMaterialNames[6])); if (SideMaterials[6] == null) { return; } } var mat = (AtmosphereMaterial)SideMaterials[6].Render; var transform = Matrix4.CreateScale(Radius * mat.Scale) * world; for (int i = 0; i < 6; i++) { int start, count; Vector3 pos; sphere.GetDrawParameters(faces[i], out start, out count, out pos); SideMaterials[6].Render.Camera = _camera; buffer.AddCommand( SideMaterials[6].Render, null, transform, lighting, sphere.VertexBuffer, PrimitiveTypes.TriangleList, 0, start, count, SortLayers.OBJECT, RenderHelpers.GetZ(transform, _camera.Position, pos) ); } } } else { throw new Exception(); } }
void ProcessSur(LibreLancer.Physics.Sur.SurFile surfile) { if (surs != null) { foreach (var mdl in surs) { mdl.Vertices.Dispose(); mdl.Elements.Dispose(); } } surs = new List <SurModel>(); if ((drawable is ModelFile)) { surs.Add(GetSurModel(surfile.GetMesh(0, false), null, surPart)); foreach (var hpid in surfile.HardpointIds) { surs.Add(GetSurModel(surfile.GetMesh(hpid, true), null, surHardpoint)); } } else { Dictionary <uint, SurModel> crcLookup = new Dictionary <uint, SurModel>(); foreach (var part in ((CmpFile)drawable).Parts) { crcLookup.Add(CrcTool.FLModelCrc(part.ObjectName), new SurModel() { Part = part }); } foreach (var part in ((CmpFile)drawable).Parts) { var crc = CrcTool.FLModelCrc(part.ObjectName); foreach (var msh in surfile.GetMesh(crc, false)) { AddVertices(crcLookup[msh.ParentCrc], msh); } foreach (var hp in part.Model.Hardpoints) { crc = CrcTool.FLModelCrc(hp.Name); Color4 c = surHardpoint; if (hp.Name.Equals("hpmount", StringComparison.OrdinalIgnoreCase)) { c = surShield; } if (surfile.HardpointIds.Contains(crc)) { surs.Add(GetSurModel(surfile.GetMesh(crc, true), null, c)); } } } foreach (var mdl in crcLookup.Values) { mdl.Vertices = new VertexBuffer(typeof(VertexPositionColor), mdl.BuildVertices.Count); mdl.Vertices.SetData(mdl.BuildVertices.ToArray()); mdl.BuildVertices = null; mdl.Elements = new ElementBuffer(mdl.BuildIndices.Count); mdl.Elements.SetData(mdl.BuildIndices.ToArray()); mdl.Vertices.SetElementBuffer(mdl.Elements); mdl.BuildIndices = null; surs.Add(mdl); } } }
public static byte[] VMeshData(Geometry g) { using (var stream = new MemoryStream()) { var writer = new BinaryWriter(stream); writer.Write((uint)0x01); //MeshType writer.Write((uint)0x04); //SurfaceType writer.Write((ushort)(g.Groups.Length)); //MeshCount writer.Write((ushort)(g.Indices.Length)); //IndexCount D3DFVF fvf = FVF(g); writer.Write((ushort)fvf); //FVF writer.Write((ushort)g.Vertices.Length); //VertexCount int startTri = 0; foreach (var dc in g.Groups) { //drawcalls must be sequential (start index isn't in VMeshData) //this error shouldn't ever throw if (startTri != dc.StartIndex) { throw new Exception("Invalid start index"); } //write TMeshHeader var crc = dc.Material != null?CrcTool.FLModelCrc(dc.Material.Name) : 0; writer.Write(crc); writer.Write((ushort)dc.BaseVertex); int max = 0; for (int i = 0; i < dc.IndexCount; i++) { max = Math.Max(max, g.Indices.Indices16[i + dc.StartIndex]); } max += dc.BaseVertex; writer.Write((ushort)max); writer.Write((ushort)dc.IndexCount); //NumRefVertices writer.Write((ushort)0); //Padding //validation startTri += dc.IndexCount; } foreach (var idx in g.Indices.Indices16) { writer.Write(idx); } foreach (var v in g.Vertices) { writer.Write(v.Position.X); writer.Write(v.Position.Y); writer.Write(v.Position.Z); if ((fvf & D3DFVF.NORMAL) == D3DFVF.NORMAL) { writer.Write(v.Normal.X); writer.Write(v.Normal.Y); writer.Write(v.Normal.Z); } if ((fvf & D3DFVF.DIFFUSE) == D3DFVF.DIFFUSE) { writer.Write(((Color4)v.Diffuse).ToAbgr()); } //Librelancer stores texture coordinates flipped internally if ((fvf & D3DFVF.TEX2) == D3DFVF.TEX2) { writer.Write(v.Texture1.X); writer.Write(1 - v.Texture1.Y); writer.Write(v.Texture2.X); writer.Write(1 - v.Texture2.Y); } else if ((fvf & D3DFVF.TEX1) == D3DFVF.TEX1) { writer.Write(v.Texture1.X); writer.Write(1 - v.Texture1.Y); } } return(stream.ToArray()); } }