Beispiel #1
0
        public int[] Query(TransformComponent transform, CollisionComponent collision)
        {
            List <int> result = new List <int>();

            if (CompactedNodes == null || CompactedNodes.Length < 1)
            {
                Logger.Warning("Queried empty CompactBvh");
                return(result.ToArray());
            }

            AABB objectAABB = collision.EncapsulatingAABB(transform);

            int[] stack    = new int[20];
            int   nodeaddr = 0;
            int   stackPtr = 0;

            while (stackPtr > -1)
            {
                // Check each child node for overlap.
                Float4 box1  = CompactedNodes[nodeaddr + 0]; // float4 [minx, maxx, miny, maxy]
                Float4 box2  = CompactedNodes[nodeaddr + 1]; // float4 [minz, maxz, child1, 0]
                Float4 box3  = CompactedNodes[nodeaddr + 2]; // float4 [minx, maxx, miny, maxy]
                Float4 box4  = CompactedNodes[nodeaddr + 3]; // float4 [minz, maxz, child2, 0]
                AABB   aabb1 = new AABB
                {
                    Min = new Float4(box1.X, box1.Y, box1.Z, 0.0f),
                    Max = new Float4(box1.W, box2.X, box2.Y, 0.0f)
                };
                AABB aabb2 = new AABB
                {
                    Min = new Float4(box2.Z, box2.W, box3.X, 0.0f),
                    Max = new Float4(box3.Y, box3.Z, box3.W, 0.0f)
                };
                int  child1   = Helpers.FloatAsInt(box4.X);
                int  child2   = Helpers.FloatAsInt(box4.Y);
                bool overlap1 = CollisionSystem.AABBAABBOverlap(objectAABB, aabb1);
                bool overlap2 = CollisionSystem.AABBAABBOverlap(objectAABB, aabb2);

                // Determine next node
                if (!overlap1 && !overlap2)
                {
                    nodeaddr = stack[stackPtr--];
                }
                else
                {
                    nodeaddr = overlap1 ? child1 : child2;

                    // Traverse 1 push 2 to stack
                    if (overlap1 && overlap2)
                    {
                        stack[++stackPtr] = child2;
                    }
                }

                // On leaf break
                while (nodeaddr < 0)
                {
                    int objectId = -nodeaddr - 2; // Leaves are stored as ~id -> ~1 == -2 -> --2 -2 = 0
                    result.Add(objectId);
                    nodeaddr = stack[stackPtr--];
                }
            }

            return(result.ToArray());
        }