public Model(obj_data obj, uint passGP_ID, uint topoIP_ID, uint matg_id) { id = (uint)obj.object_name.GetHashCode(); size = 0U; object3D = new Object3D(obj.object_name, StaticStorage.rp_id); version = 3U; passthroughGP_ID = passGP_ID; topologyIP_ID = topoIP_ID; count = 1U; items = new List <ModelItem>(); items.Add(new ModelItem { unknown1 = 0U, vertCount = (uint)obj.verts.Count, unknown2 = 0U, faceCount = (uint)obj.faces.Count, material_id = 0U }); material_group_section_id = matg_id; unknown10 = 0U; bounds_min.Z = 0.0f; bounds_min.X = 0.0f; bounds_min.Y = 0.0f; bounds_max.Z = 0.0f; bounds_max.X = 0.0f; bounds_max.Y = 0.0f; unknown11 = 0U; unknown12 = 1U; unknown13 = 6U; skinbones_ID = 0U; }
public Topology(uint sec_id, obj_data obj) { id = sec_id; size = 0U; unknown1 = 0U; count1 = (uint)(obj.faces.Count / 3); facelist = obj.faces; count2 = 0U; items2 = new byte[0]; hashname = Hash64.HashString(obj.object_name + ".Topology", 0UL); }
public Geometry(uint sec_id, obj_data newobject) { this.id = sec_id; this.size = 0U; this.vert_count = (uint)newobject.verts.Count; this.header_count = 5U; this.headers.Add(new GeometryHeader(3U, 1U)); this.headers.Add(new GeometryHeader(2U, 7U)); this.headers.Add(new GeometryHeader(3U, 2U)); this.headers.Add(new GeometryHeader(3U, 20U)); this.headers.Add(new GeometryHeader(3U, 21U)); this.verts = newobject.verts; this.uvs = newobject.uv; this.normals = newobject.normals; this.hashname = Hash64.HashString(newobject.object_name + ".Geometry", 0UL); }
public Geometry(obj_data newobject) : this() { this.vert_count = (uint)newobject.verts.Count; this.Headers.Add(new GeometryHeader(3, GeometryChannelTypes.POSITION)); // vert this.Headers.Add(new GeometryHeader(2, GeometryChannelTypes.TEXCOORD0)); // uv this.Headers.Add(new GeometryHeader(3, GeometryChannelTypes.NORMAL0)); // norm this.Headers.Add(new GeometryHeader(3, GeometryChannelTypes.BINORMAL0)); // unk20 this.Headers.Add(new GeometryHeader(3, GeometryChannelTypes.TANGENT0)); // unk21 this.verts = newobject.verts; this.UVs[0] = newobject.uv; this.normals = newobject.normals; //this.binormals; //this.tangents; this.HashName = new HashName(newobject.object_name + ".Geometry"); }
public Topology(obj_data obj) : this(obj.object_name) { this.facelist = obj.faces; }
public Model(obj_data obj, PassthroughGP passGP, TopologyIP topoIP, MaterialGroup matg, Object3D parent) : this(obj.object_name, (uint)obj.verts.Count, (uint)obj.faces.Count, passGP, topoIP, matg, parent) { }
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); }
private static void AddObject(bool is_new, obj_data obj, Model model_data_section, PassthroughGP passthrough_section, Geometry geometry_section, Topology topology_section) { List <Face> called_faces = new List <Face>(); List <int> duplicate_verts = new List <int>(); Dictionary <int, Face> dup_faces = new Dictionary <int, Face>(); bool broken = false; for (int x_f = 0; x_f < obj.faces.Count; x_f++) { Face f = obj.faces[x_f]; broken = false; foreach (Face called_f in called_faces) { if (called_f.a == f.a && called_f.b != f.b) { duplicate_verts.Add(x_f); broken = true; break; } } if (!broken) { called_faces.Add(f); } } Dictionary <int, Face> done_faces = new Dictionary <int, Face>(); foreach (int dupe in duplicate_verts) { int replacedF = -1; foreach (KeyValuePair <int, Face> pair in done_faces) { Face f = pair.Value; if (f.a == obj.faces[dupe].a && f.b == obj.faces[dupe].b) { replacedF = pair.Key; } } Face new_face; if (replacedF > -1) { new_face = new Face(obj.faces[replacedF].a, obj.faces[replacedF].b, obj.faces[dupe].c); } else { new_face = new Face((ushort)obj.verts.Count, obj.faces[dupe].b, obj.faces[dupe].c); obj.verts.Add(obj.verts[obj.faces[dupe].a]); done_faces.Add(dupe, obj.faces[dupe]); } obj.faces[dupe] = new_face; } Vector3 new_Model_data_bounds_min = new Vector3(); // Z (max), X (low), Y (low) Vector3 new_Model_data_bounds_max = new Vector3(); // Z (low), X (max), Y (max) foreach (Vector3 vert in obj.verts) { //Z // Note these were previously broken if (vert.Z < new_Model_data_bounds_min.Z) { new_Model_data_bounds_min.Z = vert.Z; } if (vert.Z > new_Model_data_bounds_max.Z) { new_Model_data_bounds_max.Z = vert.Z; } //X if (vert.X < new_Model_data_bounds_min.X) { new_Model_data_bounds_min.X = vert.X; } if (vert.X > new_Model_data_bounds_max.X) { new_Model_data_bounds_max.X = vert.X; } //Y if (vert.Y < new_Model_data_bounds_min.Y) { new_Model_data_bounds_min.Y = vert.Y; } if (vert.Y > new_Model_data_bounds_max.Y) { new_Model_data_bounds_max.Y = vert.Y; } } //Arrange UV and Normals List <Vector3> new_arranged_Geometry_normals = new List <Vector3>(); List <Vector3> new_arranged_Geometry_unknown20 = new List <Vector3>(); List <Vector3> new_arranged_Geometry_unknown21 = new List <Vector3>(); List <int> added_uvs = new List <int>(); List <int> added_normals = new List <int>(); Vector2[] new_arranged_UV = new Vector2[obj.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); Vector3[] new_arranged_Normals = new Vector3[obj.verts.Count]; for (int x = 0; x < new_arranged_Normals.Length; x++) { new_arranged_Normals[x] = new Vector3(0f, 0f, 0f); } Vector3[] new_arranged_unknown20 = new Vector3[obj.verts.Count]; Vector3[] new_arranged_unknown21 = new Vector3[obj.verts.Count]; List <Face> new_faces = new List <Face>(); for (int fcount = 0; fcount < obj.faces.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[f1.a].Equals(sentinel)) { new_arranged_UV[f1.a] = obj.uv[f1.b]; } if (new_arranged_UV[f2.a].Equals(sentinel)) { new_arranged_UV[f2.a] = obj.uv[f2.b]; } if (new_arranged_UV[f3.a].Equals(sentinel)) { new_arranged_UV[f3.a] = obj.uv[f3.b]; } } //normal if (obj.normals.Count > 0) { new_arranged_Normals[f1.a] = obj.normals[f1.c]; new_arranged_Normals[f2.a] = obj.normals[f2.c]; new_arranged_Normals[f3.a] = obj.normals[f3.c]; } Face new_f = new Face(f1.a, f2.a, f3.a); new_faces.Add(new_f); } for (int x = 0; x < new_arranged_Normals.Length; x++) { new_arranged_Normals[x] = Vector3.Normalize(new_arranged_Normals[x]); } List <Vector3> obj_verts = obj.verts; ComputeTangentBasis(ref new_faces, ref obj_verts, ref new_arranged_UV, ref new_arranged_Normals, ref new_arranged_unknown20, ref new_arranged_unknown21); List <RenderAtom> new_Model_items2 = new List <RenderAtom>(); foreach (RenderAtom modelitem in model_data_section.RenderAtoms) { RenderAtom new_model_item = new RenderAtom(); new_model_item.BaseVertex = modelitem.BaseVertex; new_model_item.TriangleCount = (uint)new_faces.Count; new_model_item.BaseIndex = modelitem.BaseIndex; new_model_item.GeometrySliceLength = (uint)obj.verts.Count; new_model_item.MaterialId = modelitem.MaterialId; new_Model_items2.Add(new_model_item); } model_data_section.RenderAtoms = new_Model_items2; if (model_data_section.version != 6) { model_data_section.BoundsMin = new_Model_data_bounds_min; model_data_section.BoundsMax = new_Model_data_bounds_max; model_data_section.BoundingRadius = obj.verts.Select(i => i.Length()).Max(); } geometry_section.vert_count = (uint)obj.verts.Count; geometry_section.verts = obj.verts; geometry_section.normals = new_arranged_Normals.ToList(); geometry_section.UVs[0] = new_arranged_UV.ToList(); geometry_section.binormals = new_arranged_unknown20.ToList(); geometry_section.tangents = new_arranged_unknown21.ToList(); topology_section.facelist = new_faces; }
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 } } }