Esempio n. 1
0
        public MeshKDTree(int MaxNestingLevel, Vector3[] vertices, int[] indices)
        {
            //this.vertices = vertices;
            //this.indices = indices;

            this.MaxNestingLevel = MaxNestingLevel;

            Vector3 AA = vertices[0];
            Vector3 BB = vertices[0];

            for (int i = 0; i < indices.Length; i++)
                this.indices.Add(indices[i]);

            for (int i = 0; i < vertices.Length; i++)
            {
                this.vertices.Add(vertices[i]);
                if (vertices[i].X > AA.X) AA.X = vertices[i].X;
                if (vertices[i].Y > AA.Y) AA.Y = vertices[i].Y;
                if (vertices[i].Z > AA.Z) AA.Z = vertices[i].Z;
                if (vertices[i].X < BB.X) BB.X = vertices[i].X;
                if (vertices[i].Y < BB.Y) BB.Y = vertices[i].Y;
                if (vertices[i].Z < BB.Z) BB.Z = vertices[i].Z;
            }

            BSPAABBMax = AA;
            BSPAABBMin = BB;

            Root = new MeshNode(null, AA, BB, MaxNestingLevel);

            int Lll = indices.Length;
            for (int i = 0; i < Lll; i = i + 3)
            {
                AA = vertices[indices[i]];
                BB = vertices[indices[i]];

                for (int j = 0; j < 3; j++)
                {
                    if (vertices[indices[i + j]].X > AA.X) AA.X = vertices[indices[i + j]].X;
                    if (vertices[indices[i + j]].Y > AA.Y) AA.Y = vertices[indices[i + j]].Y;
                    if (vertices[indices[i + j]].Z > AA.Z) AA.Z = vertices[indices[i + j]].Z;
                    if (vertices[indices[i + j]].X < BB.X) BB.X = vertices[indices[i + j]].X;
                    if (vertices[indices[i + j]].Y < BB.Y) BB.Y = vertices[indices[i + j]].Y;
                    if (vertices[indices[i + j]].Z < BB.Z) BB.Z = vertices[indices[i + j]].Z;
                }
                Add(i, Root, AA, BB);
            }
        }
Esempio n. 2
0
 public MeshNode(MeshNode parent, Vector3 AABBMax, Vector3 AABBMin, int nestingLevel)
 {
     Parent = parent;
     this.AABBMax = AABBMax;
     this.AABBMin = AABBMin;
     NestingLevel = nestingLevel;
     ListTrInd = new List<int>();
     Children = new List<MeshNode>();
 }
Esempio n. 3
0
 private void TestIntercept(MeshNode N)
 {
     Vector3 OutPos = new Vector3();
     if (HitBoundingBox(N.AABBMin, N.AABBMax, StartPosition, StopPosition - StartPosition, out OutPos))
     {
         //////////////////////////////////////////////////////////////////////////
         if (LastDistance > (StartPosition - OutPos).Length())
         {
             Vector3 Pos = new Vector3();
             Vector3 Norm = new Vector3();
             foreach (int Index in N.ListTrInd)
             {
                 if (GetInterceptPoint(out Pos, out Norm, vertices[indices[Index + 0]], vertices[indices[Index + 1]], vertices[indices[Index + 2]], StartPosition, StopPosition))
                 {
                     float d = (StartPosition - Pos).Length();
                     if (d < LastDistance)
                     {
                         StopPosition = Pos;
                         LastNormal = Norm;
                         LastDistance = d;
                     }
                 }
             }
             //////////////////////////////////////////////////////////////////////////
             if (N.Children.Count > 0)
             {
                 TestIntercept(N.Children[0]);
                 TestIntercept(N.Children[1]);
             }
         }
     }
 }
