Пример #1
0
        //35)
        public static KCLOctree FromTriangles(Triangle[] Triangles, KCLHeader Header, int MaxRootSize = 2048, int MinRootSize = 128, int MinCubeSize = 32, int MaxNrTris = 10)
        {
            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;
            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;
        }
Пример #2
0
            //Based on this algorithm: http://jgt.akpeters.com/papers/AkenineMoller01/tribox.html
            private static bool tricube_overlap(Triangle t, Vector3 Position, float BoxSize)
            {
                float half = BoxSize / 2f;
                //Position is the min pos, so add half the box size
                Position += new Vector3(half, half, half);
                Vector3 v0 = t.PointA - Position;
                Vector3 v1 = t.PointB - Position;
                Vector3 v2 = t.PointC - Position;

                if (Math.Min(Math.Min(v0.X, v1.X), v2.X) > half || Math.Max(Math.Max(v0.X, v1.X), v2.X) < -half) return false;
                if (Math.Min(Math.Min(v0.Y, v1.Y), v2.Y) > half || Math.Max(Math.Max(v0.Y, v1.Y), v2.Y) < -half) return false;
                if (Math.Min(Math.Min(v0.Z, v1.Z), v2.Z) > half || Math.Max(Math.Max(v0.Z, v1.Z), v2.Z) < -half) return false;

                float d = t.Normal.Dot(v0);
                float r = half * (Math.Abs(t.Normal.X) + Math.Abs(t.Normal.Y) + Math.Abs(t.Normal.Z));
                if (d > r || d < -r) return false;

                Vector3 e = v1 - v0;
                if (axis_test(e.Z, -e.Y, v0.Y, v0.Z, v2.Y, v2.Z, half)) return false;
                if (axis_test(-e.Z, e.X, v0.X, v0.Z, v2.X, v2.Z, half)) return false;
                if (axis_test(e.Y, -e.X, v1.X, v1.Y, v2.X, v2.Y, half)) return false;

                e = v2 - v1;
                if (axis_test(e.Z, -e.Y, v0.Y, v0.Z, v2.Y, v2.Z, half)) return false;
                if (axis_test(-e.Z, e.X, v0.X, v0.Z, v2.X, v2.Z, half)) return false;
                if (axis_test(e.Y, -e.X, v0.X, v0.Y, v1.X, v1.Y, half)) return false;

                e = v0 - v2;
                if (axis_test(e.Z, -e.Y, v0.Y, v0.Z, v1.Y, v1.Z, half)) return false;
                if (axis_test(-e.Z, e.X, v0.X, v0.Z, v1.X, v1.Z, half)) return false;
                if (axis_test(e.Y, -e.X, v1.X, v1.Y, v2.X, v2.Y, half)) return false;
                return true;
            }