Example #1
0
        private void ReloadData()
        {
            //Split collision triangles by materials between all the models
            Dictionary <int, List <Triangle> > triangleList = new Dictionary <int, List <Triangle> >();

            foreach (var model in KclFile.Models)
            {
                foreach (var prism in model.Prisms)
                {
                    var triangle = model.GetTriangle(prism);
                    if (!triangleList.ContainsKey(prism.CollisionFlags))
                    {
                        triangleList.Add(prism.CollisionFlags, new List <Triangle>());
                    }

                    triangleList[prism.CollisionFlags].Add(triangle);
                }
            }

            Renderer.models.Clear();
            Nodes.Clear();

            //Load the vertex data for rendering
            foreach (var triGroup in triangleList)
            {
                KCLModel kclmodel = new KCLModel();
                kclmodel.Text = $"COL_{triGroup.Key.ToString("X")}";

                int faceIndex = 0;

                var triangles = triGroup.Value;
                for (int i = 0; i < triangles.Count; i++)
                {
                    for (int v = 0; v < triangles[i].Vertices.Length; v++)
                    {
                        var positon   = triangles[i].Vertices[v];
                        var normal    = triangles[i].Normal;
                        var attribute = triGroup.Key;

                        kclmodel.vertices.Add(new Vertex()
                        {
                            pos = new Vector3(positon.X, positon.Y, positon.Z),
                            nrm = new Vector3(normal.X, normal.Y, normal.Z),
                            col = new Vector4(1, 1, 1, 1),
                        });
                        kclmodel.faces.Add(faceIndex + v);
                    }
                    faceIndex += 3;
                }

                Renderer.models.Add(kclmodel);
                Nodes.Add(kclmodel);
            }
        }
Example #2
0
 private static void DrawModelWireframe(KCLModel p, ShaderProgram shader)
 {
     // use vertex color for wireframe color
     GL.Uniform1(shader["colorOverride"], 1);
     GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
     GL.Enable(EnableCap.LineSmooth);
     GL.LineWidth(1.5f);
     GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
     GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
     GL.Uniform1(shader["colorOverride"], 0);
 }
Example #3
0
        private static void DrawModelSelection(KCLModel p, Shader shader)
        {
            //This part needs to be reworked for proper outline. Currently would make model disappear

            GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);

            GL.Enable(EnableCap.StencilTest);
            // use vertex color for wireframe color
            shader.SetInt("colorOverride", 1);
            GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
            GL.Enable(EnableCap.LineSmooth);
            GL.LineWidth(1.5f);
            GL.DrawElements(PrimitiveType.Triangles, p.displayFaceSize, DrawElementsType.UnsignedInt, p.Offset);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            shader.SetInt("colorOverride", 0);

            GL.Enable(EnableCap.DepthTest);
        }
Example #4
0
        static void WriteModel(BinaryDataWriter er, KCLModel mod)
        {
            long HeaderPos = er.BaseStream.Position;

            mod.Header.Write(er);
            long curpos = er.BaseStream.Position;

            //Write vertices array position
            er.BaseStream.Position = HeaderPos;
            er.Write((uint)(curpos - HeaderPos));
            er.BaseStream.Position = curpos;
            foreach (Vector3D v in mod.Vertices)
            {
                er.Write(v);
            }
            er.Align(4);
            curpos = er.BaseStream.Position;
            //Write normal array position
            er.BaseStream.Position = HeaderPos + 4;
            er.Write((uint)(curpos - HeaderPos));
            er.BaseStream.Position = curpos;
            foreach (Vector3D v in mod.Normals)
            {
                er.Write(v);
            }
            er.Align(4);
            curpos = er.BaseStream.Position;
            //Write Triangles offset
            er.BaseStream.Position = HeaderPos + 8;
            er.Write((uint)(curpos - HeaderPos));
            er.BaseStream.Position = curpos;

            foreach (KCLModel.KCLPlane p in mod.Planes)
            {
                p.Write(er);
            }
            curpos = er.BaseStream.Position;
            //Write Spatial index offset
            er.BaseStream.Position = HeaderPos + 12;
            er.Write((uint)(curpos - HeaderPos));
            er.BaseStream.Position = curpos;
            mod.Octree.Write(er);
        }
