Пример #1
0
            public KCLOctreeNode(EndianBinaryReader er, long BaseOffset)
            {
                DataOffset  = er.ReadUInt32();
                IsLeaf      = (DataOffset >> 31) == 1;
                DataOffset &= 0x7FFFFFFF;
                long curpos = er.BaseStream.Position;

                er.BaseStream.Position = BaseOffset + DataOffset;
                if (IsLeaf)
                {
                    er.BaseStream.Position += 2; //Skip starting zero
                    var tris = new List <ushort>();
                    while (true)
                    {
                        ushort v = er.ReadUInt16();
                        if (v == 0)
                        {
                            break;
                        }
                        tris.Add((ushort)(v - 1));
                    }

                    Triangles = tris.ToArray();
                }
                else
                {
                    SubNodes = new KCLOctreeNode[8];
                    for (int i = 0; i < 8; i++)
                    {
                        SubNodes[i] = new KCLOctreeNode(er, BaseOffset + DataOffset);
                    }
                }

                er.BaseStream.Position = curpos;
            }
Пример #2
0
 public KCLOctree(EndianBinaryReader er, int NrNodes)
 {
     long baseoffset = er.BaseStream.Position;
     RootNodes = new KCLOctreeNode[NrNodes];
     for (int i = 0; i < NrNodes; i++)
     {
         RootNodes[i] = new KCLOctreeNode(er, baseoffset);
     }
 }
Пример #3
0
        public KCLOctree(EndianBinaryReader er, int nrNodes)
        {
            long baseoffset = er.BaseStream.Position;

            RootNodes = new KCLOctreeNode[nrNodes];
            for (int i = 0; i < nrNodes; i++)
            {
                RootNodes[i] = new KCLOctreeNode(er, baseoffset);
            }
        }
Пример #4
0
        public KCLOctree(BinaryDataReader er, int NrNodes)
        {
            long baseoffset = er.BaseStream.Position;

            RootNodes = new KCLOctreeNode[NrNodes];
            for (int i = 0; i < NrNodes; i++)
            {
                RootNodes[i] = new KCLOctreeNode(er, baseoffset);
            }
        }
Пример #5
0
            /*public int NrUniqueTris
             * {
             *  get { return GetNrUniqueTris(new List<ushort>()); }
             * }
             *
             * private int GetNrUniqueTris(List<ushort> tris)
             * {
             *  if (IsLeaf)
             *  {
             *      int nr = 0;
             *      foreach (ushort i in Triangles)
             *      {
             *          if (!tris.Contains(i)) { tris.Add(i); nr++; }
             *      }
             *      return nr;
             *  }
             *  int total = 0;
             *  foreach (var v in SubNodes)
             *  {
             *      total += v.GetNrUniqueTris(tris);
             *  }
             *  return total;
             * }
             *
             * public int GetLeafMostTris()
             * {
             *  if (IsLeaf) return Triangles.Length;
             *  int maxnum = 0;
             *  foreach (var v in SubNodes)
             *  {
             *      int num = v.GetLeafMostTris();
             *      if (num > maxnum) maxnum = num;
             *  }
             *  return maxnum;
             * }
             *
             * public int GetDepth()
             * {
             *  if (IsLeaf) return 0;
             *  int curdepth = 0;
             *  foreach (var v in SubNodes)
             *  {
             *      int num = v.GetDepth() + 1;
             *      if (num > curdepth) curdepth = num;
             *  }
             *  return curdepth;
             * }*/
            public static KCLOctreeNode Generate(Dictionary <ushort, Triangle> Triangles, Vector3 Position,
                                                 float BoxSize, int MaxTris, int MinSize)
            {
                var n = new KCLOctreeNode();
                //Pump this box a little up, to prevent glitches
                var   midpos  = Position + new Vector3(BoxSize / 2f, BoxSize / 2f, BoxSize / 2f);
                float newsize = BoxSize + 50; // 60;
                var   newpos  = midpos - new Vector3(newsize / 2f, newsize / 2f, newsize / 2f);
                var   t       = new Dictionary <ushort, Triangle>();

                foreach (var v in Triangles)
                {
                    if (TriCubeOverlap(v.Value, newpos, newsize))
                    {
                        t.Add(v.Key, v.Value);
                    }
                }
                if (BoxSize > MinSize && t.Count > MaxTris)
                {
                    n.IsLeaf = false;
                    float childsize = BoxSize / 2f;
                    n.SubNodes = new KCLOctreeNode[8];
                    int i = 0;
                    for (int z = 0; z < 2; z++)
                    {
                        for (int y = 0; y < 2; y++)
                        {
                            for (int x = 0; x < 2; x++)
                            {
                                Vector3 pos = Position + childsize * new Vector3(x, y, z);
                                n.SubNodes[i] = Generate(t, pos, childsize, MaxTris, MinSize);
                                i++;
                            }
                        }
                    }
                }
                else
                {
                    n.IsLeaf    = true;
                    n.Triangles = t.Keys.ToArray();
                }

                return(n);
            }
