private void exportBttn_Click(object sender, EventArgs e) { var script = new List <IScriptItem>(); script.Add(new LoadModel() { File = inputFileBox.Selected }); model = ModelReader.Open(inputFileBox.Selected); var exportCmd = new Export(); var type = formatBox.SelectedItem as FileTypeInfo; if (type == null) { MessageBox.Show("Unknown format '{format}'"); return; } var outName = System.IO.Path.ChangeExtension(inputFileBox.Selected, type.Extension); exportCmd.File = outName; script.Add(exportCmd); Script.ExecuteItems(script, System.IO.Directory.GetCurrentDirectory()); MessageBox.Show($"Successfully exported model {inputFileBox.Selected.Split('\\').Last()} (placed in the input model folder)"); }
public static string ExportFile(FullModelData data, string path) { AnimationFile animationFile = new AnimationFile(); foreach (Object3D object3D in data.SectionsOfType <Object3D>()) { if (object3D.Animations.Count > 0) { AnimationFileObject animationFileObject = new AnimationFileObject(object3D.HashName.String); foreach (IAnimationController animationController in object3D.Animations) { if (animationController is LinearVector3Controller) { LinearVector3Controller linearVector3Controller = (LinearVector3Controller)animationController; animationFileObject.PositionKeyframes = new List <Keyframe <Vector3> >(linearVector3Controller.Keyframes); } else if (animationController is QuatLinearRotationController) { QuatLinearRotationController quatLinearRotationController = (QuatLinearRotationController)animationController; animationFileObject.RotationKeyframes = new List <Keyframe <Quaternion> >(quatLinearRotationController.Keyframes); } } animationFile.Objects.Add(animationFileObject); } } animationFile.Write(path); return(path); }
public static void Import(FullModelData fmd, string path) { AnimationFile animationFile = new AnimationFile(); animationFile.Read(path); foreach (AnimationFileObject animationObject in animationFile.Objects) { Object3D object3D = fmd.GetObject3DByHash(new HashName(animationObject.Name)); Log.Default.Info("Trying to add animation to " + animationObject.Name); if (object3D != null) { Log.Default.Info("Found " + animationObject.Name); object3D.Animations.Clear(); // Kill the old anims. if (animationObject.RotationKeyframes.Count > 0) { QuatLinearRotationController quatLinearRotationController = AddRotations(object3D, animationObject.RotationKeyframes); fmd.AddSection(quatLinearRotationController); } if (animationObject.PositionKeyframes.Count > 0) { LinearVector3Controller linearVector3Controller = AddPositions(object3D, animationObject.PositionKeyframes); fmd.AddSection(linearVector3Controller); } } else { Log.Default.Info("Not Found " + animationObject.Name); } } }
/// <summary> /// Import all of the default scene of a GLTF file, parenting it as specified. /// </summary> /// <param name="fmd">Diesel model to add the contents to.</param> /// <param name="path">Path of the GLTF file to import</param> /// <param name="getParentByName">Callback to find the parent of a particular model.</param> public static void Import(FullModelData fmd, string path, bool createModels, Func <string, DM.Object3D> parentFinder, IOptionReceiver _) { var gltf = GLTF.ModelRoot.Load(path); var importer = new GltfImporter(fmd); importer.ImportTree(gltf, createModels, parentFinder); }
public ObjectNode(FullModelData fmd, Sections.Object3D obj) { data = fmd; this.obj = obj; Label = $"{obj.SectionId} | {obj.Name}"; if (obj.GetType() != typeof(Sections.Object3D)) { Label += $" ({obj.GetType().Name})"; } }
public static string ExportFile(FullModelData data, string filepath) { string output_file = filepath.Replace(".model", ".obj"); GenerateOutputInfo(data, "outinfo.txt"); ExportObj(data, output_file); // TODO configure output file ExportPatternUVObj(data, filepath.Replace(".model", "_pattern_uv.obj")); // TODO configure output file return(output_file); }
public AllSectionsNode(FullModelData fmd) { data = fmd; Key = $"<AllSectionsNode<{typeof(TSection).Name}>>"; Label = $"<{typeof(TSection).Name}>"; if (typeof(TSection).GetInterfaces().Contains(typeof(Sections.IHashNamed))) { labeller = (sec) => $"{sec.SectionId} | {sec.GetType().Name} ({(sec as Sections.IHashNamed).HashName.String})"; } else { labeller = (sec) => $"{sec.SectionId} | {sec.GetType().Name}"; } }
public static bool ExecuteWithMsgBox(IEnumerable <IScriptItem> items, ref FullModelData initialModel) { try { initialModel = ExecuteItems(items, Directory.GetCurrentDirectory(), initialModel); return(true); } catch (Exception exc) { Log.Default.Warn("Exception in script file: {0}", exc); System.Windows.Forms.MessageBox.Show("There was an error in the script file:\n" + "(check the readme on GitLab for more information)\n" + exc.Message); return(false); } }
public static bool ExecuteFileWithMsgBox(ref FullModelData data, string file) { try { XElement root = XElement.Parse(File.ReadAllText(file)); var script = ParseXml(root); data = ExecuteItems(script, Directory.GetCurrentDirectory(), data); return(true); } catch (Exception exc) { Log.Default.Warn("Exception in script file: {0}", exc); System.Windows.Forms.MessageBox.Show("There was an error in the script file:\n" + "(check the readme on GitLab for more information)\n" + exc.Message); return(false); } }
public static string ExportFile(FullModelData data, string path, bool binary) { var exporter = new GltfExporter(); var gltfmodel = exporter.Convert(data); if (binary) { gltfmodel.SaveGLB(path); } else { gltfmodel.SaveGLTF(path, new GLTF.WriteSettings { JsonIndented = true }); } return(path); }
public Inspector.IInspectorNode GetRootInspector(FullModelData data) { Type inspectortype; System.Reflection.ConstructorInfo constructor; if (DeclaredRootInspectorType != null) { inspectortype = DeclaredRootInspectorType; } else { inspectortype = typeof(Inspector.AllSectionsNode <>).MakeGenericType(new Type[] { this.Type }); } constructor = inspectortype.GetConstructor(new Type[] { typeof(FullModelData) }); if (constructor == null) { throw new Exception($"The root inspector type {inspectortype.FullName} does not have a suitable constructor"); } return((Inspector.IInspectorNode)constructor.Invoke(new object[] { data })); }
/// <summary> /// Reload the tree view to reflect any new settings /// </summary> /// <remarks> /// This method reloads the model file each time it is /// called. While this may sound slow, particularly if you've /// seen how long it takes the tool to load a model when you /// first drag it in, it is <b>much</b> quicker on subsequent /// runs. /// </remarks> private void Reload() { data = null; var script = new List <Modelscript.IScriptItem>(); if (modelFile.Selected != null) { script.Add(new Modelscript.LoadModel() { File = modelFile.Selected }); } else { script.Add(new Modelscript.NewModel()); } btnSave.Enabled = !showScriptChanges.Checked; if (scriptFile.Selected != null && showScriptChanges.Checked) { script.Add(new Modelscript.RunScript() { File = scriptFile.Selected }); } // TODO: There must be a better way to deal with errors. bool success = Modelscript.Script.ExecuteWithMsgBox(script, ref data); if (!success) { return; } var rootinspector = new Inspector.ModelRootNode(data); ReconcileChildNodes(rootinspector, treeView.Nodes); }
public static void ImportNewObj(FullModelData fmd, String filepath, bool addNew, Func <string, Object3D> root_point, Importers.IOptionReceiver _) { Log.Default.Info("Importing new obj with file: {0}", filepath); //Preload the .obj List <obj_data> objects = new List <obj_data>(); List <obj_data> toAddObjects = new List <obj_data>(); using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs)) { string line; obj_data obj = new obj_data(); bool reading_faces = false; int prevMaxVerts = 0; int prevMaxUvs = 0; int prevMaxNorms = 0; string current_shade_group = null; while ((line = sr.ReadLine()) != null) { //preloading objects if (line.StartsWith("#")) { continue; } else if (line.StartsWith("o ") || line.StartsWith("g ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); current_shade_group = null; } if (String.IsNullOrEmpty(obj.object_name)) { obj.object_name = line.Substring(2); Log.Default.Debug("Object {0} named: {1}", objects.Count + 1, obj.object_name); } } else if (line.StartsWith("usemtl ")) { obj.material_name = line.Substring(7); } else if (line.StartsWith("v ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] verts = line.Replace(" ", " ").Split(' '); Vector3 vert = new Vector3(); vert.X = Convert.ToSingle(verts[1], CultureInfo.InvariantCulture); vert.Y = Convert.ToSingle(verts[2], CultureInfo.InvariantCulture); vert.Z = Convert.ToSingle(verts[3], CultureInfo.InvariantCulture); obj.verts.Add(vert); } else if (line.StartsWith("vt ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] uvs = line.Split(' '); Vector2 uv = new Vector2(); uv.X = Convert.ToSingle(uvs[1], CultureInfo.InvariantCulture); uv.Y = Convert.ToSingle(uvs[2], CultureInfo.InvariantCulture); obj.uv.Add(uv); } else if (line.StartsWith("vn ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] norms = line.Split(' '); Vector3 norm = new Vector3(); norm.X = Convert.ToSingle(norms[1], CultureInfo.InvariantCulture); norm.Y = Convert.ToSingle(norms[2], CultureInfo.InvariantCulture); norm.Z = Convert.ToSingle(norms[3], CultureInfo.InvariantCulture); obj.normals.Add(norm); } else if (line.StartsWith("s ")) { current_shade_group = line.Substring(2); } else if (line.StartsWith("f ")) { reading_faces = true; if (current_shade_group != null) { if (obj.shading_groups.ContainsKey(current_shade_group)) { obj.shading_groups[current_shade_group].Add(obj.faces.Count); } else { List <int> newfaces = new List <int>(); newfaces.Add(obj.faces.Count); obj.shading_groups.Add(current_shade_group, newfaces); } } String[] faces = line.Substring(2).Split(' '); for (int x = 0; x < 3; x++) { ushort fa = 0, fb = 0, fc = 0; if (obj.verts.Count > 0) { fa = (ushort)(Convert.ToUInt16(faces[x].Split('/')[0]) - prevMaxVerts - 1); } if (obj.uv.Count > 0) { fb = (ushort)(Convert.ToUInt16(faces[x].Split('/')[1]) - prevMaxUvs - 1); } if (obj.normals.Count > 0) { fc = (ushort)(Convert.ToUInt16(faces[x].Split('/')[2]) - prevMaxNorms - 1); } if (fa < 0 || fb < 0 || fc < 0) { throw new Exception("What the actual flapjack, something is *VERY* wrong"); } obj.faces.Add(new Face(fa, fb, fc)); } } } if (!objects.Contains(obj)) { objects.Add(obj); } } } //Read each object foreach (obj_data obj in objects) { //One would fix Tatsuto's broken shading here. //Locate the proper model var hashname = HashName.FromNumberOrString(obj.object_name); Model modelSection = fmd.parsed_sections .Where(i => i.Value is Model mod && hashname.Hash == mod.HashName.Hash) .Select(i => i.Value as Model) .FirstOrDefault(); //Apply new changes if (modelSection == null) { toAddObjects.Add(obj); continue; } PassthroughGP passthrough_section = modelSection.PassthroughGP; Geometry geometry_section = passthrough_section.Geometry; Topology topology_section = passthrough_section.Topology; AddObject(false, obj, modelSection, passthrough_section, geometry_section, topology_section); } //Add new objects if (addNew) { foreach (obj_data obj in toAddObjects) { //create new Model Material newMat = new Material(obj.material_name); fmd.AddSection(newMat); MaterialGroup newMatG = new MaterialGroup(newMat); fmd.AddSection(newMatG); Geometry newGeom = new Geometry(obj); fmd.AddSection(newGeom); Topology newTopo = new Topology(obj); fmd.AddSection(newTopo); PassthroughGP newPassGP = new PassthroughGP(newGeom, newTopo); fmd.AddSection(newPassGP); TopologyIP newTopoIP = new TopologyIP(newTopo); fmd.AddSection(newTopoIP); Object3D parent = root_point.Invoke(obj.object_name); Model newModel = new Model(obj, newPassGP, newTopoIP, newMatG, parent); fmd.AddSection(newModel); AddObject(true, obj, newModel, newPassGP, newGeom, newTopo); //Add new sections } } }
public static void ExportFile(FullModelData data, string path) { //you remove items from the parsed_sections //you edit items in the parsed_sections, they will get read and exported //Sort the sections List <Animation> animation_sections = new List <Animation>(); List <Author> author_sections = new List <Author>(); List <ISection> material_sections = new List <ISection>(); List <Object3D> object3D_sections = new List <Object3D>(); List <Model> model_sections = new List <Model>(); List <ISection> other_sections = new List <ISection>(); // Discard the old hashlist // Note that we use ToArray, which allows us to mutate the list without breaking anything foreach (SectionHeader header in data.sections.ToArray()) { if (header.type == Tags.custom_hashlist_tag) { data.RemoveSection(header.id); } } CustomHashlist hashlist = new CustomHashlist(); data.AddSection(hashlist); foreach (SectionHeader sectionheader in data.sections) { if (!data.parsed_sections.Keys.Contains(sectionheader.id)) { Log.Default.Warn($"BUG: SectionHeader with id {sectionheader.id} has no counterpart in parsed_sections"); continue; } var section = data.parsed_sections[sectionheader.id]; if (section is Animation) { animation_sections.Add(section as Animation); } else if (section is Author) { author_sections.Add(section as Author); } else if (section is MaterialGroup) { foreach (var matsec in (section as MaterialGroup).Items) { if (!data.parsed_sections.ContainsKey(matsec.SectionId)) { throw new Exception($"BUG: In MaterialGroup {section.SectionId}, Material {matsec.SectionId} isn't registered as part of the .model we're saving"); } if (!material_sections.Contains(matsec)) { material_sections.Add(matsec); } } material_sections.Add(section); } else if (section is Model) // Has to be before Object3D, since it's a subclass. { model_sections.Add(section as Model); } else if (section is Object3D) { object3D_sections.Add(section as Object3D); } else if (section != null) { other_sections.Add(section as ISection); } else { Log.Default.Warn("BUG: Somehow a null or non-section found its way into the list of sections."); } if (section is IHashContainer container) { container.CollectHashes(hashlist); } } var sections_to_write = Enumerable.Empty <ISection>() .Concat(animation_sections) .Concat(author_sections) .Concat(material_sections) .Concat(object3D_sections) .Concat(model_sections) .Concat(other_sections) .OrderedDistinct() .ToList(); //after each section, you go back and enter it's new size using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) { using (BinaryWriter bw = new BinaryWriter(fs)) { bw.Write(-1); //the - (yyyy) bw.Write((UInt32)100); //Filesize (GO BACK AT END AND CHANGE!!!) int sectionCount = data.sections.Count; bw.Write(sectionCount); //Sections count foreach (var sec in sections_to_write) { sec.StreamWrite(bw); } if (sections_to_write.Count != sectionCount) { Log.Default.Warn($"BUG : There were {sectionCount} sections to write but {sections_to_write.Count} were written"); } if (data.leftover_data != null) { bw.Write(data.leftover_data); } fs.Position = 4; bw.Write((UInt32)fs.Length); } } }
// Please don't ask what this does private static void ExportPatternUVObj(FullModelData data, string path) { List <SectionHeader> sections = data.sections; Dictionary <UInt32, ISection> parsed_sections = data.parsed_sections; byte[] leftover_data = data.leftover_data; //Generate obj ushort maxfaces = 0; UInt32 uvcount = 0; UInt32 normalcount = 0; Directory.CreateDirectory(Path.GetDirectoryName(path)); using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { foreach (SectionHeader sectionheader in sections) { if (sectionheader.type == model_data_tag) { Model model_data = (Model)parsed_sections[sectionheader.id]; if (model_data.version == 6) { continue; } PassthroughGP passthrough_section = model_data.PassthroughGP; Geometry geometry_section = passthrough_section.Geometry; Topology topology_section = passthrough_section.Topology; sw.WriteLine("#"); sw.WriteLine("# object " + model_data.Name); sw.WriteLine("#"); sw.WriteLine(); sw.WriteLine("o " + model_data.Name); foreach (Vector3 vert in geometry_section.verts) { sw.WriteLine("v " + vert.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + vert.Y.ToString("0.000000", CultureInfo.InvariantCulture) + " " + vert.Z.ToString("0.000000", CultureInfo.InvariantCulture)); } sw.WriteLine("# " + geometry_section.verts.Count + " vertices"); sw.WriteLine(); foreach (Vector2 uv in geometry_section.pattern_uvs) { sw.WriteLine("vt " + uv.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + (-uv.Y).ToString("0.000000", CultureInfo.InvariantCulture)); } sw.WriteLine("# " + geometry_section.pattern_uvs.Count + " UVs"); sw.WriteLine(); foreach (Vector3 norm in geometry_section.normals) { sw.WriteLine("vn " + norm.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + norm.Y.ToString("0.000000", CultureInfo.InvariantCulture) + " " + norm.Z.ToString("0.000000", CultureInfo.InvariantCulture)); } sw.WriteLine("# " + geometry_section.normals.Count + " Normals"); sw.WriteLine(); sw.WriteLine("g " + model_data.Name); foreach (Face face in topology_section.facelist) { //x sw.Write("f " + (maxfaces + face.a + 1)); sw.Write('/'); if (geometry_section.pattern_uvs.Count > 0) { sw.Write((uvcount + face.a + 1)); } sw.Write('/'); if (geometry_section.normals.Count > 0) { sw.Write((normalcount + face.a + 1)); } //y sw.Write(" " + (maxfaces + face.b + 1)); sw.Write('/'); if (geometry_section.pattern_uvs.Count > 0) { sw.Write((uvcount + face.b + 1)); } sw.Write('/'); if (geometry_section.normals.Count > 0) { sw.Write((normalcount + face.b + 1)); } //z sw.Write(" " + (maxfaces + face.c + 1)); sw.Write('/'); if (geometry_section.pattern_uvs.Count > 0) { sw.Write((uvcount + face.c + 1)); } sw.Write('/'); if (geometry_section.normals.Count > 0) { sw.Write((normalcount + face.c + 1)); } sw.WriteLine(); } sw.WriteLine("# " + topology_section.facelist.Count + " Faces"); sw.WriteLine(); maxfaces += (ushort)geometry_section.verts.Count; uvcount += (ushort)geometry_section.pattern_uvs.Count; normalcount += (ushort)geometry_section.normals.Count; } } sw.Close(); } fs.Close(); } }
private static void GenerateOutputInfo(FullModelData data, string path) { List <SectionHeader> sections = data.sections; Dictionary <UInt32, ISection> parsed_sections = data.parsed_sections; byte[] leftover_data = data.leftover_data; //Generate outinfo.txt - Used for research and debug purposes using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) { using (StreamWriter sw = new StreamWriter(fs)) { foreach (SectionHeader sectionheader in sections) { if (sectionheader.type == passthroughGP_tag) { PassthroughGP passthrough_section = (PassthroughGP)parsed_sections[sectionheader.id]; Geometry geometry_section = passthrough_section.Geometry; Topology topology_section = passthrough_section.Topology; sw.WriteLine("Object ID: " + sectionheader.id); sw.WriteLine("Verts (x, z, y)"); foreach (Vector3 vert in geometry_section.verts) { sw.WriteLine(vert.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + vert.Z.ToString("0.000000", CultureInfo.InvariantCulture) + " " + (-vert.Y).ToString("0.000000", CultureInfo.InvariantCulture)); } sw.WriteLine("UV (u, -v)"); foreach (Vector2 uv in geometry_section.uvs) { sw.WriteLine(uv.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + uv.Y.ToString("0.000000", CultureInfo.InvariantCulture)); } sw.WriteLine("Normals (i, j, k)"); //Testing List <Vector3> norm_tangents = new List <Vector3>(); List <Vector3> norm_binorms = new List <Vector3>(); foreach (Vector3 norm in geometry_section.normals) { sw.WriteLine(norm.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + norm.Y.ToString("0.000000", CultureInfo.InvariantCulture) + " " + norm.Z.ToString("0.000000", CultureInfo.InvariantCulture)); Vector3 norm_t; Vector3 binorm; Vector3 t1 = Vector3.Cross(norm, Vector3.UnitX); Vector3 t2 = Vector3.Cross(norm, new Vector3(0, 0, -1)); if (t1.Length() > t2.Length()) { norm_t = t1; } else { norm_t = t2; } norm_t = Vector3.Normalize(norm_t); norm_tangents.Add(norm_t); binorm = Vector3.Cross(norm, norm_t); binorm = Vector3.Normalize(binorm * -1.0f); norm_binorms.Add(binorm); } if (norm_binorms.Count > 0 && norm_tangents.Count > 0) { Vector3[] arranged_unknown20 = norm_binorms.ToArray(); Vector3[] arranged_unknown21 = norm_tangents.ToArray(); for (int fcount = 0; fcount < topology_section.facelist.Count; fcount++) { Face f = topology_section.facelist[fcount]; //unknown_20 arranged_unknown20[f.a] = norm_binorms[topology_section.facelist[fcount].a]; arranged_unknown20[f.b] = norm_binorms[topology_section.facelist[fcount].b]; arranged_unknown20[f.c] = norm_binorms[topology_section.facelist[fcount].c]; //unknown_21 arranged_unknown21[f.a] = norm_tangents[topology_section.facelist[fcount].a]; arranged_unknown21[f.b] = norm_tangents[topology_section.facelist[fcount].b]; arranged_unknown21[f.c] = norm_tangents[topology_section.facelist[fcount].c]; } norm_binorms = arranged_unknown20.ToList(); norm_tangents = arranged_unknown21.ToList(); } sw.WriteLine("Pattern UVs (u, v)"); foreach (Vector2 pattern_uv_entry in geometry_section.pattern_uvs) { sw.WriteLine(pattern_uv_entry.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + pattern_uv_entry.Y.ToString("0.000000", CultureInfo.InvariantCulture)); } int unk20tangcount = 0; int unk21tangcount = 0; sw.WriteLine("Unknown 20 (float, float, float) - Normal tangents???"); foreach (Vector3 unknown_20_entry in geometry_section.binormals) { sw.WriteLine(unknown_20_entry.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + unknown_20_entry.Y.ToString("0.000000", CultureInfo.InvariantCulture) + " " + unknown_20_entry.Z.ToString("0.000000", CultureInfo.InvariantCulture)); Vector3 normt = norm_tangents[unk20tangcount]; sw.WriteLine("* " + normt.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + normt.Y.ToString("0.000000", CultureInfo.InvariantCulture) + " " + normt.Z.ToString("0.000000", CultureInfo.InvariantCulture)); unk20tangcount++; } sw.WriteLine("Unknown 21 (float, float, float) - Normal tangents???"); foreach (Vector3 unknown_21_entry in geometry_section.tangents) { sw.WriteLine(unknown_21_entry.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + unknown_21_entry.Y.ToString("0.000000", CultureInfo.InvariantCulture) + " " + unknown_21_entry.Z.ToString("0.000000", CultureInfo.InvariantCulture)); Vector3 normt = norm_binorms[unk21tangcount]; sw.WriteLine("* " + normt.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + normt.Y.ToString("0.000000", CultureInfo.InvariantCulture) + " " + normt.Z.ToString("0.000000", CultureInfo.InvariantCulture)); unk21tangcount++; } sw.WriteLine("Unknown 15 (float, float) - Weights???"); foreach (GeometryWeightGroups unknown_15_entry in geometry_section.weight_groups) { sw.WriteLine(unknown_15_entry.Bones1.ToString() + " " + unknown_15_entry.Bones2.ToString() + " " + unknown_15_entry.Bones3.ToString() + " " + unknown_15_entry.Bones4.ToString()); //sw.WriteLine(unknown_15_entry.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + unknown_15_entry.Y.ToString("0.000000", CultureInfo.InvariantCulture)); } sw.WriteLine("Unknown 17 (float, float, float) - Weights???"); foreach (Vector3 unknown_17_entry in geometry_section.weights) { sw.WriteLine(unknown_17_entry.X.ToString("0.000000", CultureInfo.InvariantCulture) + " " + unknown_17_entry.Y.ToString("0.000000", CultureInfo.InvariantCulture)); } foreach (Byte[] gunkid in geometry_section.unknown_item_data) { if (gunkid.Length % 8 == 0) { sw.WriteLine("Unknown X (float, float)"); for (int x = 0; x < gunkid.Length;) { sw.Write(BitConverter.ToSingle(gunkid, x).ToString("0.000000", CultureInfo.InvariantCulture) + " "); x += 4; sw.Write(BitConverter.ToSingle(gunkid, x).ToString("0.000000", CultureInfo.InvariantCulture)); x += 4; sw.WriteLine(); } } else if (gunkid.Length % 12 == 0) { sw.WriteLine("Unknown X (float, float, float)"); for (int x = 0; x < gunkid.Length;) { sw.Write(BitConverter.ToSingle(gunkid, x).ToString("0.000000", CultureInfo.InvariantCulture) + " "); x += 4; sw.Write(BitConverter.ToSingle(gunkid, x).ToString("0.000000", CultureInfo.InvariantCulture) + " "); x += 4; sw.Write(BitConverter.ToSingle(gunkid, x).ToString("0.000000", CultureInfo.InvariantCulture)); x += 4; sw.WriteLine(); } } else if (gunkid.Length % 4 == 0) { sw.WriteLine("Unknown X (float)"); for (int x = 0; x < gunkid.Length;) { sw.Write(BitConverter.ToSingle(gunkid, x).ToString("0.000000", CultureInfo.InvariantCulture)); x += 4; sw.WriteLine(); } } else { sw.Write("Something else... [for debugging]"); } } sw.WriteLine("Faces (f1, f2, f3)"); foreach (Face face in topology_section.facelist) { sw.WriteLine((face.a + 1) + " " + (face.b + 1) + " " + (face.c + 1)); } sw.WriteLine(); geometry_section.PrintDetailedOutput(sw); sw.WriteLine(); } } sw.Close(); } fs.Close(); } }
public ObjectsRootNode(FullModelData fmd) { data = fmd; }
public ModelRootNode(FullModelData fmd) { data = fmd; }
private void UpdateRootPointBox() { string old_selected_name; if (rootPoints.SelectedIndex > 0) { old_selected_name = root_point_items[rootPoints.SelectedIndex].Name; } else { // Use the root point, if it exists. Otherwise, this won't match and // we'll use the default new_index of 0. old_selected_name = "root_point"; } int new_index = 0; root_point_items.Clear(); root_point_items.Add(new RootPointItem("None", 0)); if (scriptFile.Selected != null) { // If we're using a script, we unfortunately have to fully load the file to evaluate the script string model_file = baseModelFileBrowser.Enabled ? baseModelFileBrowser.Selected : null; FullModelData data = model_file != null?ModelReader.Open(model_file) : new FullModelData(); // TODO display the errors in a less intrusive way bool success = Modelscript.Script.ExecuteFileWithMsgBox(ref data, scriptFile.Selected); if (!success) { return; } foreach (Object3D obj in data.SectionsOfType <Object3D>()) { root_point_items.Add(new RootPointItem(obj.Name, obj.SectionId)); if (old_selected_name == obj.Name) { new_index = root_point_items.Count - 1; } } } else if (baseModelFileBrowser.Enabled && baseModelFileBrowser.Selected != null) { // If there is no script file, just skim the model and collect the object IDs like that. // This isn't a major improvement, but it does increase performance. StaticStorage.hashindex.Load(); ModelReader.VisitModel(baseModelFileBrowser.Selected, (reader, header) => { if (header.type == Tags.object3D_tag) { // First field of Object3D ulong hashname = reader.ReadUInt64(); string name = StaticStorage.hashindex.GetString(hashname); RootPointItem item = new RootPointItem(name, header.id); root_point_items.Add(item); Log.Default.Debug("Scanning for rootpoint: {0}", name); if (old_selected_name == name) { new_index = root_point_items.Count - 1; } } }); } rootPoints.Items.Clear(); rootPoints.Items.AddRange(root_point_items.ToArray()); rootPoints.SelectedIndex = new_index; }
public static FullModelData ExecuteItems(IEnumerable <IScriptItem> items, string workDir, FullModelData initialModel) { var state = new ScriptState { Data = initialModel, WorkDir = workDir }; state.ExecuteItems(items); return(state.Data); }
public static bool ImportNewObjPatternUV(FullModelData fm, string filepath) { Log.Default.Info("Importing new obj with file for UV patterns: {0}", filepath); //Preload the .obj List <obj_data> objects = new List <obj_data>(); try { using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read)) { using (StreamReader sr = new StreamReader(fs)) { string line; obj_data obj = new obj_data(); bool reading_faces = false; int prevMaxVerts = 0; int prevMaxUvs = 0; int prevMaxNorms = 0; while ((line = sr.ReadLine()) != null) { //preloading objects if (line.StartsWith("#")) { continue; } else if (line.StartsWith("o ") || line.StartsWith("g ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } obj.object_name = line.Substring(2); } else if (line.StartsWith("usemtl ")) { obj.material_name = line.Substring(2); } else if (line.StartsWith("v ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] verts = line.Replace(" ", " ").Split(' '); Vector3 vert = new Vector3(); vert.X = Convert.ToSingle(verts[1], CultureInfo.InvariantCulture); vert.Y = Convert.ToSingle(verts[2], CultureInfo.InvariantCulture); vert.Z = Convert.ToSingle(verts[3], CultureInfo.InvariantCulture); obj.verts.Add(vert); } else if (line.StartsWith("vt ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] uvs = line.Split(' '); Vector2 uv = new Vector2(); uv.X = Convert.ToSingle(uvs[1], CultureInfo.InvariantCulture); uv.Y = Convert.ToSingle(uvs[2], CultureInfo.InvariantCulture); obj.uv.Add(uv); } else if (line.StartsWith("vn ")) { if (reading_faces) { reading_faces = false; prevMaxVerts += obj.verts.Count; prevMaxUvs += obj.uv.Count; prevMaxNorms += obj.normals.Count; objects.Add(obj); obj = new obj_data(); } String[] norms = line.Split(' '); Vector3 norm = new Vector3(); norm.X = Convert.ToSingle(norms[1], CultureInfo.InvariantCulture); norm.Y = Convert.ToSingle(norms[2], CultureInfo.InvariantCulture); norm.Z = Convert.ToSingle(norms[3], CultureInfo.InvariantCulture); obj.normals.Add(norm); } else if (line.StartsWith("f ")) { reading_faces = true; String[] faces = line.Substring(2).Split(' '); for (int x = 0; x < 3; x++) { ushort fa = 0, fb = 0, fc = 0; if (obj.verts.Count > 0) { fa = (ushort)(Convert.ToUInt16(faces[x].Split('/')[0]) - prevMaxVerts - 1); } if (obj.uv.Count > 0) { fb = (ushort)(Convert.ToUInt16(faces[x].Split('/')[1]) - prevMaxUvs - 1); } if (obj.normals.Count > 0) { fc = (ushort)(Convert.ToUInt16(faces[x].Split('/')[2]) - prevMaxNorms - 1); } if (fa < 0 || fb < 0 || fc < 0) { throw new Exception("What the actual flapjack, something is *VERY* wrong"); } obj.faces.Add(new Face(fa, fb, fc)); } } } if (!objects.Contains(obj)) { objects.Add(obj); } } } //Read each object foreach (obj_data obj in objects) { //Locate the proper model uint modelSectionid = 0; foreach (KeyValuePair <uint, ISection> pair in fm.parsed_sections) { if (modelSectionid != 0) { break; } if (pair.Value is Model) { UInt64 tryp; if (UInt64.TryParse(obj.object_name, out tryp)) { if (tryp == ((Model)pair.Value).HashName.Hash) { modelSectionid = pair.Key; } } else { if (Hash64.HashString(obj.object_name) == ((Model)pair.Value).HashName.Hash) { modelSectionid = pair.Key; } } } } //Apply new changes if (modelSectionid == 0) { continue; } Model model_data_section = (Model)fm.parsed_sections[modelSectionid]; PassthroughGP passthrough_section = model_data_section.PassthroughGP; Geometry geometry_section = passthrough_section.Geometry; Topology topology_section = passthrough_section.Topology; //Arrange UV and Normals Vector2[] new_arranged_UV = new Vector2[geometry_section.verts.Count]; for (int x = 0; x < new_arranged_UV.Length; x++) { new_arranged_UV[x] = new Vector2(100f, 100f); } Vector2 sentinel = new Vector2(100f, 100f); if (topology_section.facelist.Count != obj.faces.Count / 3) { return(false); } for (int fcount = 0; fcount < topology_section.facelist.Count; fcount += 3) { Face f1 = obj.faces[fcount + 0]; Face f2 = obj.faces[fcount + 1]; Face f3 = obj.faces[fcount + 2]; //UV if (obj.uv.Count > 0) { if (new_arranged_UV[topology_section.facelist[fcount / 3 + 0].a].Equals(sentinel)) { new_arranged_UV[topology_section.facelist[fcount / 3 + 0].a] = obj.uv[f1.b]; } if (new_arranged_UV[topology_section.facelist[fcount / 3 + 0].b].Equals(sentinel)) { new_arranged_UV[topology_section.facelist[fcount / 3 + 0].b] = obj.uv[f2.b]; } if (new_arranged_UV[topology_section.facelist[fcount / 3 + 0].c].Equals(sentinel)) { new_arranged_UV[topology_section.facelist[fcount / 3 + 0].c] = obj.uv[f3.b]; } } } geometry_section.UVs[1] = new_arranged_UV.ToList(); passthrough_section.Geometry.UVs[1] = new_arranged_UV.ToList(); } } catch (Exception exc) { System.Windows.Forms.MessageBox.Show(exc.ToString()); return(false); } return(true); }