Example #5
0
        public void Read(byte[] file_data)
        {
            try
            {
                kcl = new KclFile(new MemoryStream(file_data), true, false, Syroot.BinaryData.ByteOrder.LittleEndian);
            }
            catch
            {
                kcl = new KclFile(new MemoryStream(file_data), true, false, Syroot.BinaryData.ByteOrder.BigEndian);
            }

            AllFlags.Clear();

            int CurModelIndx = 0;

            foreach (KclModel mdl in kcl.Models)
            {
                KCLModel kclmodel = new KCLModel();

                kclmodel.Text = "Model " + CurModelIndx;


                KclFace[] indicesArray = mdl.Faces;

                int ft = 0;
                foreach (KclFace f in mdl.Faces)
                {
                    Vertex vtx  = new Vertex();
                    Vertex vtx2 = new Vertex();
                    Vertex vtx3 = new Vertex();


                    Vector3 CrossA   = Vector3.Cross(Vec3F_To_Vec3(mdl.Normals[f.Normal1Index]), Vec3F_To_Vec3(mdl.Normals[f.DirectionIndex]));
                    Vector3 CrossB   = Vector3.Cross(Vec3F_To_Vec3(mdl.Normals[f.Normal2Index]), Vec3F_To_Vec3(mdl.Normals[f.DirectionIndex]));
                    Vector3 CrossC   = Vector3.Cross(Vec3F_To_Vec3(mdl.Normals[f.Normal3Index]), Vec3F_To_Vec3(mdl.Normals[f.DirectionIndex]));
                    Vector3 normal_a = Vec3F_To_Vec3(mdl.Normals[f.Normal1Index]);
                    Vector3 normal_b = Vec3F_To_Vec3(mdl.Normals[f.Normal2Index]);
                    Vector3 normal_c = Vec3F_To_Vec3(mdl.Normals[f.Normal3Index]);


                    float result1 = Vector3.Dot(new Vector3(CrossB.X, CrossB.Y, CrossB.Z), (new Vector3(normal_c.X, normal_c.Y, normal_c.Z)));
                    float result2 = Vector3.Dot(new Vector3(CrossA.X, CrossA.Y, CrossA.Z), (new Vector3(normal_c.X, normal_c.Y, normal_c.Z)));

                    Vector3 pos = Vec3F_To_Vec3(mdl.Positions[f.PositionIndex]);
                    Vector3 nrm = Vec3F_To_Vec3(mdl.Normals[f.Normal1Index]);

                    Vector3 Vertex1 = pos;
                    Vector3 Vertex2 = pos + CrossB * (f.Length / result1);
                    Vector3 Vertex3 = pos + CrossA * (f.Length / result2);

                    vtx.pos  = new Vector3(Vertex1.X, Vertex1.Y, Vertex1.Z);
                    vtx2.pos = new Vector3(Vertex2.X, Vertex2.Y, Vertex2.Z);
                    vtx3.pos = new Vector3(Vertex3.X, Vertex3.Y, Vertex3.Z);

                    var dir  = Vector3.Cross(Vertex2 - Vertex1, Vertex3 - Vertex1);
                    var norm = Vector3.Normalize(dir);

                    vtx.nrm  = norm;
                    vtx2.nrm = norm;
                    vtx3.nrm = norm;

                    KCLModel.Face face = new KCLModel.Face();

                    face.Text = f.CollisionFlags.ToString();

                    face.MaterialFlag = f.CollisionFlags;

                    Color color = SetMaterialColor(face);


                    AllFlags.Add(face.MaterialFlag);

                    Vector3 ColorSet = new Vector3(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f);

                    vtx.col  = new Vector3(ColorSet);
                    vtx2.col = new Vector3(ColorSet);
                    vtx3.col = new Vector3(ColorSet);

                    kclmodel.faces.Add(ft);
                    kclmodel.faces.Add(ft + 1);
                    kclmodel.faces.Add(ft + 2);

                    ft += 3;

                    kclmodel.vertices.Add(vtx);
                    kclmodel.vertices.Add(vtx2);
                    kclmodel.vertices.Add(vtx3);
                }


                models.Add(kclmodel);



                Nodes.Add(kclmodel);

                CurModelIndx++;
            }

            List <int> noDupes = AllFlags.Distinct().ToList();

            Console.WriteLine("List of all material flags (Not duped)");
            foreach (int mat in noDupes)
            {
                Console.WriteLine("Mat flag " + (CollisionType_MK8D)mat);
            }
        }