Пример #6
0
            public static KCLOctreeNode Generate(Dictionary <ushort, Triangle> Triangles, Vector3 Position, float BoxSize, int MaxTris, int MinSize, int TotOctree, int ActualOctre)
            {
                KCLOctreeNode n = new KCLOctreeNode();
                //Pump this box a little up, to prevent glitches
                Vector3 midpos  = Position + new Vector3(BoxSize / 2f, BoxSize / 2f, BoxSize / 2f);
                float   newsize = BoxSize + 50;// 60;
                Vector3 newpos  = midpos - new Vector3(newsize / 2f, newsize / 2f, newsize / 2f);
                Dictionary <ushort, Triangle> t = new Dictionary <ushort, Triangle>();

                Console.Write("\r -Generating octree: " + ActualOctre.ToString() + "/" + TotOctree.ToString());
                foreach (var v in Triangles)
                {
                    if (tricube_overlap(v.Value, newpos, newsize))
                    {
                        t.Add(v.Key, v.Value);
                    }
                }
                if (BoxSize > MinSize && t.Count > MaxTris)
                {
                    n.IsLeaf = false;
                    float childsize = BoxSize / 2f;
                    n.SubNodes = new KCLOctreeNode[8];
                    int i = 0;
                    for (int z = 0; z < 2; z++)
                    {
                        for (int y = 0; y < 2; y++)
                        {
                            for (int x = 0; x < 2; x++)
                            {
                                Vector3 pos = Position + childsize * new Vector3(x, y, z);
                                n.SubNodes[i] = KCLOctreeNode.Generate(t, pos, childsize, MaxTris, MinSize, 8, i + 1);
                                i++;
                            }
                        }
                    }
                }
                else
                {
                    n.IsLeaf    = true;
                    n.Triangles = t.Keys.ToArray();
                }
                return(n);
            }
Пример #7
0
        public static KCLOctree FromTriangles(Triangle[] Triangles, KCLHeader Header, int MaxRootSize = 2048,
                                              int MinRootSize = 128, int MinCubeSize = 32, int MaxNrTris = 10, MK7.KCL.BGArgs userarg = null, System.ComponentModel.BackgroundWorker worker = null) //35)
        {
            Header.Unknown1 = 30;
            Header.Unknown2 = 25;
            Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            Dictionary <ushort, Triangle> tt = new Dictionary <ushort, Triangle>();
            ushort index = 0;

            foreach (var t in Triangles)
            {
                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;
                }
                tt.Add(index, t);
                index++;
            }

            //in real mkds, 25 is subtracted from the min pos
            min -= new Vector3(25, 25, 25);
            //TODO: after that, from some of the components (may be more than one) 30 is subtracted aswell => How do I know from which ones I have to do that?

            //Assume the same is done for max:
            max += new Vector3(25, 25, 25);
            //TODO: +30
            Header.OctreeOrigin = min;
            Vector3 size       = max - min;
            float   mincomp    = Math.Min(Math.Min(size.X, size.Y), size.Z);
            int     CoordShift = MathUtil.GetNearest2Power(mincomp);

            if (CoordShift > MathUtil.GetNearest2Power(MaxRootSize))
            {
                CoordShift = MathUtil.GetNearest2Power(MaxRootSize);
            }
            //else if (CoordShift < Get2Power(MinRootSize)) CoordShift = Get2Power(MinRootSize);
            Header.CoordShift = (uint)CoordShift;
            int cubesize = 1 << CoordShift;
            int NrX      = (1 << MathUtil.GetNearest2Power(size.X)) / cubesize;
            int NrY      = (1 << MathUtil.GetNearest2Power(size.Y)) / cubesize;
            int NrZ      = (1 << MathUtil.GetNearest2Power(size.Z)) / cubesize;

            if (NrX <= 0)
            {
                NrX = 1;
            }
            if (NrY <= 0)
            {
                NrY = 1;
            }
            if (NrZ <= 0)
            {
                NrZ = 1;
            }
            Header.YShift = (uint)(MathUtil.GetNearest2Power(size.X) - CoordShift);
            Header.ZShift = (uint)(MathUtil.GetNearest2Power(size.X) - CoordShift + MathUtil.GetNearest2Power(size.Y) -
                                   CoordShift);
            Header.XMask = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.X);
            Header.YMask = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.Y);
            Header.ZMask = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.Z);

            KCLOctree k = new KCLOctree();

            k.RootNodes = new KCLOctreeNode[NrX * NrY * NrZ];
            int i = 0;

            if (userarg != null)
            {
                userarg.state    = 2;
                userarg.totProg  = k.RootNodes.Length;
                userarg.currProg = 0;
            }

            for (int z = 0; z < NrZ; z++)
            {
                for (int y = 0; y < NrY; y++)
                {
                    for (int x = 0; x < NrX; x++)
                    {
                        Vector3 pos = min + ((float)cubesize) * new Vector3(x, y, z);
                        k.RootNodes[i] = KCLOctreeNode.Generate(tt, pos, cubesize, MaxNrTris, MinCubeSize);
                        i++;
                        if (userarg != null)
                        {
                            if (worker.CancellationPending)
                            {
                                return(null);
                            }
                            userarg.currProg++;
                            worker.ReportProgress(0, userarg);
                        }
                    }
                }
            }

            return(k);
        }
