void MManager::FreeObjectList( ObjectList* a_List ) { ObjectList* list = a_List; while (list->GetNext()) list = list->GetNext(); list->SetNext( m_OList ); m_OList = a_List; }
ObjectList* MManager::NewObjectList() { ObjectList* retval; retval = m_OList; m_OList = m_OList->GetNext(); retval->SetNext( 0 ); retval->SetPrimitive( 0 ); return retval; }
MManager::MManager() : m_OList( 0 ) { // build a 32-byte aligned array of KdTreeNodes m_KdArray = (char*)(new KdTreeNode[1000000]); m_ObjArray = (char*)(new ObjectList[100000]); unsigned long addr = (unsigned long)m_KdArray; m_KdPtr = (KdTreeNode*)((addr + 32) & (0xffffffff - 31)); addr = (unsigned long)m_ObjArray; m_ObjPtr = (ObjectList*)((addr + 32) & (0xffffffff - 31)); ObjectList* ptr = m_ObjPtr; for ( int i = 0; i < 99995; i++ ) { ptr->SetNext( ptr + 1 ); ptr++; } ptr->SetNext( 0 ); m_OList = m_ObjPtr; }
void Scene::BuildGrid() { // initialize regular grid m_Grid = new ObjectList*[GRIDSIZE * GRIDSIZE * GRIDSIZE]; memset( m_Grid, 0, GRIDSIZE * GRIDSIZE * GRIDSIZE * 4 ); vector3 p1(-14, -5, -6), p2( 14, 8, 30 ); // calculate cell width, height and depth float dx = (p2.x - p1.x) / GRIDSIZE, dx_reci = 1.0f / dx; float dy = (p2.y - p1.y) / GRIDSIZE, dy_reci = 1.0f / dy; float dz = (p2.z - p1.z) / GRIDSIZE, dz_reci = 1.0f / dz; m_Extends = aabb( p1, p2 - p1 ); m_Light = new Primitive*[MAXLIGHTS]; m_Lights = 0; // store primitives in the grid cells for ( int p = 0; p < m_Primitives; p++ ) { if (m_Primitive[p]->IsLight()) m_Light[m_Lights++] = m_Primitive[p]; aabb bound = m_Primitive[p]->GetAABB(); vector3 bv1 = bound.GetPos(), bv2 = bound.GetPos() + bound.GetSize(); // find out which cells could contain the primitive (based on aabb) int x1 = (int)((bv1.x - p1.x) * dx_reci), x2 = (int)((bv2.x - p1.x) * dx_reci) + 1; x1 = (x1 < 0)?0:x1, x2 = (x2 > (GRIDSIZE - 1))?GRIDSIZE - 1:x2; int y1 = (int)((bv1.y - p1.y) * dy_reci), y2 = (int)((bv2.y - p1.y) * dy_reci) + 1; y1 = (y1 < 0)?0:y1, y2 = (y2 > (GRIDSIZE - 1))?GRIDSIZE - 1:y2; int z1 = (int)((bv1.z - p1.z) * dz_reci), z2 = (int)((bv2.z - p1.z) * dz_reci) + 1; z1 = (z1 < 0)?0:z1, z2 = (z2 > (GRIDSIZE - 1))?GRIDSIZE - 1:z2; // loop over candidate cells for ( int x = x1; x < x2; x++ ) for ( int y = y1; y < y2; y++ ) for ( int z = z1; z < z2; z++ ) { // construct aabb for current cell int idx = x + y * GRIDSIZE + z * GRIDSIZE * GRIDSIZE; vector3 pos( p1.x + x * dx, p1.y + y * dy, p1.z + z * dz ); aabb cell( pos, vector3( dx, dy, dz ) ); // do an accurate aabb / primitive intersection test if (m_Primitive[p]->IntersectBox( cell )) { // object intersects cell; add to object list ObjectList* l = new ObjectList(); l->SetPrimitive( m_Primitive[p] ); l->SetNext( m_Grid[idx] ); m_Grid[idx] = l; } } } }