Example #6
0
        public KCL(byte[] Data, ByteOrder bo = ByteOrder.LittleEndian)
        {
            BinaryDataReader er = new BinaryDataReader(new MemoryStream(Data));

            er.ByteOrder = ByteOrder.BigEndian;
            if (er.ReadUInt32() != 0x02020000)
            {
                throw new Exception("Wrong KCL Header");
            }
            er.ByteOrder = bo;

            /*uint OctreeOffset = */ er.ReadUInt32();
            uint ModelListOff = er.ReadUInt32();
            uint ModelCount   = er.ReadUInt32();

            for (int ModelIndex = 0; ModelIndex < ModelCount; ModelIndex++)
            {
                KCLModel mod = new KCLModel();

                er.BaseStream.Position = ModelListOff + ModelIndex * 4;
                uint CurModelOffset = er.ReadUInt32();
                er.BaseStream.Position = CurModelOffset;

                mod.Header             = new KCLModel.KCLModelHeader(er);
                er.BaseStream.Position = mod.Header.VerticesOffset + CurModelOffset;
                uint nr = (mod.Header.NormalsOffset - mod.Header.VerticesOffset) / 0xC;
                mod.Vertices = new Vector3D[nr];
                for (int i = 0; i < nr; i++)
                {
                    mod.Vertices[i] = er.ReadVector3D();
                }

                er.BaseStream.Position = mod.Header.NormalsOffset + CurModelOffset;
                nr          = (mod.Header.PlanesOffset - mod.Header.NormalsOffset) / 0xC;
                mod.Normals = new Vector3D[nr];
                for (int i = 0; i < nr; i++)
                {
                    mod.Normals[i] = er.ReadVector3D();
                }

                er.BaseStream.Position = mod.Header.PlanesOffset + CurModelOffset;
                nr         = (mod.Header.OctreeOffset - mod.Header.PlanesOffset) / 0x14;
                mod.Planes = new KCLModel.KCLPlane[nr];
                for (int i = 0; i < nr; i++)
                {
                    mod.Planes[i] = new KCLModel.KCLPlane(er);
                }

                er.BaseStream.Position = mod.Header.OctreeOffset + CurModelOffset;
                int nodes = (int)(
                    ((~mod.Header.XMask >> (int)mod.Header.CoordShift) + 1) *
                    ((~mod.Header.YMask >> (int)mod.Header.CoordShift) + 1) *
                    ((~mod.Header.ZMask >> (int)mod.Header.CoordShift) + 1));
                mod.Octree = new KCLOctree(er, nodes);

                //Generate a mesh from the octree
                //List<OBJ.Face> OctreeNodeToMesh(KCLOctree.KCLOctreeNode node)
                //{
                //	List<OBJ.Face> res = new List<OBJ.Face>();
                //	if (node.IsLeaf)
                //	{
                //		foreach (var tr in node.Triangles)
                //		{
                //			var t = mod.GetTriangle(mod.Planes[tr]);
                //			res.Add(new OBJ.Face()
                //			{
                //				VA = new OBJ.Vertex(t.PointA, t.Normal),
                //				VB = new OBJ.Vertex(t.PointB, t.Normal),
                //				VC = new OBJ.Vertex(t.PointC, t.Normal),
                //			});
                //		}
                //	}
                //	else
                //	{
                //		for (int i = 0; i < node.SubNodes.Length; i++)
                //			res.AddRange(OctreeNodeToMesh(node.SubNodes[i]));
                //	}
                //	return res;
                //}

                //var o = new OBJ();
                //for (int i = 0; i < mod.Octree.RootNodes.Length; i++)
                //{
                //	var planes = OctreeNodeToMesh(mod.Octree.RootNodes[i]);
                //	if (planes.Count == 0) continue;
                //	o.Faces.AddRange(planes);
                //}

                //o.toWritableObj().WriteObj($"F:\\oct{ModelIndex}.obj", null);

                Models.Add(mod);
            }
        }