Пример #8
0
        public void Write(EndianBinaryWriter er)
        {
            long                  basepos         = er.BaseStream.Position;
            Queue <uint>          NodeBaseOffsets = new Queue <uint>();
            Queue <KCLOctreeNode> Nodes           = new Queue <KCLOctreeNode>();

            foreach (var v in RootNodes)
            {
                NodeBaseOffsets.Enqueue(0);
                Nodes.Enqueue(v);
            }
            uint offs = (uint)(RootNodes.Length * 4);

            while (Nodes.Count > 0)
            {
                KCLOctreeNode n = Nodes.Dequeue();
                if (n.IsLeaf)
                {
                    NodeBaseOffsets.Dequeue();
                    er.Write((uint)0);
                }
                else
                {
                    n.DataOffset = offs - NodeBaseOffsets.Dequeue();
                    er.Write(n.DataOffset);
                    foreach (var v in n.SubNodes)
                    {
                        NodeBaseOffsets.Enqueue(offs);
                        Nodes.Enqueue(v);
                    }
                    offs += 8 * 4;
                }
            }
            foreach (var v in RootNodes)
            {
                NodeBaseOffsets.Enqueue(0);
                Nodes.Enqueue(v);
            }
            long leafstartpos    = er.BaseStream.Position;
            uint relleafstartpos = offs;

            er.BaseStream.Position = basepos;
            offs = (uint)(RootNodes.Length * 4);
            while (Nodes.Count > 0)
            {
                KCLOctreeNode n = Nodes.Dequeue();
                if (n.IsLeaf)
                {
                    er.Write((uint)(0x80000000 | (relleafstartpos - NodeBaseOffsets.Dequeue() - 2)));
                    long curpos = er.BaseStream.Position;
                    er.BaseStream.Position = leafstartpos;
                    foreach (var v in n.Triangles)
                    {
                        er.Write((ushort)(v + 1));
                    }
                    er.Write((ushort)0);
                    relleafstartpos       += (uint)(n.Triangles.Length * 2) + 2;
                    leafstartpos           = er.BaseStream.Position;
                    er.BaseStream.Position = curpos;
                }
                else
                {
                    er.BaseStream.Position += 4;
                    NodeBaseOffsets.Dequeue();
                    foreach (var v in n.SubNodes)
                    {
                        NodeBaseOffsets.Enqueue(offs);
                        Nodes.Enqueue(v);
                    }
                    offs += 8 * 4;
                }
            }
        }
