00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llroam.h"
00035
00036 LLRoam* LLRoamTriNode::sQueues;
00037
00038 void LLRoamTriNode::updateLink(LLRoamTriNode* old_link, LLRoamTriNode* new_link)
00039 {
00040 if (old_link == mLeft)
00041 mLeft = new_link;
00042 else if (old_link == mRight)
00043 mRight = new_link;
00044 else if (old_link == mBase)
00045 mBase = new_link;
00046 }
00047
00048 BOOL LLRoamTriNode::split(BOOL forceful)
00049 {
00050
00051 if (forceful)
00052 {
00053 initForcefulRefine();
00054 }
00055
00056
00057
00058
00059 if (!leaf())
00060 return TRUE;
00061
00062 if (mLchild == NULL)
00063 {
00064 mLchild = newLChild();
00065 mRchild = newRChild();
00066
00067
00068
00069
00070 mLchild->setLeft(mRchild);
00071 mRchild->setRight(mLchild);
00072 }
00073
00074 mLchild->setBase(mLeft);
00075 mRchild->setBase(mRight);
00076
00077 if (mLeft)
00078 mLeft->updateLink(this, mLchild);
00079 if (mRight)
00080 mRight->updateLink(this, mRchild);
00081
00082 mLeaf = FALSE;
00083
00084 patch()->numTrisInc();
00085
00086
00087 sQueues->numOfProcessedTrisInc();
00088 if (mBase == NULL)
00089 return TRUE;
00090
00091 if (mBase->base() != this)
00092 mBase->split(TRUE);
00093
00094 if (mBase->leaf())
00095 mBase->split(TRUE);
00096
00097 mLchild->setRight(mBase->Rchild());
00098 mRchild->setLeft(mBase->Lchild());
00099
00100 return TRUE;
00101 }
00102
00103 BOOL LLRoamTriNode::merge()
00104 {
00105
00106 if (leaf())
00107 return TRUE;
00108
00109 if (mBase && mBase->refine())
00110 return FALSE;
00111
00112 if (!mLchild->merge() || !mRchild->merge())
00113 return FALSE;
00114
00115
00116 mLeft = mLchild->base();
00117 mRight = mRchild->base();
00118
00119 if (mLeft)
00120 mLeft->updateLink(mLchild, this);
00121 if (mRight)
00122 mRight->updateLink(mRchild, this);
00123
00124
00125 mLeaf = TRUE;
00126
00127 patch()->numTrisDec();
00128
00129
00130 if (mBase != NULL)
00131 {
00132 if (!mBase->merge())
00133 {
00134 mLeaf = FALSE;
00135 patch()->numTrisInc();
00136 return FALSE;
00137 }
00138 }
00139
00140
00141 return TRUE;
00142 }
00143
00144 void LLRoamTriNode::mergeSimple()
00145 {
00146 mLeft = mLchild->base();
00147 mRight = mRchild->base();
00148
00149 if (mLeft)
00150 mLeft->updateLink(mLchild, this);
00151 if (mRight)
00152 mRight->updateLink(mRchild, this);
00153
00154 mLeaf = TRUE;
00155 patch()->numTrisDec();
00156 sQueues->numOfProcessedTrisInc();
00157 }
00158
00159 void LLRoamTriNode::update()
00160 {
00161 if (refine())
00162 sQueues->queueForSplit(this);
00163 else if (!leaf())
00164 sQueues->queueForMerge(this);
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 LLRoamTriNode::~LLRoamTriNode()
00185 {
00186 delete mLchild;
00187 mLchild = 0;
00188 delete mRchild;
00189 mRchild = 0;
00190
00191
00192 }
00193
00194
00195
00196 const LLRoamTriNode* LLRoamTriNode::getFirstLeaf() const
00197 {
00198 const LLRoamTriNode* node = this;
00199 while (!node->leaf())
00200 node = node->Lchild();
00201 return node;
00202 }
00203 const LLRoamTriNode* LLRoamTriNode::getNextLeaf() const
00204 {
00205 const LLRoamTriNode* child = this;
00206 const LLRoamTriNode* prev = parent();
00207 while (prev) {
00208 if (prev->Lchild() == child)
00209 return prev->Rchild()->getFirstLeaf();
00210 child = prev;
00211 prev = prev->parent();
00212 };
00213 return NULL;
00214 }
00215
00216 void LLRoam::queueForSplit(LLRoamTriNode* t, BOOL process_base)
00217 {
00218
00219
00220
00221
00222 pushSplit(t);
00223 }
00224
00225 void LLRoam::queueForMerge(LLRoamTriNode* t, BOOL process_base)
00226 {
00227
00228
00229 if (t->leaf())
00230 return;
00231 queueForMerge(t->Lchild());
00232 queueForMerge(t->Rchild());
00233 if (t->base() && process_base)
00234 queueForMerge(t->base(), FALSE);
00235 pushMerge(t);
00236 }
00237
00238
00239 void LLRoam::processSplit()
00240 {
00241 while(!mSplitQ.isEmpty())
00242 {
00243 LLRoamTriNode* tri = popSplit();
00244 if (tri->split())
00245 {
00246 tri->Lchild()->update();
00247 tri->Rchild()->update();
00248 }
00249
00250 }
00251 }
00252
00253 void LLRoam::processMerge()
00254 {
00255 while(!mMergeQ.isEmpty())
00256 {
00257 LLRoamTriNode* tri = popMerge();
00258 if (tri->refine())
00259 continue;
00260 if (tri->leaf())
00261 continue;
00262 if (!tri->Lchild()->leaf() || !tri->Rchild()->leaf())
00263 continue;
00264 if (LLRoamTriNode* b = tri->base())
00265 {
00266 if (b->leaf() || (b->Lchild()->leaf() && b->Rchild()->leaf()))
00267 {
00268 tri->mergeSimple();
00269 }
00270 }
00271
00272 }
00273 }
00274
00275 void LLRoam::process()
00276 {
00277 while(!mSplitQ.isEmpty() || !mMergeQ.isEmpty())
00278 {
00279 processMerge();
00280 processSplit();
00281 }
00282 }
00283
00284
00285 void LLRoam::flushSplit()
00286 {
00287 while(!mSplitQ.isEmpty())
00288 {
00289 LLRoamTriNode* tri = popSplit();
00290 tri->flushFromQueue();
00291 }
00292 }
00293
00294 void LLRoam::flushMerge()
00295 {
00296 while(!mMergeQ.isEmpty())
00297 {
00298 LLRoamTriNode* tri = popMerge();
00299 if (tri->leaf())
00300 continue;
00301 if (tri->base()->leaf())
00302 {
00303 tri->mergeSimple();
00304 }
00305 tri->flushFromQueue();
00306 }
00307 }