Example #7
0
        public static KCL FromOBJ(OBJ o)
        {
            KCL res = new KCL();

            res.GlobalHeader = new KCLModel.KCLModelHeader();

            Vector3D min = new Vector3D(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3D max = new Vector3D(float.MinValue, float.MinValue, float.MinValue);

            var MatDictionary = MaterialSetForm.ShowForm(o.MaterialNames);

            List <Triangle> Triangles = new List <Triangle>();

            foreach (var v in o.Faces)
            {
                var coll = MatDictionary.ContainsKey(v.Mat) ? MatDictionary[v.Mat] : (ushort)0;
                if (coll == ushort.MaxValue)
                {
                    continue;
                }

                Triangle t = new Triangle(v.VA.pos, v.VB.pos, v.VC.pos);
                t.Collision = coll;

                #region FindMaxMin
                if (t.PointA.X < min.X)
                {
                    min.X = t.PointA.X;
                }
                if (t.PointA.Y < min.Y)
                {
                    min.Y = t.PointA.Y;
                }
                if (t.PointA.Z < min.Z)
                {
                    min.Z = t.PointA.Z;
                }
                if (t.PointA.X > max.X)
                {
                    max.X = t.PointA.X;
                }
                if (t.PointA.Y > max.Y)
                {
                    max.Y = t.PointA.Y;
                }
                if (t.PointA.Z > max.Z)
                {
                    max.Z = t.PointA.Z;
                }

                if (t.PointB.X < min.X)
                {
                    min.X = t.PointB.X;
                }
                if (t.PointB.Y < min.Y)
                {
                    min.Y = t.PointB.Y;
                }
                if (t.PointB.Z < min.Z)
                {
                    min.Z = t.PointB.Z;
                }
                if (t.PointB.X > max.X)
                {
                    max.X = t.PointB.X;
                }
                if (t.PointB.Y > max.Y)
                {
                    max.Y = t.PointB.Y;
                }
                if (t.PointB.Z > max.Z)
                {
                    max.Z = t.PointB.Z;
                }

                if (t.PointC.X < min.X)
                {
                    min.X = t.PointC.X;
                }
                if (t.PointC.Y < min.Y)
                {
                    min.Y = t.PointC.Y;
                }
                if (t.PointC.Z < min.Z)
                {
                    min.Z = t.PointC.Z;
                }
                if (t.PointC.X > max.X)
                {
                    max.X = t.PointC.X;
                }
                if (t.PointC.Y > max.Y)
                {
                    max.Y = t.PointC.Y;
                }
                if (t.PointC.Z > max.Z)
                {
                    max.Z = t.PointC.Z;
                }
                #endregion

                Triangles.Add(t);
            }

            max += KCL.MaxOffset;
            min -= KCL.MinOffset;
            res.GlobalHeader.OctreeOrigin = min;
            res.GlobalHeader.OctreeMax    = max;
            var size = max - min;

            res.GlobalHeader.CoordShift = (uint)KCLOctree.next_exponent(size.X);
            res.GlobalHeader.YShift     = (uint)KCLOctree.next_exponent(size.Y);
            res.GlobalHeader.ZShift     = (uint)KCLOctree.next_exponent(size.Z);

            var  BoxSize      = size / 2f;
            uint baseTriCount = 0;
            for (int k = 0; k < 2; k++)
            {
                for (int l = 0; l < 2; l++)
                {
                    for (int m = 0; m < 2; m++)
                    {
                        var Boxmin = min + new Vector3D(BoxSize.X * m, BoxSize.Y * l, BoxSize.Z * k);
                        var mod    = KCLModel.FromTriangles(Triangles, baseTriCount, Boxmin, BoxSize / 2);
                        res.Models.Add(mod);
                        if (mod != null)
                        {
                            baseTriCount += (uint)mod.Planes.Length;
                        }
                    }
                }
            }

            res.GlobalHeader.Unknown1 = baseTriCount;

            return(res);
        }
Example #8
0
        public void Read(MarioKart.MK7.KCL kcl)
        {
            Nodes.Clear();
            Renderer.models.Clear();

            int CurModelIndx = 0;

            foreach (MarioKart.MK7.KCL.KCLModel mdl in kcl.Models)
            {
                KCLModel kclmodel = new KCLModel();

                kclmodel.Text = "Model " + CurModelIndx;

                int ft = 0;
                foreach (var plane in mdl.Planes)
                {
                    var triangle = mdl.GetTriangle(plane);
                    var normal   = triangle.Normal;
                    var pointA   = triangle.PointA;
                    var pointB   = triangle.PointB;
                    var pointC   = triangle.PointC;

                    Vertex vtx  = new Vertex();
                    Vertex vtx2 = new Vertex();
                    Vertex vtx3 = new Vertex();

                    vtx.pos  = new Vector3(Vec3D_To_Vec3(pointA));
                    vtx2.pos = new Vector3(Vec3D_To_Vec3(pointB));
                    vtx3.pos = new Vector3(Vec3D_To_Vec3(pointC));
                    vtx.nrm  = new Vector3(Vec3D_To_Vec3(normal));
                    vtx2.nrm = new Vector3(Vec3D_To_Vec3(normal));
                    vtx3.nrm = new Vector3(Vec3D_To_Vec3(normal));

                    KCLModel.Face face = new KCLModel.Face();
                    face.Text         = triangle.Collision.ToString();
                    face.MaterialFlag = triangle.Collision;

                    var     col      = MarioKart.MK7.KCLColors.GetMaterialColor(plane.CollisionType);
                    Vector3 ColorSet = new Vector3(col.R, col.G, col.B);

                    vtx.col  = new Vector4(ColorSet, 1);
                    vtx2.col = new Vector4(ColorSet, 1);
                    vtx3.col = new Vector4(ColorSet, 1);

                    kclmodel.faces.Add(ft);
                    kclmodel.faces.Add(ft + 1);
                    kclmodel.faces.Add(ft + 2);

                    ft += 3;

                    kclmodel.vertices.Add(vtx);
                    kclmodel.vertices.Add(vtx2);
                    kclmodel.vertices.Add(vtx3);
                }

                Renderer.models.Add(kclmodel);
                Nodes.Add(kclmodel);

                CurModelIndx++;
            }
        }
Example #9
0
        private void Read(MarioKart.MK7.KCL kcl)
        {
            Vector3 min = new Vector3();
            Vector3 max = new Vector3();

            Nodes.Clear();
            Renderer.OctreeNodes.Clear();
            Renderer.models.Clear();
            Renderer.KclFile = kcl;

            TreeNode modelTree = new TreeNode("Model Octree");

            LoadModelTree(modelTree, kcl.GlobalHeader.ModelOctrees);
            foreach (var node in modelTree.Nodes)
            {
                Renderer.OctreeNodes.Add((OctreeNode)node);
            }
            Nodes.Add(modelTree);

            int CurModelIndx = 0;

            foreach (MarioKart.MK7.KCL.KCLModel mdl in kcl.Models)
            {
                KCLModel kclmodel = new KCLModel();

                kclmodel.Text = "Model " + CurModelIndx;

                int ft = 0;
                foreach (var plane in mdl.Planes)
                {
                    var triangle = mdl.GetTriangle(plane);
                    var normal   = triangle.Normal;
                    var pointA   = triangle.PointA;
                    var pointB   = triangle.PointB;
                    var pointC   = triangle.PointC;

                    Vertex vtx  = new Vertex();
                    Vertex vtx2 = new Vertex();
                    Vertex vtx3 = new Vertex();

                    vtx.pos  = new Vector3(Vec3D_To_Vec3(pointA));
                    vtx2.pos = new Vector3(Vec3D_To_Vec3(pointB));
                    vtx3.pos = new Vector3(Vec3D_To_Vec3(pointC));
                    vtx.nrm  = new Vector3(Vec3D_To_Vec3(normal));
                    vtx2.nrm = new Vector3(Vec3D_To_Vec3(normal));
                    vtx3.nrm = new Vector3(Vec3D_To_Vec3(normal));

                    KCLModel.Face face = new KCLModel.Face();
                    face.Text         = triangle.Collision.ToString();
                    face.MaterialFlag = triangle.Collision;

                    var     col      = MarioKart.MK7.KCLColors.GetMaterialColor(plane.CollisionType);
                    Vector3 ColorSet = new Vector3(col.R, col.G, col.B);

                    vtx.col  = new Vector4(ColorSet, 1);
                    vtx2.col = new Vector4(ColorSet, 1);
                    vtx3.col = new Vector4(ColorSet, 1);

                    kclmodel.faces.Add(ft);
                    kclmodel.faces.Add(ft + 1);
                    kclmodel.faces.Add(ft + 2);

                    ft += 3;

                    kclmodel.vertices.Add(vtx);
                    kclmodel.vertices.Add(vtx2);
                    kclmodel.vertices.Add(vtx3);

                    #region FindMaxMin
                    if (triangle.PointA.X < min.X)
                    {
                        min.X = (float)triangle.PointA.X;
                    }
                    if (triangle.PointA.Y < min.Y)
                    {
                        min.Y = (float)triangle.PointA.Y;
                    }
                    if (triangle.PointA.Z < min.Z)
                    {
                        min.Z = (float)triangle.PointA.Z;
                    }
                    if (triangle.PointA.X > max.X)
                    {
                        max.X = (float)triangle.PointA.X;
                    }
                    if (triangle.PointA.Y > max.Y)
                    {
                        max.Y = (float)triangle.PointA.Y;
                    }
                    if (triangle.PointA.Z > max.Z)
                    {
                        max.Z = (float)triangle.PointA.Z;
                    }

                    if (triangle.PointB.X < min.X)
                    {
                        min.X = (float)triangle.PointB.X;
                    }
                    if (triangle.PointB.Y < min.Y)
                    {
                        min.Y = (float)triangle.PointB.Y;
                    }
                    if (triangle.PointB.Z < min.Z)
                    {
                        min.Z = (float)triangle.PointB.Z;
                    }
                    if (triangle.PointB.X > max.X)
                    {
                        max.X = (float)triangle.PointB.X;
                    }
                    if (triangle.PointB.Y > max.Y)
                    {
                        max.Y = (float)triangle.PointB.Y;
                    }
                    if (triangle.PointB.Z > max.Z)
                    {
                        max.Z = (float)triangle.PointB.Z;
                    }

                    if (triangle.PointC.X < min.X)
                    {
                        min.X = (float)triangle.PointC.X;
                    }
                    if (triangle.PointC.Y < min.Y)
                    {
                        min.Y = (float)triangle.PointC.Y;
                    }
                    if (triangle.PointC.Z < min.Z)
                    {
                        min.Z = (float)triangle.PointC.Z;
                    }
                    if (triangle.PointC.X > max.X)
                    {
                        max.X = (float)triangle.PointC.X;
                    }
                    if (triangle.PointC.Y > max.Y)
                    {
                        max.Y = (float)triangle.PointC.Y;
                    }
                    if (triangle.PointC.Z > max.Z)
                    {
                        max.Z = (float)triangle.PointC.Z;
                    }
                    #endregion
                }

                Renderer.Max = max;
                Renderer.Min = min;
                Renderer.models.Add(kclmodel);
                Nodes.Add(kclmodel);

                CurModelIndx++;
            }
        }