Пример #9
0
        public static KCLOctree FromTriangles(Triangle[] Triangles, KCLHeader Header, int MaxRootSize = 2048, int MinRootSize = 128, int MinCubeSize = 32, int MaxNrTris = 10)//35)
        {
            Header.Unknown1 = 30;
            Header.Unknown2 = 25;
            Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
            Dictionary <ushort, Triangle> tt = new Dictionary <ushort, Triangle>();
            ushort index = 0;

            foreach (var t in Triangles)
            {
                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;
                }
                tt.Add(index, t);
                index++;
            }
            //in real mkds, 25 is subtracted from the min pos
            //TODO: after that, from some of the components (may be more than one) 30 is subtracted aswell => How do I know from which ones I have to do that?

            min -= new Vector3(50f, 80f, 50f);
            max += new Vector3(50f, 50f, 50f);

            //TODO: +30
            Header.OctreeOrigin = min;
            Header.OctreeMax    = max;
            Vector3 size       = max - min;
            float   mincomp    = Math.Min(Math.Min(size.X, size.Y), size.Z);
            int     CoordShift = MathUtil.GetNearest2Power(mincomp);

            if (CoordShift > MathUtil.GetNearest2Power(MaxRootSize))
            {
                CoordShift = MathUtil.GetNearest2Power(MaxRootSize);
            }
            //else if (CoordShift < Get2Power(MinRootSize)) CoordShift = Get2Power(MinRootSize);
            Header.CoordShift = (uint)CoordShift;
            int cubesize = 1 << CoordShift;
            int NrX      = (1 << MathUtil.GetNearest2Power(size.X)) / cubesize;
            int NrY      = (1 << MathUtil.GetNearest2Power(size.Y)) / cubesize;
            int NrZ      = (1 << MathUtil.GetNearest2Power(size.Z)) / cubesize;

            if (NrX <= 0)
            {
                NrX = 1;
            }
            if (NrY <= 0)
            {
                NrY = 1;
            }
            if (NrZ <= 0)
            {
                NrZ = 1;
            }
            Header.YShift = (uint)(MathUtil.GetNearest2Power(size.X) - CoordShift);
            Header.ZShift = (uint)(MathUtil.GetNearest2Power(size.X) - CoordShift + MathUtil.GetNearest2Power(size.Y) - CoordShift);
            Header.XMask  = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.X);
            Header.YMask  = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.Y);
            Header.ZMask  = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.Z);
            Header.n_x    = (float)KCLOctree.next_exponent(max.X - min.X);
            Header.n_y    = (float)KCLOctree.next_exponent(max.Y - min.Y);
            Header.n_z    = (float)KCLOctree.next_exponent(max.Z - min.Z);

            KCLOctree k = new KCLOctree();

            k.RootNodes = new KCLOctreeNode[NrX * NrY * NrZ];
            int i = 0;

            for (int z = 0; z < NrZ; z++)
            {
                for (int y = 0; y < NrY; y++)
                {
                    for (int x = 0; x < NrX; x++)
                    {
                        Vector3 pos = min + ((float)cubesize) * new Vector3(x, y, z);
                        k.RootNodes[i] = KCLOctreeNode.Generate(tt, pos, cubesize, MaxNrTris, MinCubeSize);
                        i++;
                    }
                }
            }
            return(k);
        }
Пример #10
0
            /*public int NrUniqueTris
            {
                get { return GetNrUniqueTris(new List<ushort>()); }
            }

            private int GetNrUniqueTris(List<ushort> tris)
            {
                if (IsLeaf)
                {
                    int nr = 0;
                    foreach (ushort i in Triangles)
                    {
                        if (!tris.Contains(i)) { tris.Add(i); nr++; }
                    }
                    return nr;
                }
                int total = 0;
                foreach (var v in SubNodes)
                {
                    total += v.GetNrUniqueTris(tris);
                }
                return total;
            }

            public int GetLeafMostTris()
            {
                if (IsLeaf) return Triangles.Length;
                int maxnum = 0;
                foreach (var v in SubNodes)
                {
                    int num = v.GetLeafMostTris();
                    if (num > maxnum) maxnum = num;
                }
                return maxnum;
            }

            public int GetDepth()
            {
                if (IsLeaf) return 0;
                int curdepth = 0;
                foreach (var v in SubNodes)
                {
                    int num = v.GetDepth() + 1;
                    if (num > curdepth) curdepth = num;
                }
                return curdepth;
            }*/
            public static KCLOctreeNode Generate(Dictionary<ushort, Triangle> Triangles, Vector3 Position, float BoxSize, int MaxTris, int MinSize)
            {
                KCLOctreeNode n = new KCLOctreeNode();
                //Pump this box a little up, to prevent glitches
                Vector3 midpos = Position + new Vector3(BoxSize / 2f, BoxSize / 2f, BoxSize / 2f);
                float newsize = BoxSize + 50;// 60;
                Vector3 newpos = midpos - new Vector3(newsize / 2f, newsize / 2f, newsize / 2f);
                Dictionary<ushort, Triangle> t = new Dictionary<ushort, Triangle>();
                foreach (var v in Triangles)
                {
                    if (tricube_overlap(v.Value, newpos, newsize)) t.Add(v.Key, v.Value);
                }
                if (BoxSize > MinSize && t.Count > MaxTris)
                {
                    n.IsLeaf = false;
                    float childsize = BoxSize / 2f;
                    n.SubNodes = new KCLOctreeNode[8];
                    int i = 0;
                    for (int z = 0; z < 2; z++)
                    {
                        for (int y = 0; y < 2; y++)
                        {
                            for (int x = 0; x < 2; x++)
                            {
                                Vector3 pos = Position + childsize * new Vector3(x, y, z);
                                n.SubNodes[i] = KCLOctreeNode.Generate(t, pos, childsize, MaxTris, MinSize);
                                i++;
                            }
                        }
                    }
                }
                else
                {
                    n.IsLeaf = true;
                    n.Triangles = t.Keys.ToArray();
                }
                return n;
            }
