Maths & Technologies for Games Spatial Partitioning 2 CO3303 Week 9
Contents Introduction Grid-based Partitions Quad-Trees / Oct-Trees Binary Space Partitioning
Introduction / Recap Dividing a game world into partitions has many uses Have looked at PVS & portal systems To cull unseen partitions Such visibility techniques also useful for AI entities Here we introduce a range of tree-based partitions BSP / Quad / Oct trees
Grids as Spatial Partitions One of the most intuitive spatial partitions is a grid Can collect local entities for visibility culling, AI etc. Can be used to map terrain: Height maps, influence maps… Can be extended to 3D Or 2.5D – 2D grid with heights Disadvantages: May have many empty nodes, wasting memory & reducing cache efficiency Choice of partition size tricky – too small gives many empty nodes, too large and culling etc. is ineffective
Mapping a Grid to the World A grid is an integer indexed structure (e.g. an array) For a rectangle of world space Need to map between world-space coords & grid indexes (GridX,GridY) (WorldX,WorldY) Conversions for X dimension are (Y dimension similar): GridX = (int)(GridWidth * (WorldX – MinX) / (MaxX – MinX)) WorldX = MinX + (float)GridX * (MaxX – MinX) / GridWidth Second formula will give bottom-left of grid square For centre of grid square add 0.5 to GridX
Quadtrees / Octrees Quadtrees / Octrees are hierarchical partition systems Use a tree structure to represent an area/volume of space Formed by recursive subdivision Use specific division scheme Unlike portals where division into partitions was arbitrary Quadtrees are in 2D, octrees in 3D Otherwise the same Some similarities with grid system
Creating a Quadtree Root node is entire space Usually square Divide into four equal quadrants These are the children nodes Repeat division with each quadrant Until some condition is met Maximum depth An empty node Only one entity contained Etc…application dependent
Location in a Quadtree Easy to find which node point is in: Start at root node Find the quadrant the point is in Just two comparisons (X and Y) Repeat process on this quadrant Can be optimised: Have world space as square Power of 2 in size (e.g. 2048) Centred on origin Can use bitwise integer math [See Rabin]
Quadtrees for Visibility Culling Use for frustum culling: Traverse quadtree from root Cull entire nodes outside frustum Along with all entities and all child nodes in them Reject many entities at once Nodes are AABB Viewing frustum is 6 planes To test if a node is visible: Six AABB <-> plane tests Saw this idea in initial lecture on partitions. Several approaches, see: www.lighthouse3d.com/opengl/viewfrustum/index.php
Quadtree Problem Problem: Worst case: entity overlaps origin Entities aren’t points May overlap a node boundary In this case the entity needs to be in a larger parent node Worst case: entity overlaps origin Doesn’t fit in any node except root Even a tiny entity Will never be culled Hot-spots like this al the way around the boundaries of larger nodes
Loose Quadtrees Solution: Loose Quadtrees Few changes to algorithms Have nodes overlap Entities will then fit in original node area Potentially with their bounding sphere overlapping adjacent nodes Few changes to algorithms Increase node size: When inserting entities When doing frustum culling Removes hot-spot problem At the expense of larger nodes at the same level
Quadtrees for Collision Detection We saw intersection of viewing frustum with quadtree Fairly easy to find intersection of other primitives Spheres, cuboids, rays, capsules Find the set of nodes intersected And hence the set of entities that are candidates for collision Basis for collision detection / ray casting / physics systems Can help if we add adjacency information to the tree
Binary Space Partitioning A Binary Space Partition (BSP) is also a hierarchical division of space Another tree structure This one represents all space Quadtrees only cover root node Partitions separated by: Lines in 2D Planes in 3D Recursively divide each partition into two smaller ones with an arbitrary line / plane Creates a binary tree
Creating a BSP Repeatedly divide space in two Stop when: Use best line/plane to balance tree Stop when: Maximum of X elements in each partition (X = 1 here) Partitions are small enough Tree reaches certain depth Choice depends on application
Locating a Point in a BSP Given a point, easy to find which partition it is in: Start at root of tree Find which side of the dividing line/plane the point is on Follow appropriate edge Repeat until find leaf partition Example here: Check P against X Not in A, follow other edge Check P against Y Not in B, follow other edge, etc.
Reminder: which Side of a Plane? A plane is defined by: A vertex on the plane P A vector / normal N at right angles to the plane To find which side of the plane a vertex A is on: d = N • PA = |N| |PA| cos α A will be on the same side pointed at by the vector N if: N • PA is a simple operation Don’t need to calculate α
BSP for Solid/Hollow Spaces Can use the polygons in the scene as the division planes Choose a polygon as a plane All other polygons placed on one or other side of plane Polygons crossing the planes are split BSP splits space into hollow / solid volumes All polygons / entities placed in hollow ones
BSP / Brush Modelling This “traditional” style of BSP used for FPS games First appeared in Doom (original version) Often used in conjunction with a PVS Can also be used to render partitions in a strict back to front order Lends itself to a unique form of 3D modelling called brush modelling Start with a entirely solid world Cut out primitives (boxes, cylinders etc.) Entities placed in hollowed out areas Like "digging out" the level
BSP Pros / Cons BSP trees are a well established technique Real-world apps tend to use refinements of the approach Used for rendering / collision / ray-tracing Can be generated automatically Fully classify space Easy to find which partition a point is in Need good algorithm to choose dividing planes Try to balance tree, examples were unbalanced Hollow/solid BSP generates extra polygons due to splitting