예제 #1
0
 /// <summary>
 ///		Default constructor - used by BspResourceManager (do not call directly).
 /// </summary>
 /// <param name="name"></param>
 public BspLevel(string name)
 {
     this.name            = name;
     this.objectToNodeMap = new Bsp.Collections.Map();
 }
예제 #2
0
 /// <summary>
 ///		Default constructor - used by BspResourceManager (do not call directly).
 /// </summary>
 /// <param name="name"></param>
 public BspLevel(string name)
 {
     this.name = name;
     this.objectToNodeMap = new Bsp.Collections.Map();
 }
        public override void Execute(IIntersectionSceneQueryListener listener)
        {
            //Go through each leaf node in BspLevel and check movables against each other and world
            //Issue: some movable-movable intersections could be reported twice if 2 movables
            //overlap 2 leaves?
            BspLevel lvl = ((BspSceneManager) this.creator).Level;
            int leafPoint = lvl.LeafStart;
            int numLeaves = lvl.NumLeaves;

            Bsp.Collections.Map objIntersections = new Bsp.Collections.Map();
            PlaneBoundedVolume boundedVolume = new PlaneBoundedVolume(PlaneSide.Positive);

            while ((numLeaves--) != 0)
            {
                BspNode leaf = lvl.Nodes[leafPoint];
                MovableObjectCollection objects = leaf.Objects;
                int numObjects = objects.Count;

                for(int a = 0; a < numObjects; a++)
                {
                    MovableObject aObj = objects[a];
                    // Skip this object if collision not enabled
                    if((aObj.QueryFlags & queryMask) == 0)
                        continue;

                    if(a < (numObjects - 1))
                    {
                        // Check object against others in this node
                        int b = a;
                        for (++b; b < numObjects; ++b)
                        {
                            MovableObject bObj = objects[b];
                            // Apply mask to b (both must pass)
                            if ((bObj.QueryFlags & queryMask) != 0)
                            {
                                AxisAlignedBox box1 = aObj.GetWorldBoundingBox();
                                AxisAlignedBox box2 = bObj.GetWorldBoundingBox();

                                if (box1.Intersects(box2))
                                {
                                    //Check if this pair is already reported
                                    bool alreadyReported = false;
                                    IList interObjList = objIntersections.FindBucket(aObj);
                                    if (interObjList != null)
                                        if (interObjList.Contains(bObj))
                                            alreadyReported = true;

                                    if (!alreadyReported)
                                    {
                                        objIntersections.Insert(aObj,bObj);
                                        listener.OnQueryResult(aObj,bObj);
                                    }
                                }
                            }
                        }
                    }
                    // Check object against brushes

                    /*----This is for bounding sphere-----
                    float radius = aObj.BoundingRadius;
                    //-------------------------------------------*/

                    for (int brushPoint=0; brushPoint < leaf.SolidBrushes.Length; brushPoint++)
                    {
                        BspBrush brush = leaf.SolidBrushes[brushPoint];

                        if (brush == null) continue;

                        bool brushIntersect = true; // Assume intersecting for now

                        /*----This is for bounding sphere-----
                        IEnumerator planes = brush.Planes.GetEnumerator();

                        while (planes.MoveNext())
                        {
                            float dist = ((Plane)planes.Current).GetDistance(pos);
                            if (dist > radius)
                            {
                                // Definitely excluded
                                brushIntersect = false;
                                break;
                            }
                        }
                        //-------------------------------------------*/

                        boundedVolume.planes = brush.Planes;
                        //Test object as bounding box
                        if (!boundedVolume.Intersects(aObj.GetWorldBoundingBox()))
                            brushIntersect = false;

                        if (brushIntersect)
                        {
                            //Check if this pair is already reported
                            bool alreadyReported = false;
                            IList interObjList = objIntersections.FindBucket(aObj);
                            if (interObjList != null)
                                if (interObjList.Contains(brush))
                                    alreadyReported = true;

                            if (!alreadyReported)
                            {
                                objIntersections.Insert(aObj,brush);
                                // report this brush as it's WorldFragment
                                brush.Fragment.FragmentType = WorldFragmentType.PlaneBoundedRegion;
                                listener.OnQueryResult(aObj,brush.Fragment);
                            }
                        }
                    }
                }
                ++leafPoint;
            }
        }