/// <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; } }