Пример #11
0
 public KCLOctreeNode(EndianBinaryReader er, long BaseOffset)
 {
     DataOffset = er.ReadUInt32();
     IsLeaf = (DataOffset >> 31) == 1;
     DataOffset &= 0x7FFFFFFF;
     long curpos = er.BaseStream.Position;
     er.BaseStream.Position = BaseOffset + DataOffset;
     if (IsLeaf)
     {
         er.BaseStream.Position += 2;//Skip starting zero
         List<ushort> tris = new List<ushort>();
         while (true)
         {
             ushort v = er.ReadUInt16();
             if (v == 0) break;
             tris.Add((ushort)(v - 1));
         }
         Triangles = tris.ToArray();
     }
     else
     {
         SubNodes = new KCLOctreeNode[8];
         for (int i = 0; i < 8; i++)
         {
             SubNodes[i] = new KCLOctreeNode(er, BaseOffset + DataOffset);
         }
     }
     er.BaseStream.Position = curpos;
 }
Пример #12
0
        public static KCLOctree FromTriangles(Triangle[] Triangles, KCLHeader Header, int MinCubeSize = 32, int MaxNrTris = 50, uint MaxRootSize = 4096, uint MinRootSize = 128)        //35)
        {
            Vector3D min = new Vector3D(float.MaxValue, float.MaxValue, float.MaxValue);
            Vector3D max = new Vector3D(float.MinValue, float.MinValue, float.MinValue);
            Dictionary <ushort, Triangle> tt = new Dictionary <ushort, Triangle>();
            ushort index = 0;

            foreach (var t in Triangles)
            {
                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;
                }
                tt.Add(index, t);
                index++;
            }
            //in real mkds, 25 is subtracted from the min pos
            min -= MarioKart.MK7.KCL.MinOffset;
            //TODO: after that, from some of the components (may be more than one) 30 is subtracted aswell => How do I know from which ones I have to do that?

            //Assume the same is done for max:
            max += MarioKart.MK7.KCL.MaxOffset;
            //TODO: +30
            Header.OctreeOrigin = min;
            Header.OctreeMax    = max;
            Vector3D size       = max - min;
            float    mincomp    = (float)Math.Min(Math.Min(size.X, size.Y), size.Z);
            int      CoordShift = next_exponent(mincomp);

            //if (CoordShift > MathUtil.GetNearest2Power((float)MaxRootSize))
            //	CoordShift = MathUtil.GetNearest2Power((float)MaxRootSize);
            if (CoordShift < next_exponent(MinRootSize))
            {
                CoordShift = next_exponent(MinRootSize);
            }

            Header.CoordShift = (uint)CoordShift;
            int cubesize = 1 << CoordShift;
            int NrX      = (1 << next_exponent(size.X)) / cubesize;
            int NrY      = (1 << next_exponent(size.Y)) / cubesize;
            int NrZ      = (1 << next_exponent(size.Z)) / cubesize;

            if (NrX <= 0)
            {
                NrX = 1;
            }
            if (NrY <= 0)
            {
                NrY = 1;
            }
            if (NrZ <= 0)
            {
                NrZ = 1;
            }
            Header.YShift = (uint)(next_exponent(size.X) - CoordShift);
            Header.ZShift = (uint)(next_exponent(size.X) - CoordShift + next_exponent(size.Y) - CoordShift);
            Header.XMask  = 0xFFFFFFFF << next_exponent(size.X);
            Header.YMask  = 0xFFFFFFFF << next_exponent(size.Y);
            Header.ZMask  = 0xFFFFFFFF << next_exponent(size.Z);

            KCLOctree k = new KCLOctree();

            k.RootNodes = new KCLOctreeNode[NrX * NrY * NrZ];
            int i = 0;

            for (int z = 0; z < NrZ; z++)
            {
                for (int y = 0; y < NrY; y++)
                {
                    for (int x = 0; x < NrX; x++)
                    {
                        Vector3D pos = min + ((float)cubesize) * new Vector3D(x, y, z);
                        k.RootNodes[i] = KCLOctreeNode.Generate(tt, pos, cubesize, MaxNrTris, MinCubeSize);
                        i++;
                    }
                }
            }
            return(k);
        }