Esempio n. 4
0
        private bool Add(int TrInd, MeshNode N, Vector3 AA_2, Vector3 BB_2)
        {
            //Достигнут минимальный уровень
            if (N.NestingLevel < 1)
            {
                N.Parent.ListTrInd.Add(TrInd);
                return true;
            }

            int rez = TestTwoAABB(N.AABBMax, N.AABBMin, AA_2, BB_2);
            //Не поподает
            if (rez == 0)
                return false;
            float X = N.AABBMax.X - N.AABBMin.X;
            float Y = N.AABBMax.Y - N.AABBMin.Y;
            float Z = N.AABBMax.Z - N.AABBMin.Z;

            //Попадает частично
            if (rez == 1)
            {
                //////////////////////////////////////////////////////////////////////////
                N.Parent.ListTrInd.Add(TrInd);
                return true;
            }

            //Поподает полностью

            //Нужно создать потомков
            if (N.Children.Count < 1)
            {
                int Level = N.NestingLevel - 1;

                if (X > Math.Max(Y, Z))
                {
                    N.Children.Add(new MeshNode(N, N.AABBMax, new Vector3(N.AABBMax.X - X / 2f, N.AABBMin.Y, N.AABBMin.Z), Level));
                    N.Children.Add(new MeshNode(N, new Vector3(N.AABBMax.X - X / 2f, N.AABBMax.Y, N.AABBMax.Z), N.AABBMin, Level));
                    if ((AA_2.X + BB_2.X) / 2f > N.AABBMax.X - X / 2f)
                    {
                        if (Add(TrInd, N.Children[0], AA_2, BB_2)) return true;
                        if (Add(TrInd, N.Children[1], AA_2, BB_2)) return true;
                    }
                    else
                    {
                        if (Add(TrInd, N.Children[1], AA_2, BB_2)) return true;
                        if (Add(TrInd, N.Children[0], AA_2, BB_2)) return true;
                    }
                }
                else
                {
                    if (Y > Math.Max(X, Z))
                    {
                        N.Children.Add(new MeshNode(N, N.AABBMax, new DVector3(N.AABBMin.X, N.AABBMax.Y - Y / 2f, N.AABBMin.Z), Level));
                        N.Children.Add(new MeshNode(N, new DVector3(N.AABBMax.X, N.AABBMax.Y - Y / 2f, N.AABBMax.Z), N.AABBMin, Level));
                        if ((AA_2.Y + BB_2.Y) / 2f > N.AABBMax.Y - Y / 2f)
                        {
                            if (Add(TrInd, N.Children[0], AA_2, BB_2)) return true;
                            if (Add(TrInd, N.Children[1], AA_2, BB_2)) return true;
                        }
                        else
                        {
                            if (Add(TrInd, N.Children[1], AA_2, BB_2)) return true;
                            if (Add(TrInd, N.Children[0], AA_2, BB_2)) return true;
                        }
                    }
                    else
                    {
                        N.Children.Add(new MeshNode(N, N.AABBMax, new DVector3(N.AABBMin.X, N.AABBMin.Y, N.AABBMax.Z - Z / 2f), Level));
                        N.Children.Add(new MeshNode(N, new DVector3(N.AABBMax.X, N.AABBMax.Y, N.AABBMax.Z - Z / 2f), N.AABBMin, Level));
                        if ((AA_2.Z + BB_2.Z) / 2f > N.AABBMax.Z - Z / 2f)
                        {
                            if (Add(TrInd, N.Children[0], AA_2, BB_2)) return true;
                            if (Add(TrInd, N.Children[1], AA_2, BB_2)) return true;
                        }
                        else
                        {
                            if (Add(TrInd, N.Children[1], AA_2, BB_2)) return true;
                            if (Add(TrInd, N.Children[0], AA_2, BB_2)) return true;
                        }
                    }
                }
            }

            //потомки уже есть

            if (Add(TrInd, N.Children[0], AA_2, BB_2)) return true;
            if (Add(TrInd, N.Children[1], AA_2, BB_2)) return true;

            return false;
        }