Ejemplo n.º 1
0
            public static KCLOctreeNode Generate(Dictionary <ushort, Triangle> Triangles, Vector3D Position, float BoxSize, int MaxTris, int MinSize)
            {
                KCLOctreeNode n = new KCLOctreeNode();
                //Pump this box a little up, to prevent glitches

                Vector3D midpos  = Position + new Vector3D(BoxSize / 2f, BoxSize / 2f, BoxSize / 2f);
                float    newsize = BoxSize + 50;             // 60;
                Vector3D newpos  = midpos - new Vector3D(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++)
                            {
                                Vector3D pos = Position + childsize * new Vector3D(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);
            }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
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);
        }