• Main Page
  • Packages
  • Classes
  • Files
  • File List

C:/Doug/CSharp/XnaCollisionLib/XnaCollisionLib/OctTree.cs

Go to the documentation of this file.
00001 using System;
00002 using System.Collections.Generic;
00003 using Microsoft.Xna.Framework;
00004 using Microsoft.Xna.Framework.Graphics;
00005 
00006 namespace XnaCollisionLib
00007 {
00008     public class OctTree
00009     {
00010         private List<Triangle> _Triangles;
00011         private OctTree[] _Children;
00012         private BoundingBox _Box;
00013         private int _Count;
00014 
00015         private OctTree()
00016         {
00017             _Triangles = new List<Triangle>();
00018             _Children = new OctTree[8];
00019             for (int i = 0; i != _Children.Length; i++)
00020                 _Children[i] = null;
00021             _Box = new BoundingBox();
00022             _Count = 0;
00023         }
00024 
00025         private int CountTriangles()
00026         {
00027             int count = _Triangles.Count;
00028 
00029             foreach (OctTree node in _Children)
00030                 if (node != null)
00031                     count += node.CountTriangles();
00032             return count;
00033         }
00034 
00035         public int Count
00036         {
00037             get { return _Count; }
00038         }
00039 
00040         public Nullable<float> ISect(Ray ray, ref float nearestDistance, ref Triangle nearestTriangle)
00041         {
00042             Nullable<float> t = ray.Intersects(_Box);
00043 
00044             if (t.HasValue && t.Value >= 0 && t.Value < nearestDistance)
00045             {
00046                 t = null;
00047 
00048                 foreach (Triangle triangle in _Triangles)
00049                 {
00050                     Nullable<float> t2 = triangle.ISect(ray);
00051 
00052                     if (t2.HasValue && t2.Value >= 0 && t2.Value < nearestDistance)
00053                     {
00054                         nearestDistance = t2.Value;
00055                         nearestTriangle = triangle;
00056                         t = t2;
00057                     }
00058                 }
00059                 foreach (OctTree node in _Children)
00060                     if (node != null)
00061                     {
00062                         Nullable<float> t2 = node.ISect(ray, ref nearestDistance, ref nearestTriangle);
00063 
00064                         if (t2.HasValue)
00065                             t = t2;
00066                     }
00067             }
00068             return t;
00069         }
00070 
00071         public void Query(BoundingBox box, List<Triangle> triangles, Matrix transform)
00072         {
00073             if (_Box.Contains(box) == ContainmentType.Disjoint)
00074                 return;
00075 
00076             foreach (Triangle triangle in _Triangles)
00077                 triangles.Add(new Triangle(triangle, transform));
00078             foreach (OctTree node in _Children)
00079                 if (node != null)
00080                     node.Query(box, triangles, transform);
00081         }
00082 
00083         public static OctTree Create(IEnumerable<Triangle> triangles, int minTrianglesPerNode)
00084         {
00085             OctTree node = new OctTree();
00086 
00087             node._Triangles.AddRange(triangles);
00088             Create(node, minTrianglesPerNode);
00089             node._Count = node.CountTriangles();
00090 
00091             return node;
00092         }
00093 
00094         private static void Create(OctTree node, int minTrianglesPerNode)
00095         {
00096             node._Box.Min = node._Box.Max = node._Triangles[0].A;
00097             for (int i = 0; i != node._Triangles.Count; i++)
00098             {
00099                 CollisionHelper.AddToBox(ref node._Box, node._Triangles[i].A);
00100                 CollisionHelper.AddToBox(ref node._Box, node._Triangles[i].B);
00101                 CollisionHelper.AddToBox(ref node._Box, node._Triangles[i].C);
00102             }
00103             if (node._Triangles.Count < minTrianglesPerNode)
00104                 return;
00105 
00106             Vector3 center = (node._Box.Max + node._Box.Min) / 2;
00107             Vector3[] corners = node._Box.GetCorners();
00108             List<Triangle> keepTriangles = new List<Triangle>();
00109 
00110             for (int i = 0; i != 8; i++)
00111             {
00112                 node._Children[i] = new OctTree();
00113                 node._Children[i]._Box.Min = node._Children[i]._Box.Max = center;
00114                 CollisionHelper.AddToBox(ref node._Children[i]._Box, corners[i]);
00115                 for (int j = 0; j != node._Triangles.Count; j++)
00116                     if (node._Children[i]._Box.Contains(node._Triangles[j].A) != ContainmentType.Disjoint &&
00117                         node._Children[i]._Box.Contains(node._Triangles[j].B) != ContainmentType.Disjoint &&
00118                         node._Children[i]._Box.Contains(node._Triangles[j].C) != ContainmentType.Disjoint)
00119                         node._Children[i]._Triangles.Add(node._Triangles[j]);
00120                     else
00121                         keepTriangles.Add(node._Triangles[j]);
00122                 node._Triangles = new List<Triangle>(keepTriangles);
00123                 keepTriangles.Clear();
00124                 if (node._Children[i]._Triangles.Count == 0)
00125                     node._Children[i] = null;
00126                 else
00127                     Create(node._Children[i], minTrianglesPerNode);
00128             }
00129         }
00130     }
00131 }

Generated on Thu Jul 15 2010 19:56:39 for XnaCollisionLib by  doxygen 1.7.0