aboutsummaryrefslogtreecommitdiff
path: root/docs/doxygen/nel/tessellation_8cpp-source.html
diff options
context:
space:
mode:
authorneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
committerneodarz <neodarz@neodarz.net>2018-08-11 20:21:34 +0200
commit0ea5fc66924303d1bf73ba283a383e2aadee02f2 (patch)
tree2568e71a7ccc44ec23b8bb3f0ff97fb6bf2ed709 /docs/doxygen/nel/tessellation_8cpp-source.html
downloadnevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.tar.xz
nevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.zip
Initial commit
Diffstat (limited to '')
-rw-r--r--docs/doxygen/nel/tessellation_8cpp-source.html3263
1 files changed, 3263 insertions, 0 deletions
diff --git a/docs/doxygen/nel/tessellation_8cpp-source.html b/docs/doxygen/nel/tessellation_8cpp-source.html
new file mode 100644
index 00000000..1aec2208
--- /dev/null
+++ b/docs/doxygen/nel/tessellation_8cpp-source.html
@@ -0,0 +1,3263 @@
+<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<HTML>
+<HEAD>
+ <TITLE>nevrax.org : docs</TITLE>
+ <LINK REL=stylesheet TYPE="text/css" HREF="http://www.nevrax.org/inc/css/nevrax.css">
+ <link href="doxygen.css" rel="stylesheet" type="text/css">
+</HEAD>
+<BODY MARGINHEIGHT="0" MARGINWIDTH="0">
+
+<!-- uplinks -->
+<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0>
+ <TR>
+ <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD WIDTH=140 BGCOLOR=#dddddd><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD><IMG width=6 height=14 SRC="http://www.nevrax.org/inc/img/reddots.gif" ALT="#" VSPACE=2 HSPACE=2 BORDER=0 ></TD><TD VALIGN=middle>&nbsp;<A CLASS=uplinks HREF=http://www.nevrax.org><b>Home</B></FONT></A>&nbsp;&nbsp;&nbsp;</TD>
+ <TD><IMG width=6 height=14 SRC="http://www.nevrax.org/inc/img/reddots.gif" ALT="#" VSPACE=2 HSPACE=2 BORDER=0 ></TD><TD VALIGN=middle>&nbsp;<A CLASS=uplinks HREF=http://www.nevrax.com><b>nevrax.com</B></FONT></A>&nbsp;&nbsp;&nbsp;</TD>
+ </TR>
+</TABLE>
+
+<!-- banner Nevrax -->
+<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%>
+ <TR><TD BGCOLOR="#000000" BACKGROUND="http://www.nevrax.org/inc/img/black_banner.jpg"><A HREF="http://www.nevrax.org"><IMG SRC="http://www.nevrax.org/inc/img/nevrax.gif" WIDTH="170" HEIGHT="45" BORDER=0 ALT="Nevrax" ></A></TD></TR>
+</TABLE>
+
+<!-- main table -->
+<TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 height=100%>
+ <TR>
+ <TD WIDTH=16><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="10" BORDER=0 ALT=""></TD>
+ <TD WIDTH=140 BGCOLOR=#dddddd VALIGN=TOP ALIGN=middle><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="10" BORDER=0 ALT="">
+
+ <!------ Begin Box ------>
+ <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=black><TR><TD><TABLE border=0 cellspacing=2 cellpadding=0 width=120><tr><TD ALIGN=middle bgcolor=black>
+ <FONT COLOR=white FACE="sans-serif"><B>Nevrax.org</B></FONT></TD></TR><tr><td colspan=2 bgcolor=#FFFFFF>
+ <TABLE cellspacing=0 cellpadding=1 border=0>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/news/" TITLE="Rubrique news"><img width=13 height=15 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-news.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/news/" TITLE="News">News</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/mail/" TITLE="Rubrique mail"><img width=15 height=11 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-mail.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/mail/" TITLE="Mailing list archive">Mailing-list</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/docs/" TITLE="Rubrique docs"><img width=14 height=16 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-docs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/docs/" TITLE="Documentation">Documentation</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/cvs/" TITLE="Rubrique cvs"><img width=13 height=17 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-cvs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/cvs/" TITLE="CVS Web">CVS</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/bugs/" TITLE="Rubrique bugs"><img width=20 height=16 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-bugs.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/bugs/" TITLE="Bugtracking">Bugs</a></td></tr>
+ <tr><td ALIGN=middle><a class='linkbox' href="http://www.nevrax.org/GPL.php3" TITLE="Rubrique license"><img width=18 height=12 hspace=5 border=0 src=http://www.nevrax.org/inc/img/picto-gpl.gif ALT=#></A></td><td><a class='linkbox' href="http://www.nevrax.org/GPL.php3" TITLE="License">License</a></td></tr>
+ </TABLE>
+ </TD></TR></TABLE></TD></TR></TABLE>
+ <!------ End Box ------>
+
+ </TD>
+ <TD WIDTH=15><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="16" HEIGHT="16" BORDER=0 ALT=""></TD>
+ <TD ALIGN=left valign=top><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="140" HEIGHT="10" BORDER=0 ALT="">
+
+<!-- title -->
+<TABLE background="http://www.nevrax.org/inc/img/redline.gif" CELLSPACING=0 CELLPADDING=0 BORDER=0 width=100%><tr><td>
+<A HREF="http://www.nevrax.org/docs/"><img src="http://www.nevrax.org/inc/img/t_docs.gif" ALT="Docs" HEIGHT=20 BORDER=0></A>
+</td><td><IMG SRC="http://www.nevrax.org/inc/img/pixel.gif" WIDTH="1" HEIGHT="1" BORDER=0 ALT="">
+</td></tr></table>
+&nbsp;
+
+<!-- block -->
+<TABLE bgcolor="#dddddd" CELLSPACING=0 CELLPADDING=0 BORDER=0 width=100%><tr><td width=1% valign=middle><img width=6 height=14 hspace=2 vspace=2 src="http://www.nevrax.org/inc/img/reddots.gif"></TD>
+ <TD><B>Documentation</B></TD>
+ <TD ALIGN=RIGHT>&nbsp;</td>
+</tr></table>
+<!-- Generated by Doxygen 1.2.14 -->
+<center>
+<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="namespaces.html">Namespace List</a> &nbsp; <a class="qindex" href="hierarchy.html">Class Hierarchy</a> &nbsp; <a class="qindex" href="classes.html">Alphabetical List</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="namespacemembers.html">Namespace Members</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; <a class="qindexRef" doxygen="_cgi:http://www.nevrax.org/cgi-bin/nel-search.cgi" href="http://www.nevrax.org/cgi-bin/nel-search.cgi">Search</a> &nbsp; </center>
+<hr><h1>tessellation.cpp</h1><a href="tessellation_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001
+00008 <font class="comment">/* Copyright, 2000 Nevrax Ltd.</font>
+00009 <font class="comment"> *</font>
+00010 <font class="comment"> * This file is part of NEVRAX NEL.</font>
+00011 <font class="comment"> * NEVRAX NEL is free software; you can redistribute it and/or modify</font>
+00012 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
+00013 <font class="comment"> * the Free Software Foundation; either version 2, or (at your option)</font>
+00014 <font class="comment"> * any later version.</font>
+00015 <font class="comment"></font>
+00016 <font class="comment"> * NEVRAX NEL is distributed in the hope that it will be useful, but</font>
+00017 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font>
+00018 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font>
+00019 <font class="comment"> * General Public License for more details.</font>
+00020 <font class="comment"></font>
+00021 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
+00022 <font class="comment"> * along with NEVRAX NEL; see the file COPYING. If not, write to the</font>
+00023 <font class="comment"> * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,</font>
+00024 <font class="comment"> * MA 02111-1307, USA.</font>
+00025 <font class="comment"> */</font>
+00026
+00027 <font class="preprocessor">#include "<a class="code" href="std3d_8h.html">std3d.h</a>"</font>
+00028
+00029 <font class="preprocessor">#include "<a class="code" href="tessellation_8h.html">3d/tessellation.h</a>"</font>
+00030 <font class="preprocessor">#include "<a class="code" href="patch_8h.html">3d/patch.h</a>"</font>
+00031 <font class="preprocessor">#include "<a class="code" href="src_23d_2zone_8h.html">3d/zone.h</a>"</font>
+00032 <font class="preprocessor">#include "<a class="code" href="common_8h.html">nel/misc/common.h</a>"</font>
+00033 <font class="preprocessor">#include "<a class="code" href="landscape__profile_8h.html">3d/landscape_profile.h</a>"</font>
+00034 <font class="preprocessor">#include "<a class="code" href="landscape_8h.html">3d/landscape.h</a>"</font>
+00035 <font class="preprocessor">#include "<a class="code" href="patchdlm__context_8h.html">3d/patchdlm_context.h</a>"</font>
+00036 <font class="keyword">using</font> <font class="keyword">namespace </font>NLMISC;
+00037 <font class="keyword">using</font> <font class="keyword">namespace </font>std;
+00038
+00039
+00040 <font class="keyword">namespace </font>NL3D
+00041 {
+00042
+00043
+00044 <font class="comment">// ***************************************************************************</font>
+<a name="l00045"></a><a class="code" href="tessellation_8cpp.html#a0">00045</a> <font class="preprocessor">#define NL3D_TESS_USE_QUADRANT_THRESHOLD 0.1f</font>
+00046 <font class="preprocessor"></font>
+00047
+00048 <font class="comment">// ***************************************************************************</font>
+00049 <font class="comment">// The normal Uvs format.</font>
+00050 <font class="keyword">const</font> uint8 <a class="code" href="namespaceNL3D.html#a238">TileUvFmtNormal1</a>= 0;
+00051 <font class="keyword">const</font> uint8 <a class="code" href="namespaceNL3D.html#a239">TileUvFmtNormal2</a>= 1;
+00052 <font class="keyword">const</font> uint8 <a class="code" href="namespaceNL3D.html#a240">TileUvFmtNormal3</a>= 2;
+00053 <font class="keyword">const</font> uint8 <a class="code" href="namespaceNL3D.html#a241">TileUvFmtNormal4</a>= 3;
+00054 <font class="keyword">const</font> uint8 <a class="code" href="namespaceNL3D.html#a242">TileUvFmtNormal5</a>= 4;
+00055
+00056
+00057 <font class="comment">// ***************************************************************************</font>
+00058 <font class="comment">// \todo yoyo: may change this.</font>
+00059 <font class="keyword">const</font> <font class="keywordtype">float</font> <a class="code" href="namespaceNL3D.html#a243">TileSize</a>= 128;
+00060
+00061
+00062
+00063
+00064 <font class="comment">// ***************************************************************************</font>
+00065 <font class="comment">// ***************************************************************************</font>
+00066 <font class="comment">// CTileMaterial</font>
+00067 <font class="comment">// ***************************************************************************</font>
+00068 <font class="comment">// ***************************************************************************</font>
+00069
+00070
+00071 <font class="comment">// ***************************************************************************</font>
+<a name="l00072"></a><a class="code" href="structNL3D_1_1CTileMaterial.html#a0">00072</a> CTileMaterial::CTileMaterial()
+00073 {
+00074 <font class="comment">// By default, all pass are NULL.</font>
+00075 <font class="keywordflow">for</font>(uint i=0; i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>; i++)
+00076 {
+00077 <a class="code" href="structNL3D_1_1CTileMaterial.html#m4">TileFaceVectors</a>[i]= NULL;
+00078 }
+00079 }
+00080
+00081
+00082 <font class="comment">// ***************************************************************************</font>
+<a name="l00083"></a><a class="code" href="structNL3D_1_1CTileMaterial.html#a1">00083</a> <font class="keywordtype">void</font> CTileMaterial::appendTileToEachRenderPass(uint patchNumRenderableFaces)
+00084 {
+00085 <font class="keywordflow">for</font>(uint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a0">NL3D_MAX_TILE_PASS</a>;i++)
+00086 {
+00087 <font class="comment">// If RdrPass exist, add this Material Id</font>
+00088 CPatchRdrPass *rdrPass= <a class="code" href="structNL3D_1_1CTileMaterial.html#m2">Pass</a>[i].PatchRdrPass;
+00089 <font class="keywordflow">if</font>(rdrPass!=NULL)
+00090 {
+00091 <font class="comment">/* enlarge the capacity of the pass so it can renders the tile faces of this patch.</font>
+00092 <font class="comment"> * NumRenderableFaces is really too big since the tile-material surely doesn't use all</font>
+00093 <font class="comment"> * faces of the patch (except if same texture...)</font>
+00094 <font class="comment"> * But doesn't matter. Even if all the visible Tile Surface (80m*80m) is in the same pass,</font>
+00095 <font class="comment"> * it leads to only 76K final in CLandscapeGlobals::PassTriArray:</font>
+00096 <font class="comment"> * 80*80(Visible surface at 80m max) /4 (2m*2m) *2(triangles) *2 (over-estimate) *3*4(triSize)=</font>
+00097 <font class="comment"> * 76800</font>
+00098 <font class="comment"> */</font>
+00099 rdrPass-&gt;appendRdrPatchTile(i, &amp;<a class="code" href="structNL3D_1_1CTileMaterial.html#m2">Pass</a>[i], patchNumRenderableFaces);
+00100 }
+00101 }
+00102 }
+00103
+00104
+00105 <font class="comment">// ***************************************************************************</font>
+00106 <font class="comment">// ***************************************************************************</font>
+00107 <font class="comment">// CTessVertex</font>
+00108 <font class="comment">// ***************************************************************************</font>
+00109 <font class="comment">// ***************************************************************************</font>
+00110
+00111
+00112 <font class="comment">// ***************************************************************************</font>
+<a name="l00113"></a><a class="code" href="classNL3D_1_1CTessVertex.html#a1">00113</a> <font class="keywordtype">void</font> CTessVertex::computeGeomPos()
+00114 {
+00115 <font class="comment">// Compute Basic ErrorMetric.</font>
+00116 <font class="keywordtype">float</font> sqrDist= (<a class="code" href="classNL3D_1_1CTessVertex.html#m1">StartPos</a> - CLandscapeGlobals::RefineCenter).sqrnorm();
+00117 <font class="keywordtype">float</font> pgeom= <a class="code" href="classNL3D_1_1CTessVertex.html#m3">MaxFaceSize</a> * CLandscapeGlobals::OORefineThreshold / sqrDist;
+00118
+00119 <font class="comment">// Compute ErrorMetric modified by TileNear transition, only if TileNear transition.</font>
+00120 <font class="keywordflow">if</font>( sqrDist&lt; CLandscapeGlobals::TileDistFarSqr )
+00121 {
+00122 <font class="comment">// Soft optim: do it only if necessary, ie result of max(errorMetric, errorMetricModified) is foreseeable here.</font>
+00123 <font class="keywordflow">if</font>(pgeom &lt; <a class="code" href="classNL3D_1_1CTessVertex.html#m4">MaxNearLimit</a>)
+00124 {
+00125 <font class="keywordtype">float</font> f= (CLandscapeGlobals::TileDistFarSqr - sqrDist) * CLandscapeGlobals::OOTileDistDeltaSqr;
+00126 <a class="code" href="namespaceNLMISC.html#a215">clamp</a>(f, 0, 1);
+00127 <font class="comment">// ^4 gives better smooth result</font>
+00128 f= <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(f);
+00129 f= <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(f);
+00130 <font class="comment">// interpolate the errorMetric</font>
+00131 pgeom= <a class="code" href="classNL3D_1_1CTessVertex.html#m4">MaxNearLimit</a>*f + pgeom*(1-f);
+00132 }
+00133 }
+00134
+00135 <font class="comment">// Interpolate StartPos to EndPos, between 1 and 2.</font>
+00136 <font class="keywordflow">if</font>(pgeom&lt;=1.0f)
+00137 <a class="code" href="classNL3D_1_1CTessVertex.html#m0">Pos</a>= <a class="code" href="classNL3D_1_1CTessVertex.html#m1">StartPos</a>;
+00138 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(pgeom&gt;=2.0f)
+00139 <a class="code" href="classNL3D_1_1CTessVertex.html#m0">Pos</a>= <a class="code" href="classNL3D_1_1CTessVertex.html#m2">EndPos</a>;
+00140 <font class="keywordflow">else</font>
+00141 {
+00142 <font class="keywordtype">float</font> f= pgeom - 1.0f;
+00143 <a class="code" href="classNL3D_1_1CTessVertex.html#m0">Pos</a>= f * (<a class="code" href="classNL3D_1_1CTessVertex.html#m2">EndPos</a>-<a class="code" href="classNL3D_1_1CTessVertex.html#m1">StartPos</a>) + <a class="code" href="classNL3D_1_1CTessVertex.html#m1">StartPos</a>;
+00144 }
+00145 }
+00146
+00147
+00148 <font class="comment">// ***************************************************************************</font>
+00149 <font class="comment">// ***************************************************************************</font>
+00150 <font class="comment">// CTessFace</font>
+00151 <font class="comment">// ***************************************************************************</font>
+00152 <font class="comment">// ***************************************************************************</font>
+00153
+00154
+00155 <font class="comment">// ***************************************************************************</font>
+<a name="l00156"></a><a class="code" href="classNL3D_1_1CTessFace.html#r0">00156</a> CTessFace CTessFace::CantMergeFace;
+<a name="l00157"></a><a class="code" href="classNL3D_1_1CTessFace.html#p0">00157</a> CTessFace CTessFace::MultipleBindFace;
+00158
+00159
+00160 <font class="comment">// ***************************************************************************</font>
+<a name="l00161"></a><a class="code" href="classNL3D_1_1CTessFace.html#a0">00161</a> CTessFace::CTessFace()
+00162 {
+00163 <font class="comment">// Don't modify any of it!!</font>
+00164 <font class="comment">// Patch, SonLeft and SonRight nullity are very usefull for MultiplePatch faces, and CantMergeFace.</font>
+00165
+00166 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>= NULL;
+00167 <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>=<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>=<a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>= NULL;
+00168 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>=<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>=<a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>= NULL;
+00169 <a class="code" href="classNL3D_1_1CTessFace.html#z819_7">Father</a>=<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>=<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>= NULL;
+00170 <a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>=0;
+00171 <a class="code" href="classNL3D_1_1CTessFace.html#z821_0">ErrorMetricDate</a>= 0;
+00172 <font class="comment">// Size, Center, paramcoord undetermined.</font>
+00173
+00174 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>= NULL;
+00175 <font class="comment">// Very important (for split reasons). Init Tilefaces to NULL.</font>
+00176 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00177 {
+00178 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]=NULL;
+00179 }
+00180
+00181 <a class="code" href="classNL3D_1_1CTessFace.html#z819_14">RecursMarkCanMerge</a>=<font class="keyword">false</font>;
+00182 <a class="code" href="classNL3D_1_1CTessFace.html#z819_15">RecursMarkForceMerge</a>=<font class="keyword">false</font>;
+00183
+00184
+00185 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a73">ProfNTessFace</a>, 1);
+00186 }
+00187
+00188
+00189 <font class="comment">// ***************************************************************************</font>
+<a name="l00190"></a><a class="code" href="classNL3D_1_1CTessFace.html#a1">00190</a> CTessFace::~CTessFace()
+00191 {
+00192 <font class="comment">// Old Code. This is not sufficient to clear the CTessFace.</font>
+00193 <font class="comment">// Vertices and Uvs must be correctly cleared too (but difficult because of sharing).</font>
+00194 <font class="comment">/*</font>
+00195 <font class="comment"> Patch-&gt;getLandscape()-&gt;deleteTessFace(SonLeft);</font>
+00196 <font class="comment"> Patch-&gt;getLandscape()-&gt;deleteTessFace(SonRight);</font>
+00197 <font class="comment"></font>
+00198 <font class="comment"> // update neighbors.</font>
+00199 <font class="comment"> if(FBase) FBase-&gt;changeNeighbor(this, NULL);</font>
+00200 <font class="comment"> if(FLeft) FLeft-&gt;changeNeighbor(this, NULL);</font>
+00201 <font class="comment"> if(FRight) FRight-&gt;changeNeighbor(this, NULL);</font>
+00202 <font class="comment"></font>
+00203 <font class="comment"> FBase=FLeft=FRight= NULL;</font>
+00204 <font class="comment"> */</font>
+00205
+00206 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a73">ProfNTessFace</a>, -1);
+00207 }
+00208
+00209
+00210 <font class="comment">// ***************************************************************************</font>
+<a name="l00211"></a><a class="code" href="classNL3D_1_1CTessFace.html#a9">00211</a> <font class="keywordtype">float</font> CTessFace::computeNearLimit()
+00212 {
+00213 <font class="comment">// General formula for Level, function of Size, treshold etc...:</font>
+00214 <font class="comment">// WantedLevel= log2(BaseSize / sqrdist / RefineThreshold);</font>
+00215 <font class="comment">// &lt;=&gt; WantedLevel= log2( CurSize*2^Level / sqrdist / RefineThreshold).</font>
+00216 <font class="comment">// &lt;=&gt; WantedLevel= log2( ProjectedSize* 2^Level / RefineThreshold).</font>
+00217 <font class="comment">// &lt;=&gt; 2^WantedLevel= ProjectedSize* 2^Level / RefineThreshold.</font>
+00218 <font class="comment">// &lt;=&gt; ProjectedSize= (2^WantedLevel) * RefineThreshold / (2^Level);</font>
+00219 <font class="comment">// &lt;=&gt; ProjectedSize= (1&lt;&lt;WantedLevel) * RefineThreshold / (1&lt;&lt;Level);</font>
+00220 <font class="comment">// UnOptimised formula: limit= (1&lt;&lt;Patch-&gt;TileLimitLevel) / (1&lt;&lt;Level);</font>
+00221 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&lt;=20);
+00222 <font class="keyword">static</font> <font class="keyword">const</font> uint BigValue= 1&lt;&lt;20;
+00223 <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">float</font> OOBigValue= 1.0f / BigValue;
+00224 <font class="keywordflow">return</font> (1&lt;&lt;<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel) * (OOBigValue*(BigValue&gt;&gt;<a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>));
+00225 }
+00226
+00227
+00228 <font class="comment">// ***************************************************************************</font>
+<a name="l00229"></a><a class="code" href="classNL3D_1_1CTessFace.html#c0">00229</a> <font class="keywordtype">void</font> CTessFace::computeTileErrorMetric()
+00230 {
+00231 <font class="comment">// We must take a more correct errometric here: We must have sons face which have</font>
+00232 <font class="comment">// lower projectedsize than father. This is not the case if Center of face is taken (but when not in</font>
+00233 <font class="comment">// tile mode this is nearly the case). So take the min dist from 3 points.</font>
+00234 <font class="keywordtype">float</font> s0= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter).sqrnorm();
+00235 <font class="keywordtype">float</font> s1= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter).sqrnorm();
+00236 <font class="keywordtype">float</font> s2= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter).sqrnorm();
+00237 <font class="keywordtype">float</font> sqrdist= minof(s0, s1, s2);
+00238 <font class="comment">// It is also VERY important to take the min of 3, to ensure the split in TileMode when Far1 vertex begin</font>
+00239 <font class="comment">// to blend (see Patch::renderFar1() render).</font>
+00240
+00241 <font class="comment">// NB: VertexProgram geomorph take sqrdist= (SplitPoint - RefineCenter).sqrnorm();</font>
+00242 <font class="comment">// It's OK because geomorph will start "far" after the split.</font>
+00243
+00244 <font class="keywordflow">if</font>(sqrdist&lt; CLandscapeGlobals::TileDistFarSqr)
+00245 {
+00246 <font class="keywordtype">float</font> nearLimit;
+00247 nearLimit= CLandscapeGlobals::RefineThreshold * <a class="code" href="classNL3D_1_1CTessFace.html#a9">computeNearLimit</a>();
+00248 <font class="comment">// If we are not so subdivided.</font>
+00249 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>&lt;nearLimit)
+00250 {
+00251 <font class="keywordflow">if</font>(sqrdist&lt; CLandscapeGlobals::TileDistNearSqr)
+00252 {
+00253 <a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>=nearLimit;
+00254 }
+00255 <font class="keywordflow">else</font>
+00256 {
+00257 <font class="comment">// Smooth transition to the nearLimit of tesselation.</font>
+00258 <font class="keywordtype">float</font> f= ( CLandscapeGlobals::TileDistFarSqr - sqrdist ) * CLandscapeGlobals::OOTileDistDeltaSqr;
+00259 <font class="comment">// sqr gives better result, by smoothing more the start of transition.</font>
+00260 f= <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(f);
+00261 f= <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(f);
+00262 <a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a> + (nearLimit-<a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>)*f;
+00263
+00264 <font class="comment">// If threshold is big like 0.5, transition is still hard, and pops occurs. But The goal is </font>
+00265 <font class="comment">// 0.005 and less, so don't bother. </font>
+00266 }
+00267 }
+00268 }
+00269 }
+00270
+00271
+00272 <font class="comment">// ***************************************************************************</font>
+<a name="l00273"></a><a class="code" href="classNL3D_1_1CTessFace.html#a10">00273</a> <font class="keywordtype">void</font> CTessFace::updateErrorMetric()
+00274 {
+00275 <font class="comment">// If already updated for this pass...</font>
+00276 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z821_0">ErrorMetricDate</a>&gt;= CLandscapeGlobals::CurrentDate)
+00277 <font class="keywordflow">return</font>;
+00278
+00279 CVector viewdir= <a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a> - CLandscapeGlobals::RefineCenter;
+00280 <font class="keywordtype">float</font> sqrdist= viewdir.sqrnorm();
+00281
+00282 <font class="comment">// trivial formula.</font>
+00283 <font class="comment">//-----------------</font>
+00284 <a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>/ sqrdist;
+00285
+00286
+00287 <font class="comment">// Hoppe97 formula: k²= a² * ("v-e"² - ((v-e).n)²) / "v-e"^4.</font>
+00288 <font class="comment">//-----------------</font>
+00289 <font class="comment">// Can't do it because geomorph is made on Graphic card, so the simplier is the better.</font>
+00290
+00291
+00292 <font class="comment">// TileMode Impact.</font>
+00293 <font class="comment">//-----------------</font>
+00294 <font class="comment">/* TileMode Impact. We must split at least at TileLimitLevel, but only if the triangle</font>
+00295 <font class="comment"> has a chance to enter in the TileDistFar sphere.</font>
+00296 <font class="comment"> */</font>
+00297 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&lt;<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel &amp;&amp; sqrdist &lt; <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(CLandscapeGlobals::TileDistFar+<a class="code" href="classNL3D_1_1CTessFace.html#z821_4">MaxDistToSplitPoint</a>) )
+00298 {
+00299 <a class="code" href="classNL3D_1_1CTessFace.html#c0">computeTileErrorMetric</a>();
+00300 }
+00301
+00302 <a class="code" href="classNL3D_1_1CTessFace.html#z821_0">ErrorMetricDate</a>= CLandscapeGlobals::CurrentDate;
+00303 }
+00304
+00305
+00306 <font class="comment">// ***************************************************************************</font>
+<a name="l00307"></a><a class="code" href="classNL3D_1_1CTessFace.html#c1">00307</a> <font class="keyword">inline</font> <font class="keywordtype">float</font> CTessFace::computeTileEMForUpdateRefine(<font class="keywordtype">float</font> distSplitPoint, <font class="keywordtype">float</font> distMinFace, <font class="keywordtype">float</font> nearLimit)
+00308 {
+00309 <font class="keywordtype">float</font> ema;
+00310 <font class="comment">// Normal ErrorMetric simulation.</font>
+00311 ema= <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a> / <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(distSplitPoint);
+00312
+00313 <font class="comment">// TileErrorMetric simulation.</font>
+00314 <font class="keywordflow">if</font>(distMinFace &lt; CLandscapeGlobals::TileDistFar)
+00315 {
+00316 <font class="comment">// If we are not so subdivided.</font>
+00317 <font class="keywordflow">if</font>( ema&lt;nearLimit )
+00318 {
+00319 <font class="keywordflow">if</font>( distMinFace&lt; CLandscapeGlobals::TileDistNear)
+00320 {
+00321 ema= nearLimit;
+00322 }
+00323 <font class="keywordflow">else</font>
+00324 {
+00325 <font class="comment">// Smooth transition to the nearLimit of tesselation.</font>
+00326 <font class="keywordtype">float</font> f= ( CLandscapeGlobals::TileDistFarSqr - <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(distMinFace) ) * CLandscapeGlobals::OOTileDistDeltaSqr;
+00327 <font class="comment">// sqr gives better result, by smoothing more the start of transition.</font>
+00328 f= <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(f);
+00329 f= <a class="code" href="namespaceNLMISC.html#a214">sqr</a>(f);
+00330 ema= ema + (nearLimit-ema)*f;
+00331 }
+00332 }
+00333 }
+00334
+00335 <font class="keywordflow">return</font> ema * CLandscapeGlobals::OORefineThreshold;
+00336 }
+00337
+00338
+00339 <font class="comment">// ***************************************************************************</font>
+<a name="l00340"></a><a class="code" href="classNL3D_1_1CTessFace.html#a16">00340</a> <font class="keywordtype">void</font> CTessFace::computeSplitPoint()
+00341 {
+00342 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+00343 {
+00344 <font class="comment">// If it is a rectangular triangle, it will be splitted on the middle of VBase/VLeft.</font>
+00345 <font class="comment">// see splitRectangular() conventions.</font>
+00346 <font class="comment">// So for good geomorph compute per vertex, we must have this SplitPoint on this middle.</font>
+00347 <a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a>= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;EndPos + <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;EndPos)/2;
+00348 }
+00349 <font class="keywordflow">else</font>
+00350 {
+00351 <font class="comment">// If it is a square triangle, it will be splitted on middle of VLeft/VRight. </font>
+00352 <font class="comment">// So for good geomorph compute per vertex, we must have this SplitPoint on this middle.</font>
+00353 <a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a>= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;EndPos + <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;EndPos)/2;
+00354 }
+00355
+00356 <font class="comment">// compute MaxDistToSplitPoint</font>
+00357 <font class="keywordtype">float</font> d0= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;EndPos - <a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a>).sqrnorm();
+00358 <font class="keywordtype">float</font> d1= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;EndPos - <a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a>).sqrnorm();
+00359 <font class="keywordtype">float</font> d2= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;EndPos - <a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a>).sqrnorm();
+00360 <a class="code" href="classNL3D_1_1CTessFace.html#z821_4">MaxDistToSplitPoint</a>= max(d0, d1);
+00361 <a class="code" href="classNL3D_1_1CTessFace.html#z821_4">MaxDistToSplitPoint</a>= max(<a class="code" href="classNL3D_1_1CTessFace.html#z821_4">MaxDistToSplitPoint</a>, d2);
+00362 <font class="comment">// Get the distance.</font>
+00363 <a class="code" href="classNL3D_1_1CTessFace.html#z821_4">MaxDistToSplitPoint</a>= sqrtf(<a class="code" href="classNL3D_1_1CTessFace.html#z821_4">MaxDistToSplitPoint</a>);
+00364 }
+00365
+00366 <font class="comment">// ***************************************************************************</font>
+<a name="l00367"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_0">00367</a> <font class="keywordtype">void</font> CTessFace::allocTileUv(TTileUvId <a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>)
+00368 {
+00369 <font class="comment">// TileFaces must have been build.</font>
+00370 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]);
+00371
+00372 <font class="comment">// what src??</font>
+00373 CTessVertex *vertexSrc;
+00374 <font class="keywordflow">switch</font>(id)
+00375 {
+00376 <font class="keywordflow">case</font> <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>: vertexSrc= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>; <font class="keywordflow">break</font>;
+00377 <font class="keywordflow">case</font> <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>: vertexSrc= <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>; <font class="keywordflow">break</font>;
+00378 <font class="keywordflow">case</font> <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>: vertexSrc= <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>; <font class="keywordflow">break</font>;
+00379 <font class="keywordflow">default</font>: <a class="code" href="debug_8h.html#a12">nlstop</a>;
+00380 };
+00381
+00382 <font class="comment">// Do it for all possible pass</font>
+00383 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00384 {
+00385 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00386 {
+00387 CTessNearVertex *newNear= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessNearVertex();
+00388 newNear-&gt;Src= vertexSrc;
+00389 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>]= newNear;
+00390 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendNearVertexToRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>, newNear);
+00391
+00392 <font class="comment">// May Allocate/Fill VB. Do it after allocTileUv, because UVs are not comuted yet.</font>
+00393 }
+00394 }
+00395 }
+00396
+00397 <font class="comment">// ***************************************************************************</font>
+<a name="l00398"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_4">00398</a> <font class="keywordtype">void</font> CTessFace::checkCreateFillTileVB(TTileUvId <a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>)
+00399 {
+00400 <font class="comment">// TileFaces must have been build.</font>
+00401 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]);
+00402
+00403 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00404 {
+00405 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00406 {
+00407 CTessNearVertex *vertNear;
+00408 vertNear= <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>];
+00409
+00410 <font class="comment">// May Allocate/Fill VB.</font>
+00411 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkCreateVertexVBNear(vertNear);
+00412 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBNear(vertNear);
+00413 }
+00414 }
+00415 }
+00416
+00417
+00418 <font class="comment">// ***************************************************************************</font>
+<a name="l00419"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_5">00419</a> <font class="keywordtype">void</font> CTessFace::checkFillTileVB(TTileUvId <a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>)
+00420 {
+00421 <font class="comment">// TileFaces must have been build.</font>
+00422 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]);
+00423
+00424 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00425 {
+00426 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00427 {
+00428 CTessNearVertex *vertNear;
+00429 vertNear= <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>];
+00430
+00431 <font class="comment">// May Fill VB.</font>
+00432 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBNear(vertNear);
+00433 }
+00434 }
+00435 }
+00436
+00437
+00438 <font class="comment">// ***************************************************************************</font>
+<a name="l00439"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_1">00439</a> <font class="keywordtype">void</font> CTessFace::deleteTileUv(TTileUvId <a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>)
+00440 {
+00441 <font class="comment">// TileFaces must still exist.</font>
+00442 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]);
+00443
+00444 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00445 {
+00446 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00447 {
+00448 CTessNearVertex *oldNear;
+00449 oldNear= <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>];
+00450 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="driver__opengl__extension__def_8h.html#a356">id</a>]=NULL;
+00451
+00452 <font class="comment">// May delete this vertex from VB.</font>
+00453 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkDeleteVertexVBNear(oldNear);
+00454
+00455 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeNearVertexFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>, oldNear);
+00456 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessNearVertex(oldNear);
+00457 }
+00458 }
+00459 }
+00460 <font class="comment">// ***************************************************************************</font>
+<a name="l00461"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_2">00461</a> <font class="keywordtype">void</font> CTessFace::copyTileUv(TTileUvId dstId, CTessFace *srcFace, TTileUvId srcId)
+00462 {
+00463 <font class="comment">// TileFaces must have been build.</font>
+00464 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]);
+00465
+00466 <font class="comment">// Since this a ptr-copy, no need to add/remove the renderlist of near vertices.</font>
+00467
+00468 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00469 {
+00470 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00471 {
+00472 <font class="comment">// The srcface should have the same tileFaces enabled.</font>
+00473 <a class="code" href="debug_8h.html#a6">nlassert</a>(srcFace-&gt;TileFaces[i]);
+00474
+00475 <font class="comment">// copy from src.</font>
+00476 CTessNearVertex *copyNear;
+00477 copyNear= srcFace-&gt;TileFaces[i]-&gt;V[srcId];
+00478
+00479 <font class="comment">// copy to dst.</font>
+00480 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[dstId]= copyNear;
+00481 }
+00482 }
+00483 }
+00484 <font class="comment">// ***************************************************************************</font>
+<a name="l00485"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_3">00485</a> <font class="keywordtype">void</font> CTessFace::heritTileUv(CTessFace *baseFace)
+00486 {
+00487 <font class="comment">// TileFaces must have been build.</font>
+00488 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]);
+00489
+00490 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00491 {
+00492 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00493 {
+00494 <font class="comment">// The baseface should have the same tileFaces enabled.</font>
+00495 <a class="code" href="debug_8h.html#a6">nlassert</a>(baseFace-&gt;TileFaces[i]);
+00496 <font class="comment">// VBase should be allocated.</font>
+00497 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]);
+00498 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]-&gt;initMiddleUv(
+00499 *baseFace-&gt;TileFaces[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>], *baseFace-&gt;TileFaces[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]);
+00500 }
+00501 }
+00502 }
+00503
+00504
+00505 <font class="comment">// ***************************************************************************</font>
+<a name="l00506"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_6">00506</a> <font class="keywordtype">void</font> CTessFace::buildTileFaces()
+00507 {
+00508 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>);
+00509
+00510 <font class="comment">// Do nothgin for lightmap pass, of course.</font>
+00511 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00512 {
+00513 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;Pass[i].PatchRdrPass)
+00514 {
+00515 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTileFace();
+00516 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]= NULL;
+00517 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>]= NULL;
+00518 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]= NULL;
+00519 }
+00520 }
+00521 }
+00522 <font class="comment">// ***************************************************************************</font>
+<a name="l00523"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_7">00523</a> <font class="keywordtype">void</font> CTessFace::deleteTileFaces()
+00524 {
+00525 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>);
+00526
+00527 <font class="comment">// Do nothgin for lightmap pass, of course.</font>
+00528 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00529 {
+00530 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;Pass[i].PatchRdrPass)
+00531 {
+00532 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]);
+00533 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTileFace(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]);
+00534 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]= NULL;
+00535 }
+00536 <font class="keywordflow">else</font>
+00537 {
+00538 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]==NULL);
+00539 }
+00540 }
+00541 }
+00542
+00543 <font class="comment">// ***************************************************************************</font>
+<a name="l00544"></a><a class="code" href="classNL3D_1_1CTessFace.html#z822_8">00544</a> <font class="keywordtype">bool</font> CTessFace::emptyTileFaces()
+00545 {
+00546 <font class="comment">// Do nothgin for lightmap pass, of course.</font>
+00547 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00548 {
+00549 <font class="comment">// Some TileFace exist??</font>
+00550 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00551 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00552 }
+00553
+00554 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+00555 }
+00556
+00557
+00558
+00559 <font class="comment">// ***************************************************************************</font>
+<a name="l00560"></a><a class="code" href="classNL3D_1_1CTessFace.html#c6">00560</a> <font class="keywordtype">void</font> CTessFace::initTileUvRGBA(sint pass, <font class="keywordtype">bool</font> <a class="code" href="driver__opengl__extension__def_8h.html#a420">alpha</a>, CParamCoord pointCoord, CParamCoord middle, CUV &amp;uv)
+00561 {
+00562 <font class="comment">// Get good coordinate according to patch orientation.</font>
+00563 uv.U= pointCoord.S&lt;=middle.S? 0.0f: 1.0f;
+00564 uv.V= pointCoord.T&lt;=middle.T? 0.0f: 1.0f;
+00565
+00566 <font class="comment">// Get Tile Uv info: orientation and scale.</font>
+00567 uint8 orient;
+00568 CVector uvScaleBias;
+00569 <font class="keywordtype">bool</font> is256;
+00570 uint8 uvOff;
+00571 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getTileUvInfo(<a class="code" href="classNL3D_1_1CTessFace.html#z820_1">TileId</a>, pass, <a class="code" href="driver__opengl__extension__def_8h.html#a420">alpha</a>, orient, uvScaleBias, is256, uvOff);
+00572
+00573 <font class="comment">// Orient the UV.</font>
+00574 <font class="keywordtype">float</font> u= uv.U;
+00575 <font class="keywordtype">float</font> <a class="code" href="driver__opengl__extension__def_8h.html#a368">v</a>= uv.V;
+00576 <font class="comment">// Speed rotation.</font>
+00577 <font class="keywordflow">switch</font>(orient)
+00578 {
+00579 <font class="keywordflow">case</font> 0:
+00580 uv.U= u;
+00581 uv.V= <a class="code" href="driver__opengl__extension__def_8h.html#a368">v</a>;
+00582 <font class="keywordflow">break</font>;
+00583 <font class="keywordflow">case</font> 1:
+00584 uv.U= 1-<a class="code" href="driver__opengl__extension__def_8h.html#a368">v</a>;
+00585 uv.V= u;
+00586 <font class="keywordflow">break</font>;
+00587 <font class="keywordflow">case</font> 2:
+00588 uv.U= 1-u;
+00589 uv.V= 1-<a class="code" href="driver__opengl__extension__def_8h.html#a368">v</a>;
+00590 <font class="keywordflow">break</font>;
+00591 <font class="keywordflow">case</font> 3:
+00592 uv.U= <a class="code" href="driver__opengl__extension__def_8h.html#a368">v</a>;
+00593 uv.V= 1-u;
+00594 <font class="keywordflow">break</font>;
+00595 }
+00596
+00597 <font class="comment">// Do the 256x256.</font>
+00598 <font class="keywordflow">if</font>(is256)
+00599 {
+00600 uv*= 0.5;
+00601 <font class="keywordflow">if</font>(uvOff==2 || uvOff==3)
+00602 uv.U+= 0.5;
+00603 <font class="keywordflow">if</font>(uvOff==1 || uvOff==2)
+00604 uv.V+= 0.5;
+00605 }
+00606
+00607
+00608 <font class="comment">// Do the HalfPixel scale bias.</font>
+00609 <font class="keywordtype">float</font> hBiasXY, hBiasZ;
+00610 <font class="keywordflow">if</font>(is256)
+00611 {
+00612 hBiasXY= CLandscapeGlobals::TilePixelBias256;
+00613 hBiasZ = CLandscapeGlobals::TilePixelScale256;
+00614 }
+00615 <font class="keywordflow">else</font>
+00616 {
+00617 hBiasXY= CLandscapeGlobals::TilePixelBias128;
+00618 hBiasZ = CLandscapeGlobals::TilePixelScale128;
+00619 }
+00620
+00621
+00622 <font class="comment">// Scale the UV.</font>
+00623 uv.U*= uvScaleBias.z*hBiasZ;
+00624 uv.V*= uvScaleBias.z*hBiasZ;
+00625 uv.U+= uvScaleBias.x+hBiasXY;
+00626 uv.V+= uvScaleBias.y+hBiasXY;
+00627 }
+00628
+00629
+00630 <font class="comment">// ***************************************************************************</font>
+<a name="l00631"></a><a class="code" href="classNL3D_1_1CTessFace.html#c7">00631</a> <font class="keywordtype">void</font> CTessFace::initTileUvLightmap(CParamCoord pointCoord, CParamCoord middle, CUV &amp;uv)
+00632 {
+00633 <font class="comment">// Get good coordinate according to patch orientation.</font>
+00634 uv.U= pointCoord.S&lt;=middle.S? 0.0f: 1.0f;
+00635 uv.V= pointCoord.T&lt;=middle.T? 0.0f: 1.0f;
+00636
+00637 <font class="comment">// Get Tile Lightmap Uv info: bias and scale.</font>
+00638 CVector uvScaleBias;
+00639 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getTileLightMapUvInfo(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;TileS, <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;TileT, uvScaleBias);
+00640
+00641 <font class="comment">// Scale the UV.</font>
+00642 uv.U*= uvScaleBias.z;
+00643 uv.V*= uvScaleBias.z;
+00644 uv.U+= uvScaleBias.x;
+00645 uv.V+= uvScaleBias.y;
+00646 }
+00647
+00648
+00649 <font class="comment">// ***************************************************************************</font>
+<a name="l00650"></a><a class="code" href="classNL3D_1_1CTessFace.html#c8">00650</a> <font class="keywordtype">void</font> CTessFace::initTileUvDLM(CParamCoord pointCoord, CUV &amp;uv)
+00651 {
+00652 <font class="comment">// get the dlm context from the patch.</font>
+00653 CPatchDLMContext *dlmCtx= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;_DLMContext;
+00654 <font class="comment">// mmust exist at creation of the tile.</font>
+00655 <a class="code" href="debug_8h.html#a6">nlassert</a>(dlmCtx);
+00656
+00657 <font class="comment">// get coord in 0..1 range, along the patch.</font>
+00658 uv.U= pointCoord.getS();
+00659 uv.V= pointCoord.getT();
+00660
+00661 <font class="comment">// ScaleBias according to the context.</font>
+00662 uv.U*= dlmCtx-&gt;DLMUScale;
+00663 uv.V*= dlmCtx-&gt;DLMVScale;
+00664 uv.U+= dlmCtx-&gt;DLMUBias;
+00665 uv.V+= dlmCtx-&gt;DLMVBias;
+00666 }
+00667
+00668
+00669 <font class="comment">// ***************************************************************************</font>
+<a name="l00670"></a><a class="code" href="classNL3D_1_1CTessFace.html#a7">00670</a> <font class="keywordtype">void</font> CTessFace::computeTileMaterial()
+00671 {
+00672 <font class="comment">// 0. Compute TileId.</font>
+00673 <font class="comment">//-------------------</font>
+00674 <font class="comment">// Square Order Patch assumption: assume that when a CTessFace become a tile, his base can ONLY be diagonal...</font>
+00675 <font class="comment">/* a Patch:</font>
+00676 <font class="comment"> A ________</font>
+00677 <font class="comment"> |\ /|</font>
+00678 <font class="comment"> | \ / |</font>
+00679 <font class="comment"> C|__\B_/ |</font>
+00680 <font class="comment"> | / \ |</font>
+00681 <font class="comment"> | / \ |</font>
+00682 <font class="comment"> |/______\|</font>
+00683 <font class="comment"></font>
+00684 <font class="comment"> Here, if OrderS*OrderT=2*2, ABC is a new CTessFace of a Tile, and AB is the diagonal of the tile.</font>
+00685 <font class="comment"> Hence the middle of the tile is the middle of AB.</font>
+00686 <font class="comment"></font>
+00687 <font class="comment"> C must be created, but A and B may be created or copied from neighbor.</font>
+00688 <font class="comment"> */</font>
+00689 CParamCoord middle(<a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>,<a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>);
+00690 sint ts= ((sint)middle.S * (sint)<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;OrderS) / 0x8000;
+00691 sint tt= ((sint)middle.T * (sint)<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;OrderT) / 0x8000;
+00692 <a class="code" href="classNL3D_1_1CTessFace.html#z820_1">TileId</a>= tt*<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;OrderS + ts;
+00693
+00694
+00695 <font class="comment">// 1. Compute Tile Material.</font>
+00696 <font class="comment">//--------------------------</font>
+00697 <font class="comment">// if base neighbor is already at TileLimitLevel just ptr-copy, else create the TileMaterial...</font>
+00698 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a> || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Level&lt;=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel);
+00699 <font class="keywordtype">bool</font> copyFromBase;
+00700 copyFromBase= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch==<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>);
+00701 copyFromBase= copyFromBase &amp;&amp; (<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Level==<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;TileMaterial!=NULL);
+00702 <font class="comment">// NB: because of delete/recreateTileUvs(), FBase-&gt;TileMaterial may be NULL, even if face is at good TileLimitLevel.</font>
+00703 <font class="keywordflow">if</font>(copyFromBase)
+00704 {
+00705 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;TileMaterial;
+00706 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;TileId== <a class="code" href="classNL3D_1_1CTessFace.html#z820_1">TileId</a>);
+00707 }
+00708 <font class="keywordflow">else</font>
+00709 {
+00710 sint i;
+00711 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTileMaterial();
+00712 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;TileS= ts;
+00713 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;TileT= tt;
+00714
+00715 <font class="comment">// Add this new material to the render list.</font>
+00716 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendTileMaterialToRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>);
+00717
+00718 <font class="comment">// First, get a lightmap for this tile. NB: important to do this after appendTileMaterialToRenderList(), </font>
+00719 <font class="comment">// because use TessBlocks.</font>
+00720 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getTileLightMap(ts, tt, <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;Pass[<a class="code" href="landscape__def_8h.html#a6">NL3D_TILE_PASS_LIGHTMAP</a>].PatchRdrPass);
+00721
+00722 <font class="comment">// Fill pass of multi pass material.</font>
+00723 <font class="keywordflow">for</font>(i=0;i&lt;<a class="code" href="landscape__def_8h.html#a0">NL3D_MAX_TILE_PASS</a>;i++)
+00724 {
+00725 <font class="comment">// Get the correct render pass, according to the tile number, and the pass.</font>
+00726 <font class="keywordflow">if</font>(i!=<a class="code" href="landscape__def_8h.html#a6">NL3D_TILE_PASS_LIGHTMAP</a>)
+00727 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;Pass[i].PatchRdrPass= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getTileRenderPass(<a class="code" href="classNL3D_1_1CTessFace.html#z820_1">TileId</a>, i);
+00728 }
+00729
+00730 <font class="comment">// Fill Pass Info.</font>
+00731 <font class="keywordflow">for</font>(i=0;i&lt;<a class="code" href="landscape__def_8h.html#a0">NL3D_MAX_TILE_PASS</a>;i++)
+00732 {
+00733 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;Pass[i].TileMaterial= <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>;
+00734 }
+00735
+00736 <font class="comment">// Do not append this tile to each RenderPass, done in preRender().</font>
+00737 }
+00738
+00739
+00740 <font class="comment">// 2. Compute Uvs.</font>
+00741 <font class="comment">//----------------</font>
+00742 <font class="comment">// NB: TileMaterial is already setup. Usefull for initTileUvLightmap() and initTileUvRGBA().</font>
+00743
+00744 <font class="comment">// First, must create The TileFaces, according to the TileMaterial passes.</font>
+00745 <a class="code" href="classNL3D_1_1CTessFace.html#z822_6">buildTileFaces</a>();
+00746
+00747 <font class="comment">// Must allocate the Base, and insert into list.</font>
+00748 <a class="code" href="classNL3D_1_1CTessFace.html#z822_0">allocTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+00749
+00750
+00751 <font class="comment">// Init LightMap UV, in RGB0 pass, UV1..</font>
+00752 <a class="code" href="classNL3D_1_1CTessFace.html#c7">initTileUvLightmap</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]-&gt;PUv1);
+00753 <font class="comment">// Init DLM Uv, in RGB0 pass, UV2.</font>
+00754 <a class="code" href="classNL3D_1_1CTessFace.html#c8">initTileUvDLM</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]-&gt;PUv2);
+00755
+00756 <font class="comment">// Init UV RGBA, for all pass (but lightmap).</font>
+00757 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00758 {
+00759 <a class="code" href="debug_8h.html#a6">nlassert</a>(i!=<a class="code" href="landscape__def_8h.html#a6">NL3D_TILE_PASS_LIGHTMAP</a>);
+00760 <font class="comment">// If pass is valid</font>
+00761 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;Pass[i].PatchRdrPass)
+00762 {
+00763 <font class="comment">// Face must exist.</font>
+00764 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]);
+00765 <font class="comment">// Compute RGB UV in UV0.</font>
+00766 <a class="code" href="classNL3D_1_1CTessFace.html#c6">initTileUvRGBA</a>(i, <font class="keyword">false</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]-&gt;PUv0);
+00767 <font class="comment">// If transition tile, compute alpha UV in UV1. </font>
+00768 <font class="comment">// Do it also for Additive, because may have Transition</font>
+00769 <font class="keywordflow">if</font>(i== <a class="code" href="landscape__def_8h.html#a3">NL3D_TILE_PASS_RGB1</a> || i==<a class="code" href="landscape__def_8h.html#a4">NL3D_TILE_PASS_RGB2</a> || i==<a class="code" href="landscape__def_8h.html#a5">NL3D_TILE_PASS_ADD</a>)
+00770 <a class="code" href="classNL3D_1_1CTessFace.html#c6">initTileUvRGBA</a>(i, <font class="keyword">true</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]-&gt;PUv1);
+00771 }
+00772 }
+00773
+00774 <font class="comment">// UVs are computed, may create and fill VB.</font>
+00775 <a class="code" href="classNL3D_1_1CTessFace.html#z822_4">checkCreateFillTileVB</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+00776
+00777
+00778 <font class="comment">// if base neighbor is already at TileLimitLevel just ptr-copy, else create the left/right TileUvs...</font>
+00779 <font class="keywordflow">if</font>(copyFromBase)
+00780 {
+00781 <font class="comment">// Just cross-copy the pointers.</font>
+00782 <font class="comment">// Make Left near vertices be the Right vertices of FBase</font>
+00783 <a class="code" href="classNL3D_1_1CTessFace.html#z822_2">copyTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>);
+00784 <font class="comment">// Make Right near vertices be the Left vertices of FBase</font>
+00785 <a class="code" href="classNL3D_1_1CTessFace.html#z822_2">copyTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>);
+00786 }
+00787 <font class="keywordflow">else</font>
+00788 {
+00789 <font class="comment">// Must allocate the left/right uv (and insert into list).</font>
+00790 <a class="code" href="classNL3D_1_1CTessFace.html#z822_0">allocTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>);
+00791 <a class="code" href="classNL3D_1_1CTessFace.html#z822_0">allocTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>);
+00792
+00793
+00794 <font class="comment">// Init LightMap UV, in UvPass 0, UV1..</font>
+00795 <a class="code" href="classNL3D_1_1CTessFace.html#c7">initTileUvLightmap</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>]-&gt;PUv1);
+00796 <a class="code" href="classNL3D_1_1CTessFace.html#c7">initTileUvLightmap</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]-&gt;PUv1);
+00797 <font class="comment">// Init DLM Uv, in RGB0 pass, UV2.</font>
+00798 <a class="code" href="classNL3D_1_1CTessFace.html#c8">initTileUvDLM</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>]-&gt;PUv2);
+00799 <a class="code" href="classNL3D_1_1CTessFace.html#c8">initTileUvDLM</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[<a class="code" href="landscape__def_8h.html#a2">NL3D_TILE_PASS_RGB0</a>]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]-&gt;PUv2);
+00800
+00801 <font class="comment">// Init UV RGBA!</font>
+00802 <font class="keywordflow">for</font>(sint i=0;i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>;i++)
+00803 {
+00804 <a class="code" href="debug_8h.html#a6">nlassert</a>(i!=<a class="code" href="landscape__def_8h.html#a6">NL3D_TILE_PASS_LIGHTMAP</a>);
+00805 <font class="comment">// If pass is valid</font>
+00806 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;Pass[i].PatchRdrPass)
+00807 {
+00808 <font class="comment">// Face must exist.</font>
+00809 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]);
+00810 <font class="comment">// Compute RGB UV in UV0.</font>
+00811 <a class="code" href="classNL3D_1_1CTessFace.html#c6">initTileUvRGBA</a>(i, <font class="keyword">false</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>]-&gt;PUv0);
+00812 <a class="code" href="classNL3D_1_1CTessFace.html#c6">initTileUvRGBA</a>(i, <font class="keyword">false</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]-&gt;PUv0);
+00813 <font class="comment">// If transition tile, compute alpha UV in UV1.</font>
+00814 <font class="comment">// Do it also for Additive, because may have Transition</font>
+00815 <font class="keywordflow">if</font>(i== <a class="code" href="landscape__def_8h.html#a3">NL3D_TILE_PASS_RGB1</a> || i==<a class="code" href="landscape__def_8h.html#a4">NL3D_TILE_PASS_RGB2</a> || i==<a class="code" href="landscape__def_8h.html#a5">NL3D_TILE_PASS_ADD</a>)
+00816 {
+00817 <a class="code" href="classNL3D_1_1CTessFace.html#c6">initTileUvRGBA</a>(i, <font class="keyword">true</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>]-&gt;PUv1);
+00818 <a class="code" href="classNL3D_1_1CTessFace.html#c6">initTileUvRGBA</a>(i, <font class="keyword">true</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>, middle, <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]-&gt;PUv1);
+00819 }
+00820 }
+00821 }
+00822
+00823 <font class="comment">// UVs are computed, may create and fill VB.</font>
+00824 <a class="code" href="classNL3D_1_1CTessFace.html#z822_4">checkCreateFillTileVB</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>);
+00825 <a class="code" href="classNL3D_1_1CTessFace.html#z822_4">checkCreateFillTileVB</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>);
+00826 }
+00827
+00828 }
+00829 <font class="comment">// ***************************************************************************</font>
+<a name="l00830"></a><a class="code" href="classNL3D_1_1CTessFace.html#a8">00830</a> <font class="keywordtype">void</font> CTessFace::releaseTileMaterial()
+00831 {
+00832 <font class="comment">// Hence, must release the tile. TileUvBase is differnet for each of leaves.</font>
+00833 <a class="code" href="classNL3D_1_1CTessFace.html#z822_1">deleteTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+00834
+00835 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Level&lt;=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel);
+00836 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Level==<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;TileMaterial!=NULL)
+00837 {
+00838 <font class="comment">// Do not release Uvs, since neighbor need it...</font>
+00839 <font class="comment">// But release faces.</font>
+00840 <a class="code" href="classNL3D_1_1CTessFace.html#z822_7">deleteTileFaces</a>();
+00841 <font class="comment">// Do not release TileMaterial, since neighbor need it...</font>
+00842 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>= NULL;
+00843 }
+00844 <font class="keywordflow">else</font>
+00845 {
+00846 <font class="comment">// release Uvs.</font>
+00847 <a class="code" href="classNL3D_1_1CTessFace.html#z822_1">deleteTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>);
+00848 <a class="code" href="classNL3D_1_1CTessFace.html#z822_1">deleteTileUv</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>);
+00849
+00850 <font class="comment">// After, release Tile faces.</font>
+00851 <a class="code" href="classNL3D_1_1CTessFace.html#z822_7">deleteTileFaces</a>();
+00852
+00853 <font class="comment">// Release the tile lightmap part. Do it before removeTileMaterialFromRenderList().</font>
+00854 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;releaseTileLightMap(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;TileS, <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>-&gt;TileT);
+00855
+00856 <font class="comment">// Remove this material from the render list. DO it before deletion of course :).</font>
+00857 <font class="comment">// NB: TileS/TileT still valid.</font>
+00858 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeTileMaterialFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>);
+00859
+00860 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTileMaterial(<a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>);
+00861 <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>= NULL;
+00862 }
+00863 }
+00864
+00865
+00866
+00867 <font class="comment">// ***************************************************************************</font>
+<a name="l00868"></a><a class="code" href="classNL3D_1_1CTessFace.html#c9">00868</a> <font class="keywordtype">void</font> CTessFace::updateNearFarVertices()
+00869 {
+00870 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#m0">FVBase</a>);
+00871 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#m1">FVLeft</a>);
+00872 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#m2">FVRight</a>);
+00873
+00874 <a class="code" href="classNL3D_1_1CTessFace.html#m0">FVBase</a>-&gt;Src= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>;
+00875 <a class="code" href="classNL3D_1_1CTessFace.html#m1">FVLeft</a>-&gt;Src= <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>;
+00876 <a class="code" href="classNL3D_1_1CTessFace.html#m2">FVRight</a>-&gt;Src= <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>;
+00877 <a class="code" href="classNL3D_1_1CTessFace.html#m0">FVBase</a>-&gt;PCoord= <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>;
+00878 <a class="code" href="classNL3D_1_1CTessFace.html#m1">FVLeft</a>-&gt;PCoord= <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>;
+00879 <a class="code" href="classNL3D_1_1CTessFace.html#m2">FVRight</a>-&gt;PCoord= <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>;
+00880
+00881 <font class="comment">// Update VB for far vertices (if needed)</font>
+00882 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBFar(<a class="code" href="classNL3D_1_1CTessFace.html#m0">FVBase</a>);
+00883 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBFar(<a class="code" href="classNL3D_1_1CTessFace.html#m1">FVLeft</a>);
+00884 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBFar(<a class="code" href="classNL3D_1_1CTessFace.html#m2">FVRight</a>);
+00885
+00886 <font class="comment">// Near Vertices update (Src only).</font>
+00887 <font class="keywordflow">for</font>(sint i=0; i&lt;<a class="code" href="landscape__def_8h.html#a1">NL3D_MAX_TILE_FACE</a>; i++)
+00888 {
+00889 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i])
+00890 {
+00891 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]-&gt;Src= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>;
+00892 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>]-&gt;Src= <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>;
+00893 <a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]-&gt;Src= <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>;
+00894
+00895 <font class="comment">// Update VB for near vertices (if needed)</font>
+00896 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBNear(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>]);
+00897 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBNear(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>]);
+00898 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBNear(<a class="code" href="classNL3D_1_1CTessFace.html#z820_3">TileFaces</a>[i]-&gt;V[<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>]);
+00899 }
+00900 }
+00901
+00902 }
+00903
+00904
+00905 <font class="comment">// ***************************************************************************</font>
+<a name="l00906"></a><a class="code" href="classNL3D_1_1CTessFace.html#c3">00906</a> <font class="keywordtype">void</font> CTessFace::splitRectangular(<font class="keywordtype">bool</font> propagateSplit)
+00907 {
+00908 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f0= <font class="keyword">this</font>;
+00909 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f1= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>;
+00910 <font class="comment">// Rectangular case: FBase must exist.</font>
+00911 <a class="code" href="debug_8h.html#a6">nlassert</a>(f1);
+00912
+00913 <font class="comment">// In rectangular case, we split at the same time this and FBase (f0 and f1).</font>
+00914
+00915
+00916 <font class="comment">/*</font>
+00917 <font class="comment"> Tesselation is:</font>
+00918 <font class="comment"> </font>
+00919 <font class="comment"> lt rt lt top rt</font>
+00920 <font class="comment"> --------------------- ---------------------</font>
+00921 <font class="comment"> |---- | |\ |\ |</font>
+00922 <font class="comment"> | ---- f1 | | \ f1l | \ f1r |</font>
+00923 <font class="comment"> | ---- | --&gt; | \ | \ |</font>
+00924 <font class="comment"> | f0 ---- | | f0r \ | f0l \ |</font>
+00925 <font class="comment"> | ---| | \| \|</font>
+00926 <font class="comment"> --------------------- ---------------------</font>
+00927 <font class="comment"> lb rb lb bot rb</font>
+00928 <font class="comment"></font>
+00929 <font class="comment"> Why? For symetry and bind/split reasons: FBase-&gt;SonLeft-&gt;VBase is always the good vertex to take </font>
+00930 <font class="comment"> (see vertex binding).</font>
+00931 <font class="comment"> */</font>
+00932 CParamCoord pclt= f1-&gt;PVLeft;
+00933 CParamCoord pclb= f0-&gt;PVBase;
+00934 CParamCoord pcrt= f1-&gt;PVBase;
+00935 CParamCoord pcrb= f1-&gt;PVRight;
+00936 CTessVertex *vlt= f1-&gt;VLeft;
+00937 CTessVertex *vlb= f0-&gt;VBase;
+00938 CTessVertex *vrt= f1-&gt;VBase;
+00939 CTessVertex *vrb= f1-&gt;VRight;
+00940
+00941 CTessFarVertex *farvlt= f1-&gt;FVLeft;
+00942 CTessFarVertex *farvlb= f0-&gt;FVBase;
+00943 CTessFarVertex *farvrt= f1-&gt;FVBase;
+00944 CTessFarVertex *farvrb= f1-&gt;FVRight;
+00945
+00946
+00947 <font class="comment">// 1. create new vertices.</font>
+00948 <font class="comment">//------------------------</font>
+00949
+00950 <font class="comment">// Create splitted vertices.</font>
+00951 CParamCoord pctop(f1-&gt;PVBase, f1-&gt;PVLeft);
+00952 CParamCoord pcbot(f0-&gt;PVBase, f0-&gt;PVLeft);
+00953 CTessVertex *vtop= NULL;
+00954 CTessVertex *vbot= NULL;
+00955 <font class="comment">// Compute top.</font>
+00956 <font class="keywordflow">if</font>(f1-&gt;FLeft==NULL || f1-&gt;FLeft-&gt;isLeaf())
+00957 {
+00958 <font class="comment">// The base neighbor is a leaf or NULL. So must create the new vertex.</font>
+00959 vtop= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessVertex();
+00960
+00961 <font class="comment">// Compute pos.</font>
+00962 vtop-&gt;StartPos= (f1-&gt;VLeft-&gt;EndPos + f1-&gt;VBase-&gt;EndPos)/2;
+00963 vtop-&gt;EndPos= f1-&gt;Patch-&gt;computeVertex(pctop.getS(), pctop.getT());
+00964 <font class="comment">// Init Pos= InitialPos. Important in the case of enforced split.</font>
+00965 vtop-&gt;Pos= vtop-&gt;StartPos;
+00966
+00967 <font class="comment">// For geomorph (VertexProgram or soft), compute MaxFaceSize and MaxNearLimit.</font>
+00968 vtop-&gt;MaxFaceSize= f1-&gt;Size;
+00969 vtop-&gt;MaxNearLimit= f1-&gt;computeNearLimit();
+00970 }
+00971 <font class="keywordflow">else</font>
+00972 {
+00973 <font class="comment">// Else, get from neighbor.</font>
+00974 <font class="comment">// NB: since *FLeft is not a leaf, FBase-&gt;SonLeft!=NULL...</font>
+00975 <font class="comment">// NB: this work with both rectangular and square triangles.</font>
+00976 vtop= f1-&gt;FLeft-&gt;SonLeft-&gt;VBase;
+00977
+00978 <font class="comment">// For geomorph (VertexProgram or soft), compute MaxFaceSize and MaxNearLimit.</font>
+00979 vtop-&gt;MaxFaceSize= max( vtop-&gt;MaxFaceSize, f1-&gt;Size);
+00980 vtop-&gt;MaxNearLimit= max( vtop-&gt;MaxNearLimit, f1-&gt;computeNearLimit());
+00981 }
+00982 <font class="comment">// Compute bot.</font>
+00983 <font class="keywordflow">if</font>(f0-&gt;FLeft==NULL || f0-&gt;FLeft-&gt;isLeaf())
+00984 {
+00985 <font class="comment">// The base neighbor is a leaf or NULL. So must create the new vertex.</font>
+00986 vbot= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessVertex();
+00987
+00988 <font class="comment">// Compute pos.</font>
+00989 vbot-&gt;StartPos= (f0-&gt;VLeft-&gt;EndPos + f0-&gt;VBase-&gt;EndPos)/2;
+00990 vbot-&gt;EndPos= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;computeVertex(pcbot.getS(), pcbot.getT());
+00991 <font class="comment">// Init Pos= InitialPos. Important in the case of enforced split.</font>
+00992 vbot-&gt;Pos= vbot-&gt;StartPos;
+00993
+00994 <font class="comment">// For geomorph (VertexProgram or soft), compute MaxFaceSize and MaxNearLimit.</font>
+00995 vbot-&gt;MaxFaceSize= f0-&gt;Size;
+00996 vbot-&gt;MaxNearLimit= f0-&gt;computeNearLimit();
+00997 }
+00998 <font class="keywordflow">else</font>
+00999 {
+01000 <font class="comment">// Else, get from neighbor.</font>
+01001 <font class="comment">// NB: since *FLeft is not a leaf, FBase-&gt;SonLeft!=NULL...</font>
+01002 <font class="comment">// NB: this work with both rectangular and square triangles.</font>
+01003 vbot= f0-&gt;FLeft-&gt;SonLeft-&gt;VBase;
+01004
+01005 <font class="comment">// For geomorph (VertexProgram or soft), compute MaxFaceSize and MaxNearLimit.</font>
+01006 vbot-&gt;MaxFaceSize= max( vbot-&gt;MaxFaceSize, f0-&gt;Size);
+01007 vbot-&gt;MaxNearLimit= max( vbot-&gt;MaxNearLimit, f0-&gt;computeNearLimit());
+01008 }
+01009
+01010 <font class="comment">// In all case, must create new FarVertices, since rect split occurs on border!!</font>
+01011 CTessFarVertex *farvtop= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFarVertex();
+01012 CTessFarVertex *farvbot= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFarVertex();
+01013 farvtop-&gt;Src= vtop;
+01014 farvbot-&gt;Src= vbot;
+01015 farvtop-&gt;PCoord= pctop;
+01016 farvbot-&gt;PCoord= pcbot;
+01017 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFarVertexToRenderList(farvtop);
+01018 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFarVertexToRenderList(farvbot);
+01019 <font class="comment">// May Allocate/Fill VB.</font>
+01020 <font class="comment">// NB: vtop / vbot are well computed and ready for the fill in VB.</font>
+01021 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkCreateVertexVBFar(farvtop);
+01022 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBFar(farvtop);
+01023 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkCreateVertexVBFar(farvbot);
+01024 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBFar(farvbot);
+01025
+01026 <font class="comment">// For VertexProgram only, must refill the Far vertex of neighbor(s), </font>
+01027 <font class="comment">// because MaxFaceSize, and MaxNearLimit may have change.</font>
+01028 <font class="keywordflow">if</font>( CLandscapeGlobals::VertexProgramEnabled )
+01029 {
+01030 <font class="comment">// f0</font>
+01031 <font class="keywordflow">if</font>( ! (f0-&gt;FLeft==NULL || f0-&gt;FLeft-&gt;isLeaf()) )
+01032 f0-&gt;FLeft-&gt;Patch-&gt;checkFillVertexVBFar(f0-&gt;FLeft-&gt;SonLeft-&gt;FVBase);
+01033 <font class="comment">// f1</font>
+01034 <font class="keywordflow">if</font>( ! (f1-&gt;FLeft==NULL || f1-&gt;FLeft-&gt;isLeaf()) )
+01035 f1-&gt;FLeft-&gt;Patch-&gt;checkFillVertexVBFar(f1-&gt;FLeft-&gt;SonLeft-&gt;FVBase);
+01036 }
+01037
+01038
+01039 <font class="comment">// 2. Create sons, and update links.</font>
+01040 <font class="comment">//----------------------------------</font>
+01041
+01042 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f0l, *f0r;
+01043 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f1l, *f1r;
+01044
+01045 <font class="comment">// create and bind Sons.</font>
+01046 f0l= f0-&gt;SonLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFace();
+01047 f0r= f0-&gt;SonRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFace();
+01048 f1l= f1-&gt;SonLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFace();
+01049 f1r= f1-&gt;SonRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFace();
+01050
+01051 <font class="comment">// subdivision left.</font>
+01052 f0l-&gt;Patch= f0-&gt;Patch;
+01053 f0l-&gt;Father= f0;
+01054 f0l-&gt;Level= f0-&gt;Level+1;
+01055 f0l-&gt;Size= f0-&gt;Size*0.5f;
+01056 <font class="comment">// subdivision right.</font>
+01057 f0r-&gt;Patch= f0-&gt;Patch;
+01058 f0r-&gt;Father= f0;
+01059 f0r-&gt;Level= f0-&gt;Level+1;
+01060 f0r-&gt;Size= f0-&gt;Size*0.5f;
+01061 <font class="comment">// subdivision left.</font>
+01062 f1l-&gt;Patch= f1-&gt;Patch;
+01063 f1l-&gt;Father= f1;
+01064 f1l-&gt;Level= f1-&gt;Level+1;
+01065 f1l-&gt;Size= f1-&gt;Size*0.5f;
+01066 <font class="comment">// subdivision right.</font>
+01067 f1r-&gt;Patch= f1-&gt;Patch;
+01068 f1r-&gt;Father= f1;
+01069 f1r-&gt;Level= f1-&gt;Level+1;
+01070 f1r-&gt;Size= f1-&gt;Size*0.5f;
+01071
+01072 <font class="comment">// Patch coordinates.</font>
+01073 f0r-&gt;PVRight= pclt;
+01074 f0r-&gt;PVBase= pclb;
+01075 f0r-&gt;PVLeft= pcbot;
+01076 f1l-&gt;PVBase= pctop;
+01077 f1l-&gt;PVLeft= f0r-&gt;PVRight;
+01078 f1l-&gt;PVRight= f0r-&gt;PVLeft;
+01079
+01080 f0l-&gt;PVRight= pctop;
+01081 f0l-&gt;PVBase= pcbot;
+01082 f0l-&gt;PVLeft= pcrb;
+01083 f1r-&gt;PVBase= pcrt;
+01084 f1r-&gt;PVLeft= f0l-&gt;PVRight;
+01085 f1r-&gt;PVRight= f0l-&gt;PVLeft;
+01086
+01087 <font class="comment">// link existing vertex.</font>
+01088 f0r-&gt;VRight= vlt;
+01089 f0r-&gt;VBase= vlb;
+01090 f0r-&gt;VLeft= vbot;
+01091 f1l-&gt;VBase= vtop;
+01092 f1l-&gt;VLeft= f0r-&gt;VRight;
+01093 f1l-&gt;VRight= f0r-&gt;VLeft;
+01094
+01095 f0l-&gt;VRight= vtop;
+01096 f0l-&gt;VBase= vbot;
+01097 f0l-&gt;VLeft= vrb;
+01098 f1r-&gt;VBase= vrt;
+01099 f1r-&gt;VLeft= f0l-&gt;VRight;
+01100 f1r-&gt;VRight= f0l-&gt;VLeft;
+01101
+01102 <font class="comment">// link Far vertices.</font>
+01103 f0r-&gt;FVRight= farvlt;
+01104 f0r-&gt;FVBase= farvlb;
+01105 f0r-&gt;FVLeft= farvbot;
+01106 f1l-&gt;FVBase= farvtop;
+01107 f1l-&gt;FVLeft= f0r-&gt;FVRight;
+01108 f1l-&gt;FVRight= f0r-&gt;FVLeft;
+01109
+01110 f0l-&gt;FVRight= farvtop;
+01111 f0l-&gt;FVBase= farvbot;
+01112 f0l-&gt;FVLeft= farvrb;
+01113 f1r-&gt;FVBase= farvrt;
+01114 f1r-&gt;FVLeft= f0l-&gt;FVRight;
+01115 f1r-&gt;FVRight= f0l-&gt;FVLeft;
+01116
+01117 <font class="comment">// link neigbhor faces.</font>
+01118 f0r-&gt;FBase= f1l;
+01119 f1l-&gt;FBase= f0r;
+01120 f0l-&gt;FBase= f1r;
+01121 f1r-&gt;FBase= f0l;
+01122 f1l-&gt;FRight= f0l;
+01123 f0l-&gt;FRight= f1l;
+01124 f0r-&gt;FRight= f0-&gt;FRight;
+01125 <font class="keywordflow">if</font>(f0-&gt;FRight)
+01126 f0-&gt;FRight-&gt;changeNeighbor(f0, f0r);
+01127 f1r-&gt;FRight= f1-&gt;FRight;
+01128 <font class="keywordflow">if</font>(f1-&gt;FRight)
+01129 f1-&gt;FRight-&gt;changeNeighbor(f1, f1r);
+01130 <font class="comment">// 4 links (all FLeft sons ) are stil invalid here.</font>
+01131 f0l-&gt;FLeft= NULL;
+01132 f0r-&gt;FLeft= NULL;
+01133 f1l-&gt;FLeft= NULL;
+01134 f1r-&gt;FLeft= NULL;
+01135
+01136 <font class="comment">// Neigbors pointers of undetermined splitted face are not changed. Must Doesn't change this. </font>
+01137 <font class="comment">// Used and Updated in section 5. ...</font>
+01138
+01139
+01140 <font class="comment">// 3. Update Tile infos.</font>
+01141 <font class="comment">//----------------------</font>
+01142 <font class="comment">// There is no update tileinfo with rectangular patch, since tiles are always squares. (TileLimitLevel&gt;SquareLimitLevel).</font>
+01143
+01144 <font class="comment">// NB: but must test update of tile info for neighboring, ie 2 faces around the splits.</font>
+01145 <font class="comment">// For Vertex program only</font>
+01146 <font class="keywordflow">if</font>( CLandscapeGlobals::VertexProgramEnabled )
+01147 {
+01148 <font class="comment">// if neighbor face splitted, and if 2 different patchs, we must update the Tile vertices</font>
+01149 <font class="comment">// because MaxFaceSize and MaxNearLimit may have changed.</font>
+01150 <font class="keywordflow">if</font>( f0-&gt;FLeft!=NULL &amp;&amp; !f0-&gt;FLeft-&gt;isLeaf() &amp;&amp; f0-&gt;FLeft-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a> )
+01151 {
+01152 <font class="comment">// If neighbors sons at tile level, must update their Tile vertices.</font>
+01153 <font class="keywordflow">if</font>( f0-&gt;FLeft-&gt;SonLeft-&gt;Level &gt;= f0-&gt;FLeft-&gt;Patch-&gt;TileLimitLevel )
+01154 {
+01155 f0-&gt;FLeft-&gt;SonLeft-&gt;checkFillTileVB(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+01156 f0-&gt;FLeft-&gt;SonRight-&gt;checkFillTileVB(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+01157 }
+01158 }
+01159 <font class="comment">// idem for f1.</font>
+01160 <font class="keywordflow">if</font>( f1-&gt;FLeft!=NULL &amp;&amp; !f1-&gt;FLeft-&gt;isLeaf() &amp;&amp; f1-&gt;FLeft-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a> )
+01161 {
+01162 <font class="comment">// If neighbors sons at tile level, must update their Tile vertices.</font>
+01163 <font class="keywordflow">if</font>( f1-&gt;FLeft-&gt;SonLeft-&gt;Level &gt;= f1-&gt;FLeft-&gt;Patch-&gt;TileLimitLevel )
+01164 {
+01165 f1-&gt;FLeft-&gt;SonLeft-&gt;checkFillTileVB(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+01166 f1-&gt;FLeft-&gt;SonRight-&gt;checkFillTileVB(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+01167 }
+01168 }
+01169 }
+01170
+01171
+01172 <font class="comment">// 4. Compute centers.</font>
+01173 <font class="comment">//--------------------</font>
+01174 f0r-&gt;computeSplitPoint();
+01175 f0l-&gt;computeSplitPoint();
+01176 f1r-&gt;computeSplitPoint();
+01177 f1l-&gt;computeSplitPoint();
+01178
+01179
+01180 <font class="comment">// 5. Propagate, or link sons of base.</font>
+01181 <font class="comment">//------------------------------------</font>
+01182 <font class="keywordflow">for</font>(sint i=0;i&lt;2;i++)
+01183 {
+01184 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f, *fl, *fr;
+01185 <font class="comment">// TOP face.</font>
+01186 <font class="keywordflow">if</font>(i==0)
+01187 {
+01188 f= f1;
+01189 fl= f1l;
+01190 fr= f1r;
+01191 }
+01192 <font class="comment">// then BOT face.</font>
+01193 <font class="keywordflow">else</font>
+01194 {
+01195 f= f0;
+01196 fl= f0l;
+01197 fr= f0r;
+01198 }
+01199
+01200 <font class="comment">// If current face and FBase has sons, just links.</font>
+01201 <font class="keywordflow">if</font>(f-&gt;FLeft==NULL)
+01202 {
+01203 <font class="comment">// Just update sons neighbors.</font>
+01204 fl-&gt;FLeft= NULL;
+01205 fr-&gt;FLeft= NULL;
+01206 }
+01207 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(!f-&gt;FLeft-&gt;isLeaf())
+01208 {
+01209 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *toLeft, *toRight;
+01210 toLeft= f-&gt;FLeft-&gt;SonLeft;
+01211 toRight= f-&gt;FLeft-&gt;SonRight;
+01212 <font class="comment">// Cross connection of sons.</font>
+01213 <font class="keywordflow">if</font>( !f-&gt;FLeft-&gt;isRectangular() )
+01214 {
+01215 <font class="comment">// Case neigbhor is square.</font>
+01216 fl-&gt;FLeft= toLeft;
+01217 fr-&gt;FLeft= toRight;
+01218 toLeft-&gt;FRight= fl;
+01219 toRight-&gt;FLeft= fr;
+01220 }
+01221 <font class="keywordflow">else</font>
+01222 {
+01223 <font class="comment">// Case neigbhor is rectangle.</font>
+01224 fl-&gt;FLeft= toRight;
+01225 fr-&gt;FLeft= toLeft;
+01226 toLeft-&gt;FLeft= fr;
+01227 toRight-&gt;FLeft= fl;
+01228 }
+01229 }
+01230 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (propagateSplit)
+01231 {
+01232 <font class="comment">// Warning: at each iteration, the pointer of FLeft may change (because of split() which can change the neighbor </font>
+01233 <font class="comment">// and so f).</font>
+01234 <font class="keywordflow">while</font>(f-&gt;FLeft-&gt;isLeaf())
+01235 f-&gt;FLeft-&gt;split();
+01236
+01237 <font class="comment">// There is a possible bug here (maybe easily patched). Sons may have be propagated splitted.</font>
+01238 <font class="comment">// And problems may arise because this face hasn't yet good connectivity (especially for rectangles!! :) ).</font>
+01239 <a class="code" href="debug_8h.html#a6">nlassert</a>(fl-&gt;isLeaf() &amp;&amp; fr-&gt;isLeaf());
+01240 }
+01241 }
+01242
+01243
+01244 <font class="comment">// 6. Must remove father from rdr list, and insert sons.</font>
+01245 <font class="comment">//------------------------------------------------------</font>
+01246 <font class="comment">// UGLY REFCOUNT SIDE EFFECT: do the append first.</font>
+01247 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(f0l);
+01248 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(f0r);
+01249 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(f1l);
+01250 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(f1r);
+01251 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromRenderList(f0);
+01252 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromRenderList(f1);
+01253
+01254
+01255 <font class="comment">// 7. Update priority list.</font>
+01256 <font class="comment">//------------------------------------------------------</font>
+01257 <font class="comment">// Since we are freshly splitted, unlink from any list, and link to the MergePriorityList, because must look </font>
+01258 <font class="comment">// now when should merge.</font>
+01259 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_MergePriorityList.insert(0, 0, f0);
+01260 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_MergePriorityList.insert(0, 0, f1);
+01261
+01262 <font class="comment">// Since we are split, no need to test father for merge, because it cannot!</font>
+01263 <font class="keywordflow">if</font>(f0-&gt;Father)
+01264 {
+01265 <font class="comment">// remove father from any priority list.</font>
+01266 f0-&gt;Father-&gt;unlinkInPList();
+01267 }
+01268 <font class="keywordflow">if</font>(f1-&gt;Father)
+01269 {
+01270 <font class="comment">// remove father from any priority list.</font>
+01271 f1-&gt;Father-&gt;unlinkInPList();
+01272 }
+01273
+01274 }
+01275
+01276
+01277 <font class="comment">// ***************************************************************************</font>
+<a name="l01278"></a><a class="code" href="classNL3D_1_1CTessFace.html#a11">01278</a> <font class="keywordtype">void</font> CTessFace::split(<font class="keywordtype">bool</font> propagateSplit)
+01279 {
+01280
+01281 <font class="comment">// 0. Some easy ending.</font>
+01282 <font class="comment">//---------------------</font>
+01283 <font class="comment">// Already splitted??</font>
+01284 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+01285 <font class="keywordflow">return</font>;
+01286 <font class="comment">// Don't do this!!!</font>
+01287 <font class="comment">//if(Level&gt;=LS_MAXLEVEL)</font>
+01288 <font class="comment">// return;</font>
+01289 <font class="comment">// since split() may reach LS_MAXLEVEL, but enforce splits which outpass this stage!!</font>
+01290
+01291 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a80">ProfNSplits</a>, 1);
+01292
+01293
+01294 <font class="comment">// Special Rectangular case.</font>
+01295 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+01296 {
+01297 <a class="code" href="classNL3D_1_1CTessFace.html#c3">splitRectangular</a>(propagateSplit);
+01298 <font class="keywordflow">return</font>;
+01299 }
+01300
+01301 <font class="comment">// 1. Create sons, and update links.</font>
+01302 <font class="comment">//----------------------------------</font>
+01303
+01304 <font class="comment">// create and bind Sons.</font>
+01305 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFace();
+01306 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFace();
+01307
+01308 <font class="comment">// subdivision left.</font>
+01309 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Patch= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>;
+01310 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Father= <font class="keyword">this</font>;
+01311 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level= <a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>+1;
+01312 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Size= <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>*0.5f;
+01313 <font class="comment">// subdivision right.</font>
+01314 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;Patch= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>;
+01315 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;Father= <font class="keyword">this</font>;
+01316 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;Level= <a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>+1;
+01317 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;Size= <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>*0.5f;
+01318
+01319
+01320 <font class="comment">// link Left Son.</font>
+01321 <font class="comment">// link neighbor face.</font>
+01322 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>;
+01323 <font class="keywordflow">if</font>(FLeft) <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;changeNeighbor(<font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>);
+01324 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>;
+01325 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FRight= NULL; <font class="comment">// Temporary. updated later.</font>
+01326 <font class="comment">// link neighbor vertex.</font>
+01327 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>;
+01328 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>;
+01329 <font class="comment">// link neighbor Far vertex.</font>
+01330 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVLeft= <a class="code" href="classNL3D_1_1CTessFace.html#m0">FVBase</a>;
+01331 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVRight= <a class="code" href="classNL3D_1_1CTessFace.html#m1">FVLeft</a>;
+01332 <font class="comment">// Patch coordinates.</font>
+01333 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase= CParamCoord(<a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>);
+01334 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>;
+01335 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>;
+01336
+01337 <font class="comment">// linkRight Son.</font>
+01338 <font class="comment">// link neighbor face.</font>
+01339 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>;
+01340 <font class="keywordflow">if</font>(FRight) <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>-&gt;changeNeighbor(<font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>);
+01341 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FLeft= NULL; <font class="comment">// Temporary. updated later.</font>
+01342 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>;
+01343 <font class="comment">// link neighbor vertex.</font>
+01344 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>;
+01345 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>;
+01346 <font class="comment">// link neighbor Far vertex.</font>
+01347 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FVLeft= <a class="code" href="classNL3D_1_1CTessFace.html#m2">FVRight</a>;
+01348 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FVRight= <a class="code" href="classNL3D_1_1CTessFace.html#m0">FVBase</a>;
+01349 <font class="comment">// Patch coordinates.</font>
+01350 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;PVBase= CParamCoord(<a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>);
+01351 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;PVLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>;
+01352 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;PVRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>;
+01353
+01354
+01355 <font class="comment">// FBase-&gt;FBase==this. Must Doesn't change this. Used and Updated in section 5. ...</font>
+01356
+01357
+01358 <font class="comment">// 2. Update/Create Vertex infos.</font>
+01359 <font class="comment">//-------------------------------</font>
+01360
+01361 <font class="comment">// Must create/link *-&gt;VBase.</font>
+01362 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>==NULL || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf())
+01363 {
+01364 <font class="comment">// The base neighbor is a leaf or NULL. So must create the new vertex.</font>
+01365 CTessVertex *newVertex= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessVertex();
+01366 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VBase= newVertex;
+01367 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase= newVertex;
+01368
+01369 <font class="comment">// Compute pos.</font>
+01370 newVertex-&gt;StartPos= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;EndPos + <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;EndPos)/2;
+01371 newVertex-&gt;EndPos= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;computeVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getT());
+01372
+01373 <font class="comment">// Init Pos= InitialPos. Important in the case of enforced split.</font>
+01374 newVertex-&gt;Pos= newVertex-&gt;StartPos;
+01375
+01376 <font class="comment">// For geomorph (VertexProgram or soft), compute MaxFaceSize and MaxNearLimit.</font>
+01377 newVertex-&gt;MaxFaceSize= <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>;
+01378 newVertex-&gt;MaxNearLimit= <a class="code" href="classNL3D_1_1CTessFace.html#a9">computeNearLimit</a>();
+01379 }
+01380 <font class="keywordflow">else</font>
+01381 {
+01382 <font class="comment">// Else, get from neighbor.</font>
+01383 <font class="comment">// NB: since *FBase is not a leaf, FBase-&gt;SonLeft!=NULL...</font>
+01384 <font class="comment">// NB: this work with both rectangular and square triangles (see splitRectangular()).</font>
+01385 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;VBase;
+01386 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;VBase;
+01387
+01388 <font class="comment">// For geomorph (VertexProgram or soft), compute MaxFaceSize and MaxNearLimit.</font>
+01389 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxFaceSize= max( <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxFaceSize, <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>);
+01390 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxNearLimit= max( <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxNearLimit, <a class="code" href="classNL3D_1_1CTessFace.html#a9">computeNearLimit</a>());
+01391 }
+01392
+01393
+01394 <font class="comment">// Must create/link *-&gt;FVBase.</font>
+01395 <font class="comment">// HERE, we must create a FarVertex too if the neighbor is not of the same patch as me.</font>
+01396 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>==NULL || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf() || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>)
+01397 {
+01398 <font class="comment">// The base neighbor is a leaf or NULL. So must create the new far vertex.</font>
+01399 CTessFarVertex *newFar= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessFarVertex();
+01400 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FVBase= newFar;
+01401 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase= newFar;
+01402
+01403 <font class="comment">// Compute.</font>
+01404 newFar-&gt;Src= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase;
+01405 newFar-&gt;PCoord= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase;
+01406
+01407 <font class="comment">// Append.</font>
+01408 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFarVertexToRenderList(newFar);
+01409
+01410 <font class="comment">// May Allocate/Fill VB.</font>
+01411 <font class="comment">// NB: SonLeft-&gt;VBase-&gt;Pos is well computed and ready for the fill in VB.</font>
+01412 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkCreateVertexVBFar(newFar);
+01413 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkFillVertexVBFar(newFar);
+01414
+01415 <font class="comment">// For VertexProgram only, must refill the Far vertex of neighbor, </font>
+01416 <font class="comment">// because MaxFaceSize, and MaxNearLimit may have change.</font>
+01417 <font class="keywordflow">if</font>( CLandscapeGlobals::VertexProgramEnabled &amp;&amp; ! (<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>==NULL || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf()) )
+01418 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch-&gt;checkFillVertexVBFar(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;FVBase);
+01419 }
+01420 <font class="keywordflow">else</font>
+01421 {
+01422 <font class="comment">// Else, get from neighbor.</font>
+01423 <font class="comment">// NB: since *FBase is not a leaf, FBase-&gt;SonLeft!=NULL...</font>
+01424 <font class="comment">// NB: this work with both rectangular and square triangles (see splitRectangular()).</font>
+01425 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FVBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;FVBase;
+01426 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;FVBase;
+01427
+01428 <font class="comment">// NB For VertexProgram only: no need to refill the Far vertex of neighbor, because neighbor is of same Patch</font>
+01429 <font class="comment">// So MaxNearLimit and MaxFaceSize should be the same.</font>
+01430 }
+01431
+01432
+01433 <font class="comment">// 3. Update Tile infos.</font>
+01434 <font class="comment">//----------------------</font>
+01435 <font class="comment">// NB: must do it before appendFaceToRenderList().</font>
+01436 <font class="comment">// NB: must do it after compute of SonLeft-&gt;VBase-&gt;Pos for good filling in VBuffer.</font>
+01437 <font class="comment">// There is no problem with rectangular patch, since tiles are always squares.</font>
+01438 <font class="comment">// If new tile ....</font>
+01439 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level==<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+01440 {
+01441 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;computeTileMaterial();
+01442 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;computeTileMaterial();
+01443 }
+01444 <font class="comment">// else Tile herit.</font>
+01445 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level &gt; <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+01446 {
+01447 <a class="code" href="classNL3D_1_1CTessFace.html#c5">heritTileMaterial</a>();
+01448 }
+01449
+01450 <font class="comment">// For Vertex program only</font>
+01451 <font class="keywordflow">if</font>( CLandscapeGlobals::VertexProgramEnabled )
+01452 {
+01453 <font class="comment">// if neighbor face splitted, and if 2 different patchs, we must update the Tile vertices</font>
+01454 <font class="comment">// because MaxFaceSize and MaxNearLimit may have changed.</font>
+01455 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>!=NULL &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf() &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a> )
+01456 {
+01457 <font class="comment">// If neighbors sons at tile level, must update their Tile vertices.</font>
+01458 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;Level &gt;= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch-&gt;TileLimitLevel )
+01459 {
+01460 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;checkFillTileVB(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+01461 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonRight-&gt;checkFillTileVB(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+01462 }
+01463 }
+01464 }
+01465
+01466
+01467 <font class="comment">// 4. Compute centers.</font>
+01468 <font class="comment">//--------------------</font>
+01469 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;computeSplitPoint();
+01470 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;computeSplitPoint();
+01471
+01472
+01473 <font class="comment">// 5. Propagate, or link sons of base.</font>
+01474 <font class="comment">//------------------------------------</font>
+01475 <font class="comment">// If current face and FBase has sons, just links.</font>
+01476 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>==NULL)
+01477 {
+01478 <font class="comment">// Just update sons neighbors.</font>
+01479 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FRight= NULL;
+01480 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FLeft= NULL;
+01481 }
+01482 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf())
+01483 {
+01484 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *toLeft, *toRight;
+01485 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *fl, *fr;
+01486 fl= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>;
+01487 fr= <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>;
+01488 toLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft;
+01489 toRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonRight;
+01490 <font class="comment">// Cross connection of sons.</font>
+01491 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isRectangular())
+01492 {
+01493 <font class="comment">// Case neigbhor is square.</font>
+01494 fl-&gt;FRight= toRight;
+01495 fr-&gt;FLeft= toLeft;
+01496 toLeft-&gt;FRight= fr;
+01497 toRight-&gt;FLeft= fl;
+01498 }
+01499 <font class="keywordflow">else</font>
+01500 {
+01501 <font class="comment">// Case neigbhor is rectangular.</font>
+01502 fl-&gt;FRight= toLeft;
+01503 fr-&gt;FLeft= toRight;
+01504 toLeft-&gt;FLeft= fl;
+01505 toRight-&gt;FLeft= fr;
+01506 }
+01507 }
+01508 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (propagateSplit)
+01509 {
+01510 <font class="comment">// Warning: at each iteration, the pointer of FBase may change (because of split() which can change the neighbor </font>
+01511 <font class="comment">// and so "this").</font>
+01512 <font class="keywordflow">while</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf())
+01513 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;split();
+01514
+01515 <font class="comment">// There is a possible bug here (maybe easily patched). Sons may have be propagated splitted.</font>
+01516 <font class="comment">// And problems may arise because this face hasn't yet good connectivity.</font>
+01517 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;isLeaf() &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;isLeaf());
+01518 }
+01519
+01520
+01521 <font class="comment">// 6. Must remove father from rdr list, and insert sons.</font>
+01522 <font class="comment">//------------------------------------------------------</font>
+01523 <font class="comment">// UGLY REFCOUNT SIDE EFFECT: do the append first.</font>
+01524 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>);
+01525 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>);
+01526 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromRenderList(<font class="keyword">this</font>);
+01527
+01528
+01529 <font class="comment">// 7. Update priority list.</font>
+01530 <font class="comment">//------------------------------------------------------</font>
+01531 <font class="comment">// Since we are freshly splitted, unlink from any list, and link to the MergePriorityList, because must look </font>
+01532 <font class="comment">// now when should merge.</font>
+01533 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_MergePriorityList.insert(0, 0, <font class="keyword">this</font>);
+01534
+01535 <font class="comment">// Since we are split, no need to test father for merge, because it cannot!</font>
+01536 <font class="keywordflow">if</font>(Father)
+01537 {
+01538 <font class="comment">// remove father from any priority list.</font>
+01539 <a class="code" href="classNL3D_1_1CTessFace.html#z819_7">Father</a>-&gt;unlinkInPList();
+01540 }
+01541 }
+01542
+01543 <font class="comment">// ***************************************************************************</font>
+<a name="l01544"></a><a class="code" href="classNL3D_1_1CTessFace.html#c2">01544</a> <font class="keywordtype">bool</font> CTessFace::canMerge(<font class="keywordtype">bool</font> testEm)
+01545 {
+01546 <font class="keywordflow">if</font>(<font class="keyword">this</font>== &amp;<a class="code" href="classNL3D_1_1CTessFace.html#r0">CantMergeFace</a>)
+01547 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+01548
+01549 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+01550
+01551 <font class="comment">// Test diamond config (sons must be leaves).</font>
+01552 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;isLeaf())
+01553 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+01554 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;isLeaf())
+01555 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+01556 <font class="comment">// If Errormetric must be considered for this test.</font>
+01557 <font class="keywordflow">if</font>(testEm)
+01558 {
+01559 <a class="code" href="classNL3D_1_1CTessFace.html#a10">updateErrorMetric</a>();
+01560 <font class="keywordtype">float</font> ps2= <a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>;
+01561 ps2*= CLandscapeGlobals::OORefineThreshold;
+01562 <font class="keywordflow">if</font>(ps2&gt;=1.0f)
+01563 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+01564 }
+01565
+01566 <font class="comment">// Then test neighbors.</font>
+01567 <a class="code" href="classNL3D_1_1CTessFace.html#z819_14">RecursMarkCanMerge</a>= <font class="keyword">true</font>;
+01568 <font class="keywordtype">bool</font> ok= <font class="keyword">true</font>;
+01569 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+01570 {
+01571 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;RecursMarkCanMerge)
+01572 {
+01573 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;canMerge(testEm))
+01574 ok= <font class="keyword">false</font>;
+01575 }
+01576 }
+01577 <font class="keywordflow">else</font>
+01578 {
+01579 <font class="comment">// Rectangular case. May have a longer propagation...</font>
+01580 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;RecursMarkCanMerge)
+01581 {
+01582 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;canMerge(testEm))
+01583 ok= <font class="keyword">false</font>;
+01584 }
+01585 <font class="keywordflow">if</font>(ok &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a> &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;RecursMarkCanMerge)
+01586 {
+01587 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;canMerge(testEm))
+01588 ok= <font class="keyword">false</font>;
+01589 }
+01590 }
+01591 <font class="comment">// Must not return false in preceding tests, because must set RecursMarkCanMerge to false.</font>
+01592 <a class="code" href="classNL3D_1_1CTessFace.html#z819_14">RecursMarkCanMerge</a>= <font class="keyword">false</font>;
+01593
+01594 <font class="keywordflow">return</font> ok;
+01595 }
+01596
+01597
+01598 <font class="comment">// ***************************************************************************</font>
+<a name="l01599"></a><a class="code" href="classNL3D_1_1CTessFace.html#c4">01599</a> <font class="keywordtype">void</font> CTessFace::doMerge()
+01600 {
+01601 <font class="comment">// Assume that canMerge() return true.</font>
+01602 <font class="comment">// And Assume that !isLeaf().</font>
+01603 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+01604
+01605 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+01606 {
+01607 <font class="comment">// 1. Let's merge vertex.</font>
+01608 <font class="comment">//-----------------------</font>
+01609 <font class="comment">// Delete vertex, only if not already done by the neighbor (ie neighbor not already merged to a leaf).</font>
+01610 <font class="comment">// NB: this work even if neigbor is rectnagular.</font>
+01611 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> || !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf())
+01612 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase);
+01613
+01614 <font class="comment">// Delete Far Vertex. Idem, but test too if != patch...</font>
+01615 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> || !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf() || <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>)
+01616 {
+01617 <font class="comment">// May delete this vertex from VB.</font>
+01618 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkDeleteVertexVBFar(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase);
+01619
+01620 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFarVertexFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase);
+01621 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessFarVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase);
+01622 }
+01623
+01624
+01625 <font class="comment">// 2. Must remove sons from rdr list, and insert father.</font>
+01626 <font class="comment">//------------------------------------------------------</font>
+01627 <font class="comment">// Must do it BEFORE the TileFaces are released.</font>
+01628 <font class="comment">// UGLY REFCOUNT SIDE EFFECT: do the append first.</font>
+01629 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(<font class="keyword">this</font>);
+01630 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>);
+01631 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>);
+01632
+01633
+01634 <font class="comment">// 3. Let's merge Uv.</font>
+01635 <font class="comment">//-------------------</font>
+01636 <font class="comment">// Delete Uv.</font>
+01637 <font class="comment">// Must do it for this and FBase separately, since they may not have same tile level (if != patch).</font>
+01638 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level== <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+01639 {
+01640 <font class="comment">// Square patch assumption: the sons are not of the same TileId/Patch.</font>
+01641 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#f0">sameTile</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>));
+01642 <font class="comment">// release tiles: NearVertices, TileFaces, and TileMaterial.</font>
+01643 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;releaseTileMaterial();
+01644 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;releaseTileMaterial();
+01645 }
+01646 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level &gt; <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+01647 {
+01648 <font class="comment">// Delete Uv, only if not already done by the neighbor (ie neighbor not already merged to a leaf).</font>
+01649 <font class="comment">// But Always delete if neighbor exist and has not same tile as me.</font>
+01650 <font class="comment">// NB: this work with rectangular neigbor patch, since sameTile() will return false if different patch.</font>
+01651 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> || !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf() || !<a class="code" href="classNL3D_1_1CTessFace.html#f0">sameTile</a>(<font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>))
+01652 {
+01653 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;deleteTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+01654 }
+01655 <font class="comment">// In all case, must delete the tilefaces of those face.</font>
+01656 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;deleteTileFaces();
+01657 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;deleteTileFaces();
+01658 }
+01659
+01660
+01661 <font class="comment">// 4. Let's merge Face.</font>
+01662 <font class="comment">//-------------------</font>
+01663 <font class="comment">// Change father 's neighbor pointers.</font>
+01664 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FBase;
+01665 <font class="keywordflow">if</font>(FLeft) <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;changeNeighbor(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>, <font class="keyword">this</font>);
+01666 <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FBase;
+01667 <font class="keywordflow">if</font>(FRight) <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>-&gt;changeNeighbor(<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>, <font class="keyword">this</font>);
+01668 <font class="comment">// delete sons.</font>
+01669 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessFace(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>);
+01670 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessFace(<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>);
+01671 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>=NULL;
+01672 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>=NULL;
+01673
+01674 <font class="comment">// If not already done, merge the neighbor.</font>
+01675 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>!=NULL &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf())
+01676 {
+01677 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;doMerge();
+01678 }
+01679
+01680 }
+01681 <font class="keywordflow">else</font>
+01682 {
+01683 <font class="comment">// Rectangular case.</font>
+01684 <font class="comment">// Since minimum Order is 2, Sons of rectangular face are NEVER at TileLimitLevel. =&gt; no Uv merge to do.</font>
+01685 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level&lt; <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel);
+01686 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>);
+01687
+01688 <font class="comment">// 1. Let's merge vertex.</font>
+01689 <font class="comment">//-----------------------</font>
+01690 <font class="comment">// Delete vertex, only if not already done by the neighbor (ie neighbor not already merged to a leaf).</font>
+01691 <font class="comment">// NB: this work even if neigbor is rectangular (see tesselation rules in splitRectangular()).</font>
+01692 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a> || !<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;isLeaf())
+01693 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase);
+01694
+01695 <font class="comment">// Delete Far Vertex. Rect patch: neightb must be of a != pathc as me =&gt; must delete FarVertex.</font>
+01696 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a> || <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>);
+01697 <font class="comment">// May delete this vertex from VB.</font>
+01698 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;checkDeleteVertexVBFar(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase);
+01699
+01700 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFarVertexFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase);
+01701 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessFarVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FVBase);
+01702
+01703
+01704 <font class="comment">// 2. Must remove sons from rdr list, and insert father.</font>
+01705 <font class="comment">//------------------------------------------------------</font>
+01706 <font class="comment">// UGLY REFCOUNT SIDE EFFECT: do the append first.</font>
+01707 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToRenderList(<font class="keyword">this</font>);
+01708 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>);
+01709 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromRenderList(<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>);
+01710
+01711
+01712 <font class="comment">// 3. Let's merge Face.</font>
+01713 <font class="comment">//-------------------</font>
+01714 <font class="comment">// Change father 's neighbor pointers (see splitRectangular()).</font>
+01715 <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>= <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FRight;
+01716 <font class="keywordflow">if</font>(FRight) <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>-&gt;changeNeighbor(<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>, <font class="keyword">this</font>);
+01717 <font class="comment">// delete sons.</font>
+01718 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessFace(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>);
+01719 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessFace(<a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>);
+01720 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>=NULL;
+01721 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>=NULL;
+01722
+01723 <font class="comment">// First, do it for my rectangular co-worker FBase (if not already done).</font>
+01724 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf())
+01725 {
+01726 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;doMerge();
+01727 }
+01728 <font class="comment">// If not already done, merge the neighbor.</font>
+01729 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>!=NULL &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;isLeaf())
+01730 {
+01731 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;doMerge();
+01732 }
+01733 }
+01734
+01735
+01736 <font class="comment">// Update priority list.</font>
+01737 <font class="comment">//------------------------------------------------------</font>
+01738 <font class="comment">// Since we are freshly merged, unlink from any list, and link to the SplitPriorityList, because must look </font>
+01739 <font class="comment">// now when we should split again.</font>
+01740 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_SplitPriorityList.insert(0, 0, <font class="keyword">this</font>);
+01741
+01742 <font class="comment">// since we are now merged maybe re-insert father in priority list.</font>
+01743 <font class="keywordflow">if</font>(Father)
+01744 {
+01745 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_7">Father</a>-&gt;isLeaf());
+01746 <font class="comment">// If sons of father are both leaves (ie this, and the other (complexe case if rectangle) )</font>
+01747 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CTessFace.html#z819_7">Father</a>-&gt;SonLeft-&gt;isLeaf() &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_7">Father</a>-&gt;SonRight-&gt;isLeaf() )
+01748 {
+01749 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_MergePriorityList.insert(0, 0, <a class="code" href="classNL3D_1_1CTessFace.html#z819_7">Father</a>);
+01750 }
+01751 }
+01752
+01753 }
+01754
+01755
+01756 <font class="comment">// ***************************************************************************</font>
+<a name="l01757"></a><a class="code" href="classNL3D_1_1CTessFace.html#a12">01757</a> <font class="keywordtype">bool</font> CTessFace::merge()
+01758 {
+01759 <font class="comment">// Must not be a leaf.</font>
+01760 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+01761
+01762 <font class="comment">// 0. Verify if merge is posible.</font>
+01763 <font class="comment">//----------------------------</font>
+01764 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#c2">canMerge</a>(<font class="keyword">false</font>))
+01765 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+01766
+01767 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a81">ProfNMerges</a>, 1);
+01768
+01769 <font class="comment">// 1. Let's merge the face.</font>
+01770 <font class="comment">//-----------------------</font>
+01771 <font class="comment">// Propagation is done in doMerge().</font>
+01772 <a class="code" href="classNL3D_1_1CTessFace.html#c4">doMerge</a>();
+01773
+01774 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+01775 }
+01776
+01777 <font class="comment">// ***************************************************************************</font>
+<a name="l01778"></a><a class="code" href="classNL3D_1_1CTessFace.html#a13">01778</a> <font class="keywordtype">void</font> CTessFace::refineAll()
+01779 {
+01780 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a77">ProfNRefineFaces</a>, 1);
+01781 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a79">ProfNRefineLeaves</a>, <a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>()?1:0);
+01782
+01783 <font class="comment">/*</font>
+01784 <font class="comment"> if(ps&lt;RefineThreshold), the face must be merged (ie have no leaves).</font>
+01785 <font class="comment"> if(ps E [RefineThreshold, RefineTreshold*2]), the face must be splitted (ave leaves), and is geomorphed.</font>
+01786 <font class="comment"> if(ps&gt;RefineThreshold*2), the face is fully splitted/geomoprhed (tests reported on sons...).</font>
+01787 <font class="comment"> */</font>
+01788
+01789 <font class="comment">// Test for Split or merge.</font>
+01790 <font class="comment">//-----------------------</font>
+01791 {
+01792 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a78">ProfNRefineComputeFaces</a>, 1);
+01793
+01794 <a class="code" href="classNL3D_1_1CTessFace.html#a10">updateErrorMetric</a>();
+01795 <font class="keywordtype">float</font> ps=<a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>;
+01796 ps*= CLandscapeGlobals::OORefineThreshold;
+01797 <font class="comment">// 1.0f is the point of split().</font>
+01798 <font class="comment">// 2.0f is the end of geomorph.</font>
+01799
+01800
+01801 <font class="comment">// Test split/merge.</font>
+01802 <font class="comment">//---------------------</font>
+01803 <font class="comment">// If wanted, not already done, and limit not reached, split().</font>
+01804 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+01805 {
+01806 <font class="keywordflow">if</font>(ps&gt;1.0f &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&lt; (<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel + CLandscapeGlobals::TileMaxSubdivision) )
+01807 <a class="code" href="classNL3D_1_1CTessFace.html#a11">split</a>();
+01808 }
+01809 <font class="keywordflow">else</font>
+01810 {
+01811 <font class="comment">// Else, if splitted, must merge (if not already the case).</font>
+01812 <font class="keywordflow">if</font>(ps&lt;1.0f)
+01813 {
+01814 <font class="comment">// Merge only if agree, and neighbors agree.</font>
+01815 <font class="comment">// canMerge() test all the good thing: FBase==CantMergeFace, or this is rectangular etc...</font>
+01816 <font class="comment">// The test is propagated to neighbors.</font>
+01817 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#c2">canMerge</a>(<font class="keyword">true</font>))
+01818 {
+01819 <a class="code" href="classNL3D_1_1CTessFace.html#a12">merge</a>();
+01820 }
+01821 }
+01822 }
+01823 }
+01824
+01825 <font class="comment">// Recurs.</font>
+01826 <font class="comment">//-----------------------</font>
+01827 <font class="keywordflow">if</font>(SonLeft)
+01828 {
+01829 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;refineAll();
+01830 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;refineAll();
+01831 }
+01832
+01833 }
+01834
+01835
+01836 <font class="comment">// ***************************************************************************</font>
+01837 <font class="comment">// Some updateRefine***() Doc:</font>
+01838
+01839 <font class="comment">// Split or merge, and meaning of errorMetric:</font>
+01840 <font class="comment">/*</font>
+01841 <font class="comment"> if(errorMetric&lt;RefineThreshold), the face must be merged (ie have no leaves).</font>
+01842 <font class="comment"> if(errorMetric E [RefineThreshold, RefineTreshold*2]), the face must be splitted (ave leaves), and is geomorphed.</font>
+01843 <font class="comment"> if(errorMetric&gt;RefineThreshold*2), the face is fully splitted/geomoprhed.</font>
+01844 <font class="comment">*/</font>
+01845
+01846
+01847 <font class="comment">// Compute distNormalSplitMerge: distance from refineCenter to normal split/merge (ie without tile transition):</font>
+01848 <font class="comment">/* </font>
+01849 <font class="comment"> normal ErrorMetric formula is:</font>
+01850 <font class="comment"> em = Size*OORefineThreshold/ dist^2; with dist == (SplitPoint - CLandscapeGlobals::RefineCenter).norm()</font>
+01851 <font class="comment"> So inverse this function and we have:</font>
+01852 <font class="comment"> dist= sqrt(Size*OORefineThreshold/em).</font>
+01853 <font class="comment"> Split or merge is when em==1, so </font>
+01854 <font class="comment"> distSplitMerge= sqrt(Size*OORefineThreshold)</font>
+01855 <font class="comment">*/</font>
+01856
+01857
+01858 <font class="comment">// Compute distTileTransSplitMerge.</font>
+01859 <font class="comment">/* When we are sure that CLandscapeGlobals::TileDistNear &lt; distMinFace &lt; CLandscapeGlobals::TileDistFar, </font>
+01860 <font class="comment"> the clamp in the original formula is skipped</font>
+01861 <font class="comment"> </font>
+01862 <font class="comment"> So the TileErrorMetric formula is:</font>
+01863 <font class="comment"></font>
+01864 <font class="comment"> {</font>
+01865 <font class="comment"> ema= Sife*OORefineThreshold / distSP^2.</font>
+01866 <font class="comment"> f= (TileDistFar^2 - distMinFace^2) * OOTileDeltaDist^2</font>
+01867 <font class="comment"> f= f ^ 4. // no clamp. see above.</font>
+01868 <font class="comment"> emb= NL*f + ema*(1-f)</font>
+01869 <font class="comment"> emFinal= max(ema, emb).</font>
+01870 <font class="comment"> }</font>
+01871 <font class="comment"></font>
+01872 <font class="comment"> The problem is that the formula is too complex (degree 8 equation). </font>
+01873 <font class="comment"> So search for the result recursively.</font>
+01874 <font class="comment">*/</font>
+01875
+01876
+01877 <font class="comment">// Quadrant Selection</font>
+01878 <font class="comment">/*</font>
+01879 <font class="comment"> Quadrant/Direction is interesting for updateRefineSplit() only.</font>
+01880 <font class="comment"> In the 2 most simples cases, the action we want is "Know when we enters in a bounding volume"</font>
+01881 <font class="comment"> This fit well for Quadrant notion.</font>
+01882 <font class="comment"></font>
+01883 <font class="comment"> In the case "TileDistNear to TileDistFar", the rule is too complicated and there is also</font>
+01884 <font class="comment"> the notion of "Know when we LEAVE the TileDistFar sphere around the face" which is incompatible</font>
+01885 <font class="comment"> with Quadrant behavior (since can go in any direction to leave the sphere).</font>
+01886 <font class="comment"></font>
+01887 <font class="comment"> updateRefineMerge() are at least all notion of "Know when we LEAVE the SplitSphere around the SplitPoint"</font>
+01888 <font class="comment"> which is incompatible with Quadrant behavior.</font>
+01889 <font class="comment"> This is why updateRefineMerge() don't bother at all quadrant, and so the _MergePriorityList is inited with 0</font>
+01890 <font class="comment"> quadrants.</font>
+01891 <font class="comment"></font>
+01892 <font class="comment">*/</font>
+01893
+01894 <font class="comment">// ***************************************************************************</font>
+<a name="l01895"></a><a class="code" href="classNL3D_1_1CTessFace.html#a14">01895</a> <font class="keywordtype">void</font> CTessFace::updateRefineSplit()
+01896 {
+01897 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a77">ProfNRefineFaces</a>, 1);
+01898
+01899 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>);
+01900 <font class="comment">// The face must be not splitted, because tested for split.</font>
+01901 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+01902
+01903 <font class="comment">/*</font>
+01904 <font class="comment"> NB: see above for some updateRefine*** doc.</font>
+01905 <font class="comment"> */</font>
+01906
+01907 <font class="comment">// Test for Split.</font>
+01908 <font class="comment">//-----------------------</font>
+01909 <font class="keywordtype">bool</font> splitted= <font class="keyword">false</font>;
+01910 {
+01911 <a class="code" href="classNL3D_1_1CTessFace.html#a10">updateErrorMetric</a>();
+01912 <font class="keywordtype">float</font> ps=<a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>;
+01913 ps*= CLandscapeGlobals::OORefineThreshold;
+01914 <font class="comment">// 1.0f is the point of split().</font>
+01915 <font class="comment">// 2.0f is the end of geomorph.</font>
+01916
+01917
+01918 <font class="comment">// Test split.</font>
+01919 <font class="comment">//---------------------</font>
+01920 <font class="comment">// If wanted and limit not reached, split().</font>
+01921 <font class="keywordflow">if</font>(ps&gt;1.0f &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&lt; (<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel + CLandscapeGlobals::TileMaxSubdivision) )
+01922 {
+01923 <a class="code" href="classNL3D_1_1CTessFace.html#a11">split</a>();
+01924
+01925 <font class="comment">// if split ok</font>
+01926 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+01927 {
+01928 splitted= <font class="keyword">true</font>;
+01929 }
+01930 }
+01931 }
+01932
+01933
+01934 <font class="comment">// Insert the face in the priority list.</font>
+01935 <font class="comment">//-----------------------</font>
+01936 <font class="comment">// If splitted, then insertion in Landscape-&gt;MergePriorityList at 0 has been done. so nothing to update.</font>
+01937 <font class="comment">// Else, must compute when whe should re-test.</font>
+01938 <font class="keywordflow">if</font>(!splitted)
+01939 {
+01940 <font class="comment">// the face is not splitted here.</font>
+01941 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+01942
+01943 <font class="keywordtype">float</font> minDeltaDistToUpdate;
+01944
+01945 <font class="comment">// by default insert in the quadrant-less rolling table.</font>
+01946 uint quadrantId= 0;
+01947
+01948
+01949 CVector dirToSplitPoint= <a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a> - CLandscapeGlobals::RefineCenter;
+01950 <font class="comment">// The distance of SplitPoint to center.</font>
+01951 <font class="keywordtype">float</font> distSplitPoint= dirToSplitPoint.norm();
+01952 <font class="comment">// The distance where we should split/merge. see updateRefin() doc.</font>
+01953 <font class="keywordtype">float</font> distNormalSplitMerge= (float)sqrt(<a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>*CLandscapeGlobals::OORefineThreshold);
+01954
+01955
+01956 <font class="comment">// If the face is at its max subdivision</font>
+01957 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&gt;=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel+CLandscapeGlobals::TileMaxSubdivision)
+01958 {
+01959 <font class="comment">// special case: the face do not need to be tested for splitting, because Max subdivision reached.</font>
+01960 <font class="comment">// Hence just unlink from any list, and return.</font>
+01961 <a class="code" href="classNL3D_1_1CTessFacePListNode.html#a5">unlinkInPList</a>();
+01962 <font class="keywordflow">return</font>;
+01963 }
+01964 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&gt;=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+01965 {
+01966 <font class="comment">// Always normal ErrorMetric. Because Faces at Tile level decide to split or merge their sons independently </font>
+01967 <font class="comment">// of "Tile ErrorMetric".</font>
+01968
+01969 <font class="comment">// The test is "when do we enter in the Split area?", so we can use Quadrant PriorityList</font>
+01970 quadrantId= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_SplitPriorityList.selectQuadrant(dirToSplitPoint);
+01971
+01972 <font class="comment">// compute distance to split as default "No Quadrant"</font>
+01973 minDeltaDistToUpdate= distSplitPoint - distNormalSplitMerge;
+01974
+01975 <font class="comment">// If a quadrant is selected, try to use it</font>
+01976 <font class="keywordflow">if</font>(quadrantId&gt;0)
+01977 {
+01978 <font class="keyword">const</font> CVector &amp;quadrantDir= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_SplitPriorityList.getQuadrantDirection(quadrantId);
+01979
+01980 <font class="comment">// We must not approach the SplitPoint at distNormalSplitMerge</font>
+01981 <font class="keywordtype">float</font> dMin= quadrantDir*dirToSplitPoint - distNormalSplitMerge;
+01982
+01983 <font class="comment">// If the dist with quadrant is too small then use the std way (without quadrant).</font>
+01984 <font class="keywordflow">if</font>( dMin&lt;<a class="code" href="tessellation_8cpp.html#a0">NL3D_TESS_USE_QUADRANT_THRESHOLD</a> )
+01985 quadrantId= 0;
+01986 <font class="comment">// else ok, use quadrant behavior</font>
+01987 <font class="keywordflow">else</font>
+01988 minDeltaDistToUpdate= dMin;
+01989 }
+01990 }
+01991 <font class="keywordflow">else</font>
+01992 {
+01993 <font class="comment">// Compute Distance of the face from RefineCenter. It is the min of the 3 points, as in computeTileErrorMetric().</font>
+01994 CVector dirToV0= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter;
+01995 CVector dirToV1= <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter;
+01996 CVector dirToV2= <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter;
+01997 <font class="keywordtype">float</font> s0= dirToV0.sqrnorm();
+01998 <font class="keywordtype">float</font> s1= dirToV1.sqrnorm();
+01999 <font class="keywordtype">float</font> s2= dirToV2.sqrnorm();
+02000 <font class="keywordtype">float</font> distMinFace= (float)sqrt( minof(s0, s1, s2) );
+02001
+02002 <font class="comment">// compute the delta distance to the normal split point. See above for doc.</font>
+02003 <font class="keywordtype">float</font> normalEMDeltaDist;
+02004 normalEMDeltaDist= distSplitPoint - distNormalSplitMerge;
+02005
+02006
+02007 <font class="comment">/* </font>
+02008 <font class="comment"> There is 3 possibles cases, according to level, and the distances minFaceDist:</font>
+02009 <font class="comment"> */</font>
+02011 <font class="keywordflow">if</font>( distMinFace &gt; CLandscapeGlobals::TileDistFar )
+02012 {
+02013 <font class="comment">// The test is "when do we enter in the Split area OR in TileDistFar area?", so we can use Quadrant PriorityList</font>
+02014 quadrantId= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_SplitPriorityList.selectQuadrant(dirToSplitPoint);
+02015
+02016 <font class="comment">// compute deltaDist as default "Direction less quadrant"</font>
+02017 minDeltaDistToUpdate= normalEMDeltaDist;
+02018 <font class="comment">// We must know when we enter in TileErrorMetric zone, because the computing is different.</font>
+02019 minDeltaDistToUpdate= <a class="code" href="bit__set_8cpp.html#a0">min</a>(minDeltaDistToUpdate, distMinFace - CLandscapeGlobals::TileDistFar);
+02020
+02021 <font class="comment">// try with quadrant if &gt; 0.</font>
+02022 <font class="keywordflow">if</font>(quadrantId&gt;0)
+02023 {
+02024 <font class="keyword">const</font> CVector &amp;quadrantDir= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_SplitPriorityList.getQuadrantDirection(quadrantId);
+02025
+02026 <font class="comment">// We must not approach the SplitPoint at distNormalSplitMerge</font>
+02027 <font class="keywordtype">float</font> dMin= quadrantDir*dirToSplitPoint - distNormalSplitMerge;
+02028 <font class="comment">// and we must not reach one of the 3 sphere (Vi, TileDistFar).</font>
+02029 <font class="keywordtype">float</font> d0 = quadrantDir*dirToV0 - CLandscapeGlobals::TileDistFar;
+02030 <font class="keywordtype">float</font> d1 = quadrantDir*dirToV1 - CLandscapeGlobals::TileDistFar;
+02031 <font class="keywordtype">float</font> d2 = quadrantDir*dirToV2 - CLandscapeGlobals::TileDistFar;
+02032 <font class="comment">// take min dist</font>
+02033 dMin= minof(dMin, d0, d1, d2);
+02034
+02035 <font class="comment">// If the dist with quadrant is too small then use the std way (without quadrant).</font>
+02036 <font class="keywordflow">if</font>( dMin&lt;<a class="code" href="tessellation_8cpp.html#a0">NL3D_TESS_USE_QUADRANT_THRESHOLD</a> )
+02037 quadrantId= 0;
+02038 <font class="comment">// else ok, use quadrant behavior</font>
+02039 <font class="keywordflow">else</font>
+02040 minDeltaDistToUpdate= dMin;
+02041 }
+02042 }
+02044 <font class="keywordflow">else</font> <font class="keywordflow">if</font>( distMinFace &gt; CLandscapeGlobals::TileDistNear )
+02045 {
+02046 <font class="comment">// NB: can't use quadrant behavior here. Leave quadrantId at 0.</font>
+02047
+02048 <font class="comment">// Profile</font>
+02049 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a82">ProfNRefineInTileTransition</a>, 1);
+02050
+02051 <font class="comment">// Compute distance to split/Merge in TileTransition</font>
+02052 <font class="keywordtype">float</font> distTileTransSplitMerge;
+02053 <font class="keywordtype">float</font> maxDeltaDist= 8;
+02054 <font class="keywordtype">float</font> minDeltaDist= 0;
+02055 uint nbRecurs= 6;
+02056 <font class="keywordtype">float</font> nearLimit;
+02057 nearLimit= CLandscapeGlobals::RefineThreshold * <a class="code" href="classNL3D_1_1CTessFace.html#a9">computeNearLimit</a>();
+02058 <font class="comment">// search the distance to split recursively.</font>
+02059 <font class="keywordflow">for</font>(uint i=0; i&lt; nbRecurs; i++)
+02060 {
+02061 <font class="keywordtype">float</font> pivotDeltaDist= (maxDeltaDist-minDeltaDist)/2;
+02062 <font class="comment">// If the em computed with this distance is still &lt;1 (ie merged), then we can move further.</font>
+02063 <font class="keywordflow">if</font> ( <a class="code" href="classNL3D_1_1CTessFace.html#c1">computeTileEMForUpdateRefine</a>(distSplitPoint-pivotDeltaDist, distMinFace-pivotDeltaDist, nearLimit ) &lt; 1)
+02064 minDeltaDist= pivotDeltaDist;
+02065 <font class="comment">// else we must move not as far</font>
+02066 <font class="keywordflow">else</font>
+02067 maxDeltaDist= pivotDeltaDist;
+02068 }
+02069 <font class="comment">// And so take the minimum resulting delta distance</font>
+02070 distTileTransSplitMerge= minDeltaDist;
+02071
+02072 <font class="comment">// take the min with distance of distMinFace to the TileDistNear and TileDistFar sphere, because formula change at</font>
+02073 <font class="comment">// those limits.</font>
+02074 minDeltaDistToUpdate= <a class="code" href="bit__set_8cpp.html#a0">min</a>(distTileTransSplitMerge, CLandscapeGlobals::TileDistFar - distMinFace );
+02075 minDeltaDistToUpdate= <a class="code" href="bit__set_8cpp.html#a0">min</a>(minDeltaDistToUpdate, distMinFace - CLandscapeGlobals::TileDistNear);
+02076 }
+02078 <font class="keywordflow">else</font>
+02079 {
+02080 <font class="comment">// because the face is not a Tile Level (ie Level&lt;Patch-&gt;TileLimitLevel), it should be splitted, </font>
+02081 <font class="comment">// and won't merge until reaching at least the TileDistNear sphere.</font>
+02082 <font class="comment">// if not splited (should not arise), force the split next time.</font>
+02083 minDeltaDistToUpdate= 0;
+02084 }
+02085
+02086 }
+02087
+02088 <font class="comment">// Profile.</font>
+02089 <font class="keywordflow">if</font>(minDeltaDistToUpdate&lt;0.0625)
+02090 {
+02091 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a83">ProfNRefineWithLowDistance</a>, 1);
+02092 }
+02093
+02094
+02095 <font class="comment">// insert in the Split priority list.</font>
+02096 <font class="comment">// Until the RefineCenter move under minDeltaDistToUpdate, we don't need to test face.</font>
+02097 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_SplitPriorityList.insert(quadrantId, minDeltaDistToUpdate, <font class="keyword">this</font>);
+02098 }
+02099 }
+02100
+02101
+02102 <font class="comment">// ***************************************************************************</font>
+<a name="l02103"></a><a class="code" href="classNL3D_1_1CTessFace.html#a15">02103</a> <font class="keywordtype">void</font> CTessFace::updateRefineMerge()
+02104 {
+02105 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a77">ProfNRefineFaces</a>, 1);
+02106
+02107 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>);
+02108 <font class="comment">// The face must be splitted, because tested for merge.</font>
+02109 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+02110
+02111 <font class="comment">/*</font>
+02112 <font class="comment"> NB: see above for some updateRefine*** doc.</font>
+02113 <font class="comment"> */</font>
+02114
+02115 <font class="comment">// Test for merge.</font>
+02116 <font class="comment">//-----------------------</font>
+02117 <font class="keywordtype">bool</font> merged= <font class="keyword">false</font>;
+02118 {
+02119 <a class="code" href="classNL3D_1_1CTessFace.html#a10">updateErrorMetric</a>();
+02120 <font class="keywordtype">float</font> ps=<a class="code" href="classNL3D_1_1CTessFace.html#z821_3">ErrorMetric</a>;
+02121 ps*= CLandscapeGlobals::OORefineThreshold;
+02122 <font class="comment">// 1.0f is the point of split().</font>
+02123 <font class="comment">// 2.0f is the end of geomorph.</font>
+02124
+02125
+02126 <font class="comment">// Test merge.</font>
+02127 <font class="comment">//---------------------</font>
+02128 <font class="comment">// Else, must merge ??</font>
+02129 <font class="keywordflow">if</font>(ps&lt;1.0f)
+02130 {
+02131 <font class="comment">// Merge only if agree, and neighbors agree.</font>
+02132 <font class="comment">// canMerge() test all the good thing: FBase==CantMergeFace, or this is rectangular etc...</font>
+02133 <font class="comment">// The test is propagated to neighbors.</font>
+02134 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#c2">canMerge</a>(<font class="keyword">true</font>))
+02135 {
+02136 <a class="code" href="classNL3D_1_1CTessFace.html#a12">merge</a>();
+02137
+02138 <font class="comment">// NB: here, merge() is not propagated to fathers (supposed to be not very usefull).</font>
+02139
+02140 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02141 {
+02142 merged= <font class="keyword">true</font>;
+02143 }
+02144 }
+02145 }
+02146 }
+02147
+02148
+02149 <font class="comment">// Insert the face in the priority list.</font>
+02150 <font class="comment">//-----------------------</font>
+02151 <font class="comment">// If merged, then insertion in Landscape-&gt;SplitPriorityList at 0 has been done. so nothing to update.</font>
+02152 <font class="comment">// Else, must compute when whe should re-test.</font>
+02153 <font class="keywordflow">if</font>(!merged)
+02154 {
+02155 <font class="comment">// the face is splitted here.</font>
+02156 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+02157
+02158 <font class="keywordtype">float</font> minDeltaDistToUpdate;
+02159
+02160
+02161 <font class="comment">// The distance of SplitPoint to center.</font>
+02162 <font class="keywordtype">float</font> distSplitPoint= (<a class="code" href="classNL3D_1_1CTessFace.html#z821_2">SplitPoint</a> - CLandscapeGlobals::RefineCenter).norm();
+02163 <font class="comment">// Compute distance from refineCenter to normal split/merge (ie without tile transition).</font>
+02164 <font class="keywordtype">float</font> distNormalSplitMerge= (float)sqrt(<a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>*CLandscapeGlobals::OORefineThreshold);
+02165
+02166
+02167 <font class="comment">// If the face is at its max subdivision</font>
+02168 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&gt;=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel+CLandscapeGlobals::TileMaxSubdivision)
+02169 {
+02170 <font class="comment">// since the face is splitted, then must test always this face, because we must merge it (as soon as it is possible).</font>
+02171 minDeltaDistToUpdate= 0;
+02172 }
+02173 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&gt;=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+02174 {
+02175 <font class="comment">// Always normal ErrorMetric. Because Faces at Tile level decide to split or merge their sons independently </font>
+02176 <font class="comment">// of "Tile ErrorMetric".</font>
+02177 <font class="comment">// since splitted, compute distance to merge.</font>
+02178 minDeltaDistToUpdate= distNormalSplitMerge - distSplitPoint;
+02179 <font class="comment">// NB: it is possible that minDeltaDistToUpdate&lt;0. A good example is when we are enforced split.</font>
+02180 <font class="comment">// Then, distSplitMerge may be &lt; distSplitPoint, meaning we should have not split, but a neigbhor has enforced us.</font>
+02181 <font class="comment">// So now, must test every frame if we can merge....</font>
+02182 minDeltaDistToUpdate= max( 0.f, minDeltaDistToUpdate );
+02183 }
+02184 <font class="keywordflow">else</font>
+02185 {
+02186 <font class="comment">// Compute Distance of the face from RefineCenter. It is the min of the 3 points, as in computeTileErrorMetric().</font>
+02187 <font class="keywordtype">float</font> s0= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter).sqrnorm();
+02188 <font class="keywordtype">float</font> s1= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter).sqrnorm();
+02189 <font class="keywordtype">float</font> s2= (<a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;EndPos - CLandscapeGlobals::RefineCenter).sqrnorm();
+02190 <font class="keywordtype">float</font> distMinFace= (float)sqrt( minof(s0, s1, s2) );
+02191
+02192 <font class="comment">// compute the delta distance to the normal split point. See above for doc.</font>
+02193 <font class="keywordtype">float</font> normalEMDeltaDist;
+02194 normalEMDeltaDist= distNormalSplitMerge - distSplitPoint;
+02195 normalEMDeltaDist= max( 0.f, normalEMDeltaDist );
+02196
+02197
+02198 <font class="comment">/* </font>
+02199 <font class="comment"> There is 3 possibles cases, according to level, and the distances minFaceDist:</font>
+02200 <font class="comment"> */</font>
+02202 <font class="keywordflow">if</font>( distMinFace &gt; CLandscapeGlobals::TileDistFar )
+02203 {
+02204 <font class="comment">// normal geomorph. Any face compute the distance to the SplitPoint, and take min with distance to</font>
+02205 <font class="comment">// the TileDistFar sphere. </font>
+02206 minDeltaDistToUpdate= normalEMDeltaDist;
+02207
+02208 <font class="comment">// We must know when we enter in TileErrorMetric zone, because the computing is different.</font>
+02209 minDeltaDistToUpdate= <a class="code" href="bit__set_8cpp.html#a0">min</a>(minDeltaDistToUpdate, distMinFace - CLandscapeGlobals::TileDistFar);
+02210 }
+02212 <font class="keywordflow">else</font> <font class="keywordflow">if</font>( distMinFace &gt; CLandscapeGlobals::TileDistNear )
+02213 {
+02214 <font class="comment">// Profile</font>
+02215 <a class="code" href="landscape__profile_8h.html#a2">NL3D_PROFILE_LAND_ADD</a>(<a class="code" href="namespaceNL3D.html#a82">ProfNRefineInTileTransition</a>, 1);
+02216
+02217
+02218 <font class="comment">// Compute distance to split/Merge in TileTransition</font>
+02219 <font class="keywordtype">float</font> distTileTransSplitMerge;
+02220 <font class="keywordtype">float</font> maxDeltaDist= 8;
+02221 <font class="keywordtype">float</font> minDeltaDist= 0;
+02222 uint nbRecurs= 6;
+02223 <font class="keywordtype">float</font> nearLimit;
+02224 nearLimit= CLandscapeGlobals::RefineThreshold * <a class="code" href="classNL3D_1_1CTessFace.html#a9">computeNearLimit</a>();
+02225 <font class="comment">// Since splitted, compute distance to merge.</font>
+02226 <font class="comment">// search the distance recursively.</font>
+02227 <font class="keywordflow">for</font>(uint i=0; i&lt; nbRecurs; i++)
+02228 {
+02229 <font class="keywordtype">float</font> pivotDeltaDist= (maxDeltaDist-minDeltaDist)/2;
+02230 <font class="comment">// If the em computed with this distance is still &gt;1 (ie splitted), then we can move further.</font>
+02231 <font class="keywordflow">if</font> ( <a class="code" href="classNL3D_1_1CTessFace.html#c1">computeTileEMForUpdateRefine</a>(distSplitPoint+pivotDeltaDist, distMinFace+pivotDeltaDist, nearLimit ) &gt; 1)
+02232 minDeltaDist= pivotDeltaDist;
+02233 <font class="comment">// else we must move not as far</font>
+02234 <font class="keywordflow">else</font>
+02235 maxDeltaDist= pivotDeltaDist;
+02236 }
+02237 <font class="comment">// And so take the minimum resulting delta distance</font>
+02238 distTileTransSplitMerge= minDeltaDist;
+02239
+02240 <font class="comment">// take the min with distance of distMinFace to the TileDistNear and TileDistFar sphere, because formula change at</font>
+02241 <font class="comment">// those limits.</font>
+02242 minDeltaDistToUpdate= <a class="code" href="bit__set_8cpp.html#a0">min</a>(distTileTransSplitMerge, CLandscapeGlobals::TileDistFar - distMinFace );
+02243 minDeltaDistToUpdate= <a class="code" href="bit__set_8cpp.html#a0">min</a>(minDeltaDistToUpdate, distMinFace - CLandscapeGlobals::TileDistNear);
+02244 }
+02246 <font class="keywordflow">else</font>
+02247 {
+02248 <font class="comment">// because the face is not a Tile Level (ie Level&lt;Patch-&gt;TileLimitLevel), it should be splitted, </font>
+02249 <font class="comment">// and won't merge until reaching at least the TileDistNear sphere.</font>
+02250 <font class="comment">// Since splitted, Must enter in TileErrorMetric area to know when to merge.</font>
+02251 minDeltaDistToUpdate= CLandscapeGlobals::TileDistNear - distMinFace;
+02252 }
+02253
+02254 }
+02255
+02256 <font class="comment">// Merge Refine Threshold: because of enforced splits, we have lot of faces whit minDeltaDistToUpdate&lt;0, because</font>
+02257 <font class="comment">// they alwayas want to merge. To avoid this, add a delta, which delay the test for merge.</font>
+02258 <font class="comment">// The caveat is that faces which do not need this may merge later. But 2 meters won't add too many faces.</font>
+02259 minDeltaDistToUpdate+= <a class="code" href="landscape__def_8h.html#a7">NL3D_REFINE_MERGE_THRESHOLD</a>;
+02260
+02261 <font class="comment">// insert in the Merge priority list.</font>
+02262 <font class="comment">// Until the RefineCenter move under minDeltaDistToUpdate, we don't need to test face.</font>
+02263 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;_MergePriorityList.insert(0, minDeltaDistToUpdate, <font class="keyword">this</font>);
+02264 }
+02265 }
+02266
+02267
+02268 <font class="comment">// ***************************************************************************</font>
+<a name="l02269"></a><a class="code" href="classNL3D_1_1CTessFace.html#a17">02269</a> <font class="keywordtype">void</font> CTessFace::unbind()
+02270 {
+02271 <font class="comment">// NB: since CantMergeFace has a NULL patch ptr, it is unbound too.</font>
+02272
+02273 <font class="comment">// Square case.</font>
+02274 <font class="comment">//=============</font>
+02275 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02276 {
+02277 <font class="comment">// Change Left/Right neighbors.</font>
+02278 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02279 {
+02280 <font class="comment">// FLeft and FRight pointers are only valid in Leaves nodes.</font>
+02281 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>)
+02282 {
+02283 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;changeNeighbor(<font class="keyword">this</font>, NULL);
+02284 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>= NULL;
+02285 }
+02286 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>)
+02287 {
+02288 <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>-&gt;changeNeighbor(<font class="keyword">this</font>, NULL);
+02289 <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>= NULL;
+02290 }
+02291 }
+02292 <font class="comment">// Change Base neighbors.</font>
+02293 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>)
+02294 {
+02295 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *oldNeigbhorFace= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>;
+02296
+02297 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;changeNeighbor(<font class="keyword">this</font>, NULL);
+02298 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>= NULL;
+02299 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02300 {
+02301 <font class="comment">// Duplicate the VBase of sons, so the unbind is correct and no vertices are shared.</font>
+02302 CTessVertex *old= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase;
+02303 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessVertex();
+02304 *(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase)= *old;
+02305 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase;
+02306
+02307 <font class="comment">// For geomorph (VertexProgram or soft), compute good MaxFaceSize and MaxNearLimit (change since unbinded)</font>
+02308 <font class="comment">// update us.</font>
+02309 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxFaceSize= <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>;
+02310 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxNearLimit= <a class="code" href="classNL3D_1_1CTessFace.html#a9">computeNearLimit</a>();
+02311 <font class="comment">// update our neigbhor, only if not a multiple patch face.</font>
+02312 <font class="keywordflow">if</font>(oldNeigbhorFace-&gt;Patch)
+02313 {
+02314 old-&gt;MaxFaceSize= oldNeigbhorFace-&gt;Size;
+02315 old-&gt;MaxNearLimit= oldNeigbhorFace-&gt;computeNearLimit();
+02316 }
+02317 }
+02318 }
+02319 }
+02320 <font class="comment">// Rectangular case.</font>
+02321 <font class="comment">//==================</font>
+02322 <font class="keywordflow">else</font>
+02323 {
+02324 <font class="comment">// Doens't need to test FBase, since must be same patch.</font>
+02325 <font class="comment">// In rectangular, FLeft has the behavior of FBase in square case.</font>
+02326 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>)
+02327 {
+02328 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *oldNeigbhorFace= <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>;
+02329
+02330 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;changeNeighbor(<font class="keyword">this</font>, NULL);
+02331 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>= NULL;
+02332 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02333 {
+02334 <font class="comment">// Duplicate the VBase of sons, so the unbind is correct and no vertices are shared.</font>
+02335 <font class="comment">// NB: this code is a bit different from square case.</font>
+02336 CTessVertex *old= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase;
+02337 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;newTessVertex();
+02338 *(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase)= *old;
+02339 <font class="comment">// This is the difference: (see rectangle tesselation rules).</font>
+02340 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase;
+02341 <font class="comment">// Yoyo_patch_himself (12/02/2001): I forgot this one!!</font>
+02342 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft);
+02343 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;VRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase;
+02344
+02345
+02346 <font class="comment">// For geomorph (VertexProgram or soft), compute good MaxFaceSize and MaxNearLimit (change since unbinded)</font>
+02347 <font class="comment">// update us.</font>
+02348 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxFaceSize= <a class="code" href="classNL3D_1_1CTessFace.html#z821_1">Size</a>;
+02349 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;MaxNearLimit= <a class="code" href="classNL3D_1_1CTessFace.html#a9">computeNearLimit</a>();
+02350 <font class="comment">// update our neigbhor, only if not a multiple patch face.</font>
+02351 <font class="keywordflow">if</font>(oldNeigbhorFace-&gt;Patch)
+02352 {
+02353 old-&gt;MaxFaceSize= oldNeigbhorFace-&gt;Size;
+02354 old-&gt;MaxNearLimit= oldNeigbhorFace-&gt;computeNearLimit();
+02355 }
+02356 }
+02357 }
+02358 <font class="comment">// But FRight still valid in leaves nodes only.</font>
+02359 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02360 {
+02361 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>-&gt;Patch!=<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>)
+02362 {
+02363 <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>-&gt;changeNeighbor(<font class="keyword">this</font>, NULL);
+02364 <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>= NULL;
+02365 }
+02366 }
+02367 }
+02368
+02369 <font class="comment">// Propagate unbind.</font>
+02370 <font class="comment">//==================</font>
+02371 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02372 {
+02373 <font class="comment">// update sons vertex pointers (since they may have been updated by me or my grandfathers).</font>
+02374 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02375 {
+02376 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>;
+02377 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>;
+02378 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>;
+02379 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>;
+02380 }
+02381 <font class="keywordflow">else</font>
+02382 {
+02383 <font class="comment">// Rectangular case. Update only ptrs which may have changed.</font>
+02384 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VLeft= <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>;
+02385 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VBase= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>;
+02386 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VRight= <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>;
+02387 }
+02388
+02389 <font class="comment">// Must re-create good Vertex links for Far and Near Vertices!!!</font>
+02390 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;updateNearFarVertices();
+02391 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;updateNearFarVertices();
+02392 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02393 {
+02394 <font class="comment">//NB: must do this for Base neighbor (see unbind() rectangular case...).</font>
+02395 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonRight);
+02396 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;updateNearFarVertices();
+02397 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonRight-&gt;updateNearFarVertices();
+02398 }
+02399
+02400 <font class="comment">// unbind the sons.</font>
+02401 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;unbind();
+02402 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;unbind();
+02403 }
+02404
+02405 }
+02406 <font class="comment">// ***************************************************************************</font>
+<a name="l02407"></a><a class="code" href="classNL3D_1_1CTessFace.html#a18">02407</a> <font class="keywordtype">void</font> CTessFace::forceMerge()
+02408 {
+02409 <font class="keywordflow">if</font>(<font class="keyword">this</font>== &amp;<a class="code" href="classNL3D_1_1CTessFace.html#r0">CantMergeFace</a>)
+02410 <font class="keywordflow">return</font>;
+02411
+02412 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02413 {
+02414 <font class="comment">// First, force merge of Sons and neighbor sons, to have a diamond configuration.</font>
+02415 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;forceMerge();
+02416 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;forceMerge();
+02417
+02418 <font class="comment">// forceMerge of necessary neighbors.</font>
+02419 <a class="code" href="classNL3D_1_1CTessFace.html#z819_15">RecursMarkForceMerge</a>=<font class="keyword">true</font>;
+02420 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02421 {
+02422 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;RecursMarkForceMerge)
+02423 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;forceMerge();
+02424 }
+02425 <font class="keywordflow">else</font>
+02426 {
+02427 <font class="comment">// Rectangular case. May have a longer propagation...</font>
+02428 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;RecursMarkForceMerge)
+02429 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;forceMerge();
+02430 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a> &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;RecursMarkForceMerge)
+02431 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>-&gt;forceMerge();
+02432 }
+02433 <a class="code" href="classNL3D_1_1CTessFace.html#z819_15">RecursMarkForceMerge</a>=<font class="keyword">false</font>;
+02434
+02435 <font class="comment">// If still a parent, merge.</font>
+02436 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02437 <a class="code" href="classNL3D_1_1CTessFace.html#a12">merge</a>();
+02438 }
+02439 }
+02440
+02441
+02442 <font class="comment">// ***************************************************************************</font>
+<a name="l02443"></a><a class="code" href="classNL3D_1_1CTessFace.html#a23">02443</a> <font class="keywordtype">void</font> CTessFace::forceMergeAtTileLevel()
+02444 {
+02445 <font class="keywordflow">if</font>(<font class="keyword">this</font>== &amp;<a class="code" href="classNL3D_1_1CTessFace.html#r0">CantMergeFace</a>)
+02446 <font class="keywordflow">return</font>;
+02447
+02448 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02449 {
+02450 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;forceMergeAtTileLevel();
+02451 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;forceMergeAtTileLevel();
+02452 }
+02453 <font class="keywordflow">else</font>
+02454 {
+02455 <font class="comment">// If we are at tile subdivision, we must force our sons to merge.</font>
+02456 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>==<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+02457 <a class="code" href="classNL3D_1_1CTessFace.html#a18">forceMerge</a>();
+02458 }
+02459 }
+02460
+02461
+02462 <font class="comment">// ***************************************************************************</font>
+<a name="l02463"></a><a class="code" href="classNL3D_1_1CTessFace.html#a24">02463</a> <font class="keywordtype">void</font> CTessFace::averageTesselationVertices()
+02464 {
+02465 <font class="comment">// If we are not splitted, no-op.</font>
+02466 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02467 <font class="keywordflow">return</font>;
+02468
+02469
+02470 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *neighbor;
+02471 <font class="comment">// Normal square case.</font>
+02472 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02473 {
+02474 neighbor= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>;
+02475 }
+02476 <font class="comment">// Special Rectangular case.</font>
+02477 <font class="keywordflow">else</font>
+02478 {
+02479 <font class="comment">// NB: here, just need to compute average of myself with FLeft, because my neighbor FBase </font>
+02480 <font class="comment">// is on same patch (see splitRectangular()), and is average with its FLeft neighbor is done </font>
+02481 <font class="comment">// on an other branch of the recurs call.</font>
+02482 neighbor= <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>;
+02483 }
+02484
+02485
+02486 <font class="comment">/* Try to average with neighbor.</font>
+02487 <font class="comment"> - if no neighbor, no-op :).</font>
+02488 <font class="comment"> - if neighbor is bind 1/N (CantMergeFace), no-op too, because the vertex is a BaseVertex, so don't modify.</font>
+02489 <font class="comment"> - if my patch is same than my neighbor, then we are on a same patch :), and so no need to average.</font>
+02490 <font class="comment"> */</font>
+02491 <font class="keywordflow">if</font>(neighbor!=NULL &amp;&amp; neighbor!=&amp;<a class="code" href="classNL3D_1_1CTessFace.html#r0">CantMergeFace</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>!= neighbor-&gt;Patch)
+02492 {
+02493 <a class="code" href="debug_8h.html#a6">nlassert</a>(neighbor-&gt;Patch);
+02494 <a class="code" href="debug_8h.html#a6">nlassert</a>(!neighbor-&gt;isLeaf());
+02495 <font class="comment">// must compute average beetween me and my neighbor.</font>
+02496 <font class="comment">// NB: this work with both rectangular and square triangles (see split*()).</font>
+02497 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase == neighbor-&gt;SonLeft-&gt;VBase);
+02498
+02499 CVector v0= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;computeVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getT());
+02500 CVector v1= neighbor-&gt;Patch-&gt;computeVertex(neighbor-&gt;SonLeft-&gt;PVBase.getS(), neighbor-&gt;SonLeft-&gt;PVBase.getT());
+02501
+02502 <font class="comment">// And so set the average.</font>
+02503 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;EndPos= (v0+v1)/2;
+02504 }
+02505
+02506
+02507 <font class="comment">// Do same thing for sons. NB: see above, we are not a leaf.</font>
+02508 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;averageTesselationVertices();
+02509 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;averageTesselationVertices();
+02510 }
+02511
+02512
+02513 <font class="comment">// ***************************************************************************</font>
+<a name="l02514"></a><a class="code" href="classNL3D_1_1CTessFace.html#a25">02514</a> <font class="keywordtype">void</font> CTessFace::refreshTesselationGeometry()
+02515 {
+02516 <font class="comment">// must enlarge the little tessBlock (if any), for clipping.</font>
+02517 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;extendTessBlockWithEndPos(<font class="keyword">this</font>);
+02518
+02519 <font class="comment">// If we are not splitted, no-op.</font>
+02520 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02521 <font class="keywordflow">return</font>;
+02522
+02523
+02524 <font class="comment">/* NB: rectangular case: just need to take SonLeft-&gt;VBase, because my neighbor on FBase will compute his son</font>
+02525 <font class="comment"> on an other branch of the recurs call.</font>
+02526 <font class="comment"> */</font>
+02527 <font class="comment">// re-compute this position (maybe with new noise geometry in Tile Edition).</font>
+02528 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;EndPos= <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;computeVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getT());
+02529 <font class="comment">// overwrite cur Pos (NB: specialy hardcoded for Tile edition).</font>
+02530 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;Pos= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;EndPos;
+02531
+02532 <font class="comment">// Do same thing for sons. NB: see above, we are not a leaf.</font>
+02533 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;refreshTesselationGeometry();
+02534 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;refreshTesselationGeometry();
+02535 }
+02536
+02537
+02538 <font class="comment">// ***************************************************************************</font>
+<a name="l02539"></a><a class="code" href="classNL3D_1_1CTessFace.html#a20">02539</a> <font class="keywordtype">bool</font> CTessFace::updateBindEdge(CTessFace *&amp;edgeFace, <font class="keywordtype">bool</font> &amp;splitWanted)
+02540 {
+02541 <font class="comment">// Return true, when the bind should be Ok, or if a split has occured.</font>
+02542 <font class="comment">// Return false only if pointers are updated, without splits.</font>
+02543
+02544 <font class="keywordflow">if</font>(edgeFace==NULL)
+02545 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02546
+02547 <font class="keywordflow">if</font>(edgeFace-&gt;isLeaf())
+02548 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02549
+02550 <font class="comment">/*</font>
+02551 <font class="comment"> Look at the callers, and you'll see that "this" is always a leaf.</font>
+02552 <font class="comment"> Therefore, edgeFace is a valid pointer (either if it is FLeft, FRight or FBase).</font>
+02553 <font class="comment"> */</font>
+02554
+02555 <font class="comment">// MultiPatch face case.</font>
+02556 <font class="comment">//======================</font>
+02557 <font class="comment">// If neighbor is a multiple face.</font>
+02558 <font class="keywordflow">if</font>(edgeFace-&gt;Patch==NULL &amp;&amp; edgeFace-&gt;FBase==<font class="keyword">this</font>)
+02559 {
+02560 splitWanted= <font class="keyword">true</font>;
+02561 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02562 }
+02563
+02564
+02565 <font class="comment">// neighbor is a "Square face" case.</font>
+02566 <font class="comment">//==================================</font>
+02567 <font class="keywordflow">if</font>(!edgeFace-&gt;isRectangular())
+02568 {
+02569 <font class="comment">// NB: this code works either if I AM a rectangular face or a square face.</font>
+02570
+02571 <font class="comment">// If the neighbor is splitted on ourself, split...</font>
+02572 <font class="keywordflow">if</font>(edgeFace-&gt;FBase==<font class="keyword">this</font>)
+02573 {
+02574 splitWanted= <font class="keyword">true</font>;
+02575 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02576 }
+02577 <font class="keywordflow">else</font>
+02578 {
+02579 <font class="comment">// Just update pointers...</font>
+02580 <font class="keywordflow">if</font>(edgeFace-&gt;FLeft==<font class="keyword">this</font>)
+02581 {
+02582 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *sonLeft= edgeFace-&gt;SonLeft;
+02583 sonLeft-&gt;FBase= <font class="keyword">this</font>;
+02584 edgeFace= sonLeft;
+02585 }
+02586 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(edgeFace-&gt;FRight==<font class="keyword">this</font>)
+02587 {
+02588 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *sonRight= edgeFace-&gt;SonRight;
+02589 sonRight-&gt;FBase= <font class="keyword">this</font>;
+02590 edgeFace= sonRight;
+02591 }
+02592 <font class="keywordflow">else</font>
+02593 {
+02594 <font class="comment">// Look at the callers, and you'll see that "this" is always a leaf.</font>
+02595 <font class="comment">// Therefore, we should never be here.</font>
+02596 <a class="code" href="debug_8h.html#a12">nlstop</a>;
+02597 }
+02598 }
+02599 }
+02600 <font class="comment">// neighbor is a "Rectangle face" case.</font>
+02601 <font class="comment">//=====================================</font>
+02602 <font class="keywordflow">else</font>
+02603 {
+02604 <font class="comment">// NB: this code works either if I AM a rectangular face or a square face.</font>
+02605
+02606 <font class="comment">// If the neighbor is splitted on ourself, split...</font>
+02607 <font class="comment">// Test FLeft because of rectangular case... :)</font>
+02608 <font class="comment">// FBase should be tested too. If edgeFace-&gt;FBase==this, I should be myself a rectangular face.</font>
+02609 <font class="keywordflow">if</font>(edgeFace-&gt;FLeft==<font class="keyword">this</font> || edgeFace-&gt;FBase==<font class="keyword">this</font>)
+02610 {
+02611 splitWanted= <font class="keyword">true</font>;
+02612 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02613 }
+02614 <font class="keywordflow">else</font>
+02615 {
+02616 <font class="keywordflow">if</font>(edgeFace-&gt;FRight==<font class="keyword">this</font>)
+02617 {
+02618 <font class="comment">// See rectangular tesselation rules, too know why we do this.</font>
+02619 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *sonRight= edgeFace-&gt;SonRight;
+02620 sonRight-&gt;FRight= <font class="keyword">this</font>;
+02621 edgeFace= sonRight;
+02622 }
+02623 <font class="keywordflow">else</font>
+02624 {
+02625 <font class="comment">// Look at the callers, and you'll see that "this" is always a leaf.</font>
+02626 <font class="comment">// Therefore, we should never be here.</font>
+02627 <a class="code" href="debug_8h.html#a12">nlstop</a>;
+02628 }
+02629 }
+02630 }
+02631
+02632 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+02633 }
+02634
+02635
+02636
+02637 <font class="comment">// ***************************************************************************</font>
+<a name="l02638"></a><a class="code" href="classNL3D_1_1CTessFace.html#a22">02638</a> <font class="keywordtype">void</font> CTessFace::updateBindAndSplit()
+02639 {
+02640 <font class="keywordtype">bool</font> splitWanted= <font class="keyword">false</font>;
+02641 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f0= NULL;
+02642 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f1= NULL;
+02643 <font class="comment">/*</font>
+02644 <font class="comment"> Look at the callers, and you'll see that "this" is always a leaf.</font>
+02645 <font class="comment"> Therefore, FBase, FLeft and FRight are good pointers, and *FLeft and *FRight should be Ok too.</font>
+02646 <font class="comment"> */</font>
+02647 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+02648 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a20">updateBindEdge</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>, splitWanted));
+02649 <font class="comment">// FLeft and FRight pointers are only valid in Leaves nodes.</font>
+02650 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a20">updateBindEdge</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>, splitWanted));
+02651 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a20">updateBindEdge</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>, splitWanted));
+02652 <font class="comment">// In rectangular case, we MUST also update edges of FBase.</font>
+02653 <font class="comment">// Because splitRectangular() split those two faces at the same time.</font>
+02654 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02655 {
+02656 f0= <font class="keyword">this</font>;
+02657 f1= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>;
+02658 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>);
+02659 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf());
+02660 <font class="comment">// Doesn't need to update FBase-&gt;FBase, since it's me!</font>
+02661 <font class="comment">// FLeft and FRight pointers are only valid in Leaves nodes.</font>
+02662 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;updateBindEdge(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;FLeft, splitWanted));
+02663 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;updateBindEdge(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;FRight, splitWanted));
+02664 }
+02665
+02666
+02667
+02668 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *fmult= NULL;
+02669 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *fmult0= NULL;
+02670 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *fmult1= NULL;
+02671 <font class="comment">// If multipatch face case.</font>
+02672 <font class="comment">//=========================</font>
+02673 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02674 {
+02675 <font class="comment">// multipatch face case are detected when face-&gt;Patch==NULL !!!</font>
+02676 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;Patch==NULL)
+02677 {
+02678 fmult= <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>;
+02679 <font class="comment">// First, trick: FBase is NULL, so during the split. =&gt; no ptr problem.</font>
+02680 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>= NULL;
+02681 }
+02682 }
+02683 <font class="keywordflow">else</font>
+02684 {
+02685 <font class="comment">// multipatch face case are detected when face-&gt;Patch==NULL !!!</font>
+02686 <font class="keywordflow">if</font>(f0-&gt;FLeft &amp;&amp; f0-&gt;FLeft-&gt;Patch==NULL)
+02687 {
+02688 fmult0= f0-&gt;FLeft;
+02689 <font class="comment">// First, trick: neighbor is NULL, so during the split. =&gt; no ptr problem.</font>
+02690 f0-&gt;FLeft= NULL;
+02691 }
+02692 <font class="comment">// multipatch face case are detected when face-&gt;Patch==NULL !!!</font>
+02693 <font class="keywordflow">if</font>(f1-&gt;FLeft &amp;&amp; f1-&gt;FLeft-&gt;Patch==NULL)
+02694 {
+02695 fmult1= f1-&gt;FLeft;
+02696 <font class="comment">// First, trick: neighbor is NULL, so during the split. =&gt; no ptr problem.</font>
+02697 f1-&gt;FLeft= NULL;
+02698 }
+02699 }
+02700
+02701 <font class="comment">// Then split, and propagate.</font>
+02702 <font class="comment">//===========================</font>
+02703 <a class="code" href="classNL3D_1_1CTessFace.html#a11">split</a>(<font class="keyword">false</font>);
+02704 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+02705 {
+02706 <font class="keywordflow">if</font>(FBase)
+02707 {
+02708 <font class="keywordflow">while</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf())
+02709 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;updateBindAndSplit();
+02710 }
+02711 <font class="comment">// There is a possible bug here (maybe easily patched). Sons may have be propagated splitted.</font>
+02712 <font class="comment">// And problems may arise because this face hasn't yet good connectivity.</font>
+02713 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;isLeaf() &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;isLeaf());
+02714 }
+02715 <font class="keywordflow">else</font>
+02716 {
+02717 <font class="keywordflow">if</font>(f0-&gt;FLeft)
+02718 {
+02719 <font class="keywordflow">while</font>(f0-&gt;FLeft-&gt;isLeaf())
+02720 f0-&gt;FLeft-&gt;updateBindAndSplit();
+02721 }
+02722 <font class="keywordflow">if</font>(f1-&gt;FLeft)
+02723 {
+02724 <font class="keywordflow">while</font>(f1-&gt;FLeft-&gt;isLeaf())
+02725 f1-&gt;FLeft-&gt;updateBindAndSplit();
+02726 }
+02727 <font class="comment">// There is a possible bug here (maybe easily patched). Sons may have be propagated splitted.</font>
+02728 <font class="comment">// And problems may arise because this face hasn't yet good connectivity.</font>
+02729 <a class="code" href="debug_8h.html#a6">nlassert</a>(f0-&gt;SonLeft-&gt;isLeaf() &amp;&amp; f0-&gt;SonRight-&gt;isLeaf());
+02730 <a class="code" href="debug_8h.html#a6">nlassert</a>(f1-&gt;SonLeft-&gt;isLeaf() &amp;&amp; f1-&gt;SonRight-&gt;isLeaf());
+02731 }
+02732
+02733
+02734 <font class="comment">// If multipatch face case, update neighbors.</font>
+02735 <font class="comment">//===========================================</font>
+02736 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>() &amp;&amp; fmult)
+02737 {
+02738 <font class="comment">// Update good Face neighbors.</font>
+02739 <font class="comment">//============================</font>
+02740 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;FRight= fmult-&gt;SonRight;
+02741 fmult-&gt;SonRight-&gt;changeNeighbor(&amp;CTessFace::MultipleBindFace, <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>);
+02742
+02743 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;FLeft= fmult-&gt;SonLeft;
+02744 fmult-&gt;SonLeft-&gt;changeNeighbor(&amp;CTessFace::MultipleBindFace, <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>);
+02745
+02746 <font class="comment">// NB: this work auto with 1/2 or 1/4. See CPatch::bind(), to understand.</font>
+02747 <font class="comment">// In 1/4 case, fmult-&gt;SonLeft and fmult-&gt;SonRight are themselves MultiPatch face. So it will recurse.</font>
+02748
+02749 <font class="comment">// Update good vertex pointer.</font>
+02750 <font class="comment">//============================</font>
+02751 CTessVertex *vert= fmult-&gt;VBase;
+02752
+02753 <font class="comment">// Copy the good coordinate: those splitted (because of noise).</font>
+02754 vert-&gt;Pos= vert-&gt;StartPos= vert-&gt;EndPos= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase-&gt;EndPos;
+02755 <font class="comment">// But delete the pointer.</font>
+02756 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessVertex(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase);
+02757 <font class="comment">// And update sons pointers, to good vertex.</font>
+02758 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;VBase= vert;
+02759 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;VBase= vert;
+02760 <font class="comment">// Compute correct centers.</font>
+02761 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;computeSplitPoint();
+02762 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;computeSplitPoint();
+02763
+02764
+02765 <font class="comment">// Update good Far vertex pointer.</font>
+02766 <font class="comment">//================================</font>
+02767 <font class="comment">// Because *-&gt;VBase may have been merged to the multiple bind face, Near/FarVertices which pointed on it must</font>
+02768 <font class="comment">// be setup.</font>
+02769 <font class="comment">// We do not have to propagate this vertex ptr change since sons are leaves!!</font>
+02770 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;isLeaf() &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;isLeaf());
+02771 <font class="comment">// update pointers on vertex.</font>
+02772 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;updateNearFarVertices();
+02773 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;updateNearFarVertices();
+02774
+02775
+02776 <font class="comment">// Bind FBase to a false face which indicate a bind 1/N.</font>
+02777 <font class="comment">// This face prevent for "this" face to be merged...</font>
+02778 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>= &amp;<a class="code" href="classNL3D_1_1CTessFace.html#r0">CantMergeFace</a>;
+02779
+02780 <font class="comment">// Therefore, the vertex will be never deleted (since face not merged).</font>
+02781 <font class="comment">// The only way to do this, is to unbind the patch from all (then the vertex is cloned), then the merge will be Ok.</font>
+02782 }
+02783 <font class="comment">// Else if rectangular.</font>
+02784 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(fmult0 || fmult1)
+02785 {
+02786 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *f;
+02787 sint i;
+02788
+02789 <font class="comment">// Same reasoning for rectangular patchs, as above.</font>
+02790 <font class="keywordflow">for</font>(i=0;i&lt;2;i++)
+02791 {
+02792 <font class="keywordflow">if</font>(i==0)
+02793 f= f0, fmult= fmult0;
+02794 <font class="keywordflow">else</font>
+02795 f= f1, fmult= fmult1;
+02796 <font class="keywordflow">if</font>(fmult)
+02797 {
+02798 <font class="comment">// Update good Face neighbors (when I am a rectangle).</font>
+02799 <font class="comment">//============================</font>
+02800 <font class="comment">// Consider the fmult face as a square face.</font>
+02801 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *toLeft, *toRight;
+02802 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *fl=f-&gt;SonLeft, *fr=f-&gt;SonRight;
+02803 toLeft= fmult-&gt;SonLeft;
+02804 toRight= fmult-&gt;SonRight;
+02805 <font class="comment">// Cross connection of sons.</font>
+02806 fl-&gt;FLeft= toLeft;
+02807 fr-&gt;FLeft= toRight;
+02808 toLeft-&gt;changeNeighbor(&amp;CTessFace::MultipleBindFace, fl);
+02809 toRight-&gt;changeNeighbor(&amp;CTessFace::MultipleBindFace, fr);
+02810
+02811 <font class="comment">// Update good vertex pointer.</font>
+02812 <font class="comment">//============================</font>
+02813 CTessVertex *vert= fmult-&gt;VBase;
+02814
+02815 <font class="comment">// Copy the good coordinate: those splitted (because of noise).</font>
+02816 <font class="comment">// NB: this work too with rectangular patch (see tesselation rules).</font>
+02817 vert-&gt;Pos= vert-&gt;StartPos= vert-&gt;EndPos= fl-&gt;VBase-&gt;EndPos;
+02818 <font class="comment">// But delete the pointer.</font>
+02819 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;getLandscape()-&gt;deleteTessVertex(fl-&gt;VBase);
+02820 <font class="comment">// And update sons pointers, to good vertex (rectangular case, see tesselation rules).</font>
+02821 fl-&gt;VBase= vert;
+02822 fr-&gt;VLeft= vert;
+02823 f-&gt;FBase-&gt;SonLeft-&gt;VRight= vert;
+02824
+02825 <font class="comment">// Point to a bind 1/N indicator.</font>
+02826 f-&gt;FLeft= &amp;<a class="code" href="classNL3D_1_1CTessFace.html#r0">CantMergeFace</a>;
+02827 }
+02828 }
+02829 <font class="comment">// After all updates done. recompute centers of both sons 's faces, and update far vertices pointers.</font>
+02830 <font class="keywordflow">for</font>(i=0;i&lt;2;i++)
+02831 {
+02832 <font class="keywordflow">if</font>(i==0)
+02833 f= f0;
+02834 <font class="keywordflow">else</font>
+02835 f= f1;
+02836 <font class="comment">// Compute correct centers.</font>
+02837 f-&gt;SonRight-&gt;computeSplitPoint();
+02838 f-&gt;SonLeft-&gt;computeSplitPoint();
+02839
+02840 <font class="comment">// Update good Far vertex pointer.</font>
+02841 <font class="comment">//================================</font>
+02842 <font class="comment">// Because *-&gt;VBase may have been merged to the multiple bind face, Near/FarVertices which pointed on it must</font>
+02843 <font class="comment">// be setup.</font>
+02844 <font class="comment">// We do not have to propagate this vertex ptr change, since sons are leaves!!</font>
+02845 <a class="code" href="debug_8h.html#a6">nlassert</a>(f-&gt;SonLeft-&gt;isLeaf() &amp;&amp; f-&gt;SonRight-&gt;isLeaf());
+02846 <font class="comment">// update pointers on vertex.</font>
+02847 f-&gt;SonLeft-&gt;updateNearFarVertices();
+02848 f-&gt;SonRight-&gt;updateNearFarVertices();
+02849 }
+02850 }
+02851 }
+02852
+02853
+02854 <font class="comment">// ***************************************************************************</font>
+<a name="l02855"></a><a class="code" href="classNL3D_1_1CTessFace.html#a21">02855</a> <font class="keywordtype">void</font> CTessFace::updateBind()
+02856 {
+02857 <font class="comment">/*</font>
+02858 <font class="comment"> Remind that updateBind() is called ONLY on the patch which is binded (not the neighbors).</font>
+02859 <font class="comment"> Since updateBind() is called on the bintree, and that precedent propagated split may have occur, we may not</font>
+02860 <font class="comment"> be a leaf here. So we are not sure that FLeft and FRight are good, and we doesn't need to update them (since we have</font>
+02861 <font class="comment"> sons).</font>
+02862 <font class="comment"> Also, since we are splitted, and correctly linked (this may not be the case in updateBindAndSplit()), FBase IS</font>
+02863 <font class="comment"> correct. His FBase neighbor and him form a diamond. So we don't need to update him.</font>
+02864 <font class="comment"></font>
+02865 <font class="comment"> Same remarks for rectangular patchs.</font>
+02866 <font class="comment"> */</font>
+02867 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02868 {
+02869 <font class="keywordtype">bool</font> splitWanted= <font class="keyword">false</font>;
+02870 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a20">updateBindEdge</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>, splitWanted));
+02871 <font class="comment">// FLeft and FRight pointers are only valid in Leaves nodes.</font>
+02872 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a20">updateBindEdge</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>, splitWanted));
+02873 <font class="keywordflow">while</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a20">updateBindEdge</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>, splitWanted));
+02874 <font class="keywordflow">if</font>(splitWanted)
+02875 <a class="code" href="classNL3D_1_1CTessFace.html#a22">updateBindAndSplit</a>();
+02876 }
+02877
+02878
+02879 <font class="comment">// Recurse to sons.</font>
+02880 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02881 {
+02882 <font class="comment">// Update bind of sons.</font>
+02883 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;updateBind();
+02884 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;updateBind();
+02885 }
+02886 }
+02887
+02888 <font class="comment">// ***************************************************************************</font>
+02889 <font class="keyword">static</font> <font class="keyword">inline</font> <font class="keywordtype">bool</font> <a class="code" href="namespaceNL3D.html#a462">matchEdge</a>(<font class="keyword">const</font> CVector2f &amp;uv0, <font class="keyword">const</font> CVector2f &amp;uv1, <font class="keyword">const</font> CVector2f &amp;uva, <font class="keyword">const</font> CVector2f &amp;uvb)
+02890 {
+02891 <font class="keywordflow">if</font>(uv0==uva &amp;&amp; uv1==uvb)
+02892 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02893 <font class="keywordflow">if</font>(uv0==uvb &amp;&amp; uv1==uva)
+02894 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02895 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+02896 }
+02897
+02898 <font class="comment">// ***************************************************************************</font>
+<a name="l02899"></a><a class="code" href="classNL3D_1_1CTessFace.html#a19">02899</a> CTessFace *CTessFace::linkTessFaceWithEdge(<font class="keyword">const</font> CVector2f &amp;uv0, <font class="keyword">const</font> CVector2f &amp;uv1, CTessFace *linkTo)
+02900 {
+02901 <font class="comment">// Compute 0,1 coords of 3 patch coords.</font>
+02902 CVector2f vb( <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getT() );
+02903 CVector2f vl( <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>.getT() );
+02904 CVector2f vr( <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>.getT() );
+02905
+02906 <font class="comment">// Search if one of the 3 edges of this triangle match the wanted edge.</font>
+02907 <font class="comment">// Base Edge</font>
+02908 <font class="keywordflow">if</font>(<a class="code" href="namespaceNL3D.html#a462">matchEdge</a>(uv0, uv1, vl, vr))
+02909 {
+02910 <font class="comment">// If leaf, check if unbound (else ptr is invalid)</font>
+02911 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>==NULL || !<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+02912 <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>= linkTo;
+02913 <font class="keywordflow">return</font> <font class="keyword">this</font>;
+02914 }
+02915 <font class="comment">// Left Edge</font>
+02916 <font class="keywordflow">if</font>(<a class="code" href="namespaceNL3D.html#a462">matchEdge</a>(uv0, uv1, vb, vl))
+02917 {
+02918 <font class="comment">// If leaf, check if unbound (else ptr is invalid)</font>
+02919 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>==NULL || !<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>());
+02920 <a class="code" href="classNL3D_1_1CTessFace.html#z819_5">FLeft</a>= linkTo;
+02921 <font class="keywordflow">return</font> <font class="keyword">this</font>;
+02922 }
+02923 <font class="comment">// Right Edge</font>
+02924 <font class="keywordflow">if</font>(<a class="code" href="namespaceNL3D.html#a462">matchEdge</a>(uv0, uv1, vb, vr))
+02925 {
+02926 <font class="comment">// If leaf, check if unbound (else ptr is invalid)</font>
+02927 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>==NULL || !<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02928 <a class="code" href="classNL3D_1_1CTessFace.html#z819_6">FRight</a>= linkTo;
+02929 <font class="keywordflow">return</font> <font class="keyword">this</font>;
+02930 }
+02931
+02932
+02933 <font class="comment">// If not found here, recurs to children</font>
+02934 <a class="code" href="classNL3D_1_1CTessFace.html#a0">CTessFace</a> *ret= NULL;
+02935 <font class="keywordflow">if</font>( !<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>() )
+02936 {
+02937 ret= <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;linkTessFaceWithEdge(uv0, uv1, linkTo);
+02938 <font class="comment">// if no found in this branch, recusr right branch.</font>
+02939 <font class="keywordflow">if</font>(!ret)
+02940 ret= <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;linkTessFaceWithEdge(uv0, uv1, linkTo);
+02941 }
+02942
+02943 <font class="comment">// return the result from subBranchs</font>
+02944 <font class="keywordflow">return</font> ret;
+02945 }
+02946
+02947
+02948 <font class="comment">// ***************************************************************************</font>
+<a name="l02949"></a><a class="code" href="classNL3D_1_1CTessFace.html#a3">02949</a> <font class="keywordtype">bool</font> CTessFace::isRectangular()<font class="keyword"> const</font>
+02950 <font class="keyword"></font>{
+02951 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CTessFace.html#z819_13">Level</a>&lt;<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;SquareLimitLevel;
+02952 }
+02953
+02954
+02955
+02956 <font class="comment">// ***************************************************************************</font>
+02957 <font class="comment">// ***************************************************************************</font>
+02958 <font class="comment">// For changePatchTexture.</font>
+02959 <font class="comment">// ***************************************************************************</font>
+02960 <font class="comment">// ***************************************************************************</font>
+02961
+02962
+02963 <font class="comment">// ***************************************************************************</font>
+<a name="l02964"></a><a class="code" href="classNL3D_1_1CTessFace.html#a26">02964</a> <font class="keywordtype">void</font> CTessFace::deleteTileUvs()
+02965 {
+02966 <font class="comment">// NB: NearVertices are removed from renderlist with deleteTileUv (called in releaseTileMaterial()).</font>
+02967
+02968 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+02969 {
+02970 <font class="comment">// Must delete the materials of leaves first.</font>
+02971 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;deleteTileUvs();
+02972 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;deleteTileUvs();
+02973 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level== <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+02974 {
+02975 <font class="comment">// Square patch assumption: the sons are not of the same TileId/Patch.</font>
+02976 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#f0">sameTile</a>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>));
+02977 <font class="comment">// release tiles.</font>
+02978 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;releaseTileMaterial();
+02979 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;releaseTileMaterial();
+02980 }
+02981 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level &gt; <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+02982 {
+02983 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> || !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf());
+02984
+02985 <font class="comment">// Delete Uv, only if not already done by the neighbor (ie neighbor has yet TileFaces!!).</font>
+02986 <font class="comment">// But Always delete if neighbor exist and has not same tile as me.</font>
+02987 <font class="comment">// NB: this work with rectangular neigbor patch, since sameTile() will return false if different patch.</font>
+02988 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a> || !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;emptyTileFaces() || !<a class="code" href="classNL3D_1_1CTessFace.html#f0">sameTile</a>(<font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>))
+02989 {
+02990 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;deleteTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+02991 }
+02992 <font class="comment">// In all case, must delete the tilefaces of those face.</font>
+02993 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;deleteTileFaces();
+02994 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;deleteTileFaces();
+02995 <font class="comment">// For createTileUvs, it is important to mark those faces as NO TileMaterial.</font>
+02996 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;TileMaterial= NULL;
+02997 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;TileMaterial= NULL;
+02998 }
+02999 }
+03000 <font class="keywordflow">else</font>
+03001 {
+03002 <font class="comment">// NB: this is done always BELOW tile creation (see above).</font>
+03003 <font class="comment">// Do this only for tiles.</font>
+03004 <font class="keywordflow">if</font>(TileMaterial)
+03005 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;removeFaceFromTileRenderList(<font class="keyword">this</font>);
+03006 }
+03007
+03008 }
+03009
+03010
+03011 <font class="comment">// ***************************************************************************</font>
+<a name="l03012"></a><a class="code" href="classNL3D_1_1CTessFace.html#a27">03012</a> <font class="keywordtype">void</font> CTessFace::recreateTileUvs()
+03013 {
+03014 <font class="comment">// NB: NearVertices are append to renderlist with allocTileUv (called in computeTileMaterial()/heritTileMaterial()).</font>
+03015
+03016 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+03017 {
+03018 <font class="comment">// Must recreate the materials of parent first.</font>
+03019
+03020 <font class="comment">// There is no problem with rectangular patch, since tiles are always squares.</font>
+03021 <font class="comment">// If new tile ....</font>
+03022 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level==<a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+03023 {
+03024 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;computeTileMaterial();
+03025 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;computeTileMaterial();
+03026 }
+03027 <font class="comment">// else Tile herit.</font>
+03028 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;Level &gt; <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;TileLimitLevel)
+03029 {
+03030 <a class="code" href="classNL3D_1_1CTessFace.html#c5">heritTileMaterial</a>();
+03031 }
+03032
+03033 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;recreateTileUvs();
+03034 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;recreateTileUvs();
+03035 }
+03036 <font class="keywordflow">else</font>
+03037 {
+03038 <font class="comment">// NB: this is done always AFTER tile creation (see above).</font>
+03039 <font class="comment">// Do this only for tiles.</font>
+03040 <font class="keywordflow">if</font>(TileMaterial)
+03041 <a class="code" href="classNL3D_1_1CTessFace.html#z819_0">Patch</a>-&gt;appendFaceToTileRenderList(<font class="keyword">this</font>);
+03042 }
+03043 }
+03044
+03045
+03046
+03047 <font class="comment">// ***************************************************************************</font>
+<a name="l03048"></a><a class="code" href="classNL3D_1_1CTessFace.html#c5">03048</a> <font class="keywordtype">void</font> CTessFace::heritTileMaterial()
+03049 {
+03050 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;TileMaterial= <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>;
+03051 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;TileId= <a class="code" href="classNL3D_1_1CTessFace.html#z820_1">TileId</a>;
+03052 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;buildTileFaces();
+03053 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;copyTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>, <font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+03054 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;copyTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>, <font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>);
+03055
+03056 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;TileMaterial= <a class="code" href="classNL3D_1_1CTessFace.html#z820_2">TileMaterial</a>;
+03057 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;TileId= <a class="code" href="classNL3D_1_1CTessFace.html#z820_1">TileId</a>;
+03058 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;buildTileFaces();
+03059 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;copyTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s1">IdUvLeft</a>, <font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>);
+03060 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;copyTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s2">IdUvRight</a>, <font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+03061
+03062 <font class="comment">// Create, or link to the tileUv.</font>
+03063 <font class="comment">// Try to link to a neighbor TileUv.</font>
+03064 <font class="comment">// Can only work iff exist, and iff FBase is same patch, and same TileId.</font>
+03065 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>!=NULL &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;isLeaf() &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft-&gt;TileMaterial!=NULL &amp;&amp; <a class="code" href="classNL3D_1_1CTessFace.html#f0">sameTile</a>(<font class="keyword">this</font>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>) )
+03066 {
+03067 <font class="comment">// Ok!! link to the (existing) TileUv.</font>
+03068 <font class="comment">// FBase-&gt;SonLeft!=NULL since FBase-&gt;isLeaf()==false.</font>
+03069 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;copyTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+03070 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;copyTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_4">FBase</a>-&gt;SonLeft, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+03071 }
+03072 <font class="keywordflow">else</font>
+03073 {
+03074 <font class="comment">// Allocate a new vertex, and copy it to SonLeft and SonRight.</font>
+03075 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;allocTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+03076 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;copyTileUv(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>, <a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+03077
+03078 <font class="comment">// Fill the new near vertex, with middle of Left/Right father.</font>
+03079 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;heritTileUv(<font class="keyword">this</font>);
+03080
+03081 <font class="comment">// UVs are computed, may create and fill VB.</font>
+03082 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;checkCreateFillTileVB(<a class="code" href="classNL3D_1_1CTessFace.html#z820_0s0">IdUvBase</a>);
+03083 }
+03084
+03085 }
+03086
+03087
+03088 <font class="comment">// ***************************************************************************</font>
+03089 <font class="comment">// ***************************************************************************</font>
+03090 <font class="comment">// For getTesselatedPos</font>
+03091 <font class="comment">// ***************************************************************************</font>
+03092 <font class="comment">// ***************************************************************************</font>
+03093
+03094
+03095 <font class="comment">// ***************************************************************************</font>
+<a name="l03096"></a><a class="code" href="classNL3D_1_1CTessFace.html#a28">03096</a> <font class="keywordtype">void</font> CTessFace::getTesselatedPos(<font class="keyword">const</font> CUV &amp;uv, <font class="keywordtype">bool</font> verifInclusion, CVector &amp;ret)
+03097 {
+03098 CVector uvPos(uv.U, uv.V, 0);
+03099
+03100 <font class="comment">// may verif if uv is In this triangle. supposed true if rectangular branch.</font>
+03101 <font class="keywordflow">if</font>(verifInclusion &amp;&amp; !(<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>() &amp;&amp; !<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>()) )
+03102 {
+03103 CVector uvs[3];
+03104 uvs[0].set( <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getT(), 0);
+03105 uvs[1].set( <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>.getT(), 0);
+03106 uvs[2].set( <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>.getT(), 0);
+03107 <font class="keywordflow">for</font>(sint i=0; i&lt;3; i++)
+03108 {
+03109 CVector dUv= uvs[(i+1)%3] - uvs[i];
+03110 CVector normalUv(dUv.y, -dUv.x, 0);
+03111 <font class="comment">// if out this 2D plane, uv is out this triangle</font>
+03112 <font class="keywordflow">if</font>(normalUv * (uvPos-uvs[i]) &lt;0)
+03113 <font class="keywordflow">return</font>;
+03114 }
+03115 }
+03116
+03117 <font class="comment">// compute tesselated pos in this face.</font>
+03118 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+03119 <font class="comment">// ok, no more sons, let's do it.</font>
+03120 <a class="code" href="classNL3D_1_1CTessFace.html#c10">computeTesselatedPos</a>(uv, ret);
+03121 <font class="keywordflow">else</font>
+03122 {
+03123 <font class="comment">// must subdivide.</font>
+03124 <font class="comment">// if we are rectangular (strange tesselation), must test in both leaves, else, choose only one.</font>
+03125 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a3">isRectangular</a>())
+03126 {
+03127 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;getTesselatedPos(uv, <font class="keyword">true</font>, ret);
+03128 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;getTesselatedPos(uv, <font class="keyword">true</font>, ret);
+03129 }
+03130 <font class="keywordflow">else</font>
+03131 {
+03132 <font class="comment">// Compute the uv plane which separate the 2 leaves.</font>
+03133 CVector uvBase, uvMiddle;
+03134 uvBase.set ( <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getT(), 0);
+03135 uvMiddle.set( <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;PVBase.getT(), 0);
+03136 CVector dUv= uvMiddle - uvBase;
+03137 CVector normalUv(dUv.y, -dUv.x, 0);
+03138 <font class="comment">// choose what leaf to recurs.</font>
+03139 <font class="keywordflow">if</font>(normalUv * (uvPos - uvBase) &lt;0)
+03140 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;getTesselatedPos(uv, <font class="keyword">false</font>, ret);
+03141 <font class="keywordflow">else</font>
+03142 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;getTesselatedPos(uv, <font class="keyword">false</font>, ret);
+03143
+03144 }
+03145 }
+03146
+03147 }
+03148
+03149
+03150 <font class="comment">// ***************************************************************************</font>
+<a name="l03151"></a><a class="code" href="classNL3D_1_1CTessFace.html#c10">03151</a> <font class="keywordtype">void</font> CTessFace::computeTesselatedPos(<font class="keyword">const</font> CUV &amp;uv, CVector &amp;ret)
+03152 {
+03153 CVector uvPos(uv.U, uv.V, 0);
+03154
+03155 <font class="comment">// compute the UV triangle of this face.</font>
+03156 CTriangle uvTri;
+03157 uvTri.V0.set( <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_10">PVBase</a>.getT(), 0);
+03158 uvTri.V1.set( <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_11">PVLeft</a>.getT(), 0);
+03159 uvTri.V2.set( <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>.getS(), <a class="code" href="classNL3D_1_1CTessFace.html#z819_12">PVRight</a>.getT(), 0);
+03160
+03161 <font class="comment">// must interpolate the position with given UV, so compute XYZ gradients.</font>
+03162 CVector Gx;
+03163 CVector Gy;
+03164 CVector Gz;
+03165 <font class="comment">// If VertexProgram activated</font>
+03166 <font class="keywordflow">if</font>( CLandscapeGlobals::VertexProgramEnabled )
+03167 {
+03168 <font class="comment">// then Must update geomorphed position because not done !!</font>
+03169 <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;computeGeomPos();
+03170 <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;computeGeomPos();
+03171 <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;computeGeomPos();
+03172 }
+03173 <font class="comment">// NB: take geomorphed position.</font>
+03174 uvTri.computeGradient(<a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;Pos.x, <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;Pos.x, <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;Pos.x, Gx);
+03175 uvTri.computeGradient(<a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;Pos.y, <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;Pos.y, <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;Pos.y, Gy);
+03176 uvTri.computeGradient(<a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;Pos.z, <a class="code" href="classNL3D_1_1CTessFace.html#z819_2">VLeft</a>-&gt;Pos.z, <a class="code" href="classNL3D_1_1CTessFace.html#z819_3">VRight</a>-&gt;Pos.z, Gz);
+03177
+03178 <font class="comment">// Compute interpolated position.</font>
+03179 ret= <a class="code" href="classNL3D_1_1CTessFace.html#z819_1">VBase</a>-&gt;Pos;
+03180 uvPos-= uvTri.V0;
+03181 ret.x+= Gx*uvPos;
+03182 ret.y+= Gy*uvPos;
+03183 ret.z+= Gz*uvPos;
+03184
+03185 }
+03186
+03187
+03188 <font class="comment">// ***************************************************************************</font>
+<a name="l03189"></a><a class="code" href="classNL3D_1_1CTessFace.html#a29">03189</a> <font class="keywordtype">void</font> CTessFace::appendTessellationLeaves(std::vector&lt;const CTessFace*&gt; &amp;leaves)<font class="keyword"> const</font>
+03190 <font class="keyword"></font>{
+03191 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CTessFace.html#a2">isLeaf</a>())
+03192 leaves.push_back(<font class="keyword">this</font>);
+03193 <font class="keywordflow">else</font>
+03194 {
+03195 <a class="code" href="classNL3D_1_1CTessFace.html#z819_8">SonLeft</a>-&gt;appendTessellationLeaves(leaves);
+03196 <a class="code" href="classNL3D_1_1CTessFace.html#z819_9">SonRight</a>-&gt;appendTessellationLeaves(leaves);
+03197 }
+03198 }
+03199
+03200
+03201 } <font class="comment">// NL3D</font>
+</pre></div>
+
+<!-- footer -->
+<BR><FONT Size=+5>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </FONT>
+</TD>
+<TD WIDTH=15><IMG SRC=http://www.nevrax.org/inc/img/pixel.gif WIDTH=15 HEIGHT=15 BORDER=0 ALT=""></TD>
+</TR>
+</TABLE>
+</BODY>
+</HTML>