Example #1
0
 internal NNS_VECTOR4D Assign(VecFx32 vec)
 {
     this.x = (float)vec.x;
     this.y = (float)vec.y;
     this.z = (float)vec.z;
     return(this);
 }
Example #2
0
        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
            });
        }
Example #3
0
        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");
        }
Example #4
0
        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++;
            }
        }