Beispiel #1
0
        /// <summary>
        /// Check for collisions with terrain or other organisms
        /// Build a list of unique possible collision targets (tiles or other organisms) using the quad tree.
        /// Initially, just check quickly to see if we are in any danger of hitting any of them. Cull those that
        /// are definitely irrelevant, then look more closely.
        /// </summary>
        private void CheckForCollisions()
        {
            Renderable[] candidate = new Renderable[2000];
            int numCandidates = 0;

            // Don't bother if we're an organism with no physics (e.g. the lab) - things can collide with us but not us with them
            if (Dynamic == false)
                return;

            // Search our list of quads and extract tiles or organisms that we share a bottom-level quad with.
            // Bottom level quads are enough, because no part of us extends beyond this/these.
            foreach (Map quad in myMaps)
            {
                if (quad.Level == Map.NumLevels-1)							// Only search smallest quad or quads
                {
                    foreach (Renderable target in quad.OrganismList)		// look at each ORGANISM in quad
                    {
                        if (target==this)									// ignore self!!!
                            continue;

                        bool found = false;
                        for (int i=0; i<numCandidates; i++)					// if this object isn't already in our list...
                        {
                            if (candidate[i]==target)
                            {
                                found=true;
                                break;
                            }
                        }
                        if (found==false)
                            candidate[numCandidates++] = target;			// ...add it
                    }

                    foreach (Renderable target in quad.TerrainList)			// look at each TILE in quad
                    {
                        bool found = false;
                        for (int i=0; i<numCandidates; i++)					// if this object isn't already in our list...
                        {
                            if (candidate[i]==target)
                            {
                                found=true;
                                break;
                            }
                        }
                        if (found==false)
                            candidate[numCandidates++] = target;			// ...add it
                    }

                }
            }

            // Now cull those that are definitely not a risk because their bounding sphere doesn't intersect ours
            for (int i=0; i<numCandidates; i++)
            {
                // How far, if at all, do we penetrate the candidate
                if (this.AbsSphere.IsPenetrating(candidate[i].AbsSphere)==false)
                    candidate[i] = null;
            }

            // Now we're left with objects whose bounding spheres overlap ours, so examine them more closely.
            for (int i=0; i<numCandidates; i++)
            {
                if (candidate[i]!=null)
                {
                    CheckForCollisions2(candidate[i]);
                }
            }
        }
Beispiel #2
0
 /// <summary>
 /// Second-level collision detection. The supplied object's bounding sphere overlaps with ours.
 /// Drop down to the cell level and look more closely
 /// </summary>
 /// <param name="obj"></param>
 private void CheckForCollisions2(Renderable candidate)
 {
     // For each of our cells, look to see if it collides with ANY part of the candidate.
     foreach (Cell cell in partList)
     {
         // Do we penetrate the candidate at all?
         if (cell.AbsSphere.IsPenetrating(candidate.AbsSphere))
         {
             // Call the target class's virtual method to test more precisely and return any collision force
             cell.propulsionForce += candidate.CollisionTest(cell); /// *Scene.ElapsedTime * 100f;
         }
     }
 }
Beispiel #3
0
 /// <summary>
 /// Add a Renderable object to the batch
 /// </summary>
 /// <param name="newObj"></param>
 public void Add(Renderable newObj)
 {
     for (int i=0; i<batch.Count; i++)
     {
         if (batch[i].DistSq <= newObj.DistSq)
         {
             batch.Insert(i,newObj);
             return;
         }
     }
     batch.Add(newObj);
 }
Beispiel #4
0
 /// <summary>
 /// Add a Renderable object to the batch with no depth sorting (for objects that don't need it)
 /// </summary>
 /// <param name="newObj"></param>
 public void AddUnsorted(Renderable newObj)
 {
     batch.Add(newObj);
 }
Beispiel #5
0
 /// <summary>
 /// Overload of above to test whether a given 3D renderable object is within frustrum
 /// </summary>
 /// <param name="obj"></param>
 /// <returns></returns>
 public static int CanSee(Renderable obj)
 {
     return (CanSee(obj.AbsSphere.Centre,obj.AbsSphere.Radius, 6));
 }
Beispiel #6
0
        /// <summary>
        /// Recursively remove the object from this node and, if it was present, all relevant subnodes
        /// </summary>
        /// <param name="obj">reference to the object to remove</param>
        private void RecursiveDel(Renderable obj)
        {
            int found=-1;

            if (obj is Organism)
                found = organismList.IndexOf((Organism)obj);						// search correct array for object
            else if (obj is Terrain)
                found = terrainList.IndexOf((Terrain)obj);
            else if (obj is Water)
                found = waterList.IndexOf((Water)obj);
            else
                found = sceneryList.IndexOf((Scenery)obj);

            if (found>=0)															// if present at this node
            {
                if (level < NumLevels-1)
                {
                    child[0].RecursiveDel(obj);										// remove it from any child nodes
                    child[1].RecursiveDel(obj);
                    child[2].RecursiveDel(obj);
                    child[3].RecursiveDel(obj);
                }
                if (obj is Organism)
                {
                    organismList.RemoveAt(found);									// delete the object from my list
                    obj.DelMap(this);												// and remove me to the object's own list
                }
                else if (obj is Terrain)
                {
                    terrainList.RemoveAt(found);									// delete the object from my list
                }
                else if (obj is Water)
                {
                    waterList.RemoveAt(found);										// delete the object from my list
                }
                else
                {
                    sceneryList.RemoveAt(found);									// delete the object from my list
                }

            }
        }
Beispiel #7
0
        /// <summary>
        /// Recursively add an object to a node and its children (if it lies within bounds)
        /// </summary>
        /// <param name="obj"></param>
        private void RecursiveAdd(Renderable obj)
        {
            if (obj.IsIn(bounds))													// if the obj is within my boundary
            {
                if (obj is Organism)
                {
                    organismList.Add((Organism)obj);								// add the object to my Organism list
                    obj.AddMap(this);												// and add me to the object's own list
                }
                else if (obj is Terrain)
                {
                    terrainList.Add((Terrain)obj);									// add the object to my Terrain list
                }
                else if (obj is Water)
                {
                    waterList.Add((Water)obj);										// add the object to my Water list
                }
                else
                {
                    sceneryList.Add((Scenery)obj);									// add the object to my Scenery list
                }

                if (level < NumLevels-1)
                {
                    child[0].RecursiveAdd(obj);										// and recursively try my children
                    child[1].RecursiveAdd(obj);										// (if it isn't within my boundary
                    child[2].RecursiveAdd(obj);										// none of my children will contain
                    child[3].RecursiveAdd(obj);										// it either)
                }
            }
        }
Beispiel #8
0
 /// <summary>
 /// Remove an object completely from the quadtree
 /// </summary>
 /// <remarks>
 /// Object should be Disposed of after this call, if no longer needed
 /// (while a reference to it still exists)
 /// </remarks>
 public static void Remove(Renderable obj)
 {
     root.RecursiveDel(obj);													// remove from all relevant nodes
     //Engine.EventHUD.WriteLine("Obj removed from quadtree: "+obj);
 }
Beispiel #9
0
 /// <summary>
 /// Add an object to the quadtree
 /// </summary>
 /// <remarks>Object gets added to every node in the tree that bounds it</remarks>
 public static void Add(Renderable obj)
 {
     root.RecursiveAdd(obj);
     //Engine.EventHUD.WriteLine(String.Format("Obj {0} added to quadtree",root.objects.Count));
 }