\input default.mac
\keya{}\leftline{void\symbol{}\ \normal{}NV_PureKdTreeRenderAction\symbol{}::\normal{}TraverseNode\symbol{}(\normal{}KdTreeNode\symbol{}\ *\normal{}pCurrNode\symbol{}) }
\leftline{ 1:\ \ \ $\{$ }
\leftline{ 2:\ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_bLeaf\symbol{}) }
\leftline{ 3:\ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{ 4:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ this\ has\ a\ frame\ counter\ to\ prevent\ double\ rendering }
\symbol{}\leftline{ 5:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}RenderGeometry\symbol{}(); }
\leftline{ 6:\ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{ 7:\ \ \ \ \ \ \ \ \ \ \keya{}else\symbol{} }
\leftline{ 8:\ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{ 9:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}Point3f\symbol{}\ \ \ \ \ \ \normal{}ptViewpoint\symbol{}\ \ =\ \normal{}GetState\symbol{}()->\normal{}GetCamera\symbol{}()->\normal{}GetPosition\symbol{}(); }
\leftline{10:\ \ \  }
\leftline{11:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//----\ insert\ the\ children\ in\ the\ reverse\ order\ as\ they\ shall\ be\ dealt\ with }
\symbol{}\leftline{12:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}ptViewpoint\symbol{}[\normal{}pCurrNode\symbol{}->\normal{}m_iSplitAxis\symbol{}]\ >\ \normal{}pCurrNode\symbol{}->\normal{}m_fSplitValue\symbol{}) }
\leftline{13:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{14:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pLeftChild\symbol{}); }
\leftline{15:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pRightChild\symbol{}); }
\leftline{16:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{17:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}else\symbol{} }
\leftline{18:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{19:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pRightChild\symbol{}); }
\leftline{20:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_pLeftChild\symbol{}); }
\leftline{21:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{22:\ \ \ \ \ \ \ \ \ \ $\}$\ \comment{}//\ no\ leaf }
\symbol{}\leftline{23:\ \ \ $\}$ }
\leftline{24:\ \ \  }
\leftline{25:\ \ \  }
\comment{}\leftline{26:\ \ \ //----\ the\ actual\ render\ algorithm }
\keya{}\leftline{27:\ \ \ void\symbol{}\ \ \ \normal{}NV_PureKdTreeRenderAction\symbol{}::\normal{}RenderSorted\symbol{}() }
\leftline{28:\ \ \ $\{$ }
\leftline{29:\ \ \ \ \ \ \ \ \ \ \normal{}KdTreeNode\symbol{}\ \ \ \ *\ \normal{}pCurrNode\symbol{}; }
\leftline{30:\ \ \ \ \ \ \ \ \ \ \keya{}int\symbol{}\ \ \ \ \ \ \normal{}iTestCounter\symbol{}\ \ \ \ =\ \normal{}0\symbol{}; }
\leftline{31:\ \ \  }
\leftline{32:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ clear\ the\ two\ needed\ datastructures }
\symbol{}\leftline{33:\ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Clear\symbol{}(); }
\leftline{34:\ \ \ \ \ \ \ \ \ \ \normal{}m_NVTestQueue.Clear\symbol{}(); }
\leftline{35:\ \ \  }
\leftline{36:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ generate\ the\ occlusion\ queries }
\symbol{}\leftline{37:\ \ \ \ \ \ \ \ \ \ \normal{}glGenOcclusionQueriesNV\symbol{}(\normal{}m_nNumNodes\symbol{},\ \normal{}m_pOcclusionQueries\symbol{}); }
\leftline{38:\ \ \  }
\leftline{39:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ take\ the\ root\ as\ a\ start }
\symbol{}\leftline{40:\ \ \ \ \ \ \ \ \ \ \normal{}m_pKdTree\symbol{}->\normal{}m_iPlaneMask\symbol{}\ \ \ \ \ \ \ =\ \normal{}0x3f\symbol{};\ \ \ \ \ \ \ \comment{}//\ =\ 0011\ 1111\ which\ means\ that\ at\ the\ beginning,\ all\ six\ planes\ have\ to\ frustum\ culled }
\symbol{}\leftline{41:\ \ \ \ \ \ \ \ \ \ \normal{}m_TraverseStack.Push\symbol{}(\normal{}m_pKdTree\symbol{}); }
\leftline{42:\ \ \  }
\leftline{43:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ the\ loop }
\symbol{}\leftline{44:\ \ \ \ \ \ \ \ \ \ \keya{}while\symbol{}\ ((!\normal{}m_TraverseStack.Empty\symbol{}())\ ||\ (!\normal{}m_NVTestQueue.Empty\symbol{}())) }
\leftline{45:\ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{46:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}bool\symbol{}\ \normal{}result_available\symbol{}; }
\leftline{47:\ \ \  }
\leftline{48:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}while\symbol{}\ (!\normal{}m_NVTestQueue.Empty\symbol{}()\ \&\&\  }
\leftline{49:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\normal{}m_TraverseStack.Empty\symbol{}()\ || }
\leftline{50:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (\normal{}result_available\symbol{}\ =\ \normal{}ResultAvailable\symbol{}(\normal{}m_NVTestQueue.GetFirst\symbol{}()->\normal{}m_nTest\symbol{})) }
\leftline{51:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ) }
\leftline{52:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ) }
\leftline{53:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{54:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}\ =\ \normal{}m_NVTestQueue.GetFirst\symbol{}();\ \normal{}m_NVTestQueue.RemoveFirst\symbol{}(); }
\leftline{55:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  }
\leftline{56:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ the\ next\ line\ is\ only\ interesting\ if\ we\ want\ to\ avoid\ double\ rendering\ already\ here: }
\symbol{}\leftline{57:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//bool\ was_visible\ =\ pCurrNode->m_bVisible\ \&\&\ (m_nLastVisitedId\ ==\ (GetCurrentFrame()\ -\ 1)); }
\symbol{}\leftline{58:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  }
\leftline{59:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ update\ visibility\ classification\ (this\ is\ the\ wait\ variety!) }
\symbol{}\leftline{60:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{}\ =\ \normal{}GetVisiblePixels\symbol{}(\normal{}pCurrNode\symbol{}->\normal{}m_nTest\symbol{})\ >\ \normal{}Settings\symbol{}::\normal{}Global\symbol{}()->\normal{}get_nvocc_pixel_treshold\symbol{}(); }
\leftline{61:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_nLastVisitedId\symbol{}\ =\ \normal{}GetCurrentFrame\symbol{}(); }
\leftline{62:\ \ \  }
\leftline{63:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{})\ \comment{}//\ \&\&\ !was_visible)\ \ \ \ \ \ //\ note:\ could\ prevent\ double\ rendering\ already\ here! }
\symbol{}\leftline{64:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{65:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}MakeParentsVisible\symbol{}(); }
\leftline{66:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}TraverseNode\symbol{}(\normal{}pCurrNode\symbol{}); }
\leftline{67:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$\ \comment{}//\ visible }
\symbol{}\leftline{68:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{69:\ \ \  }
\leftline{70:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//----\ the\ second\ part\ manages\ the\ distance\ heap }
\symbol{}\leftline{71:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (!\normal{}m_TraverseStack.Empty\symbol{}()) }
\leftline{72:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{73:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//----\ get\ the\ element\ with\ the\ lowest\ distance }
\symbol{}\leftline{74:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}\ \ \ =\ \normal{}m_TraverseStack.Pop\symbol{}();\ \ \ \ \ \ \ \ \ \ \  }
\leftline{75:\ \ \  }
\leftline{76:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ question:\ what\ is\ the\ difference\ if\ we\ do\ frustum\ culling\ only\ after\ setting\ visibility? }
\symbol{}\leftline{77:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}IsWithinViewFrustum\symbol{}()) }
\leftline{78:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{79:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}bool\symbol{}\ \normal{}was_visible\symbol{}\ =\ \normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{}\ \&\&\ (\normal{}pCurrNode\symbol{}->\normal{}m_nLastVisitedId\symbol{}\ ==\ (\normal{}GetCurrentFrame\symbol{}()\ -\ \normal{}1\symbol{})); }
\leftline{80:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  }
\leftline{81:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ note:\ this\ is\ actually\ only\ done\ for\ internal\ nodes\ and\ could\ be\ skipped\ for\ leaf\ nodes }
\symbol{}\leftline{82:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \comment{}//\ in\ which\ case\ leaf\ node\ double\ rendering\ could\ be\ prevented\ here\ (see\ above) }
\symbol{}\leftline{83:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_bVisible\symbol{}\ =\ \normal{}FALSE\symbol{}; }
\leftline{84:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}pCurrNode\symbol{}->\normal{}m_nLastVisitedId\symbol{}\ =\ \normal{}GetCurrentFrame\symbol{}(); }
\leftline{85:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  }
\leftline{86:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_bLeaf\symbol{}\ ||\ !\normal{}was_visible\symbol{}) }
\leftline{87:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{88:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}pCurrNode\symbol{}->\normal{}m_pSuccessor\symbol{}->\normal{}IssueNVTest\symbol{}(\normal{}m_pOcclusionQueries\symbol{}[\normal{}iTestCounter\symbol{}]))\ ++\normal{}iTestCounter\symbol{}; }
\leftline{89:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}m_NVTestQueue.Append\symbol{}(\normal{}pCurrNode\symbol{}); }
\leftline{90:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{91:\ \ \  }
\leftline{92:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \keya{}if\symbol{}\ (\normal{}was_visible\symbol{}) }
\leftline{93:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\{$ }
\leftline{94:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \normal{}TraverseNode\symbol{}(\normal{}pCurrNode\symbol{}); }
\leftline{95:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{96:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{97:\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{98:\ \ \ \ \ \ \ \ \ \ $\}$ }
\leftline{99:\ \ \  }
\leftline{100:\ \ \ \ \ \ \ \ \ \ \comment{}//----\ tell\ the\ driver\ that\ the\ occlusion\ queries\ won't\ be\ needed\ any\ more }
\symbol{}\leftline{101:\ \ \ \ \ \ \ \ \ \ \normal{}glDeleteOcclusionQueriesNV\symbol{}(\normal{}m_nNumNodes\symbol{},\ \normal{}m_pOcclusionQueries\symbol{}); }
\leftline{102:\ \ \  }
\leftline{103:\ \ \ $\}$