public override void Execute(IIntersectionSceneQueryListener listener) { var set = new Dictionary <MovableObject, MovableObject>(); // Iterate over all movable types foreach (Core.MovableObjectFactory factory in Root.Instance.MovableObjectFactories.Values) { MovableObjectCollection col = creator.GetMovableObjectCollection(factory.Type); foreach (MovableObject e in col.Values) { PCZone zone = ((PCZSceneNode)(e.ParentSceneNode)).HomeZone; var list = new List <PCZSceneNode>(); //find the nodes that intersect the AAB ((PCZSceneManager)creator).FindNodesIn(e.GetWorldBoundingBox(), ref list, zone, null); //grab all moveables from the node that intersect... foreach (PCZSceneNode node in list) { foreach (MovableObject m in node.Objects) { // MovableObject m = if (m != e && !set.ContainsKey(m) && !set.ContainsKey(e) && (m.QueryFlags & queryMask) != 0 && (m.TypeFlags & this.queryTypeMask) != 0 && m.IsAttached && e.GetWorldBoundingBox().Intersects(m.GetWorldBoundingBox())) { listener.OnQueryResult(e, m); // deal with attached objects, since they are not directly attached to nodes if (m.MovableType == "Entity") { var e2 = (Entity)m; foreach (MovableObject c in e2.SubEntities) { if ((c.QueryFlags & queryMask) != 0 && e.GetWorldBoundingBox().Intersects(c.GetWorldBoundingBox())) { listener.OnQueryResult(e, c); } } } } set.Add(e, m); } } } } }
public override void Execute( IIntersectionSceneQueryListener listener ) { MovableObjectFactoryMap factories = Root.Instance.MovableObjectFactories; IEnumerator enumFactories = factories.GetEnumerator(); while ( enumFactories.Current != null ) { KeyValuePair<string, MovableObjectFactory> map = (KeyValuePair<string, MovableObjectFactory>)enumFactories.Current; MovableObjectCollection movableObjects = this.creator.GetMovableObjectCollection( map.Value.Type ); IEnumerator enumA = movableObjects.GetEnumerator(); while ( enumA.Current != null ) { MovableObject objectA = (MovableObject)enumA.Current; // skip group if query type doesn't match if ( ( this.QueryTypeMask & objectA.TypeFlags ) == 0 ) { break; } // skip if unattached or filtered out by query flags if ( !objectA.IsInScene || ( objectA.QueryFlags & this.queryMask ) == 0 ) { continue; } // Check against later objects in the same group IEnumerator enumB = enumA; while ( enumB.Current != null ) { MovableObject objectB = (MovableObject)enumB.Current; if ( ( ( this.QueryMask & objectB.QueryFlags ) != 0 ) && objectB.IsInScene ) { AxisAlignedBox box1 = objectA.GetWorldBoundingBox(); AxisAlignedBox box2 = objectB.GetWorldBoundingBox(); if ( box1.Intersects( box2 ) ) { listener.OnQueryResult( objectA, objectB ); } } enumB.MoveNext(); } // Check against later groups IEnumerator enumFactoriesLater = enumFactories; while ( enumFactoriesLater.Current != null ) { KeyValuePair<string, MovableObjectFactory> mapLater = (KeyValuePair<string, MovableObjectFactory>)enumFactoriesLater.Current; MovableObjectCollection movableObjectsLater = this.creator.GetMovableObjectCollection( mapLater.Value.Type ); IEnumerator enumC = movableObjectsLater.GetEnumerator(); while ( enumC.Current != null ) { MovableObject objectC = (MovableObject)enumC.Current; // skip group if query type doesn't match if ( ( this.QueryTypeMask & objectC.TypeFlags ) == 0 ) { break; } if ( ( ( this.QueryMask & objectC.QueryFlags ) != 0 ) && objectC.IsInScene ) { AxisAlignedBox box1 = objectA.GetWorldBoundingBox(); AxisAlignedBox box2 = objectC.GetWorldBoundingBox(); if ( box1.Intersects( box2 ) ) { listener.OnQueryResult( objectA, objectC ); } } enumC.MoveNext(); } enumFactoriesLater.MoveNext(); } enumA.MoveNext(); } enumFactories.MoveNext(); } }
/// <summary> /// Go through each leaf node in <see cref="BspLevel"/> and check movables against each other and against <see cref="BspBrush"/> fragments. /// The bounding boxes of object are used when checking for the intersections. /// </summary> /// <param name="listener"></param> public override void Execute( IIntersectionSceneQueryListener listener ) { //Issue: some movable-movable intersections could be reported twice if 2 movables //overlap 2 leaves? BspLevel lvl = ( (BspSceneManager)creator ).Level; int leafPoint = lvl.LeafStart; int numLeaves = lvl.NumLeaves; this.objIntersections.Clear(); this.brushIntersections.Clear(); while ( --numLeaves >= 0 ) { BspNode leaf = lvl.Nodes[ leafPoint ]; this.objectsDone.Clear(); foreach ( MovableObject aObj in leaf.Objects.Values ) { // skip this object if collision not enabled if ( ( aObj.QueryFlags & queryMask ) == 0 ) { continue; } // get it's bounds AxisAlignedBox aBox = aObj.GetWorldBoundingBox(); // check object against the others in this node foreach ( MovableObject bObj in this.objectsDone ) { if ( aBox.Intersects( bObj.GetWorldBoundingBox() ) ) { // check if this pair is already reported IList interObjList = this.objIntersections.FindBucket( aObj ); if ( interObjList == null || interObjList.Contains( bObj ) == false ) { this.objIntersections.Add( aObj, bObj ); listener.OnQueryResult( aObj, bObj ); } } } if ( ( QueryTypeMask & (uint)SceneQueryTypeMask.WorldGeometry ) != 0 ) { // check object against brushes if ( ( QueryTypeMask & (ulong)SceneQueryTypeMask.WorldGeometry ) != 0 ) { foreach ( BspBrush brush in leaf.SolidBrushes ) { if ( brush == null ) { continue; } // test brush against object this.boundedVolume.planes = brush.Planes; if ( this.boundedVolume.Intersects( aBox ) ) { // check if this pair is already reported IList interBrushList = this.brushIntersections.FindBucket( aObj ); if ( interBrushList == null || interBrushList.Contains( brush ) == false ) { this.brushIntersections.Add( aObj, brush ); // report this brush as it's WorldFragment listener.OnQueryResult( aObj, brush.Fragment ); } } } } } this.objectsDone.Add( aObj ); } ++leafPoint; } }
/// <summary> /// <see cref="IntersectionSceneQuery"/> /// </summary> public override void Execute( IIntersectionSceneQueryListener listener ) { // Do movables to movables as before base.Execute( listener ); SceneQuery.WorldFragment frag = new SceneQuery.WorldFragment(); // Do entities to world SceneManager sceneMgr = (SceneManager)( this.creator ); for(int i = 0; i < sceneMgr.Entities.Count; i++) { Entity entityA = sceneMgr.Entities[i]; // Apply mask if ( ( entityA.QueryFlags & queryMask) == 0 ) { AxisAlignedBox box = entityA.GetWorldBoundingBox( ); ArrayList opList = new ArrayList(); /* for ( int j = 0; j < mOptions->world_height; j++ ) { for ( int i = 0; i < mOptions->world_width; i++ ) { // if ( sceneMgr->mPages[ i ][ j ]->isLoaded( ) == true ) // { // sceneMgr->mPages[ i ][ j ]->getIPLRenderOpsInBox( box, opList ); // } } } */ for ( int j = 0; j < opList.Count; ++j ) { frag.FragmentType = WorldFragmentType.RenderOperation; frag.RenderOp = (RenderOperation) opList[i]; listener.OnQueryResult( entityA, frag ); } } } }
public override void Execute( IIntersectionSceneQueryListener listener ) { var set = new Dictionary<MovableObject, MovableObject>(); // Iterate over all movable types foreach ( Core.MovableObjectFactory factory in Root.Instance.MovableObjectFactories.Values ) { MovableObjectCollection col = creator.GetMovableObjectCollection( factory.Type ); foreach ( MovableObject e in col.Values ) { PCZone zone = ( (PCZSceneNode)( e.ParentSceneNode ) ).HomeZone; var list = new List<PCZSceneNode>(); //find the nodes that intersect the AAB ( (PCZSceneManager)creator ).FindNodesIn( e.GetWorldBoundingBox(), ref list, zone, null ); //grab all moveables from the node that intersect... foreach ( PCZSceneNode node in list ) { foreach ( MovableObject m in node.Objects ) { // MovableObject m = if ( m != e && !set.ContainsKey( m ) && !set.ContainsKey( e ) && ( m.QueryFlags & queryMask ) != 0 && ( m.TypeFlags & this.queryTypeMask ) != 0 && m.IsAttached && e.GetWorldBoundingBox().Intersects( m.GetWorldBoundingBox() ) ) { listener.OnQueryResult( e, m ); // deal with attached objects, since they are not directly attached to nodes if ( m.MovableType == "Entity" ) { var e2 = (Entity)m; foreach ( MovableObject c in e2.SubEntities ) { if ( ( c.QueryFlags & queryMask ) != 0 && e.GetWorldBoundingBox().Intersects( c.GetWorldBoundingBox() ) ) { listener.OnQueryResult( e, c ); } } } } set.Add( e, m ); } } } } }
/// <summary> /// Executes the query and returns each match through a listener interface. /// </summary> /// <remarks> /// Note that this method does not store the results of the query internally /// so does not update the 'last result' value. This means that this version of /// execute is more lightweight and therefore more efficient than the version /// which returns the results as a collection. /// </remarks> /// <param name="listener">Listener object to handle the result callbacks.</param> public abstract void Execute( IIntersectionSceneQueryListener listener );
/// <summary> /// <see cref="IntersectionSceneQuery"/> /// </summary> public override void Execute(IIntersectionSceneQueryListener listener) { // Do movables to movables as before base.Execute(listener); SceneQuery.WorldFragment frag = new SceneQuery.WorldFragment(); // Do entities to world SceneManager sceneMgr = (SceneManager)(this.creator); for (int i = 0; i < sceneMgr.Entities.Count; i++) { Entity entityA = sceneMgr.Entities[i]; // Apply mask if ((entityA.QueryFlags & queryMask) == 0) { AxisAlignedBox box = entityA.GetWorldBoundingBox( ); ArrayList opList = new ArrayList(); /* * * for ( int j = 0; j < mOptions->world_height; j++ ) * * { * * for ( int i = 0; i < mOptions->world_width; i++ ) * * { * * // if ( sceneMgr->mPages[ i ][ j ]->isLoaded( ) == true ) * * // { * * // sceneMgr->mPages[ i ][ j ]->getIPLRenderOpsInBox( box, opList ); * * // } * * } * * } * */ for (int j = 0; j < opList.Count; ++j) { frag.FragmentType = WorldFragmentType.RenderOperation; frag.RenderOp = (RenderOperation)opList[i]; listener.OnQueryResult(entityA, frag); } } } }
public override void Execute(IIntersectionSceneQueryListener listener) { foreach (Dictionary<string, MovableObject> objectMap in creator.MovableObjectMaps) { ICollection<MovableObject> movableObjects = objectMap.Values; int numEntries = movableObjects.Count; MovableObject[] movableObjectArray = new MovableObject[numEntries]; movableObjects.CopyTo(movableObjectArray, 0); for (int a = 0; a < (numEntries - 1); a++) { MovableObject aobj = movableObjectArray[a]; // skip if unattached or filtered out by query flags if (!aobj.IsAttached || (aobj.QueryFlags & queryMask) == 0) { continue; } // Loop b from a+1 to last int b = a; for (++b; b != (numEntries - 1); ++b) { MovableObject bobj = movableObjectArray[b]; // skip if unattached or filtered out by query flags if (!bobj.IsAttached || (bobj.QueryFlags & queryMask) == 0) { continue; } // Apply mask to b (both must pass) if ((bobj.QueryFlags & this.queryMask) != 0) { AxisAlignedBox box1 = aobj.GetWorldBoundingBox(); AxisAlignedBox box2 = bobj.GetWorldBoundingBox(); if (box1.Intersects(box2)) { listener.OnQueryResult(aobj, bobj); } } } } } }
/// <summary> /// Executes the query and returns each match through a listener interface. /// </summary> /// <remarks> /// Note that this method does not store the results of the query internally /// so does not update the 'last result' value. This means that this version of /// execute is more lightweight and therefore more efficient than the version /// which returns the results as a collection. /// </remarks> /// <param name="listener">Listener object to handle the result callbacks.</param> public abstract void Execute(IIntersectionSceneQueryListener listener);
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; } }