private void mnuImportOBJ_Click(object sender, RoutedEventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.DefaultExt = ".obj"; dlg.Filter = "Wavefront .OBJ|*.obj"; if (dlg.ShowDialog().GetValueOrDefault(false)) { RW4ModelSectionView sectionView = this.DataContext as RW4ModelSectionView; VertexFormat vertexFormatSection = (VertexFormat)sectionView.Model.Sections.First(s => s.TypeCode == SectionTypeCodes.VertexFormat).obj; RW4Section section = sectionView.Section; SporeMaster.RenderWare4.RW4Mesh meshSection = section.obj as SporeMaster.RenderWare4.RW4Mesh; IConverter converter = new WaveFrontOBJConverter(); RW4Mesh newMesh = converter.Import(meshSection, dlg.FileName); meshSection.vertices.vertices.section.obj = newMesh.vertices.vertices; meshSection.triangles.triangles.section.obj = newMesh.triangles.triangles; this.DataContext = sectionView; section.Changed(); } }
private void mnuExportOBJ_Click(object sender, RoutedEventArgs e) { SaveFileDialog dlg = new SaveFileDialog(); dlg.DefaultExt = ".obj"; dlg.Filter = "WaveFront .OBJ|*.obj"; if (dlg.ShowDialog().GetValueOrDefault(false)) { if (this.DataContext != null && this.DataContext.GetType() == typeof(RW4ModelSectionView)) { matDiffuseMain.Brush = new SolidColorBrush(Colors.LightGray); RW4ModelSectionView sectionView = this.DataContext as RW4ModelSectionView; // listBoxTextures.ItemsSource = sectionView.Model.Sections.Where<RW4Section>(s => s.TypeCode == SectionTypeCodes.Texture); RW4Section section = sectionView.Section; RW4Mesh mesh = section.obj as RW4Mesh; mesh.Export(dlg.FileName); } } }
private void TangentSolver(RW4Mesh mesh) { int vertexCount = mesh.vertices.vertices.Length; SporeMaster.RenderWare4.VertexBuffer vertices = mesh.vertices.vertices; Buffer <Triangle> triangles = mesh.triangles.triangles; Vector3[] tan1 = new Vector3[vertices.Length]; Vector3[] tan2 = new Vector3[vertices.Length]; int triangleCount = mesh.triangles.triangles.Length; for (int i = 0; i < triangleCount; i += 3) { Triangle i1 = triangles[i]; Vertex v1 = vertices[(int)i1.i]; Vertex v2 = vertices[(int)i1.j]; Vertex v3 = vertices[(int)i1.k]; var x1 = v2.Position.X - v1.Position.X; var x2 = v3.Position.X - v1.Position.X; var y1 = v2.Position.Y - v1.Position.Y; var y2 = v3.Position.Y - v1.Position.Y; var z1 = v2.Position.Z - v1.Position.Z; var z2 = v3.Position.Z - v1.Position.Z; var s1 = v2.TextureCoordinates.X - v1.TextureCoordinates.X; var s2 = v3.TextureCoordinates.X - v1.TextureCoordinates.X; var t1 = v2.TextureCoordinates.Y - v1.TextureCoordinates.Y; var t2 = v3.TextureCoordinates.Y - v1.TextureCoordinates.Y; float r = 1.0f / (s1 * t2 - s2 * t1); var sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); var tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); tan1[i1.i] += sdir; tan1[i1.j] += sdir; tan1[i1.k] += sdir; tan2[i1.i] += tdir; tan2[i1.j] += tdir; tan2[i1.k] += tdir; } for (int i = 0; i < mesh.vertices.vertices.Length; i++) { Vector3 normal = new Vector3(mesh.vertices.vertices[i].Normal.X, mesh.vertices.vertices[i].Normal.Y, mesh.vertices.vertices[i].Normal.Z); // Gram-Schmidt orthogonalize Vector3 tangent = tan1[i] - normal * Vector3.Dot(normal, tan1[i]); tangent.Normalize(); // Calculate handedness (here maybe you need to switch >= with <= depend on the geometry winding order) float tangentdir = (Vector3.Dot(Vector3.Cross(normal, tan1[i]), tan2[i]) >= 0.0f) ? 1.0f : -1.0f; Vector3 binormal = Vector3.Cross(normal, tangent) * tangentdir; Vertex v = mesh.vertices.vertices[i]; VertexUByte4Value tangentValue = (VertexUByte4Value)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TANGENT && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_UBYTE4); tangentValue.X = (byte)(tangent.X * 127.5F + 127.5F); tangentValue.Y = (byte)(tangent.Y * 127.5F + 127.5F); tangentValue.Z = (byte)(tangent.Z * 127.5F + 127.5F); tangentValue.W = (byte)255; mesh.vertices.vertices[i] = v; } }
void pack(OgreXmlReader src_model, RW4Model model) { model.FileType = RW4Model.FileTypes.Model; RW4Skeleton skel = new RW4Skeleton(); skel.unk1 = 0x8d6da0; skel.mat3 = new Matrices4x3() { items = new Mat4x3[] { new Mat4x3() { m = new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } } } }; skel.mat4 = new Matrices4x4() { items = new Mat4x4[] { new Mat4x4() { m = new float[] { /* 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,*/ 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } } } }; skel.jointInfo = new RW4HierarchyInfo() { id = "skeleton1".FNV(), items = new RW4HierarchyInfo.Item[] { new RW4HierarchyInfo.Item { index=0, name_fnv = "joint1".FNV(), flags=1, parent=null } }, }; var anim = new Anim() { skeleton_id = skel.jointInfo.id, flags = 3, length = 1.25f, channel_names = (from j in skel.jointInfo.items select j.name_fnv).ToArray(), }; anim.channel_frame_pose = new JointPose[,] { { new JointPose{ qx=0, qy=0, qz=0, qs=1, tx=0, ty=0, tz=0, sx=1, sy=1, sz=1, time=1.25f } } }; var mesh = new RW4Mesh() { vertices = new RW4VertexArray(), triangles = new RW4TriangleArray(), }; mesh.vertices.unk2 = 0; //< ? mesh.vertices.format = new VertexFormat() { blob = RW4Garbage.vertex_format }; mesh.vertices.vertices = new Buffer<Vertex>(0); mesh.vertices.vertices.Assign(src_model.vertices); mesh.triangles.unk1 = 0; //< ? mesh.triangles.triangles = new Buffer<Triangle>(0); mesh.triangles.triangles.Assign(src_model.triangles); var texture = new Texture() { width = 64, height = 64, mipmapInfo = 0x708, textureType = Texture.DXT5, unk1 = 0, texData = new TextureBlob() { blob = new byte[5488] } }; var texture_format = new RW4TexMetadata() { unk_data_1 = RW4Garbage.texture_format_1, unk_data_2 = RW4Garbage.texture_format_2, texture = texture }; var meshMaterial = new RWMeshMaterialAssignment() { mesh = mesh, mat = new RW4TexMetadata[] { texture_format } }; model.AddObject(anim, Anim.type_code); model.AddObject(mesh.vertices.format, VertexFormat.type_code); model.AddObject(skel.mat4, Matrices4x4.type_code); model.AddObject(skel.mat3, Matrices4x3.type_code); skel.mat3.section.fixup_offsets.Add(16); // !? model.AddObject(skel, RW4Skeleton.type_code); model.AddObject(mesh.triangles.triangles, Buffer<Triangle>.type_code); model.AddObject(mesh.triangles, RW4TriangleArray.type_code); model.AddObject(mesh, RW4Mesh.type_code); model.AddObject(texture_format, RW4TexMetadata.type_code); model.AddObject(meshMaterial, RWMeshMaterialAssignment.type_code); model.AddObject(skel.jointInfo, RW4HierarchyInfo.type_code); model.AddObject(mesh.vertices.vertices, Buffer<Vertex>.type_code); model.AddObject(mesh.vertices, RW4VertexArray.type_code); model.AddObject(texture.texData, TextureBlob.type_code); model.AddObject(texture, Texture.type_code); }