internal NNS_VECTOR4D Assign(VecFx32 vec) { this.x = (float)vec.x; this.y = (float)vec.y; this.z = (float)vec.z; return(this); }
public static ModelBounds Calculate(Dictionary <int, List <VecFx32> > vertices) { var min = new VecFx32(int.MaxValue); var max = new VecFx32(int.MinValue); foreach (var mesh in vertices.Values) { foreach (var vtx in mesh) { //Set Min if (vtx.X < min.X) { min.X = vtx.X; } if (vtx.Y < min.Y) { min.Y = vtx.Y; } if (vtx.Z < min.Z) { min.Z = vtx.Z; } //Set Max if (vtx.X > max.X) { max.X = vtx.X; } if (vtx.Y > max.Y) { max.Y = vtx.Y; } if (vtx.Z > max.Z) { max.Z = vtx.Z; } } } return(new ModelBounds { Min = min, Max = max }); }
private static void Test() { var test = new Dictionary <VecFx32, int>(); test.Add(new VecFx32(0, 0, 0), 134); Console.WriteLine(test[new VecFx32(0, 0, 0)]); var vec = new VecFx32(34.5654f, 3423.54f, 9087.3f); Console.ReadLine(); /*new ImdConverter(@"E:\ermel\Desktop\conversion_tests\DK_FBX_2\DK_FBX\new_tex_18\dk_new_test.fbx", * new ConversionSettings * { * Magnify = 0.0625f * } * ).Write(@"E:\ermel\Desktop\conversion_tests\_imd\dk.imd");*/ //new ImdConverter(@"E:\ermel\Desktop\conversion_tests\test.fbx", // new ImdConverterSettings // { // RotateX180 = true // } //).Write(@"E:\ermel\Desktop\conversion_tests\_imd\test.imd"); /* * new ImdConverter(@"E:\ermel\Desktop\conversion_tests\ac.fbx", * new ConversionSettings * { * Magnify = 0.0625f, * RotateX180 = true * } * ).Write(@"E:\ermel\Desktop\conversion_tests\_imd\ac.imd");*/ /*new ImdConverter(@"E:\ermel\Desktop\conversion_tests\testBox.fbx", * new ConversionSettings * { * RotateX180 = true * } * ).Write(@"E:\ermel\Desktop\conversion_tests\_imd\testBox.imd");*/ //new ImdConverter(@"E:\ermel\Hackdom\DSHack\EKDS\GRAPHICS\GRAPHICS\Models\Characters\Isabelle\tex\isabelle.obj").Write(@"E:\ermel\Desktop\conversion_tests\_imd\isabelle.imd"); }
private void GetPolygons(Dictionary <int, int> matMap) { var posScale = _imd.Body.ModelInfo.PosScale; var rootNode = _imd.Body.NodeArray.Nodes[0]; var polygonId = 0; foreach (var mesh in _meshes) { var meshId = mesh.Key; var sceneMesh = _scene.Meshes[meshId]; var materialId = matMap[sceneMesh.MaterialIndex]; var material = _imd.Body.MaterialArray.Materials[materialId]; var useNormals = material.Light0 == "on" || material.Light1 == "on" || material.Light2 == "on" || material.Light3 == "on"; var texture = material.TexImageIdx != -1 ? _imd.Body.TexImageArray.TexImages[material.TexImageIdx] : null; var polygon = new Polygon { Index = polygonId, Name = $"polygon{polygonId}", ClrFlag = !useNormals && sceneMesh.HasVertexColors(0) ? "on" : "off", TexFlag = texture != null ? "on" : "off", NrmFlag = useNormals ? "on" : "off", }; var matrixPrimitive = new MatrixPrimitive { Index = 0, PrimitiveArray = new PrimitiveArray { Primitives = new List <Primitive>() } }; polygon.MatrixPrimitives.Add(matrixPrimitive); var finalPrimList = new List <Primitive>(); var primList = new List <Stripping.Primitive>(); var posList = new Dictionary <VecFx32, int>(); var clrList = new Dictionary <(int r, int g, int b), int>(); var texList = new Dictionary <(int s, int t), int>(); var nrmList = new Dictionary <(int x, int y, int z), int>(); foreach (var face in sceneMesh.Faces) { var prim = new Stripping.Primitive(); if (face.IndexCount == 3) { prim.Type = Stripping.Primitive.PrimitiveType.Triangles; polygon.TriangleSize++; } else if (face.IndexCount == 4) { prim.Type = Stripping.Primitive.PrimitiveType.Quads; polygon.QuadSize++; } else { continue; //Other shapes????! } polygon.PolygonSize++; foreach (var vertexIndex in face.Indices) { var vertex = _meshes[meshId][vertexIndex]; prim.Matrices.Add(-1); //Vertex Colors if (!useNormals && sceneMesh.HasVertexColors(0)) { var c = sceneMesh.VertexColorChannels[0][vertexIndex]; var clr = ((int)Math.Round(c.R * 31), (int)Math.Round(c.G * 31), (int)Math.Round(c.B * 31)); int clrIdx = clrList.Count; if (clrList.ContainsKey(clr)) { clrIdx = clrList[clr]; } else { clrList.Add(clr, clrIdx); } prim.Colors.Add(clrIdx); } else { prim.Colors.Add(-1); } //Texture Coordinates if (texture != null) { var texCoord = sceneMesh.TextureCoordinateChannels[0][vertexIndex]; var texC = ((int)Math.Round(texCoord.X * texture.Width * 16), (int)Math.Round((-texCoord.Y * texture.Height + texture.Height) * 16)); int texIdx = texList.Count; if (texList.ContainsKey(texC)) { texIdx = texList[texC]; } else { texList.Add(texC, texIdx); } prim.TexCoords.Add(texIdx); } else { prim.TexCoords.Add(-1); } //Normals if (useNormals) { var normal = sceneMesh.Normals[vertexIndex]; int nx = (int)Math.Round(normal.X * 512) & 0x3FF; if (nx == 512) { nx--; } int ny = (int)Math.Round(normal.Y * 512) & 0x3FF; if (ny == 512) { ny--; } int nz = (int)Math.Round(normal.Z * 512) & 0x3FF; if (nz == 512) { nz--; } var nrm = (nx, ny, nz); int nrmIdx = nrmList.Count; if (nrmList.ContainsKey(nrm)) { nrmIdx = nrmList[nrm]; } else { nrmList.Add(nrm, nrmIdx); } prim.Normals.Add(nrmIdx); } else { prim.Normals.Add(-1); } //Vertex var posScaled = vertex >> posScale; int posIdx = posList.Count; if (posList.ContainsKey(posScaled)) { posIdx = posList[posScaled]; } else { posList.Add(posScaled, posIdx); } prim.Positions.Add(posIdx); } prim.VertexCount = face.IndexCount; primList.Add(prim); } var poss = posList.Keys.ToArray(); var clrs = clrList.Keys.ToArray(); var texs = texList.Keys.ToArray(); var nrms = nrmList.Keys.ToArray(); Stripping.Primitive[] newPrims; if (_settings.UsePrimitiveStrip) { newPrims = QuadStripper.Process(primList.ToArray()); newPrims = TriStripper.Process(newPrims); } else { //No stripping newPrims = primList.ToArray(); } //merge all tris and quads { var tmp = new List <Stripping.Primitive>(newPrims.Where(a => a.Type == Stripping.Primitive.PrimitiveType.TriangleStrip || a.Type == Stripping.Primitive.PrimitiveType.QuadStrip)); var tris = new Stripping.Primitive { Type = Stripping.Primitive.PrimitiveType.Triangles }; var quads = new Stripping.Primitive { Type = Stripping.Primitive.PrimitiveType.Quads }; foreach (var p in newPrims) { if (p.Type == Stripping.Primitive.PrimitiveType.Triangles) { tris.AddVtx(p, 0); tris.AddVtx(p, 1); tris.AddVtx(p, 2); } else if (p.Type == Stripping.Primitive.PrimitiveType.Quads) { quads.AddVtx(p, 0); quads.AddVtx(p, 1); quads.AddVtx(p, 2); quads.AddVtx(p, 3); } } if (tris.VertexCount != 0) { tmp.Add(tris); } if (quads.VertexCount != 0) { tmp.Add(quads); } newPrims = tmp.ToArray(); } Array.Sort(newPrims); foreach (var prim in newPrims) { var primitive = new Primitive(); switch (prim.Type) { case Stripping.Primitive.PrimitiveType.Triangles: primitive.Type = "triangles"; break; case Stripping.Primitive.PrimitiveType.Quads: primitive.Type = "quads"; break; case Stripping.Primitive.PrimitiveType.TriangleStrip: primitive.Type = "triangle_strip"; break; case Stripping.Primitive.PrimitiveType.QuadStrip: primitive.Type = "quad_strip"; break; default: throw new Exception("Unexpected primitive type!"); } var prevVtx = new VecFx32(); int prevClrIdx = -1; for (int i = 0; i < prim.VertexCount; i++) { if (texture != null) { primitive.Commands.Add(new TextureCoordCommand(texs[prim.TexCoords[i]].s / 16f, texs[prim.TexCoords[i]].t / 16f)); } if (useNormals) { primitive.Commands.Add(new NormalCommand((nrms[prim.Normals[i]].x / 512f, nrms[prim.Normals[i]].y / 512f, nrms[prim.Normals[i]].z / 512f))); } else if (!useNormals && sceneMesh.HasVertexColors(0) && prevClrIdx != prim.Colors[i]) { primitive.Commands.Add(new ColorCommand(clrs[prim.Colors[i]].r, clrs[prim.Colors[i]].g, clrs[prim.Colors[i]].b)); prevClrIdx = prim.Colors[i]; } var vtx = poss[prim.Positions[i]]; var diff = vtx - prevVtx; if (i != 0 && diff.X == 0) { primitive.Commands.Add(new PosYzCommand(vtx.ToVector3())); } else if (i != 0 && diff.Y == 0) { primitive.Commands.Add(new PosXzCommand(vtx.ToVector3())); } else if (i != 0 && diff.Z == 0) { primitive.Commands.Add(new PosXyCommand(vtx.ToVector3())); } else if (i != 0 && diff.X < 512 && diff.X >= -512 && diff.Y < 512 && diff.Y >= -512 && diff.Z < 512 && diff.Z >= -512) { primitive.Commands.Add(new PosDiffCommand(diff.ToVector3())); } else if ((vtx.X & 0x3F) == 0 && (vtx.Y & 0x3F) == 0 && (vtx.Z & 0x3F) == 0) { primitive.Commands.Add(new PosShortCommand(vtx.ToVector3())); } else { primitive.Commands.Add(new PosXyzCommand(vtx.ToVector3())); } prevVtx = vtx; polygon.VertexSize++; primitive.VertexSize++; } primitive.Index = finalPrimList.Count; finalPrimList.Add(primitive); } if (finalPrimList.Count == 0) { continue; } finalPrimList[0].Commands.Insert(0, new MatrixCommand { Index = 0 }); matrixPrimitive.PrimitiveArray.Primitives.AddRange(finalPrimList); _imd.Body.PolygonArray.Polygons.Add(polygon); _imd.Body.OutputInfo.PolygonSize += polygon.PolygonSize; _imd.Body.OutputInfo.TriangleSize += polygon.TriangleSize; _imd.Body.OutputInfo.QuadSize += polygon.QuadSize; _imd.Body.OutputInfo.VertexSize += polygon.VertexSize; if (_settings.CompressNodeMode == "unite_combine") { rootNode.PolygonSize += polygon.PolygonSize; rootNode.TriangleSize += polygon.TriangleSize; rootNode.QuadSize += polygon.QuadSize; rootNode.VertexSize += polygon.VertexSize; rootNode.Displays.Add(new NodeDisplay { Index = rootNode.Displays.Count, Polygon = polygonId, Material = materialId, Priority = 0 }); } else { //throw new NotSupportedException("Only Compress Node Mode \"unite_combine\" is supported for now"); } polygonId++; } }