aboutsummaryrefslogtreecommitdiff
path: root/docs/doxygen/nel/mrm__builder_8cpp-source.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--docs/doxygen/nel/mrm__builder_8cpp-source.html2630
1 files changed, 2630 insertions, 0 deletions
diff --git a/docs/doxygen/nel/mrm__builder_8cpp-source.html b/docs/doxygen/nel/mrm__builder_8cpp-source.html
new file mode 100644
index 00000000..aa5fa06f
--- /dev/null
+++ b/docs/doxygen/nel/mrm__builder_8cpp-source.html
@@ -0,0 +1,2630 @@
+<!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>mrm_builder.cpp</h1><a href="mrm__builder_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001
+00007 <font class="comment">/* Copyright, 2000 Nevrax Ltd.</font>
+00008 <font class="comment"> *</font>
+00009 <font class="comment"> * This file is part of NEVRAX NEL.</font>
+00010 <font class="comment"> * NEVRAX NEL is free software; you can redistribute it and/or modify</font>
+00011 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
+00012 <font class="comment"> * the Free Software Foundation; either version 2, or (at your option)</font>
+00013 <font class="comment"> * any later version.</font>
+00014 <font class="comment"></font>
+00015 <font class="comment"> * NEVRAX NEL is distributed in the hope that it will be useful, but</font>
+00016 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font>
+00017 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font>
+00018 <font class="comment"> * General Public License for more details.</font>
+00019 <font class="comment"></font>
+00020 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
+00021 <font class="comment"> * along with NEVRAX NEL; see the file COPYING. If not, write to the</font>
+00022 <font class="comment"> * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,</font>
+00023 <font class="comment"> * MA 02111-1307, USA.</font>
+00024 <font class="comment"> */</font>
+00025
+00026 <font class="preprocessor">#include "<a class="code" href="std3d_8h.html">std3d.h</a>"</font>
+00027
+00028 <font class="preprocessor">#include "<a class="code" href="mrm__builder_8h.html">3d/mrm_builder.h</a>"</font>
+00029 <font class="preprocessor">#include "<a class="code" href="mrm__parameters_8h.html">3d/mrm_parameters.h</a>"</font>
+00030 <font class="keyword">using</font> <font class="keyword">namespace </font>NLMISC;
+00031 <font class="keyword">using</font> <font class="keyword">namespace </font>std;
+00032
+00033
+00034 <font class="keyword">namespace </font>NL3D
+00035 {
+00036
+00037
+00038 <font class="comment">// ***************************************************************************</font>
+00039 <font class="comment">// ***************************************************************************</font>
+00040 <font class="comment">// Tools Methods.</font>
+00041 <font class="comment">// ***************************************************************************</font>
+00042 <font class="comment">// ***************************************************************************</font>
+00043
+00044
+00045 <font class="comment">// ***************************************************************************</font>
+00046 <font class="keyword">static</font> <font class="keywordtype">bool</font> <a class="code" href="namespaceNL3D.html#a383">findElement</a>(vector&lt;sint&gt; &amp;array, sint elt)
+00047 {
+00048 <font class="keywordflow">return</font> find(array.begin(), array.end(), elt) != array.end();
+00049 }
+00050 <font class="comment">// ***************************************************************************</font>
+00051 <font class="keyword">static</font> <font class="keywordtype">bool</font> <a class="code" href="namespaceNL3D.html#a384">deleteElement</a>(vector&lt;sint&gt; &amp;array, sint elt)
+00052 {
+00053 <font class="keywordtype">bool</font> found=<font class="keyword">false</font>;
+00054 vector&lt;sint&gt;::iterator it=array.begin();
+00055
+00056 <font class="keywordflow">while</font>( (it=find(array.begin(), array.end(), elt)) != array.end() )
+00057 found=<font class="keyword">true</font>, array.erase(it);
+00058
+00059 <font class="keywordflow">return</font> found;
+00060 <font class="comment">// Must not use remove&lt;&gt; since it do not modify size ... (???)</font>
+00061 <font class="comment">// This seems not to work.</font>
+00062 <font class="comment">//return remove(array.begin(), array.end(), elt)!=array.end();</font>
+00063 }
+00064
+00065
+00066 <font class="comment">// ***************************************************************************</font>
+00067 <font class="comment">// ***************************************************************************</font>
+00068 <font class="comment">// Edge Cost methods.</font>
+00069 <font class="comment">// ***************************************************************************</font>
+00070 <font class="comment">// ***************************************************************************</font>
+00071
+00072
+00073 <font class="comment">// ***************************************************************************</font>
+<a name="l00074"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_0">00074</a> <font class="keywordtype">bool</font> CMRMBuilder::vertexHasOneWedge(sint numvertex)
+00075 {
+00076 CMRMVertex &amp;vert= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[numvertex];
+00077 <font class="keywordflow">for</font>(sint attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+00078 {
+00079 sint numwedge=-1;
+00080 <font class="keywordflow">for</font>(sint i=0;i&lt;(sint)vert.SharedFaces.size();i++)
+00081 {
+00082 sint <a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[vert.SharedFaces[i]].getAssociatedWedge(attId, numvertex);
+00083 <font class="keywordflow">if</font>(numwedge&gt;=0 &amp;&amp; numwedge!=<a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00084 <font class="keywordflow">else</font> numwedge=<a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>;
+00085 }
+00086 }
+00087 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+00088 }
+00089 <font class="comment">// ***************************************************************************</font>
+<a name="l00090"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_1">00090</a> <font class="keywordtype">bool</font> CMRMBuilder::vertexHasOneMaterial(sint numvertex)
+00091 {
+00092 sint matId=-1;
+00093 CMRMVertex &amp;vert= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[numvertex];
+00094 <font class="keywordflow">for</font>(sint i=0;i&lt;(sint)vert.SharedFaces.size();i++)
+00095 {
+00096 sint m= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[vert.SharedFaces[i]].MaterialId;
+00097 <font class="keywordflow">if</font>(matId&gt;=0 &amp;&amp; matId!=m) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00098 <font class="keywordflow">else</font> matId=m;
+00099 }
+00100 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+00101 }
+00102 <font class="comment">// ***************************************************************************</font>
+<a name="l00103"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_2">00103</a> <font class="keywordtype">bool</font> CMRMBuilder::vertexContinue(sint numvertex)
+00104 {
+00105 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_0">vertexHasOneWedge</a>(numvertex) &amp;&amp; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_1">vertexHasOneMaterial</a>(numvertex);
+00106 }
+00107 <font class="comment">// ***************************************************************************</font>
+<a name="l00108"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_3">00108</a> <font class="keywordtype">bool</font> CMRMBuilder::vertexClosed(sint numvertex)
+00109 {
+00110 CMRMVertex &amp;vert= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[numvertex];
+00111 map&lt;CMRMEdge, sint&gt; EdgeShare;
+00112 <font class="comment">// Init to 0.</font>
+00113 sint i;
+00114 <font class="keywordflow">for</font>(i=0;i&lt;(sint)vert.SharedFaces.size();i++)
+00115 {
+00116 CMRMFaceBuild &amp;f=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[vert.SharedFaces[i]];
+00117 EdgeShare[f.getEdge(0)]= 0;
+00118 EdgeShare[f.getEdge(1)]= 0;
+00119 EdgeShare[f.getEdge(2)]= 0;
+00120 }
+00121 <font class="comment">// Inc count.</font>
+00122 <font class="keywordflow">for</font>(i=0;i&lt;(sint)vert.SharedFaces.size();i++)
+00123 {
+00124 CMRMFaceBuild &amp;f=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[vert.SharedFaces[i]];
+00125 EdgeShare[f.getEdge(0)]++;
+00126 EdgeShare[f.getEdge(1)]++;
+00127 EdgeShare[f.getEdge(2)]++;
+00128 }
+00129 <font class="comment">// Test open edges.</font>
+00130 <font class="keywordflow">for</font>(i=0;i&lt;(sint)vert.SharedFaces.size();i++)
+00131 {
+00132 CMRMFaceBuild &amp;f=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[vert.SharedFaces[i]];
+00133 sint v0= f.Corner[0].Vertex;
+00134 sint v1= f.Corner[1].Vertex;
+00135 sint v2= f.Corner[2].Vertex;
+00136 <font class="keywordflow">if</font>(EdgeShare[f.getEdge(0)]&lt;2 &amp;&amp; (v0==numvertex || v1==numvertex)) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00137 <font class="keywordflow">if</font>(EdgeShare[f.getEdge(1)]&lt;2 &amp;&amp; (v1==numvertex || v2==numvertex)) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00138 <font class="keywordflow">if</font>(EdgeShare[f.getEdge(2)]&lt;2 &amp;&amp; (v0==numvertex || v2==numvertex)) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00139 }
+00140 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+00141 }
+00142 <font class="comment">// ***************************************************************************</font>
+<a name="l00143"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_4">00143</a> <font class="keywordtype">float</font> CMRMBuilder::getDeltaFaceNormals(sint numvertex)
+00144 {
+00145 <font class="comment">// return a positive value of Somme(|DeltaNormals|) / NNormals.</font>
+00146 CMRMVertex &amp;vert= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[numvertex];
+00147 <font class="keywordtype">float</font> delta=0;
+00148 CVector refNormal;
+00149 sint nfaces=vert.SharedFaces.size();
+00150 <font class="keywordflow">for</font>(sint i=0;i&lt;nfaces;i++)
+00151 {
+00152 CVector normal;
+00153 CVector &amp;v0= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i].Corner[0].Vertex].Current;
+00154 CVector &amp;v1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i].Corner[1].Vertex].Current;
+00155 CVector &amp;v2= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i].Corner[2].Vertex].Current;
+00156 normal= (v1-v0)^(v2-v0);
+00157 normal.normalize();
+00158 <font class="keywordflow">if</font>(i==0)
+00159 refNormal=normal;
+00160 <font class="keywordflow">else</font>
+00161 delta+=(1-refNormal*normal);
+00162 }
+00163 <font class="keywordflow">if</font>(nfaces&lt;2)
+00164 <font class="keywordflow">return</font> 0;
+00165 <font class="keywordflow">else</font>
+00166 <font class="keywordflow">return</font> delta/(nfaces-1);
+00167 }
+00168 <font class="comment">// ***************************************************************************</font>
+<a name="l00169"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_5">00169</a> <font class="keywordtype">bool</font> CMRMBuilder::edgeContinue(<font class="keyword">const</font> CMRMEdge &amp;edge)
+00170 {
+00171 sint v0= edge.v0;
+00172 sint v1= edge.v1;
+00173 CMRMVertex &amp;Vertex1=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v0];
+00174
+00175 <font class="comment">// build list sharing edge.</font>
+00176 vector&lt;sint&gt; deletedFaces;
+00177 sint i;
+00178 <font class="keywordflow">for</font>(i=0;i&lt;(sint)Vertex1.SharedFaces.size();i++)
+00179 {
+00180 sint numFace= Vertex1.SharedFaces[i];
+00181 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].hasVertex(v1))
+00182 deletedFaces.push_back(numFace);
+00183 }
+00184
+00185 sint matId=-1;
+00186 <font class="comment">// test if faces have same material.</font>
+00187 <font class="keywordflow">for</font>(i=0;i&lt;(sint)deletedFaces.size();i++)
+00188 {
+00189 sint m;
+00190 m= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[deletedFaces[i]].MaterialId;
+00191 <font class="keywordflow">if</font>(matId&gt;=0 &amp;&amp; matId!=m) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00192 <font class="keywordflow">else</font> matId=m;
+00193 }
+00194
+00195 <font class="comment">// test if faces have same wedge (for all att).</font>
+00196 <font class="keywordflow">for</font>(sint attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+00197 {
+00198 sint numwedge1=-1,numwedge2=-1;
+00199 <font class="keywordflow">for</font>(i=0;i&lt;(sint)deletedFaces.size();i++)
+00200 {
+00201 sint <a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>;
+00202 <a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[deletedFaces[i]].getAssociatedWedge(attId, v0);
+00203 <font class="keywordflow">if</font>(numwedge1&gt;=0 &amp;&amp; numwedge1!=<a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00204 <font class="keywordflow">else</font> numwedge1=<a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>;
+00205 <a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[deletedFaces[i]].getAssociatedWedge(attId, v1);
+00206 <font class="keywordflow">if</font>(numwedge2&gt;=0 &amp;&amp; numwedge2!=<a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00207 <font class="keywordflow">else</font> numwedge2=<a class="code" href="driver__opengl__extension__def_8h.html#a367">w</a>;
+00208 }
+00209 }
+00210
+00211 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+00212 }
+00213 <font class="comment">// ***************************************************************************</font>
+<a name="l00214"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_6">00214</a> <font class="keywordtype">bool</font> CMRMBuilder::edgeNearUniqueMatFace(<font class="keyword">const</font> CMRMEdge &amp;edge)
+00215 {
+00216 sint v0= edge.v0;
+00217 sint v1= edge.v1;
+00218 CMRMVertex &amp;Vertex1=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v0];
+00219
+00220 <font class="comment">// build list sharing edge.</font>
+00221 vector&lt;sint&gt; deletedFaces;
+00222 sint i;
+00223 <font class="keywordflow">for</font>(i=0;i&lt;(sint)Vertex1.SharedFaces.size();i++)
+00224 {
+00225 sint numFace= Vertex1.SharedFaces[i];
+00226 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].hasVertex(v1))
+00227 deletedFaces.push_back(numFace);
+00228 }
+00229
+00230 <font class="comment">// test if faces are not isolated OneMaterial faces.</font>
+00231 <font class="keywordflow">for</font>(i=0;i&lt;(sint)deletedFaces.size();i++)
+00232 {
+00233 CMRMFaceBuild &amp;f=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[deletedFaces[i]];
+00234 <font class="keywordflow">if</font>( !<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_5">edgeContinue</a>(f.getEdge(0)) &amp;&amp;
+00235 !<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_5">edgeContinue</a>(f.getEdge(1)) &amp;&amp;
+00236 !<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_5">edgeContinue</a>(f.getEdge(2)))
+00237 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+00238 }
+00239
+00240 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00241 }
+00242
+00243 <font class="comment">// ***************************************************************************</font>
+<a name="l00244"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_7">00244</a> <font class="keywordtype">float</font> CMRMBuilder::computeEdgeCost(<font class="keyword">const</font> CMRMEdge &amp;edge)
+00245 {
+00246 sint v1= edge.v0;
+00247 sint v2= edge.v1;
+00248 <font class="comment">// more expensive is the edge, later it will collapse.</font>
+00249
+00250
+00251 <font class="comment">// **** standard cost</font>
+00252
+00253 <font class="comment">// compute size of the edge.</font>
+00254 <font class="keywordtype">float</font> cost=(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v1].Current-<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v2].Current).norm();
+00255
+00256 <font class="comment">// compute "curvature" of the edge.</font>
+00257 <font class="keywordtype">float</font> faceCost= (<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_4">getDeltaFaceNormals</a>(v1)+<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_4">getDeltaFaceNormals</a>(v2));
+00258 <font class="comment">// totally plane faces (faceCost==0) must be collapsed with respect to size (and not random if cost==0).</font>
+00259 <font class="comment">// else we may have Plane Mesh (like flags) that will collapse in a very ugly way.</font>
+00260 faceCost= max(faceCost, 0.01f);
+00261
+00262 <font class="comment">// modulate size with curvature.</font>
+00263 cost*= faceCost;
+00264
+00265 <font class="comment">// Like H.Hope, add a weight on discontinuities..</font>
+00266 <font class="keywordflow">if</font>( !<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_2">vertexContinue</a>(v1) &amp;&amp; !<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_2">vertexContinue</a>(v2) )
+00267 {
+00268 <font class="comment">// Nb: don't do this on discontinuities edges, unless the unique material face will collapse (pffiou!!).</font>
+00269 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_5">edgeContinue</a>(edge) || <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_6">edgeNearUniqueMatFace</a>(edge) )
+00270 cost*=4;
+00271 }
+00272
+00273 <font class="comment">// **** Interface Sewing cost</font>
+00274 <font class="keywordflow">if</font>(_HasMeshInterfaces)
+00275 {
+00276 <font class="comment">// if the 2 vertices comes from the same Sewing Interface mesh (must be a real interface id)</font>
+00277 sint meshSewingId= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v1].InterfaceLink.InterfaceId;
+00278 <font class="keywordflow">if</font>( meshSewingId&gt;=0 &amp;&amp; meshSewingId == <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v2].InterfaceLink.InterfaceId)
+00279 {
+00280 <font class="comment">// Then the edge is one of the sewing interface mesh. must do special things for it</font>
+00281 CMRMSewingMesh &amp;sewingMesh= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_2">_SewingMeshes</a>[meshSewingId];
+00282 uint dummy;
+00283
+00284 <font class="comment">// get the sewing edge id</font>
+00285 CMRMEdge sewingEdge;
+00286 sewingEdge.v0= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v1].InterfaceLink.InterfaceVertexId;
+00287 sewingEdge.v1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[v2].InterfaceLink.InterfaceVertexId;
+00288 <font class="comment">// if the current sewing lod want to collapse this edge</font>
+00289 sint collapseId= sewingMesh.mustCollapseEdge(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_3">_CurrentLodComputed</a>, sewingEdge, dummy);
+00290 <font class="keywordflow">if</font>(collapseId&gt;=0)
+00291 {
+00292 <font class="comment">// Then set a negative priority (ie will collapse as soon as possible). from -N to -1.</font>
+00293 <font class="comment">// NB: sort them according to collapseId</font>
+00294 cost= (float)(-sewingMesh.getNumCollapseEdge(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_3">_CurrentLodComputed</a>) + collapseId);
+00295 }
+00296 <font class="keywordflow">else</font>
+00297 {
+00298 <font class="comment">// This edge must not collapse at this Lod, set an infinite priority (hope will never collapse).</font>
+00299 cost= FLT_MAX;
+00300 }
+00301 }
+00302 }
+00303
+00304 <font class="keywordflow">return</font> cost;
+00305 }
+00306
+00307
+00308
+00309
+00310 <font class="comment">// ***************************************************************************</font>
+00311 <font class="comment">// ***************************************************************************</font>
+00312 <font class="comment">// Collapse Methods.</font>
+00313 <font class="comment">// ***************************************************************************</font>
+00314 <font class="comment">// ***************************************************************************</font>
+00315
+00316
+00317 <font class="comment">// ***************************************************************************</font>
+<a name="l00318"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_0">00318</a> <font class="keywordtype">bool</font> CMRMBuilder::faceShareWedges(CMRMFaceBuild *face, sint attribId, sint numVertex1, sint numVertex2)
+00319 {
+00320 sint numWedge1= face-&gt;getAssociatedWedge(attribId, numVertex1);
+00321 sint numWedge2= face-&gt;getAssociatedWedge(attribId, numVertex2);
+00322 <font class="keywordflow">if</font>(numWedge1&lt;0) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00323 <font class="keywordflow">if</font>(numWedge2&lt;0) <font class="keywordflow">return</font> <font class="keyword">false</font>;
+00324
+00325 CMRMAttribute &amp;w1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attribId][numWedge1];
+00326 CMRMAttribute &amp;w2= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attribId][numWedge2];
+00327 <font class="keywordflow">return</font> w1.Shared &amp;&amp; w2.Shared &amp;&amp; w1.NbSharedFaces&gt;0 &amp;&amp; w2.NbSharedFaces&gt;0;
+00328 }
+00329
+00330
+00331 <font class="comment">// ***************************************************************************</font>
+<a name="l00332"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_1">00332</a> <font class="keywordtype">void</font> CMRMBuilder::insertFaceIntoEdgeList(CMRMFaceBuild &amp;f)
+00333 {
+00334 <font class="keywordtype">float</font> len;
+00335 <font class="keywordflow">if</font>(f.ValidIt0)
+00336 {
+00337 len= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_7">computeEdgeCost</a>(f.getEdge(0));
+00338 f. It0= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.insert( TEdgeMap::value_type( len, CMRMEdgeFace(f.getEdge(0),&amp;f) ) );
+00339 }
+00340 <font class="keywordflow">if</font>(f.ValidIt1)
+00341 {
+00342 len= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_7">computeEdgeCost</a>(f.getEdge(1));
+00343 f. It1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.insert( TEdgeMap::value_type( len, CMRMEdgeFace(f.getEdge(1),&amp;f) ) );
+00344 }
+00345 <font class="keywordflow">if</font>(f.ValidIt2)
+00346 {
+00347 len= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_7">computeEdgeCost</a>(f.getEdge(2));
+00348 f. It2= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.insert( TEdgeMap::value_type( len, CMRMEdgeFace(f.getEdge(2),&amp;f) ) );
+00349 }
+00350 }
+00351 <font class="comment">// ***************************************************************************</font>
+<a name="l00352"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_2">00352</a> <font class="keywordtype">void</font> CMRMBuilder::removeFaceFromEdgeList(CMRMFaceBuild &amp;f)
+00353 {
+00354 <font class="keywordflow">if</font>(f.ValidIt0)
+00355 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.erase(f.It0);
+00356 <font class="keywordflow">if</font>(f.ValidIt1)
+00357 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.erase(f.It1);
+00358 <font class="keywordflow">if</font>(f.ValidIt2)
+00359 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.erase(f.It2);
+00360 }
+00361
+00362
+00363
+00364 <font class="comment">// ***************************************************************************</font>
+<a name="l00365"></a><a class="code" href="structNL3D_1_1CTmpVertexWeight.html">00365</a> <font class="keyword">struct </font>CTmpVertexWeight
+00366 {
+<a name="l00367"></a><a class="code" href="structNL3D_1_1CTmpVertexWeight.html#m0">00367</a> uint32 <a class="code" href="structNL3D_1_1CTmpVertexWeight.html#m0">MatrixId</a>;
+<a name="l00368"></a><a class="code" href="structNL3D_1_1CTmpVertexWeight.html#m1">00368</a> <font class="keywordtype">float</font> <a class="code" href="structNL3D_1_1CTmpVertexWeight.html#m1">Weight</a>;
+00369 <font class="comment">// For find().</font>
+<a name="l00370"></a><a class="code" href="structNL3D_1_1CTmpVertexWeight.html#a0">00370</a> <font class="keywordtype">bool</font> <a class="code" href="structNL3D_1_1CTmpVertexWeight.html#a0">operator==</a>(<font class="keyword">const</font> CTmpVertexWeight &amp;o)<font class="keyword"> const</font>
+00371 <font class="keyword"> </font>{
+00372 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CTmpVertexWeight.html#m0">MatrixId</a>==o.MatrixId;
+00373 }
+00374 <font class="comment">// For sort().</font>
+<a name="l00375"></a><a class="code" href="structNL3D_1_1CTmpVertexWeight.html#a1">00375</a> <font class="keywordtype">bool</font> <a class="code" href="structNL3D_1_1CTmpVertexWeight.html#a1">operator&lt;</a>(<font class="keyword">const</font> CTmpVertexWeight &amp;o)<font class="keyword"> const</font>
+00376 <font class="keyword"> </font>{
+00377 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CTmpVertexWeight.html#m1">Weight</a>&gt;o.Weight;
+00378 }
+00379
+00380 };
+00381
+00382
+00383 <font class="comment">// ***************************************************************************</font>
+<a name="l00384"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_6">00384</a> CMesh::CSkinWeight CMRMBuilder::collapseSkinWeight(<font class="keyword">const</font> CMesh::CSkinWeight &amp;sw1, <font class="keyword">const</font> CMesh::CSkinWeight &amp;sw2, <font class="keywordtype">float</font> interValue)<font class="keyword"> const</font>
+00385 <font class="keyword"></font>{
+00386 <font class="comment">// If fast interpolation.</font>
+00387 <font class="keywordflow">if</font>(interValue==0)
+00388 <font class="keywordflow">return</font> sw1;
+00389 <font class="keywordflow">if</font>(interValue==1)
+00390 <font class="keywordflow">return</font> sw2;
+00391
+00392 <font class="comment">// else, must blend a skinWeight: must identify matrix which exist in the 2 sws, and add new ones.</font>
+00393 uint nbMats1=0;
+00394 uint nbMats2=0;
+00395 <font class="keyword">static</font> vector&lt;CTmpVertexWeight&gt; sws;
+00396 sws.reserve(<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a> * 2);
+00397 sws.clear();
+00398
+00399 <font class="comment">// For all weights of sw1.</font>
+00400 uint i;
+00401 <font class="keywordflow">for</font>(i=0; i&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; i++)
+00402 {
+00403 CTmpVertexWeight vw;
+00404 vw.MatrixId= sw1.MatrixId[i];
+00405 vw.Weight= sw1.Weights[i]*(1-interValue);
+00406 <font class="comment">// if this weight is not null.</font>
+00407 <font class="keywordflow">if</font>(vw.Weight&gt;0)
+00408 {
+00409 <font class="comment">// add it to the list.</font>
+00410 sws.push_back(vw);
+00411 }
+00412 <font class="comment">// For skinning reduction.</font>
+00413 <font class="keywordflow">if</font>(sw1.Weights[i]&gt;0)
+00414 nbMats1++;
+00415 }
+00416
+00417
+00418 <font class="comment">// For all weights of sw1.</font>
+00419 <font class="keywordflow">for</font>(i=0; i&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; i++)
+00420 {
+00421 CTmpVertexWeight vw;
+00422 vw.MatrixId= sw2.MatrixId[i];
+00423 vw.Weight= sw2.Weights[i]*(interValue);
+00424 <font class="comment">// if this weight is not null.</font>
+00425 <font class="keywordflow">if</font>(vw.Weight&gt;0)
+00426 {
+00427 <font class="comment">// add it or add influence to the matrix.</font>
+00428 vector&lt;CTmpVertexWeight&gt;::iterator it= find(sws.begin(), sws.end(), vw);
+00429 <font class="keywordflow">if</font>(it== sws.end())
+00430 sws.push_back(vw);
+00431 <font class="keywordflow">else</font>
+00432 it-&gt;Weight+= vw.Weight;
+00433 }
+00434 <font class="comment">// For skinning reduction.</font>
+00435 <font class="keywordflow">if</font>(sw2.Weights[i]&gt;0)
+00436 nbMats2++;
+00437 }
+00438
+00439
+00440 <font class="comment">// Then keep just the best.</font>
+00441 <font class="comment">// sort by Weight decreasing order.</font>
+00442 sort(sws.begin(), sws.end());
+00443
+00444 <font class="comment">// clamp the result to the wanted max matrix.</font>
+00445 uint nbMatsOut;
+00446 <font class="keywordflow">switch</font>(_SkinReduction)
+00447 {
+00448 <font class="keywordflow">case</font> CMRMParameters::SkinReductionMin:
+00449 nbMatsOut= <a class="code" href="bit__set_8cpp.html#a0">min</a>(nbMats1, nbMats2);
+00450 <font class="keywordflow">break</font>;
+00451 <font class="keywordflow">case</font> CMRMParameters::SkinReductionMax:
+00452 nbMatsOut= max(nbMats1, nbMats2);
+00453 <font class="keywordflow">break</font>;
+00454 <font class="keywordflow">case</font> CMRMParameters::SkinReductionBest:
+00455 nbMatsOut= <a class="code" href="bit__set_8cpp.html#a0">min</a>( sws.size(), (uint)<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a> );
+00456 <font class="keywordflow">break</font>;
+00457 <font class="keywordflow">default</font>:
+00458 <a class="code" href="debug_8h.html#a12">nlstop</a>;
+00459 };
+00460 <font class="comment">// For security.</font>
+00461 nbMatsOut= <a class="code" href="bit__set_8cpp.html#a0">min</a>(nbMatsOut, sws.size());
+00462 <a class="code" href="debug_8h.html#a6">nlassert</a>(nbMatsOut&lt;=<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>);
+00463
+00464
+00465 <font class="comment">// Then output the result to the skinWeight, normalizing.</font>
+00466 <font class="keywordtype">float</font> sumWeight=0;
+00467 <font class="keywordflow">for</font>(i= 0; i&lt;nbMatsOut; i++)
+00468 {
+00469 sumWeight+= sws[i].Weight;
+00470 }
+00471
+00472 CMesh::CSkinWeight ret;
+00473 <font class="comment">// Fill only needed matrix (other are rested in CMesh::CSkinWeight ctor).</font>
+00474 <font class="keywordflow">for</font>(i= 0; i&lt;nbMatsOut; i++)
+00475 {
+00476 ret.MatrixId[i]= sws[i].MatrixId;
+00477 ret.Weights[i]= sws[i].Weight / sumWeight;
+00478 }
+00479
+00480 <font class="keywordflow">return</font> ret;
+00481 }
+00482
+00483 <font class="comment">// ***************************************************************************</font>
+<a name="l00484"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_3">00484</a> sint CMRMBuilder::collapseEdge(<font class="keyword">const</font> CMRMEdge &amp;edge)
+00485 {
+00486 sint i,j;
+00487 <font class="keywordtype">float</font> InterValue;
+00488 sint edgeV1=edge.v0;
+00489 sint edgeV2=edge.v1;
+00490
+00491
+00492 <font class="comment">// 0. collapse the vertices.</font>
+00493 <font class="comment">//==========================</font>
+00494
+00495 <font class="comment">// edge.Vertex1 kept, but morphed.</font>
+00496 <font class="comment">// edge.Vertex2 deleted, and must know on which vertex it collapse.</font>
+00497 CMRMVertex &amp;Vertex1=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[edgeV1], &amp;Vertex2=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[edgeV2];
+00498
+00499 <font class="comment">// Interpolation choice.</font>
+00500 <font class="comment">// Default is to interpolate vertex 0 to the middle of the edge.</font>
+00501 InterValue=0.5;
+00502 <font class="comment">//InterValue=1;</font>
+00503 <font class="comment">// **** If at least one vertex of the edge is on a mesh sewing interface, must change InterValue</font>
+00504 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_1">_HasMeshInterfaces</a> &amp;&amp; (Vertex1.InterfaceLink.InterfaceId&gt;=0 || Vertex2.InterfaceLink.InterfaceId&gt;=0) )
+00505 {
+00506 <font class="comment">// If this is an edge of a mesh sewing interface</font>
+00507 <font class="keywordflow">if</font>(Vertex1.InterfaceLink.InterfaceId==Vertex2.InterfaceLink.InterfaceId)
+00508 {
+00509 <font class="comment">// Then the edge is one of the sewing interface mesh. must do special things for it</font>
+00510 CMRMSewingMesh &amp;sewingMesh= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_2">_SewingMeshes</a>[Vertex1.InterfaceLink.InterfaceId];
+00511
+00512 <font class="comment">// get the sewing edge id</font>
+00513 CMRMEdge sewingEdge;
+00514 sewingEdge.v0= Vertex1.InterfaceLink.InterfaceVertexId;
+00515 sewingEdge.v1= Vertex2.InterfaceLink.InterfaceVertexId;
+00516
+00517 <font class="comment">// Get the edge in the sewing mesh which is said to be collapsed</font>
+00518 uint vertToCollapse;
+00519 sint collapseId= sewingMesh.mustCollapseEdge(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_3">_CurrentLodComputed</a>, sewingEdge, vertToCollapse);
+00520 <font class="comment">// if exist</font>
+00521 <font class="keywordflow">if</font>(collapseId&gt;=0)
+00522 {
+00523 <font class="comment">// if it is v0 which must collapse, then InterValue=1</font>
+00524 <font class="keywordflow">if</font>(vertToCollapse==(uint)sewingEdge.v0)
+00525 InterValue= 1;
+00526 <font class="keywordflow">else</font>
+00527 InterValue= 0;
+00528
+00529 }
+00530 <font class="keywordflow">else</font>
+00531 {
+00532 <font class="comment">// This should not happens. But it is still possible if this edge don't want to collapse but if their</font>
+00533 <font class="comment">// is no more choice. Take a default value</font>
+00534 InterValue= 0;
+00535 }
+00536 }
+00537 <font class="keywordflow">else</font>
+00538 {
+00539 <font class="comment">// must collapse to the vertex on the sewing interface (as if it was open)</font>
+00540 <font class="keywordflow">if</font>(Vertex1.InterfaceLink.InterfaceId&gt;=0)
+00541 {
+00542 <font class="comment">// NB: it is possible that both vertices are on a different sewing interface... still collapse (must have to)</font>
+00543 InterValue= 0;
+00544 }
+00545 <font class="keywordflow">else</font>
+00546 {
+00547 <font class="comment">// Then Vertex2 is on a sewing interface, collapse to it</font>
+00548 InterValue= 1;
+00549 }
+00550 }
+00551 }
+00552 <font class="comment">// **** Else, on special cases, it is much more efficient to interpolate at start or at end of edge.</font>
+00553 <font class="keywordflow">else</font>
+00554 {
+00555 <font class="comment">// If one vertex is "open", ie his shared faces do not represent a closed Fan, then interpolate to this one, </font>
+00556 <font class="comment">// so the mesh has the same silhouette.</font>
+00557 <font class="keywordtype">bool</font> vc1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_3">vertexClosed</a>(edgeV1);
+00558 <font class="keywordtype">bool</font> vc2= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_3">vertexClosed</a>(edgeV2);
+00559 <font class="keywordflow">if</font>(!vc1 &amp;&amp; vc2) InterValue=0;
+00560 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(vc1 &amp;&amp; !vc2) InterValue=1;
+00561 <font class="keywordflow">else</font>
+00562 {
+00563 <font class="comment">// Do the same test but with vertex continue: it is preferable to not move the boundaries </font>
+00564 <font class="comment">// of a material, or a mapping.</font>
+00565 <font class="keywordtype">bool</font> vc1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_2">vertexContinue</a>(edgeV1);
+00566 <font class="keywordtype">bool</font> vc2= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_2">vertexContinue</a>(edgeV2);
+00567 <font class="keywordflow">if</font>(!vc1 &amp;&amp; vc2) InterValue=0;
+00568 <font class="keywordflow">if</font>(vc1 &amp;&amp; !vc2) InterValue=1;
+00569 }
+00570 }
+00571 <font class="comment">/*BENCH_TotalCollapses++;</font>
+00572 <font class="comment"> if(InterValue==0.5)</font>
+00573 <font class="comment"> BENCH_MiddleCollapses++;*/</font>
+00574
+00575 <font class="comment">// Collapse the Vertex.</font>
+00576 <font class="comment">//========================</font>
+00577 Vertex1.Current= Vertex1.Current*(1-InterValue) + Vertex2.Current*InterValue;
+00578 <font class="keywordflow">for</font> (i = 0; i &lt; (sint)Vertex1.BSCurrent.size(); ++i)
+00579 Vertex1.BSCurrent[i] = Vertex1.BSCurrent[i]*(1-InterValue) + Vertex2.BSCurrent[i]*InterValue;
+00580 Vertex2.CollapsedTo= edgeV1;
+00581 <font class="keywordflow">if</font>(_Skinned)
+00582 Vertex1.CurrentSW= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_6">collapseSkinWeight</a>(Vertex1.CurrentSW, Vertex2.CurrentSW, InterValue);
+00583 <font class="keywordflow">if</font>( _HasMeshInterfaces )
+00584 Vertex1.InterfaceLink= InterValue&lt;0.5f? Vertex1.InterfaceLink : Vertex2.InterfaceLink;
+00585
+00586 <font class="comment">// \todo yoyo: TODO_BUG: Don't know why, but vertices may point on deleted faces.</font>
+00587 <font class="comment">// Temp: we destroy here thoses face from SharedFaces...</font>
+00588 <font class="keywordflow">for</font>(i=0;i&lt;(sint)Vertex1.SharedFaces.size();i++)
+00589 {
+00590 sint numFace= Vertex1.SharedFaces[i];
+00591 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].Deleted)
+00592 <a class="code" href="namespaceNL3D.html#a384">deleteElement</a>(Vertex1.SharedFaces, numFace), i--;
+00593 }
+00594 <font class="keywordflow">for</font>(i=0;i&lt;(sint)Vertex2.SharedFaces.size();i++)
+00595 {
+00596 sint numFace= Vertex2.SharedFaces[i];
+00597 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].Deleted)
+00598 <a class="code" href="namespaceNL3D.html#a384">deleteElement</a>(Vertex2.SharedFaces, numFace), i--;
+00599 }
+00600
+00601
+00602 <font class="comment">// Build Neighbor faces.</font>
+00603 vector&lt;sint&gt; neighboorFaces;
+00604 <font class="keywordflow">for</font>(i=0;i&lt;(sint)Vertex1.SharedFaces.size();i++)
+00605 {
+00606 sint numFace= Vertex1.SharedFaces[i];
+00607 <font class="keywordflow">if</font>(!<a class="code" href="namespaceNL3D.html#a383">findElement</a>(neighboorFaces, numFace))
+00608 neighboorFaces.push_back(numFace);
+00609 }
+00610 <font class="keywordflow">for</font>(i=0;i&lt;(sint)Vertex2.SharedFaces.size();i++)
+00611 {
+00612 sint numFace= Vertex2.SharedFaces[i];
+00613 <font class="keywordflow">if</font>(!<a class="code" href="namespaceNL3D.html#a383">findElement</a>(neighboorFaces, numFace))
+00614 neighboorFaces.push_back(numFace);
+00615 }
+00616
+00617 <font class="comment">// Build faces which will be destroyed (may 1 or 2, maybe more for non conventionnal meshes).</font>
+00618 vector&lt;sint&gt; deletedFaces;
+00619 <font class="keywordflow">for</font>(i=0;i&lt;(sint)Vertex1.SharedFaces.size();i++)
+00620 {
+00621 sint numFace= Vertex1.SharedFaces[i];
+00622 <a class="code" href="debug_8h.html#a6">nlassert</a>(!<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].Deleted);
+00623 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].hasVertex(edgeV2))
+00624 deletedFaces.push_back(numFace);
+00625 }
+00626
+00627
+00628 <font class="comment">// 1. Collapse the wedges.</font>
+00629 <font class="comment">//========================</font>
+00630
+00631 <font class="comment">// For ALL Attributes.</font>
+00632 <font class="keywordflow">for</font>(sint attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+00633 {
+00634 <font class="comment">// a/ Stock the wedge interpolation in each destroyed face.</font>
+00635 <font class="comment">//------------------------------------------------------</font>
+00636 <font class="keywordflow">for</font>(i=0;i&lt;(sint)deletedFaces.size();i++)
+00637 {
+00638 CMRMFaceBuild &amp;face= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[deletedFaces[i]];
+00639
+00640 CVectorH &amp;w0= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][ face.getAssociatedWedge(attId, edgeV1) ].Current;
+00641 CVectorH &amp;w1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][ face.getAssociatedWedge(attId, edgeV2) ].Current;
+00642
+00643 CVectorH &amp;itp= face.InterpolatedAttribute;
+00644 itp.x= w0.x*(1-InterValue) + w1.x*InterValue;
+00645 itp.y= w0.y*(1-InterValue) + w1.y*InterValue;
+00646 itp.z= w0.z*(1-InterValue) + w1.z*InterValue;
+00647 itp.w= w0.w*(1-InterValue) + w1.w*InterValue;
+00648
+00649 <font class="keywordflow">for</font> (j = 0; j &lt; (sint)face.BSInterpolated.size(); ++j)
+00650 {
+00651 CVectorH &amp;w0 = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][face.getAssociatedWedge(attId, edgeV1)].BSCurrent[j];
+00652 CVectorH &amp;w1 = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][face.getAssociatedWedge(attId, edgeV2)].BSCurrent[j];
+00653 CVectorH &amp;itb = face.BSInterpolated[j];
+00654 itb.x = w0.x*(1-InterValue) + w1.x*InterValue;
+00655 itb.y = w0.y*(1-InterValue) + w1.y*InterValue;
+00656 itb.z = w0.z*(1-InterValue) + w1.z*InterValue;
+00657 itb.w = w0.w*(1-InterValue) + w1.w*InterValue;
+00658 }
+00659 }
+00660
+00661
+00662 <font class="comment">// b/ Build wedge list to be modify.</font>
+00663 <font class="comment">//----------------------------------</font>
+00664 vector&lt;sint&gt; wedges;
+00665
+00666 <font class="keywordflow">for</font>(i=0;i&lt;(sint)neighboorFaces.size();i++)
+00667 {
+00668 CMRMFaceBuild &amp;face= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[neighboorFaces[i]];
+00669 sint numWedge;
+00670
+00671 numWedge= face.getAssociatedWedge(attId, edgeV1);
+00672 <font class="keywordflow">if</font>(numWedge&gt;=0 &amp;&amp; !<a class="code" href="namespaceNL3D.html#a383">findElement</a>(wedges, numWedge))
+00673 wedges.push_back(numWedge);
+00674
+00675 numWedge= face.getAssociatedWedge(attId, edgeV2);
+00676 <font class="keywordflow">if</font>(numWedge&gt;=0 &amp;&amp; !<a class="code" href="namespaceNL3D.html#a383">findElement</a>(wedges, numWedge))
+00677 wedges.push_back(numWedge);
+00678 }
+00679
+00680
+00681 <font class="comment">// c/ Count numFaces which point on those wedges. (- deleted faces).</font>
+00682 <font class="comment">//------------------------------------------------------------------</font>
+00683
+00684 <font class="keywordflow">for</font>(i=0;i&lt;(sint)wedges.size();i++)
+00685 {
+00686 sint numWedge= wedges[i];
+00687 CMRMAttribute &amp;wedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][numWedge];
+00688
+00689 wedge.NbSharedFaces=0;
+00690 wedge.Shared=<font class="keyword">false</font>;
+00691
+00692 <font class="comment">// Count total ref count.</font>
+00693 <font class="keywordflow">for</font>(j=0;j&lt;(sint)neighboorFaces.size();j++)
+00694 {
+00695 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[neighboorFaces[j]].hasWedge(attId, numWedge))
+00696 wedge.NbSharedFaces++;
+00697 }
+00698
+00699 <font class="comment">// Minus deleted faces.</font>
+00700 <font class="keywordflow">for</font>(j=0;j&lt;(sint)deletedFaces.size();j++)
+00701 {
+00702 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[deletedFaces[j]].hasWedge(attId, numWedge))
+00703 {
+00704 wedge.NbSharedFaces--;
+00705 wedge.Shared=<font class="keyword">true</font>;
+00706 wedge.InterpolatedFace=deletedFaces[j];
+00707 }
+00708 }
+00709 }
+00710
+00711
+00712 <font class="comment">// d/ Collapse wedge following 3 possibles cases.</font>
+00713 <font class="comment">//-----------------------------------------------</font>
+00714
+00715
+00716 <font class="keywordflow">for</font>(i=0;i&lt;(sint)wedges.size();i++)
+00717 {
+00718 sint numWedge= wedges[i];
+00719 CMRMAttribute &amp;wedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][numWedge];
+00720
+00721 <font class="comment">// if wedge not shared...</font>
+00722 <font class="keywordflow">if</font>(!wedge.Shared)
+00723 {
+00724 <font class="comment">// We've got an "exterior wedge" which lost no corner =&gt; do not merge it nor delete it. </font>
+00725 <font class="comment">// Leave it as the same value (extrapolate it may not be a good solution).</font>
+00726 }
+00727 <font class="keywordflow">else</font>
+00728 {
+00729 <font class="comment">// if wedge dissapears, notify.</font>
+00730 <font class="keywordflow">if</font>(wedge.NbSharedFaces==0)
+00731 {
+00732 wedge.CollapsedTo=-2;
+00733 <font class="comment">// Do not change his value. (as specified in Hope article).</font>
+00734 }
+00735 <font class="keywordflow">else</font>
+00736 {
+00737 CMRMFaceBuild &amp;face= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[wedge.InterpolatedFace];
+00738
+00739 <font class="comment">// Must interpolate it.</font>
+00740 wedge.Current= face.InterpolatedAttribute;
+00741 wedge.BSCurrent = face.BSInterpolated;
+00742
+00743 <font class="comment">// Must merge the wedge of the second vertex on first</font>
+00744 <font class="comment">// ONLY IF 2 interpolated wedges are shared and NbSharedFaces!=0.</font>
+00745 <font class="keywordflow">if</font>( numWedge==face.getAssociatedWedge(attId, edgeV2) &amp;&amp;
+00746 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_0">faceShareWedges</a>(&amp;face, attId, edgeV1, edgeV2) )
+00747 {
+00748 wedge.CollapsedTo= face.getAssociatedWedge(attId, edgeV1);
+00749 }
+00750 }
+00751 }
+00752 }
+00753
+00754 }
+00755
+00756 <font class="comment">// 3. collapse faces.</font>
+00757 <font class="comment">//===================</font>
+00758
+00759 <font class="comment">// delete face shared by edge.</font>
+00760 <font class="keywordflow">for</font>(i=0;i&lt;(sint)deletedFaces.size();i++)
+00761 {
+00762 sint numFace= deletedFaces[i];
+00763 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].Deleted=<font class="keyword">true</font>;
+00764
+00765 <font class="comment">// release edges from list.</font>
+00766 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_2">removeFaceFromEdgeList</a>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace]);
+00767 <font class="comment">// ivalid all it!!</font>
+00768 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[numFace].invalidAllIts(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>);
+00769
+00770
+00771 <font class="comment">// delete from vertex1 and 2 the deleted faces.</font>
+00772 <a class="code" href="namespaceNL3D.html#a384">deleteElement</a>( Vertex1.SharedFaces, numFace);
+00773 <a class="code" href="namespaceNL3D.html#a384">deleteElement</a>( Vertex2.SharedFaces, numFace);
+00774 }
+00775
+00776
+00777 <font class="comment">// must ref correctly the faces.</font>
+00778 <font class="keywordflow">for</font>(i=0;i&lt;(sint)neighboorFaces.size();i++)
+00779 {
+00780 CMRMFaceBuild &amp;face=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[neighboorFaces[i]];
+00781
+00782 <font class="comment">// good vertices</font>
+00783 <font class="keywordflow">if</font>(face.Corner[0].Vertex ==edgeV2) face.Corner[0].Vertex=edgeV1;
+00784 <font class="keywordflow">if</font>(face.Corner[1].Vertex ==edgeV2) face.Corner[1].Vertex=edgeV1;
+00785 <font class="keywordflow">if</font>(face.Corner[2].Vertex ==edgeV2) face.Corner[2].Vertex=edgeV1;
+00786 <font class="comment">// nb: doesn't matter if deletedFaces are modified...</font>
+00787
+00788 <font class="comment">// good wedges</font>
+00789 <font class="keywordflow">for</font>(sint attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+00790 {
+00791 sint newWedge;
+00792 newWedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][ face.Corner[0].Attributes[attId] ].CollapsedTo;
+00793 <font class="keywordflow">if</font>(newWedge&gt;=0) face.Corner[0].Attributes[attId]= newWedge;
+00794 newWedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][ face.Corner[1].Attributes[attId] ].CollapsedTo;
+00795 <font class="keywordflow">if</font>(newWedge&gt;=0) face.Corner[1].Attributes[attId]= newWedge;
+00796 newWedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][ face.Corner[2].Attributes[attId] ].CollapsedTo;
+00797 <font class="keywordflow">if</font>(newWedge&gt;=0) face.Corner[2].Attributes[attId]= newWedge;
+00798 }
+00799
+00800 <font class="comment">// good edges.</font>
+00801 <font class="comment">/* Those ones are updated in collapseEdges(): they are removed from the edgeCollapseList, </font>
+00802 <font class="comment"> then they are re-inserted with good Vertex indices.</font>
+00803 <font class="comment"> */</font>
+00804 }
+00805
+00806
+00807 <font class="comment">// The vertex1 has now the shared env of vertex2.</font>
+00808 Vertex1.SharedFaces.insert(Vertex1.SharedFaces.end(), Vertex2.SharedFaces.begin(),
+00809 Vertex2.SharedFaces.end());
+00810
+00811
+00812 <font class="keywordflow">return</font> deletedFaces.size();
+00813 }
+00814
+00815
+00816 <font class="comment">// ***************************************************************************</font>
+<a name="l00817"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_4">00817</a> sint CMRMBuilder::followVertex(sint i)
+00818 {
+00819 CMRMVertex &amp;vert=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i];
+00820 <font class="keywordflow">if</font>(vert.CollapsedTo&gt;=0)
+00821 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_4">followVertex</a>(vert.CollapsedTo);
+00822 <font class="keywordflow">else</font>
+00823 <font class="keywordflow">return</font> i;
+00824 }
+00825 <font class="comment">// ***************************************************************************</font>
+<a name="l00826"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_5">00826</a> sint CMRMBuilder::followWedge(sint attribId, sint i)
+00827 {
+00828 CMRMAttribute &amp;wedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attribId][i];
+00829 <font class="keywordflow">if</font>(wedge.CollapsedTo&gt;=0)
+00830 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_5">followWedge</a>(attribId, wedge.CollapsedTo);
+00831 <font class="keywordflow">else</font>
+00832 <font class="keywordflow">return</font> i;
+00833 }
+00834
+00835
+00836 <font class="comment">// ***************************************************************************</font>
+00837 <font class="comment">// ***************************************************************************</font>
+00838 <font class="comment">// Mesh Level method.</font>
+00839 <font class="comment">// ***************************************************************************</font>
+00840 <font class="comment">// ***************************************************************************</font>
+00841
+00842
+00843 <font class="comment">// ***************************************************************************</font>
+<a name="l00844"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#a0">00844</a> CMRMBuilder::CMRMBuilder()
+00845 {
+00846 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>= 0;
+00847 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a>= <font class="keyword">false</font>;
+00848 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_1">_HasMeshInterfaces</a>= <font class="keyword">false</font>;
+00849 }
+00850
+00851 <font class="comment">// ***************************************************************************</font>
+<a name="l00852"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_0">00852</a> <font class="keywordtype">void</font> CMRMBuilder::init(<font class="keyword">const</font> CMRMMesh &amp;baseMesh)
+00853 {
+00854 sint i, attId;
+00855
+00856
+00857 <font class="comment">// First clear ALL.</font>
+00858 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>.clear();
+00859 <font class="keywordflow">for</font>(attId=0;attId&lt;<a class="code" href="mrm__mesh_8h.html#a0">NL3D_MRM_MAX_ATTRIB</a>;attId++)
+00860 {
+00861 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId].clear();
+00862 }
+00863 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.clear();
+00864 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.clear();
+00865
+00866
+00867 <font class="comment">// resize.</font>
+00868 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>= baseMesh.NumAttributes;
+00869 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>.resize(baseMesh.Vertices.size());
+00870 <font class="keywordflow">for</font>(attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+00871 {
+00872 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId].resize(baseMesh.Attributes[attId].size());
+00873 }
+00874 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.resize(baseMesh.Faces.size());
+00875
+00876
+00877 <font class="comment">// Then copy.</font>
+00878 <font class="keywordflow">for</font>(i=0;i&lt;(sint)baseMesh.Vertices.size();i++)
+00879 {
+00880 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].Current= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].Original= baseMesh.Vertices[i];
+00881 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].BSCurrent.resize(baseMesh.BlendShapes.size());
+00882 <font class="keywordflow">for</font>(uint32 j = 0; j &lt;baseMesh.BlendShapes.size() ;++j)
+00883 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].BSCurrent[j]= baseMesh.BlendShapes[j].Vertices[i];
+00884 <font class="keywordflow">if</font>(_Skinned)
+00885 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].CurrentSW= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].OriginalSW= baseMesh.SkinWeights[i];
+00886 <font class="keywordflow">if</font>(_HasMeshInterfaces)
+00887 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].InterfaceLink= baseMesh.InterfaceLinks[i];
+00888 }
+00889 <font class="keywordflow">for</font>(attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+00890 {
+00891 <font class="keywordflow">for</font>(i=0;i&lt;(sint)baseMesh.Attributes[attId].size();i++)
+00892 {
+00893 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i].Current= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i].Original=
+00894 baseMesh.Attributes[attId][i];
+00895 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i].BSCurrent.resize(baseMesh.BlendShapes.size());
+00896 <font class="keywordflow">for</font>(uint32 j = 0; j &lt;baseMesh.BlendShapes.size() ;++j)
+00897 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i].BSCurrent[j]= baseMesh.BlendShapes[j].Attributes[attId][i];
+00898 }
+00899 }
+00900 <font class="keywordflow">for</font>(i=0;i&lt;(sint)baseMesh.Faces.size();i++)
+00901 {
+00902 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i]= baseMesh.Faces[i];
+00903 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i].BSInterpolated.resize(baseMesh.BlendShapes.size());
+00904 }
+00905
+00906
+00907 <font class="comment">// Create vertices sharedFaces.</font>
+00908 <font class="keywordflow">for</font>(i=0;i&lt;(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.size();i++)
+00909 {
+00910 CMRMFaceBuild &amp;face= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i];
+00911
+00912 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[face.Corner[0].Vertex].SharedFaces.push_back(i);
+00913 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[face.Corner[1].Vertex].SharedFaces.push_back(i);
+00914 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[face.Corner[2].Vertex].SharedFaces.push_back(i);
+00915 }
+00916
+00917
+00918 <font class="comment">// Compute EdgeCost.</font>
+00919 <font class="keywordflow">for</font>(i=0;i&lt;(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.size();i++)
+00920 {
+00921 CMRMFaceBuild &amp;f= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i];
+00922 <font class="comment">// At start, valid all edges.</font>
+00923 f. ValidIt0= <font class="keyword">true</font>;
+00924 f. ValidIt1= <font class="keyword">true</font>;
+00925 f. ValidIt2= <font class="keyword">true</font>;
+00926 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_1">insertFaceIntoEdgeList</a>(f);
+00927 }
+00928 }
+00929 <font class="comment">// ***************************************************************************</font>
+<a name="l00930"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_1">00930</a> <font class="keywordtype">void</font> CMRMBuilder::collapseEdges(sint nWantedFaces)
+00931 {
+00932 <a class="code" href="namespaceNL3D.html#a161">ItEdgeMap</a> EdgeIt;
+00933
+00934 sint nCurrentFaces=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.size();
+00935 sint bug0=0,bug2=0,bug3=0;
+00936
+00937 <font class="keywordflow">while</font>(nCurrentFaces&gt;nWantedFaces)
+00938 {
+00939 bug0++;
+00940 EdgeIt= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.begin();
+00941
+00942 <font class="keywordflow">if</font>(EdgeIt== <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.end())
+00943 <font class="keywordflow">break</font>;
+00944
+00945 <font class="comment">// 0. Look if edge already deleted</font>
+00946 <font class="comment">//================================</font>
+00947 CMRMEdge edge=(*EdgeIt).second;
+00948
+00949 <font class="comment">// Is it valid?? (ie his vertices exist yet??).</font>
+00950 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[ edge.v0 ].CollapsedTo&gt;=0
+00951 || <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[ edge.v1 ].CollapsedTo&gt;=0)
+00952 {
+00953 <font class="comment">// \todo yoyo: TODO_BUG: potential bug here...</font>
+00954 CMRMFaceBuild &amp;f= *(EdgeIt-&gt;second.Face);
+00955 <a class="code" href="debug_8h.html#a6">nlassert</a>(f.validEdgeIt(EdgeIt-&gt;second));
+00956 f.invalidEdgeIt(EdgeIt-&gt;second, <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>);
+00957 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.erase(EdgeIt);
+00958 bug2++;
+00959 <font class="keywordflow">continue</font>;
+00960 }
+00961 <font class="comment">// \todo yoyo: TODO_BUG: potential bug here...</font>
+00962 <font class="comment">// If a mesh is "open" it will crash if a "hole collapse"...</font>
+00963 <font class="keywordflow">if</font>(edge.v0==edge.v1)
+00964 {
+00965 CMRMFaceBuild &amp;f= *(EdgeIt-&gt;second.Face);
+00966 <a class="code" href="debug_8h.html#a6">nlassert</a>(f.validEdgeIt(EdgeIt-&gt;second));
+00967 f.invalidEdgeIt(EdgeIt-&gt;second, <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>);
+00968 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_4">EdgeCollapses</a>.erase(EdgeIt);
+00969 bug3++;
+00970 <font class="keywordflow">continue</font>;
+00971 }
+00972
+00973
+00974 <font class="comment">// 1. else, OK, collapse it!!</font>
+00975 <font class="comment">//===========================</font>
+00976 sint vertexCollapsed= edge.v0;
+00977 nCurrentFaces-= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_3">collapseEdge</a>(edge);
+00978
+00979
+00980 <font class="comment">// 2. Must reorder all his neighborhood.</font>
+00981 <font class="comment">//======================================</font>
+00982 CMRMVertex &amp;vert=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[vertexCollapsed];
+00983 sint i;
+00984 <font class="comment">// we delete from list modified edges, and we re-add them with their new value.</font>
+00985 <font class="keywordflow">for</font>(i=0;i&lt;(sint)vert.SharedFaces.size();i++)
+00986 {
+00987 CMRMFaceBuild &amp;f= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[vert.SharedFaces[i]];
+00988 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_2">removeFaceFromEdgeList</a>(f);
+00989 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_1">insertFaceIntoEdgeList</a>(f);
+00990 }
+00991
+00992 }
+00993 }
+00994 <font class="comment">// ***************************************************************************</font>
+<a name="l00995"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_3">00995</a> <font class="keywordtype">void</font> CMRMBuilder::saveCoarserMesh(CMRMMesh &amp;coarserMesh)
+00996 {
+00997 sint i,attId,<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>;
+00998 <font class="comment">// First clear ALL.</font>
+00999 coarserMesh.Vertices.clear();
+01000 coarserMesh.SkinWeights.clear();
+01001 coarserMesh.InterfaceLinks.clear();
+01002 <font class="keywordflow">for</font>(attId=0;attId&lt;<a class="code" href="mrm__mesh_8h.html#a0">NL3D_MRM_MAX_ATTRIB</a>;attId++)
+01003 {
+01004 coarserMesh.Attributes[attId].clear();
+01005 }
+01006 coarserMesh.Faces.clear();
+01007 coarserMesh.NumAttributes= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;
+01008
+01009 <font class="comment">// Vertices.</font>
+01010 <font class="comment">//==========</font>
+01011 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>=0;
+01012 <font class="keywordflow">for</font>(i=0;i&lt;(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>.size();i++)
+01013 {
+01014 CMRMVertex &amp;vert=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i];
+01015 <font class="keywordflow">if</font>(vert.CollapsedTo==-1) <font class="comment">// if exist yet.</font>
+01016 {
+01017 vert.CoarserIndex=<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>;
+01018 coarserMesh.Vertices.push_back(vert.Current);
+01019 <font class="keywordflow">if</font>(_Skinned)
+01020 coarserMesh.SkinWeights.push_back(vert.CurrentSW);
+01021 <font class="keywordflow">if</font>(_HasMeshInterfaces)
+01022 coarserMesh.InterfaceLinks.push_back(vert.InterfaceLink);
+01023
+01024 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>++;
+01025 }
+01026 <font class="keywordflow">else</font>
+01027 vert.CoarserIndex=-1; <font class="comment">// indicate that this vertex no more exist and is to be geomorphed to an other.</font>
+01028 }
+01029
+01030
+01031 <font class="comment">// Attributes.</font>
+01032 <font class="comment">//============</font>
+01033 <font class="keywordflow">for</font>(attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+01034 {
+01035 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>=0;
+01036 <font class="keywordflow">for</font>(i=0;i&lt;(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId].size();i++)
+01037 {
+01038 CMRMAttribute &amp;wedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i];
+01039 <font class="keywordflow">if</font>(wedge.CollapsedTo==-1) <font class="comment">// if exist yet.</font>
+01040 {
+01041 wedge.CoarserIndex=<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>;
+01042 coarserMesh.Attributes[attId].push_back(wedge.Current);
+01043 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>++;
+01044 }
+01045 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(wedge.CollapsedTo==-2) <font class="comment">// else if totaly destroyed.</font>
+01046 {
+01047 <font class="comment">// Insert this wedge in the coarser mesh.</font>
+01048 <font class="comment">// NB: the coarser mesh faces do not use it anymore, but FinerMesh use it</font>
+01049 <font class="comment">// for geomorph (LODMesh.CoarserFaces may point to it).</font>
+01050 <font class="comment">// NB: look at buildFinalMRM(), it works fine for all cases.</font>
+01051 wedge.CoarserIndex=<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>;
+01052 coarserMesh.Attributes[attId].push_back(wedge.Current);
+01053 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>++;
+01054 }
+01055 <font class="keywordflow">else</font>
+01056 wedge.CoarserIndex=-1; <font class="comment">// indicate that this wedge no more exist and is to be geomorphed to an other.</font>
+01057 }
+01058 }
+01059
+01060 <font class="comment">// Faces.</font>
+01061 <font class="comment">//=======</font>
+01062 <font class="keywordflow">for</font>(i=0;i&lt;(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.size();i++)
+01063 {
+01064 CMRMFaceBuild &amp;face=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[i];
+01065 <font class="keywordflow">if</font>(!face.Deleted)
+01066 {
+01067 CMRMFace newFace;
+01068 <font class="comment">// Material.</font>
+01069 newFace.MaterialId= face.MaterialId;
+01070 <font class="keywordflow">for</font>(sint j=0;j&lt;3;j++)
+01071 {
+01072 <font class="comment">// Vertex.</font>
+01073 newFace.Corner[j].Vertex= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[face.Corner[j].Vertex].CoarserIndex;
+01074 <a class="code" href="debug_8h.html#a6">nlassert</a>(newFace.Corner[j].Vertex&gt;=0);
+01075 <font class="comment">// Attributes.</font>
+01076 <font class="keywordflow">for</font>(attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+01077 {
+01078 sint oldidx= face.Corner[j].Attributes[attId];
+01079 newFace.Corner[j].Attributes[attId]= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][oldidx].CoarserIndex;
+01080 <a class="code" href="debug_8h.html#a6">nlassert</a>(newFace.Corner[j].Attributes[attId]&gt;=0);
+01081 }
+01082
+01083 }
+01084
+01085 coarserMesh.Faces.push_back(newFace);
+01086 }
+01087 }
+01088
+01089 }
+01090
+01091
+01092 <font class="comment">// ***************************************************************************</font>
+<a name="l01093"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_2">01093</a> <font class="keywordtype">void</font> CMRMBuilder::makeLODMesh(CMRMMeshGeom &amp;lodMesh)
+01094 {
+01095 sint i,j,attId,<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>,coidx;
+01096
+01097 <font class="comment">// for all faces of this mesh, find target in the coarser mesh.</font>
+01098 <font class="keywordflow">for</font>(i=0;i&lt;(sint)lodMesh.CoarserFaces.size();i++)
+01099 {
+01100 CMRMFace &amp;face= lodMesh.CoarserFaces[i];
+01101
+01102 <font class="comment">// For 3 corners.</font>
+01103 <font class="keywordflow">for</font>(j=0;j&lt;3;j++)
+01104 {
+01105 <font class="comment">// Vertex.</font>
+01106 <font class="comment">// The index is yet the index in the finer mesh.</font>
+01107 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>= face.Corner[j].Vertex;
+01108 <font class="comment">// the index in the coarser mesh is vert.CoarserIndex.</font>
+01109 coidx= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>].CoarserIndex;
+01110 <font class="comment">// but if this vertex is collapsed, must find the good index (yet in the finer mesh)</font>
+01111 <font class="keywordflow">if</font>(coidx==-1)
+01112 {
+01113 <font class="comment">// find to which we must collapse.</font>
+01114 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_4">followVertex</a>(<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>);
+01115 <font class="comment">// and so we have the coarser index. this one must be valid.</font>
+01116 coidx= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>].CoarserIndex;
+01117 <a class="code" href="debug_8h.html#a6">nlassert</a>(coidx&gt;=0);
+01118 }
+01119 <font class="comment">// update corner of CoarserFace.</font>
+01120 face.Corner[j].Vertex= coidx;
+01121
+01122
+01123 <font class="comment">// Do exactly same thing for all attributes.</font>
+01124 <font class="keywordflow">for</font>(attId=0;attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++)
+01125 {
+01126 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>= face.Corner[j].Attributes[attId];
+01127 coidx= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>].CoarserIndex;
+01128 <font class="keywordflow">if</font>(coidx==-1)
+01129 {
+01130 <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_5">followWedge</a>(attId, <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>);
+01131 coidx= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>].CoarserIndex;
+01132 <a class="code" href="debug_8h.html#a6">nlassert</a>(coidx&gt;=0);
+01133 }
+01134 face.Corner[j].Attributes[attId]= coidx;
+01135 }
+01136 }
+01137 }
+01138
+01139 }
+01140
+01141 <font class="comment">// ***************************************************************************</font>
+01142 <font class="comment">// Transform source blend shapes to source blend shapes modified (just calculate new vertex/attr position)</font>
+01143 <font class="comment">/*void CMRMBuilder::computeBsVerticesAttributes(vector&lt;CMRMMesh&gt; &amp;srcBsMeshs, vector&lt;CMRMMesh&gt; &amp;bsMeshsMod)</font>
+01144 <font class="comment">{</font>
+01145 <font class="comment"> sint i, j, k, attId;</font>
+01146 <font class="comment"></font>
+01147 <font class="comment"> bsMeshsMod.resize (srcBsMeshs.size());</font>
+01148 <font class="comment"> for (k = 0; k &lt; (sint)srcBsMeshs.size(); ++k)</font>
+01149 <font class="comment"> {</font>
+01150 <font class="comment"> CMRMMesh &amp;rBsMesh = srcBsMeshs[k];</font>
+01151 <font class="comment"> CMRMMesh &amp;rBsMeshMod = bsMeshsMod[k];</font>
+01152 <font class="comment"></font>
+01153 <font class="comment"> // Calculate modified vertices with the linear equation back tracking help</font>
+01154 <font class="comment"> rBsMeshMod.Vertices.resize (rBsMesh.Vertices.size());</font>
+01155 <font class="comment"> for (i = 0; i &lt; (sint)rBsMesh.Vertices.size(); ++i)</font>
+01156 <font class="comment"> {</font>
+01157 <font class="comment"> CLinearEquation &amp;LinEq = TmpVertices[i].CurrentLinEq;</font>
+01158 <font class="comment"> rBsMeshMod.Vertices[i] = CVector(0.0f, 0.0f, 0.0f);</font>
+01159 <font class="comment"> for (j = 0; j &lt; (sint)LinEq.Elts.size(); ++j)</font>
+01160 <font class="comment"> {</font>
+01161 <font class="comment"> rBsMeshMod.Vertices[i] += LinEq.Elts[j].factor * rBsMesh.Vertices[LinEq.Elts[j].index];</font>
+01162 <font class="comment"> }</font>
+01163 <font class="comment"> }</font>
+01164 <font class="comment"></font>
+01165 <font class="comment"> // All attributes</font>
+01166 <font class="comment"> rBsMeshMod.NumAttributes = NumAttributes;</font>
+01167 <font class="comment"> for (attId = 0; attId &lt; NumAttributes; attId++)</font>
+01168 <font class="comment"> {</font>
+01169 <font class="comment"> rBsMeshMod.Attributes[attId].resize (rBsMesh.Attributes[attId].size());</font>
+01170 <font class="comment"> for (i = 0; i &lt; (sint)rBsMesh.Attributes[attId].size(); ++i)</font>
+01171 <font class="comment"> {</font>
+01172 <font class="comment"> CLinearEquation &amp;LinEq = TmpAttributes[attId][i].CurrentLinEq;</font>
+01173 <font class="comment"> rBsMeshMod.Attributes[attId][i] = CVectorH(0.0f, 0.0f, 0.0f, 0.0f);</font>
+01174 <font class="comment"> for (j = 0; j &lt; (sint)LinEq.Elts.size(); ++j)</font>
+01175 <font class="comment"> {</font>
+01176 <font class="comment"> rBsMeshMod.Attributes[attId][i].x += LinEq.Elts[j].factor * rBsMesh.Attributes[attId][LinEq.Elts[j].index].x;</font>
+01177 <font class="comment"> rBsMeshMod.Attributes[attId][i].y += LinEq.Elts[j].factor * rBsMesh.Attributes[attId][LinEq.Elts[j].index].y;</font>
+01178 <font class="comment"> rBsMeshMod.Attributes[attId][i].z += LinEq.Elts[j].factor * rBsMesh.Attributes[attId][LinEq.Elts[j].index].z;</font>
+01179 <font class="comment"> rBsMeshMod.Attributes[attId][i].w += LinEq.Elts[j].factor * rBsMesh.Attributes[attId][LinEq.Elts[j].index].w;</font>
+01180 <font class="comment"> }</font>
+01181 <font class="comment"> }</font>
+01182 <font class="comment"> }</font>
+01183 <font class="comment"> }</font>
+01184 <font class="comment">}*/</font>
+01185
+01186 <font class="comment">// ***************************************************************************</font>
+01187 <font class="comment">// Transform source Blend Shape Meshes Modified into coarser blend shape mesh (compact vertices)</font>
+<a name="l01188"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#c1">01188</a> <font class="keywordtype">void</font> CMRMBuilder::makeCoarserBS (vector&lt;CMRMBlendShape&gt; &amp;csBsMeshs)
+01189 {
+01190 uint32 i, k;
+01191 sint32 nSizeVert, nSizeAttr, attId;
+01192
+01193 <font class="comment">// Calculate size of vertices array</font>
+01194 nSizeVert = 0;
+01195 <font class="keywordflow">for</font> (i = 0; i &lt; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>.size(); ++i)
+01196 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].CoarserIndex &gt; nSizeVert)
+01197 nSizeVert = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i].CoarserIndex;
+01198 ++nSizeVert;
+01199
+01200 <font class="keywordflow">for</font> (k = 0; k &lt; csBsMeshs.size(); ++k)
+01201 {
+01202 CMRMBlendShape &amp;rBsCoarserMesh = csBsMeshs[k];
+01203
+01204 rBsCoarserMesh.Vertices.resize (nSizeVert);
+01205 rBsCoarserMesh.NumAttributes = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;
+01206
+01207 <font class="comment">// Vertices</font>
+01208 <font class="keywordflow">for</font>(i = 0; i &lt; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>.size(); ++i)
+01209 {
+01210 CMRMVertex &amp;vert = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i];
+01211 <font class="keywordflow">if</font> (vert.CoarserIndex != -1)
+01212 {
+01213 rBsCoarserMesh.Vertices[vert.CoarserIndex] = vert.BSCurrent[k];
+01214 }
+01215 }
+01216
+01217 <font class="keywordflow">for</font> (attId = 0; attId &lt; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>; attId++)
+01218 {
+01219 <font class="comment">// Calculate size of attribute attId array</font>
+01220 nSizeAttr = 0;
+01221 <font class="keywordflow">for</font>(i = 0; i &lt; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId].size(); i++)
+01222 <font class="keywordflow">if</font> (<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i].CoarserIndex &gt; nSizeAttr)
+01223 nSizeAttr = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i].CoarserIndex;
+01224 ++nSizeAttr;
+01225
+01226 rBsCoarserMesh.Attributes[attId].resize (nSizeAttr);
+01227
+01228 <font class="keywordflow">for</font> (i = 0; i &lt; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId].size(); i++)
+01229 {
+01230 CMRMAttribute &amp;wedge = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][i];
+01231 <font class="keywordflow">if</font> (wedge.CoarserIndex != -1)
+01232 {
+01233 rBsCoarserMesh.Attributes[attId][wedge.CoarserIndex] = wedge.BSCurrent[k];
+01234 }
+01235 }
+01236 }
+01237 }
+01238 }
+01239
+01240 <font class="comment">// ***************************************************************************</font>
+<a name="l01241"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_4">01241</a> <font class="keywordtype">void</font> CMRMBuilder::makeFromMesh(<font class="keyword">const</font> CMRMMesh &amp;baseMesh, CMRMMeshGeom &amp;lodMesh, CMRMMesh &amp;coarserMesh, sint nWantedFaces)
+01242 {
+01243 <font class="comment">// Init Tmp values in MRM builder.</font>
+01244 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_0">init</a>(baseMesh);
+01245
+01246 <font class="comment">// compute MRM too next tgt face.</font>
+01247 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_1">collapseEdges</a>(nWantedFaces);
+01248
+01249 <font class="comment">// save the coarser mesh.</font>
+01250 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_3">saveCoarserMesh</a>(coarserMesh);
+01251 <font class="comment">// Build coarser BlendShapes.</font>
+01252 coarserMesh.BlendShapes.resize(baseMesh.BlendShapes.size());
+01253 <a class="code" href="classNL3D_1_1CMRMBuilder.html#c1">makeCoarserBS</a>(coarserMesh.BlendShapes);
+01254
+01255 <font class="comment">// build the lodMesh (baseMesh, with vertex/Attributes collapse infos).</font>
+01256 lodMesh= baseMesh;
+01257 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_2">makeLODMesh</a>(lodMesh);
+01258
+01259 <font class="comment">// end for this level.</font>
+01260 }
+01261
+01262
+01263
+01264 <font class="comment">// ***************************************************************************</font>
+01265 <font class="comment">// ***************************************************************************</font>
+01266 <font class="comment">// Global MRM Level method.</font>
+01267 <font class="comment">// ***************************************************************************</font>
+01268 <font class="comment">// ***************************************************************************</font>
+01269
+01270
+01271 <font class="comment">// ***************************************************************************</font>
+<a name="l01272"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z630_1">01272</a> <font class="keywordtype">void</font> CMRMBuilder::buildAllLods(<font class="keyword">const</font> CMRMMesh &amp;baseMesh, std::vector&lt;CMRMMeshGeom&gt; &amp;lodMeshs,
+01273 uint nWantedLods, uint divisor)
+01274 {
+01275 sint nFaces= baseMesh.Faces.size();
+01276 sint nBaseFaces;
+01277 sint i;
+01278 CMRMMesh srcMesh = baseMesh;
+01279
+01280 <font class="comment">// coarsest LOD will have those number of faces.</font>
+01281 nBaseFaces=nFaces/divisor;
+01282 nBaseFaces=max(nBaseFaces,4);
+01283
+01284 <font class="comment">// must have at least 2 LOD to be really intersting. But the rest of the process work too with only one Lod!!</font>
+01285 <a class="code" href="debug_8h.html#a6">nlassert</a>(nWantedLods&gt;=1);
+01286 lodMeshs.resize(nWantedLods);
+01287
+01288 <font class="comment">// If only one lod asked, must init some Tmp Global values (like NumAttributes)</font>
+01289 <font class="keywordflow">if</font>(nWantedLods==1)
+01290 {
+01291 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_3">_CurrentLodComputed</a>= 0;
+01292 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_0">init</a>(baseMesh);
+01293 }
+01294
+01295 <font class="comment">// must fill all LODs, from end to start. do not proces last lod since it will be the coarsest mesh.</font>
+01296 <font class="keywordflow">for</font>(i=nWantedLods-1;i&gt;0;i--)
+01297 {
+01298 sint nbWantedFaces;
+01299
+01300 <font class="comment">// for sewing computing</font>
+01301 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_3">_CurrentLodComputed</a>= i;
+01302
+01303 <font class="comment">// Linear.</font>
+01304 nbWantedFaces= nBaseFaces + (nFaces-nBaseFaces) * (i-1)/(nWantedLods-1);
+01305 nbWantedFaces=max(nbWantedFaces,4);
+01306
+01307 <font class="comment">// Build this LOD.</font>
+01308 CMRMMesh csMesh;
+01309 <font class="comment">// The mesh</font>
+01310 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z627_4">makeFromMesh</a>(srcMesh, lodMeshs[i], csMesh, nbWantedFaces);
+01311
+01312 <font class="comment">// next mesh to process is csMesh.</font>
+01313 srcMesh = csMesh;
+01314 }
+01315 <font class="comment">// the first lodMedsh gets the coarsest mesh.</font>
+01316 lodMeshs[0]= srcMesh;
+01317 }
+01318
+01319
+01320 <font class="comment">// ***************************************************************************</font>
+<a name="l01321"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z630_2">01321</a> <font class="keywordtype">void</font> CMRMBuilder::buildFinalMRM(std::vector&lt;CMRMMeshGeom&gt; &amp;lodMeshs, CMRMMeshFinal &amp;finalMRM)
+01322 {
+01323 sint i,j;
+01324 sint lodId, attId;
+01325 sint nLods= lodMeshs.size();
+01326
+01327 <font class="comment">// Init.</font>
+01328 <font class="comment">// ===============</font>
+01329 finalMRM.reset();
+01330 finalMRM.NumAttributes= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;
+01331 finalMRM.Skinned= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a>;
+01332 CMRMMeshFinal::CWedge::NumAttributesToCompare= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;
+01333 CMRMMeshFinal::CWedge::CompareSkinning= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a>;
+01334 finalMRM.Lods.resize(nLods);
+01335
+01336
+01337 <font class="comment">// Build Wedges, and faces index.</font>
+01338 <font class="comment">// ===============</font>
+01339 <font class="comment">// for all lods.</font>
+01340 <font class="keywordflow">for</font>(lodId=0; lodId&lt;nLods; lodId++)
+01341 {
+01342 CMRMMeshGeom &amp;lodMesh= lodMeshs[lodId];
+01343 CMRMMeshGeom &amp;lodMeshPrec= lodMeshs[lodId==0?0:lodId-1];
+01344 <font class="comment">// for all face corner.</font>
+01345 <font class="keywordflow">for</font>(i=0; i&lt;(sint)lodMesh.Faces.size();i++)
+01346 {
+01347 <font class="comment">// The current face.</font>
+01348 CMRMFace &amp;face= lodMesh.Faces[i];
+01349 <font class="comment">// the current face, but which points to the prec LOD vertices/attributes.</font>
+01350 CMRMFace &amp;faceCoarser= lodMesh.CoarserFaces[i];
+01351 <font class="comment">// for 3 corners.</font>
+01352 <font class="keywordflow">for</font>(j=0;j&lt;3;j++)
+01353 {
+01354 CMRMCorner &amp;corner= face.Corner[j];
+01355 CMRMCorner &amp;cornerCoarser= faceCoarser.Corner[j];
+01356 <font class="comment">// start and end wedge (geomorph), maybe same.</font>
+01357 CMRMMeshFinal::CWedge wedgeStart;
+01358 CMRMMeshFinal::CWedge wedgeEnd;
+01359
+01360 <font class="comment">// fill wedgeStart with values from lodMesh.</font>
+01361 wedgeStart.Vertex= lodMesh.Vertices[corner.Vertex];
+01362 <font class="keywordflow">if</font>(_Skinned)
+01363 wedgeStart.VertexSkin= lodMesh.SkinWeights[corner.Vertex];
+01364 <font class="keywordflow">for</font>(attId=0; attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>; attId++)
+01365 {
+01366 wedgeStart.Attributes[attId]= lodMesh.Attributes[attId][corner.Attributes[attId]];
+01367 }
+01368
+01369 <font class="comment">// if geomorph possible (ie not lod 0).</font>
+01370 <font class="keywordflow">if</font>(lodId&gt;0)
+01371 {
+01372 <font class="comment">// fill wedgeEnd with values from coarser lodMesh.</font>
+01373 wedgeEnd.Vertex= lodMeshPrec.Vertices[cornerCoarser.Vertex];
+01374 <font class="keywordflow">if</font>(_Skinned)
+01375 wedgeEnd.VertexSkin= lodMeshPrec.SkinWeights[cornerCoarser.Vertex];
+01376 <font class="keywordflow">for</font>(attId=0; attId&lt;<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>; attId++)
+01377 {
+01378 wedgeEnd.Attributes[attId]= lodMeshPrec.Attributes[attId][cornerCoarser.Attributes[attId]];
+01379 }
+01380 }
+01381 <font class="keywordflow">else</font>
+01382 {
+01383 <font class="comment">// no geomorph.</font>
+01384 wedgeEnd= wedgeStart;
+01385 }
+01386
+01387 <font class="comment">// find/insert wedge, and get Ids. NB: if start/end same, same indices.</font>
+01388 sint wedgeStartId= finalMRM.findInsertWedge(wedgeStart);
+01389 sint wedgeEndId= finalMRM.findInsertWedge(wedgeEnd);
+01390
+01391 <font class="comment">// store in TmpCorner.</font>
+01392 corner.WedgeStartId= wedgeStartId;
+01393 corner.WedgeEndId= wedgeEndId;
+01394 }
+01395 }
+01396
+01397 <font class="comment">// Here, the number of wedge indicate the max number of wedge this LOD needs.</font>
+01398 finalMRM.Lods[lodId].NWedges= finalMRM.Wedges.size();
+01399 }
+01400
+01401
+01402 <font class="comment">// Count NBWedges necessary for geomorph, and compute Dest geomorph wedges ids.</font>
+01403 <font class="comment">// ===============</font>
+01404 <font class="comment">// the number of geomorph required for one LOD.</font>
+01405 sint sglmGeom;
+01406 <font class="comment">// the number of geomorph required for all LOD (max of sglmGeom).</font>
+01407 sint sglmGeomMax= 0;
+01408
+01409 <font class="comment">// Do not process lod 0, since no geomorph.</font>
+01410 <font class="keywordflow">for</font>(lodId=1; lodId&lt;nLods; lodId++)
+01411 {
+01412 CMRMMeshGeom &amp;lodMesh= lodMeshs[lodId];
+01413
+01414 <font class="comment">// reset the GeomMap, the one which indicate if we have already inserted a geomorph.</font>
+01415 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.clear();
+01416 sglmGeom= 0;
+01417
+01418 <font class="comment">// for all face corner.</font>
+01419 <font class="keywordflow">for</font>(i=0; i&lt;(sint)lodMesh.Faces.size();i++)
+01420 {
+01421 <font class="comment">// The current face.</font>
+01422 CMRMFace &amp;face= lodMesh.Faces[i];
+01423 <font class="comment">// for 3 corners.</font>
+01424 <font class="keywordflow">for</font>(j=0;j&lt;3;j++)
+01425 {
+01426 CMRMCorner &amp;corner= face.Corner[j];
+01427
+01428 <font class="comment">// if not same wedge Ids, this is a geomorphed wedge.</font>
+01429 <font class="keywordflow">if</font>(corner.WedgeStartId != corner.WedgeEndId)
+01430 {
+01431 <font class="comment">// search if it exist yet in the set.</font>
+01432 CMRMWedgeGeom geom;
+01433 geom.Start= corner.WedgeStartId;
+01434 geom.End= corner.WedgeEndId;
+01435 sint geomDest= sglmGeom;
+01436 <font class="comment">// if don't find this geom in the set, then it is a new one.</font>
+01437 TGeomMap::const_iterator it= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.find(geom);
+01438 <font class="keywordflow">if</font>(it == <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.end())
+01439 {
+01440 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.insert( make_pair(geom, geomDest) );
+01441 sglmGeom++;
+01442 }
+01443 <font class="keywordflow">else</font>
+01444 geomDest= it-&gt;second;
+01445
+01446 <font class="comment">// store this Geom Id in the corner.</font>
+01447 corner.WedgeGeomId= geomDest;
+01448 }
+01449 }
+01450 }
+01451
+01452 <font class="comment">// take the max.</font>
+01453 sglmGeomMax= max(sglmGeomMax, sglmGeom);
+01454 }
+01455
+01456
+01457 <font class="comment">// inform the finalMRM.</font>
+01458 finalMRM.NGeomSpace= sglmGeomMax;
+01459
+01460
+01461 <font class="comment">// decal all wedges/ face index.</font>
+01462 <font class="comment">// ===============</font>
+01463 <font class="comment">// insert an empty space for dest geomorph.</font>
+01464 finalMRM.Wedges.insert(finalMRM.Wedges.begin(), sglmGeomMax, CMRMMeshFinal::CWedge());
+01465
+01466 <font class="comment">// Parse all faces corner of All lods, and decal Start/End Wedge index.</font>
+01467 <font class="keywordflow">for</font>(lodId=0; lodId&lt;nLods; lodId++)
+01468 {
+01469 CMRMMeshGeom &amp;lodMesh= lodMeshs[lodId];
+01470
+01471 <font class="comment">// for all face corner.</font>
+01472 <font class="keywordflow">for</font>(i=0; i&lt;(sint)lodMesh.Faces.size();i++)
+01473 {
+01474 <font class="comment">// The current face.</font>
+01475 CMRMFace &amp;face= lodMesh.Faces[i];
+01476 <font class="comment">// for 3 corners.</font>
+01477 <font class="keywordflow">for</font>(j=0;j&lt;3;j++)
+01478 {
+01479 CMRMCorner &amp;corner= face.Corner[j];
+01480
+01481 <font class="comment">// decal indices.</font>
+01482 corner.WedgeStartId+= sglmGeomMax;
+01483 corner.WedgeEndId+= sglmGeomMax;
+01484 }
+01485 }
+01486
+01487 <font class="comment">// increment too the number of wedge required for this Lod.</font>
+01488 finalMRM.Lods[lodId].NWedges+= sglmGeomMax;
+01489 }
+01490
+01491
+01492 <font class="comment">// fill faces.</font>
+01493 <font class="comment">// ===============</font>
+01494 <font class="comment">// Parse all faces corner of All lods, and build Faces/Geomorphs..</font>
+01495 <font class="keywordflow">for</font>(lodId=0; lodId&lt;nLods; lodId++)
+01496 {
+01497 CMRMMeshGeom &amp;lodMesh= lodMeshs[lodId];
+01498 CMRMMeshFinal::CLod &amp;lodDest= finalMRM.Lods[lodId];
+01499
+01500 <font class="comment">// alloc final faces of this LOD.</font>
+01501 lodDest.Faces.resize(lodMesh.Faces.size());
+01502
+01503 <font class="comment">// reset the GeomMap, the one which indicate if we have already inserted a geomorph.</font>
+01504 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.clear();
+01505
+01506 <font class="comment">// for all face corner.</font>
+01507 <font class="keywordflow">for</font>(i=0; i&lt;(sint)lodMesh.Faces.size();i++)
+01508 {
+01509 <font class="comment">// The current face.</font>
+01510 CMRMFace &amp;face= lodMesh.Faces[i];
+01511 <font class="comment">// The dest face.</font>
+01512 CMRMMeshFinal::CFace &amp;faceDest= lodDest.Faces[i];
+01513 <font class="comment">// fill good material.</font>
+01514 faceDest.MaterialId= face.MaterialId;
+01515
+01516 <font class="comment">// for 3 corners.</font>
+01517 <font class="keywordflow">for</font>(j=0;j&lt;3;j++)
+01518 {
+01519 CMRMCorner &amp;corner= face.Corner[j];
+01520
+01521 <font class="comment">// if not same wedge Ids, this is a geomorphed wedge.</font>
+01522 <font class="keywordflow">if</font>(corner.WedgeStartId != corner.WedgeEndId)
+01523 {
+01524 <font class="comment">// geomorph, so point to geomorphed wedge.</font>
+01525 faceDest.WedgeId[j]= corner.WedgeGeomId;
+01526
+01527 <font class="comment">// Build the geomorph, add it to the list (if not yet inserted).</font>
+01528 CMRMWedgeGeom geom;
+01529 geom.Start= corner.WedgeStartId;
+01530 geom.End= corner.WedgeEndId;
+01531 <font class="comment">// if don't find this geom in the set, then it is a new one.</font>
+01532 TGeomMap::const_iterator it= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.find(geom);
+01533 <font class="keywordflow">if</font>(it == <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.end())
+01534 {
+01535 <font class="comment">// mark it as inserted.</font>
+01536 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z629_1">_GeomMap</a>.insert( make_pair(geom, corner.WedgeGeomId) );
+01537 <font class="comment">// and we must insert this geom in the array.</font>
+01538 <a class="code" href="debug_8h.html#a6">nlassert</a>( corner.WedgeGeomId==(sint)lodDest.Geomorphs.size() );
+01539 lodDest.Geomorphs.push_back(geom);
+01540 }
+01541 }
+01542 <font class="keywordflow">else</font>
+01543 {
+01544 <font class="comment">// no geomorph, so just point to good wedge.</font>
+01545 faceDest.WedgeId[j]= corner.WedgeStartId;
+01546 }
+01547 }
+01548 }
+01549 }
+01550
+01551
+01552 <font class="comment">// process all wedges, and compute NSkinMatUsed, skipping geomorphs.</font>
+01553 <font class="comment">// ===============</font>
+01554 <font class="comment">// NB: this works because weights are sorted from biggest to lowest.</font>
+01555 <font class="keywordflow">if</font>(_Skinned)
+01556 {
+01557 <font class="keywordflow">for</font>(i=finalMRM.NGeomSpace; i&lt;(sint)finalMRM.Wedges.size();i++)
+01558 {
+01559 CMRMMeshFinal::CWedge &amp;wedge= finalMRM.Wedges[i];
+01560 <font class="keywordflow">for</font>(j=0; j&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; j++)
+01561 {
+01562 <font class="keywordflow">if</font>(wedge.VertexSkin.Weights[j]==0)
+01563 <font class="keywordflow">break</font>;
+01564 }
+01565 <a class="code" href="debug_8h.html#a6">nlassert</a>(j&gt;0);
+01566 wedge.NSkinMatUsed= j;
+01567 }
+01568 }
+01569
+01570 <font class="comment">// Blend Shape Stuff</font>
+01571 finalMRM.MRMBlendShapesFinals.resize (lodMeshs[0].BlendShapes.size());
+01572 <font class="keywordflow">for</font> (lodId = 0; lodId &lt; nLods; ++lodId)
+01573 {
+01574 CMRMMeshGeom &amp;lodMesh= lodMeshs[lodId];
+01575 CMRMMeshGeom &amp;lodMeshPrec= lodMeshs[lodId==0?0:lodId-1];
+01576
+01577 <font class="comment">// for all face corner.</font>
+01578 <font class="keywordflow">for</font> (i = 0; i &lt; (sint)lodMesh.Faces.size(); ++i)
+01579 {
+01580 <font class="comment">// The current face.</font>
+01581 CMRMFace &amp;face = lodMesh.Faces[i];
+01582 <font class="comment">// the current face, but which points to the prec LOD vertices/attributes.</font>
+01583 CMRMFace &amp;faceCoarser = lodMesh.CoarserFaces[i];
+01584 <font class="comment">// for 3 corners.</font>
+01585 <font class="keywordflow">for</font> (j = 0; j &lt; 3; ++j)
+01586 {
+01587 CMRMCorner &amp;corner = face.Corner[j];
+01588 CMRMCorner &amp;cornerCoarser = faceCoarser.Corner[j];
+01589
+01590 sint startDestIndex = corner.WedgeStartId;
+01591
+01592 <font class="keywordflow">for</font> (sint k = 0; k &lt; (sint)finalMRM.MRMBlendShapesFinals.size(); ++k)
+01593 {
+01594 CMRMMeshFinal::CMRMBlendShapeFinal &amp;rBSFinal = finalMRM.MRMBlendShapesFinals[k];
+01595
+01596 rBSFinal.Wedges.resize (finalMRM.Wedges.size());
+01597 <font class="comment">// Fill WedgeStart used by this corner.</font>
+01598 rBSFinal.Wedges[startDestIndex].Vertex = lodMesh.BlendShapes[k].Vertices[corner.Vertex];
+01599 <font class="keywordflow">for</font> (attId = 0; attId &lt; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>; ++attId)
+01600 {
+01601 rBSFinal.Wedges[startDestIndex].Attributes[attId] = lodMesh.BlendShapes[k].Attributes[attId][corner.Attributes[attId]];
+01602 }
+01603
+01604 <font class="comment">// If geomorph, must fill the end too</font>
+01605 <font class="keywordflow">if</font>(lodId&gt;0 &amp;&amp; corner.WedgeStartId != corner.WedgeEndId)
+01606 {
+01607 sint endDestIndex = corner.WedgeEndId;
+01608
+01609 rBSFinal.Wedges[endDestIndex].Vertex = lodMeshPrec.BlendShapes[k].Vertices[cornerCoarser.Vertex];
+01610 <font class="keywordflow">for</font> (attId = 0; attId &lt; <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>; ++attId)
+01611 {
+01612 rBSFinal.Wedges[endDestIndex].Attributes[attId] = lodMeshPrec.BlendShapes[k].Attributes[attId][cornerCoarser.Attributes[attId]];
+01613 }
+01614 }
+01615 }
+01616
+01617 }
+01618 }
+01619 }
+01620 }
+01621
+01622
+01623
+01624 <font class="comment">// ***************************************************************************</font>
+01625 <font class="comment">// ***************************************************************************</font>
+01626 <font class="comment">// Interface to MeshBuild Part.</font>
+01627 <font class="comment">// ***************************************************************************</font>
+01628 <font class="comment">// ***************************************************************************</font>
+01629
+01630
+01631
+01632 <font class="comment">// ***************************************************************************</font>
+<a name="l01633"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_1">01633</a> sint CMRMBuilder::findInsertAttributeInBaseMesh(CMRMMesh &amp;baseMesh, sint attId, sint vertexId, <font class="keyword">const</font> CVectorH &amp;att)
+01634 {
+01635 <font class="comment">// find this attribute in the map.</font>
+01636 CAttributeKey key;
+01637 key.VertexId= vertexId;
+01638 key.Attribute= att;
+01639 TAttributeMap::iterator it= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_11">_AttributeMap</a>[attId].find(key);
+01640
+01641 <font class="comment">// if attribute not found in the map, then insert a new one.</font>
+01642 <font class="keywordflow">if</font>(it==<a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_11">_AttributeMap</a>[attId].end())
+01643 {
+01644 sint idx= baseMesh.Attributes[attId].size();
+01645 <font class="comment">// insert into the array.</font>
+01646 baseMesh.Attributes[attId].push_back(att);
+01647 <font class="comment">// insert into the map.</font>
+01648 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_11">_AttributeMap</a>[attId].insert(make_pair(key, idx));
+01649 <font class="keywordflow">return</font> idx;
+01650 }
+01651 <font class="keywordflow">else</font>
+01652 {
+01653 <font class="comment">// return the one found.</font>
+01654 <font class="keywordflow">return</font> it-&gt;second;
+01655 }
+01656 }
+01657
+01658
+01659 <font class="comment">// ***************************************************************************</font>
+<a name="l01660"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_2">01660</a> sint CMRMBuilder::findInsertNormalInBaseMesh(CMRMMesh &amp;baseMesh, sint attId, sint vertexId, <font class="keyword">const</font> CVector &amp;normal)
+01661 {
+01662 CVectorH att;
+01663 att= normal;
+01664 att.w= 0;
+01665 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_1">findInsertAttributeInBaseMesh</a>(baseMesh, attId, vertexId, att);
+01666 }
+01667
+01668
+01669 <font class="comment">// ***************************************************************************</font>
+<a name="l01670"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_3">01670</a> sint CMRMBuilder::findInsertColorInBaseMesh(CMRMMesh &amp;baseMesh, sint attId, sint vertexId, CRGBA col)
+01671 {
+01672 CVectorH att;
+01673 att.x= col.R;
+01674 att.y= col.G;
+01675 att.z= col.B;
+01676 att.w= col.A;
+01677 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_1">findInsertAttributeInBaseMesh</a>(baseMesh, attId, vertexId, att);
+01678 }
+01679
+01680
+01681 <font class="comment">// ***************************************************************************</font>
+<a name="l01682"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_4">01682</a> sint CMRMBuilder::findInsertUvwInBaseMesh(CMRMMesh &amp;baseMesh, sint attId, sint vertexId, <font class="keyword">const</font> <a class="code" href="classNLMISC_1_1CUVW.html">NLMISC::CUVW</a> &amp;uvw)
+01683 {
+01684 CVectorH att;
+01685 att.x= uvw.<a class="code" href="classNLMISC_1_1CUVW.html#m0">U</a>;
+01686 att.y= uvw.<a class="code" href="classNLMISC_1_1CUVW.html#m1">V</a>;
+01687 att.z= uvw.<a class="code" href="classNLMISC_1_1CUVW.html#m2">W</a>;
+01688 att.w= 0;
+01689 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_1">findInsertAttributeInBaseMesh</a>(baseMesh, attId, vertexId, att);
+01690 }
+01691
+01692
+01693 <font class="comment">// ***************************************************************************</font>
+<a name="l01694"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_5">01694</a> CRGBA CMRMBuilder::attToColor(<font class="keyword">const</font> CVectorH &amp;att)<font class="keyword"> const</font>
+01695 <font class="keyword"></font>{
+01696 CRGBA ret;
+01697 <font class="keywordtype">float</font> tmp;
+01698 tmp= att.x; <a class="code" href="namespaceNLMISC.html#a215">clamp</a>(tmp, 0, 255);
+01699 ret.R= (uint8)(uint)tmp;
+01700 tmp= att.y; <a class="code" href="namespaceNLMISC.html#a215">clamp</a>(tmp, 0, 255);
+01701 ret.G= (uint8)(uint)tmp;
+01702 tmp= att.z; <a class="code" href="namespaceNLMISC.html#a215">clamp</a>(tmp, 0, 255);
+01703 ret.B= (uint8)(uint)tmp;
+01704 tmp= att.w; <a class="code" href="namespaceNLMISC.html#a215">clamp</a>(tmp, 0, 255);
+01705 ret.A= (uint8)(uint)tmp;
+01706
+01707 <font class="keywordflow">return</font> ret;
+01708 }
+01709
+01710
+01711 <font class="comment">// ***************************************************************************</font>
+<a name="l01712"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_6">01712</a> <a class="code" href="classNLMISC_1_1CUVW.html">NLMISC::CUVW</a> CMRMBuilder::attToUvw(<font class="keyword">const</font> CVectorH &amp;att)<font class="keyword"> const</font>
+01713 <font class="keyword"></font>{
+01714 <font class="keywordflow">return</font> CUVW(att.x, att.y, att.z);
+01715 }
+01716
+01717
+01718 <font class="comment">// ***************************************************************************</font>
+<a name="l01719"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_7">01719</a> uint32 CMRMBuilder::buildMrmBaseMesh(<font class="keyword">const</font> CMesh::CMeshBuild &amp;mbuild, CMRMMesh &amp;baseMesh)
+01720 {
+01721 sint i,j,k;
+01722 sint nFaces;
+01723 sint attId;
+01724 <font class="comment">// build the supported VertexFormat.</font>
+01725 uint32 retVbFlags= CVertexBuffer::PositionFlag;
+01726
+01727
+01728 <font class="comment">// reset the baseMesh.</font>
+01729 baseMesh= CMRMMesh();
+01730 <font class="comment">// reset Tmp.</font>
+01731 <font class="keywordflow">for</font>(attId=0; attId&lt;<a class="code" href="mrm__mesh_8h.html#a0">NL3D_MRM_MAX_ATTRIB</a>;attId++)
+01732 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_11">_AttributeMap</a>[attId].clear();
+01733
+01734
+01735 <font class="comment">// Compute number of attributes used by the MeshBuild.</font>
+01736 <font class="comment">// ========================</font>
+01737 <font class="comment">// Compute too </font>
+01738 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; CVertexBuffer::NormalFlag)
+01739 {
+01740 baseMesh.NumAttributes++;
+01741 retVbFlags|= CVertexBuffer::NormalFlag;
+01742 }
+01743 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; CVertexBuffer::PrimaryColorFlag)
+01744 {
+01745 baseMesh.NumAttributes++;
+01746 retVbFlags|= CVertexBuffer::PrimaryColorFlag;
+01747 }
+01748 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; CVertexBuffer::SecondaryColorFlag)
+01749 {
+01750 baseMesh.NumAttributes++;
+01751 retVbFlags|= CVertexBuffer::SecondaryColorFlag;
+01752 }
+01753 <font class="keywordflow">for</font>(k=0; k&lt;CVertexBuffer::MaxStage;k++)
+01754 {
+01755 uint flag=CVertexBuffer::TexCoord0Flag&lt;&lt;k;
+01756 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; flag)
+01757 {
+01758 baseMesh.NumAttributes++;
+01759 retVbFlags|=flag;
+01760 }
+01761 }
+01762 <a class="code" href="debug_8h.html#a6">nlassert</a>(baseMesh.NumAttributes&lt;=<a class="code" href="mrm__mesh_8h.html#a0">NL3D_MRM_MAX_ATTRIB</a>);
+01763
+01764
+01765 <font class="comment">// Fill basics: Vertices and Faces materials / index to vertices.</font>
+01766 <font class="comment">// ========================</font>
+01767 <font class="comment">// Just copy vertices.</font>
+01768 baseMesh.Vertices= mbuild.Vertices;
+01769 <font class="comment">// Just copy SkinWeights.</font>
+01770 <font class="keywordflow">if</font>(_Skinned)
+01771 baseMesh.SkinWeights= mbuild.SkinWeights;
+01772 <font class="comment">// Just copy InterfaceLinks</font>
+01773 <font class="keywordflow">if</font>(_HasMeshInterfaces)
+01774 baseMesh.InterfaceLinks= mbuild.InterfaceLinks;
+01775 <font class="comment">// Resize faces.</font>
+01776 nFaces= mbuild.Faces.size();
+01777 baseMesh.Faces.resize(nFaces);
+01778 <font class="keywordflow">for</font>(i=0; i&lt;nFaces; i++)
+01779 {
+01780 <font class="comment">// copy material Id.</font>
+01781 baseMesh.Faces[i].MaterialId= mbuild.Faces[i].MaterialId;
+01782 <font class="comment">// Copy Vertex index.</font>
+01783 <font class="keywordflow">for</font>(j=0; j&lt;3; j++)
+01784 {
+01785 baseMesh.Faces[i].Corner[j].Vertex= mbuild.Faces[i].Corner[j].Vertex;
+01786 }
+01787 }
+01788
+01789 <font class="comment">// Resolve attributes discontinuities and Fill attributes of the baseMesh.</font>
+01790 <font class="comment">// ========================</font>
+01791 <font class="comment">// For all corners.</font>
+01792 <font class="keywordflow">for</font>(i=0; i&lt;nFaces; i++)
+01793 {
+01794 <font class="keywordflow">for</font>(j=0; j&lt;3; j++)
+01795 {
+01796 <font class="keyword">const</font> CMesh::CCorner &amp;srcCorner= mbuild.Faces[i].Corner[j];
+01797 CMRMCorner &amp;destCorner= baseMesh.Faces[i].Corner[j];
+01798 attId= 0;
+01799
+01800 <font class="comment">// For all activated attributes in mbuild, find/insert the attribute in the baseMesh.</font>
+01801 <font class="comment">// NB: 2 attributes are said to be different if they have not the same value OR if they don't lie </font>
+01802 <font class="comment">// on the same vertex. This is very important for MRM computing.</font>
+01803 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; CVertexBuffer::NormalFlag)
+01804 {
+01805 destCorner.Attributes[attId]= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_2">findInsertNormalInBaseMesh</a>(baseMesh, attId, destCorner.Vertex, srcCorner.Normal);
+01806 attId++;
+01807 }
+01808 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; CVertexBuffer::PrimaryColorFlag)
+01809 {
+01810 destCorner.Attributes[attId]= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_3">findInsertColorInBaseMesh</a>(baseMesh, attId, destCorner.Vertex, srcCorner.Color);
+01811 attId++;
+01812 }
+01813 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; CVertexBuffer::SecondaryColorFlag)
+01814 {
+01815 destCorner.Attributes[attId]= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_3">findInsertColorInBaseMesh</a>(baseMesh, attId, destCorner.Vertex, srcCorner.Specular);
+01816 attId++;
+01817 }
+01818 <font class="keywordflow">for</font>(k=0; k&lt;CVertexBuffer::MaxStage;k++)
+01819 {
+01820 <font class="keywordflow">if</font>(mbuild.VertexFlags &amp; (CVertexBuffer::TexCoord0Flag&lt;&lt;k))
+01821 {
+01822 destCorner.Attributes[attId]= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_4">findInsertUvwInBaseMesh</a>(baseMesh, attId, destCorner.Vertex, srcCorner.Uvws[k]);
+01823 attId++;
+01824 }
+01825 }
+01826 }
+01827 }
+01828
+01829
+01830
+01831 <font class="comment">// End. clear Tmp infos.</font>
+01832 <font class="comment">// ========================</font>
+01833 <font class="comment">// reset Tmp.</font>
+01834 <font class="keywordflow">for</font>(attId=0; attId&lt;<a class="code" href="mrm__mesh_8h.html#a0">NL3D_MRM_MAX_ATTRIB</a>;attId++)
+01835 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_11">_AttributeMap</a>[attId].clear();
+01836
+01837 <font class="keywordflow">return</font> retVbFlags;
+01838 }
+01839
+01840
+01841
+01842 <font class="comment">// ***************************************************************************</font>
+<a name="l01843"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_10">01843</a> CMesh::CSkinWeight CMRMBuilder::normalizeSkinWeight(<font class="keyword">const</font> CMesh::CSkinWeight &amp;sw)<font class="keyword"> const</font>
+01844 <font class="keyword"></font>{
+01845 uint nbMats= 0;
+01846 <font class="keyword">static</font> vector&lt;CTmpVertexWeight&gt; sws;
+01847 sws.reserve(<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>);
+01848 sws.clear();
+01849
+01850 <font class="comment">// For all weights of sw1.</font>
+01851 uint i;
+01852 <font class="keywordflow">for</font>(i=0; i&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; i++)
+01853 {
+01854 CTmpVertexWeight vw;
+01855 vw.MatrixId= sw.MatrixId[i];
+01856 vw.Weight= sw.Weights[i];
+01857 <font class="comment">// if this weight is not null.</font>
+01858 <font class="keywordflow">if</font>(vw.Weight&gt;0)
+01859 {
+01860 <font class="comment">// add it to the list.</font>
+01861 sws.push_back(vw);
+01862 nbMats++;
+01863 }
+01864 }
+01865
+01866 <font class="comment">// sort by Weight decreasing order.</font>
+01867 sort(sws.begin(), sws.end());
+01868
+01869
+01870 <font class="comment">// Then output the result to the skinWeight, normalizing.</font>
+01871 <font class="keywordtype">float</font> sumWeight=0;
+01872 <font class="keywordflow">for</font>(i= 0; i&lt;nbMats; i++)
+01873 {
+01874 sumWeight+= sws[i].Weight;
+01875 }
+01876
+01877 CMesh::CSkinWeight ret;
+01878 <font class="comment">// Fill only needed matrix (other are rested in CMesh::CSkinWeight ctor).</font>
+01879 <font class="keywordflow">for</font>(i= 0; i&lt;nbMats; i++)
+01880 {
+01881 ret.MatrixId[i]= sws[i].MatrixId;
+01882 ret.Weights[i]= sws[i].Weight / sumWeight;
+01883 }
+01884
+01885 <font class="keywordflow">return</font> ret;
+01886 }
+01887
+01888
+01889 <font class="comment">// ***************************************************************************</font>
+<a name="l01890"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_9">01890</a> <font class="keywordtype">void</font> CMRMBuilder::normalizeBaseMeshSkin(CMRMMesh &amp;baseMesh)<font class="keyword"> const</font>
+01891 <font class="keyword"></font>{
+01892 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a>);
+01893
+01894 <font class="keywordflow">for</font>(uint i=0; i&lt;baseMesh.SkinWeights.size(); i++)
+01895 {
+01896 baseMesh.SkinWeights[i]= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_10">normalizeSkinWeight</a>(baseMesh.SkinWeights[i]);
+01897 }
+01898 }
+01899
+01900
+01901
+01902 <font class="comment">// ***************************************************************************</font>
+<a name="l01903"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_8">01903</a> <font class="keywordtype">void</font> CMRMBuilder::buildMeshBuildMrm(<font class="keyword">const</font> CMRMMeshFinal &amp;finalMRM, CMeshMRMGeom::CMeshBuildMRM &amp;mbuild, uint32 vbFlags, uint32 nbMats, <font class="keyword">const</font> CMesh::CMeshBuild &amp;mb)
+01904 {
+01905 sint i,j,k;
+01906 sint attId;
+01907
+01908 <font class="comment">// reset the mbuild.</font>
+01909 mbuild= CMeshMRMGeom::CMeshBuildMRM();
+01910 <font class="comment">// Setup VB.</font>
+01911
+01912 <font class="keywordtype">bool</font> useFormatExt = <font class="keyword">false</font>;
+01913 <font class="comment">// Check wether there are texture coordinates with more than 2 compnents, which force us to use an extended vertex format</font>
+01914 <font class="keywordflow">for</font> (k = 0; k &lt; CVertexBuffer::MaxStage; ++k)
+01915 {
+01916 <font class="keywordflow">if</font> (
+01917 (vbFlags &amp; (CVertexBuffer::TexCoord0Flag &lt;&lt; k))
+01918 &amp;&amp; mb.NumCoords[k] != 2)
+01919 {
+01920 useFormatExt = <font class="keyword">true</font>;
+01921 <font class="keywordflow">break</font>;
+01922 }
+01923 }
+01924
+01925 uint numTexCoordUsed = 0;
+01926
+01927
+01928 <font class="keywordflow">for</font> (k = 0; k &lt; CVertexBuffer::MaxStage; ++k)
+01929 {
+01930 <font class="keywordflow">if</font> (vbFlags &amp; (CVertexBuffer::TexCoord0Flag &lt;&lt; k))
+01931 {
+01932 numTexCoordUsed = k;
+01933 }
+01934 }
+01935
+01936 <font class="keywordflow">if</font> (!useFormatExt)
+01937 {
+01938 <font class="comment">// setup standard format</font>
+01939 mbuild.VBuffer.setVertexFormat(vbFlags);
+01940 }
+01941 <font class="keywordflow">else</font> <font class="comment">// setup extended format</font>
+01942 {
+01943 mbuild.VBuffer.clearValueEx();
+01944 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::PositionFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3);
+01945 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::NormalFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Normal, CVertexBuffer::Float3);
+01946 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::PrimaryColorFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::PrimaryColor, CVertexBuffer::UChar4);
+01947 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::SecondaryColorFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::SecondaryColor, CVertexBuffer::UChar4);
+01948 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::WeightFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Weight, CVertexBuffer::Float4);
+01949 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::PaletteSkinFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::PaletteSkin, CVertexBuffer::UChar4);
+01950 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::FogFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Fog, CVertexBuffer::Float1);
+01951
+01952 <font class="keywordflow">for</font> (k = 0; k &lt; CVertexBuffer::MaxStage; ++k)
+01953 {
+01954 <font class="keywordflow">if</font> (vbFlags &amp; (CVertexBuffer::TexCoord0Flag &lt;&lt; k))
+01955 {
+01956 <font class="keywordflow">switch</font>(mb.NumCoords[k])
+01957 {
+01958 <font class="keywordflow">case</font> 2:
+01959 mbuild.VBuffer.addValueEx((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + k), CVertexBuffer::Float2);
+01960 <font class="keywordflow">break</font>;
+01961 <font class="keywordflow">case</font> 3:
+01962 mbuild.VBuffer.addValueEx((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + k), CVertexBuffer::Float3);
+01963 <font class="keywordflow">break</font>;
+01964 <font class="keywordflow">default</font>:
+01965 <a class="code" href="debug_8h.html#a6">nlassert</a>(0);
+01966 <font class="keywordflow">break</font>;
+01967 }
+01968 }
+01969 }
+01970 mbuild.VBuffer.initEx();
+01971 }
+01972
+01973
+01974
+01975
+01976 <font class="comment">// Setup the VertexBuffer.</font>
+01977 <font class="comment">// ========================</font>
+01978 <font class="comment">// resize the VB.</font>
+01979 mbuild.VBuffer.setNumVertices(finalMRM.Wedges.size());
+01980 <font class="comment">// Setup SkinWeights.</font>
+01981 <font class="keywordflow">if</font>(_Skinned)
+01982 mbuild.SkinWeights.resize(finalMRM.Wedges.size());
+01983
+01984 <font class="comment">// fill the VB.</font>
+01985 <font class="keywordflow">for</font>(i=0; i&lt;(sint)finalMRM.Wedges.size(); i++)
+01986 {
+01987 <font class="keyword">const</font> CMRMMeshFinal::CWedge &amp;wedge= finalMRM.Wedges[i];
+01988
+01989 <font class="comment">// setup Vertex.</font>
+01990 mbuild.VBuffer.setVertexCoord(i, wedge.Vertex);
+01991
+01992 <font class="comment">// seutp attributes.</font>
+01993 attId= 0;
+01994
+01995 <font class="comment">// For all activated attributes in mbuild, retriev the attribute from the finalMRM.</font>
+01996 <font class="keywordflow">if</font>(vbFlags &amp; CVertexBuffer::NormalFlag)
+01997 {
+01998 mbuild.VBuffer.setNormalCoord(i, wedge.Attributes[attId] );
+01999 attId++;
+02000 }
+02001 <font class="keywordflow">if</font>(vbFlags &amp; CVertexBuffer::PrimaryColorFlag)
+02002 {
+02003 mbuild.VBuffer.setColor(i, <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_5">attToColor</a>(wedge.Attributes[attId]) );
+02004 attId++;
+02005 }
+02006 <font class="keywordflow">if</font>(vbFlags &amp; CVertexBuffer::SecondaryColorFlag)
+02007 {
+02008 mbuild.VBuffer.setSpecular(i, <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_5">attToColor</a>(wedge.Attributes[attId]) );
+02009 attId++;
+02010 }
+02011 <font class="keywordflow">for</font>(k=0; k&lt;CVertexBuffer::MaxStage;k++)
+02012 {
+02013 <font class="keywordflow">if</font>(vbFlags &amp; (CVertexBuffer::TexCoord0Flag&lt;&lt;k))
+02014 {
+02015 <font class="keywordflow">switch</font>(mb.NumCoords[k])
+02016 {
+02017 <font class="keywordflow">case</font> 2:
+02018 mbuild.VBuffer.setTexCoord(i, k, (CUV) <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_6">attToUvw</a>(wedge.Attributes[attId]) );
+02019 <font class="keywordflow">break</font>;
+02020 <font class="keywordflow">case</font> 3:
+02021 {
+02022 CUVW uvw = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_6">attToUvw</a>(wedge.Attributes[attId]);
+02023 mbuild.VBuffer.setValueFloat3Ex((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + k), i, uvw.U, uvw.V, uvw.W);
+02024 }
+02025 <font class="keywordflow">break</font>;
+02026 <font class="keywordflow">default</font>:
+02027 <a class="code" href="debug_8h.html#a6">nlassert</a>(0);
+02028 <font class="keywordflow">break</font>;
+02029 }
+02030 attId++;
+02031 }
+02032 }
+02033
+02034 <font class="comment">// Setup SkinWeights.</font>
+02035 <font class="keywordflow">if</font>(_Skinned)
+02036 {
+02037 mbuild.SkinWeights[i]= wedge.VertexSkin;
+02038 }
+02039 }
+02040
+02041
+02042 <font class="comment">// Build Lods.</font>
+02043 <font class="comment">// ========================</font>
+02044 <font class="comment">// resize</font>
+02045 mbuild.Lods.resize(finalMRM.Lods.size());
+02046 <font class="comment">// fill.</font>
+02047 <font class="keywordflow">for</font>(i=0; i&lt;(sint)finalMRM.Lods.size(); i++)
+02048 {
+02049 <font class="keyword">const</font> CMRMMeshFinal::CLod &amp;srcLod= finalMRM.Lods[i];
+02050 CMeshMRMGeom::CLod &amp;destLod= mbuild.Lods[i];
+02051
+02052 <font class="comment">// Basic.</font>
+02053 <font class="comment">//---------</font>
+02054
+02055 <font class="comment">// Copy NWedges infos.</font>
+02056 destLod.NWedges= srcLod.NWedges;
+02057 <font class="comment">// Copy Geomorphs infos.</font>
+02058 destLod.Geomorphs= srcLod.Geomorphs;
+02059
+02060
+02061 <font class="comment">// Reorder faces by rdrpass.</font>
+02062 <font class="comment">//---------</font>
+02063
+02064 <font class="comment">// First count the number of faces used by this LOD for each material </font>
+02065 vector&lt;sint&gt; matCount;
+02066 <font class="comment">// resize, and reset to 0.</font>
+02067 matCount.clear();
+02068 matCount.resize(nbMats, 0);
+02069 <font class="comment">// For each face of this Lods, incr the mat face counter.</font>
+02070 <font class="keywordflow">for</font>(j= 0; j&lt;(sint)srcLod.Faces.size(); j++)
+02071 {
+02072 sint matId= srcLod.Faces[j].MaterialId;
+02073 <a class="code" href="debug_8h.html#a6">nlassert</a>(matId&gt;=0);
+02074 <a class="code" href="debug_8h.html#a6">nlassert</a>(matId&lt;(sint)nbMats);
+02075 <font class="comment">// increment the refcount of this material by this LOD.</font>
+02076 matCount[matId]++;
+02077 }
+02078
+02079 <font class="comment">// Then for each material not empty, create a rdrPass, and ref it for this material.</font>
+02080 vector&lt;sint&gt; rdrPassIndex; <font class="comment">// material to rdrPass map.</font>
+02081 rdrPassIndex.resize(nbMats);
+02082 <font class="keywordflow">for</font>(j=0; j&lt;(sint)nbMats; j++)
+02083 {
+02084 <font class="keywordflow">if</font>(matCount[j]==0)
+02085 rdrPassIndex[j]= -1;
+02086 <font class="keywordflow">else</font>
+02087 {
+02088 <font class="comment">// map material to rdrPass.</font>
+02089 sint idRdrPass= destLod.RdrPass.size();
+02090 rdrPassIndex[j]= idRdrPass;
+02091 <font class="comment">// create a rdrPass.</font>
+02092 destLod.RdrPass.push_back(CMeshMRMGeom::CRdrPass());
+02093 <font class="comment">// assign the good materialId to this rdrPass.</font>
+02094 destLod.RdrPass[idRdrPass].MaterialId= j;
+02095 <font class="comment">// reserve the array of faces of this rdrPass.</font>
+02096 destLod.RdrPass[idRdrPass].PBlock.reserveTri(matCount[j]);
+02097 }
+02098 }
+02099
+02100 <font class="comment">// Then for each face, add it to the good rdrPass of this Lod.</font>
+02101 <font class="keywordflow">for</font>(j= 0; j&lt;(sint)srcLod.Faces.size(); j++)
+02102 {
+02103 sint matId= srcLod.Faces[j].MaterialId;
+02104 sint idRdrPass= rdrPassIndex[matId];
+02105 <font class="comment">// add this face to the good rdrPass.</font>
+02106 sint w0= srcLod.Faces[j].WedgeId[0];
+02107 sint w1= srcLod.Faces[j].WedgeId[1];
+02108 sint w2= srcLod.Faces[j].WedgeId[2];
+02109 destLod.RdrPass[idRdrPass].PBlock.addTri(w0, w1, w2);
+02110 }
+02111
+02112
+02113 <font class="comment">// Build skin info for this Lod.</font>
+02114 <font class="comment">//---------</font>
+02115 <font class="keywordflow">for</font>(j=0; j&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; j++)
+02116 {
+02117 destLod.InfluencedVertices[j].clear();
+02118 }
+02119 destLod.MatrixInfluences.clear();
+02120 <font class="keywordflow">if</font>(_Skinned)
+02121 {
+02122 <font class="comment">// This is the set which tell what wedge has already been inserted.</font>
+02123 set&lt;uint&gt; wedgeInfSet;
+02124
+02125 <font class="comment">// First, build the list of vertices influenced by this Lod.</font>
+02126 <font class="keywordflow">for</font>(j= 0; j&lt;(sint)srcLod.Faces.size(); j++)
+02127 {
+02128 <font class="keywordflow">for</font>(k=0; k&lt;3; k++)
+02129 {
+02130 sint wedgeId= srcLod.Faces[j].WedgeId[k];
+02131 <font class="comment">// If it is a geomorph</font>
+02132 <font class="keywordflow">if</font>(wedgeId&lt;finalMRM.NGeomSpace)
+02133 {
+02134 <font class="comment">// add the start and end to the list (if not here). NB: wedgeId is both the id </font>
+02135 <font class="comment">// of the dest wedge, and the id of the geomorph.</font>
+02136 sint wedgeStartId= destLod.Geomorphs[wedgeId].Start;
+02137 sint wedgeEndId= destLod.Geomorphs[wedgeId].End;
+02138 uint nMatUsedStart= finalMRM.Wedges[wedgeStartId].NSkinMatUsed;
+02139 uint nMatUsedEnd= finalMRM.Wedges[wedgeEndId].NSkinMatUsed;
+02140
+02141 <font class="comment">// if insertion in the set work, add to the good array.</font>
+02142 <font class="keywordflow">if</font>( wedgeInfSet.insert(wedgeStartId).second )
+02143 destLod.InfluencedVertices[nMatUsedStart-1].push_back(wedgeStartId);
+02144 <font class="keywordflow">if</font>( wedgeInfSet.insert(wedgeEndId).second )
+02145 destLod.InfluencedVertices[nMatUsedEnd-1].push_back(wedgeEndId);
+02146 }
+02147 <font class="keywordflow">else</font>
+02148 {
+02149 uint nMatUsed= finalMRM.Wedges[wedgeId].NSkinMatUsed;
+02150
+02151 <font class="comment">// just add this wedge to the list (if not here).</font>
+02152 <font class="comment">// if insertion in the set work, add to the array.</font>
+02153 <font class="keywordflow">if</font>( wedgeInfSet.insert(wedgeId).second )
+02154 destLod.InfluencedVertices[nMatUsed-1].push_back(wedgeId);
+02155 }
+02156 }
+02157 }
+02158
+02159 <font class="comment">// Optimisation: for better cache, sort the destLod.InfluencedVertices in increasing order.</font>
+02160 <font class="keywordflow">for</font>(j=0; j&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; j++)
+02161 {
+02162 sort(destLod.InfluencedVertices[j].begin(), destLod.InfluencedVertices[j].end());
+02163 }
+02164
+02165
+02166 <font class="comment">// Then Build the MatrixInfluences array, for all thoses Influenced Vertices only.</font>
+02167 <font class="comment">// This is the map MatrixId -&gt; MatrixInfId.</font>
+02168 map&lt;uint, uint&gt; matrixInfMap;
+02169
+02170 <font class="comment">// For all influenced vertices, flags matrix they use.</font>
+02171 uint iSkinMat;
+02172 <font class="keywordflow">for</font>(iSkinMat= 0; iSkinMat&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; iSkinMat++)
+02173 {
+02174 <font class="keywordflow">for</font>(j= 0; j&lt;(sint)destLod.InfluencedVertices[iSkinMat].size(); j++)
+02175 {
+02176 uint wedgeId= destLod.InfluencedVertices[iSkinMat][j];
+02177
+02178 <font class="comment">// take the original wedge.</font>
+02179 <font class="keyword">const</font> CMRMMeshFinal::CWedge &amp;wedge= finalMRM.Wedges[wedgeId];
+02180 <font class="comment">// For all matrix with not null influence...</font>
+02181 <font class="keywordflow">for</font>(k= 0; k&lt;<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; k++)
+02182 {
+02183 <font class="keywordtype">float</font> matWeight= wedge.VertexSkin.Weights[k];
+02184
+02185 <font class="comment">// This check the validity of skin weights sort. If false, problem before in the algo.</font>
+02186 <font class="keywordflow">if</font>((uint)k&lt;iSkinMat+1)
+02187 {
+02188 <a class="code" href="debug_8h.html#a6">nlassert</a>( matWeight&gt;0 );
+02189 }
+02190 <font class="keywordflow">else</font>
+02191 {
+02192 <a class="code" href="debug_8h.html#a6">nlassert</a>( matWeight==0 );
+02193 }
+02194 <font class="comment">// if not null influence.</font>
+02195 <font class="keywordflow">if</font>(matWeight&gt;0)
+02196 {
+02197 uint matId= wedge.VertexSkin.MatrixId[k];
+02198
+02199 <font class="comment">// search/insert the matrixInfId.</font>
+02200 map&lt;uint, uint&gt;::iterator it= matrixInfMap.find(matId);
+02201 <font class="keywordflow">if</font>( it==matrixInfMap.end() )
+02202 {
+02203 uint matInfId= destLod.MatrixInfluences.size();
+02204 matrixInfMap.insert( make_pair(matId, matInfId) );
+02205 <font class="comment">// create the new MatrixInfluence.</font>
+02206 destLod.MatrixInfluences.push_back(matId);
+02207 }
+02208 }
+02209 }
+02210 }
+02211 }
+02212
+02213 }
+02214
+02215 }
+02216
+02217 <font class="comment">// Indicate Skinning.</font>
+02218 mbuild.Skinned= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a>;
+02219
+02220
+02221
+02222 <font class="keywordtype">bool</font> useTgSpace = mb.MeshVertexProgram != NULL ? mb.MeshVertexProgram-&gt;needTangentSpace() : <font class="keyword">false</font>;
+02223
+02224 <font class="comment">// Construct Blend Shapes</font>
+02226 <font class="comment"> mbuild.BlendShapes.resize (finalMRM.MRMBlendShapesFinals.size());</font>
+02227 <font class="keywordflow">for</font> (k = 0; k &lt; (sint)mbuild.BlendShapes.size(); ++k)
+02228 {
+02229 CBlendShape &amp;rBS = mbuild.BlendShapes[k];
+02230 sint32 nNbVertVB = finalMRM.Wedges.size();
+02231 <font class="keywordtype">bool</font> bIsDeltaPos = <font class="keyword">false</font>;
+02232 rBS.deltaPos.resize (nNbVertVB, CVector(0.0f,0.0f,0.0f));
+02233 <font class="keywordtype">bool</font> bIsDeltaNorm = <font class="keyword">false</font>;
+02234 rBS.deltaNorm.resize (nNbVertVB, CVector(0.0f,0.0f,0.0f));
+02235 <font class="keywordtype">bool</font> bIsDeltaUV = <font class="keyword">false</font>;
+02236 rBS.deltaUV.resize (nNbVertVB, CUV(0.0f,0.0f));
+02237 <font class="keywordtype">bool</font> bIsDeltaCol = <font class="keyword">false</font>;
+02238 rBS.deltaCol.resize (nNbVertVB, CRGBAF(0.0f,0.0f,0.0f,0.0f));
+02239 <font class="keywordtype">bool</font> bIsDeltaTgSpace = <font class="keyword">false</font>;
+02240 <font class="keywordflow">if</font> (useTgSpace)
+02241 {
+02242 rBS.deltaTgSpace.resize(nNbVertVB, CVector::Null);
+02243 }
+02244
+02245 rBS.VertRefs.resize (nNbVertVB, 0xffffffff);
+02246
+02247 <font class="keywordflow">for</font> (i = 0; i &lt; nNbVertVB; i++)
+02248 {
+02249 <font class="keyword">const</font> CMRMMeshFinal::CWedge &amp;rWedgeRef = finalMRM.Wedges[i];
+02250 <font class="keyword">const</font> CMRMMeshFinal::CWedge &amp;rWedgeTar = finalMRM.MRMBlendShapesFinals[k].Wedges[i];
+02251
+02252 CVector delta = rWedgeTar.Vertex - rWedgeRef.Vertex;
+02253 CVectorH attr;
+02254
+02255 <font class="keywordflow">if</font> (delta.norm() &gt; 0.001f)
+02256 {
+02257 rBS.deltaPos[i] = delta;
+02258 rBS.VertRefs[i] = i;
+02259 bIsDeltaPos = <font class="keyword">true</font>;
+02260 }
+02261
+02262 attId = 0;
+02263 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::NormalFlag)
+02264 {
+02265 attr = rWedgeRef.Attributes[attId];
+02266 CVector NormRef = CVector(attr.x, attr.y, attr.z);
+02267 attr = rWedgeTar.Attributes[attId];
+02268 CVector NormTar = CVector(attr.x, attr.y, attr.z);
+02269 delta = NormTar - NormRef;
+02270 <font class="keywordflow">if</font> (delta.norm() &gt; 0.001f)
+02271 {
+02272 rBS.deltaNorm[i] = delta;
+02273 rBS.VertRefs[i] = i;
+02274 bIsDeltaNorm = <font class="keyword">true</font>;
+02275 }
+02276 attId++;
+02277 }
+02278
+02279 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::PrimaryColorFlag)
+02280 {
+02281 attr = rWedgeRef.Attributes[attId];
+02282 CRGBAF RGBARef = CRGBAF(attr.x/255.0f, attr.y/255.0f, attr.z/255.0f, attr.w/255.0f);
+02283 attr = rWedgeTar.Attributes[attId];
+02284 CRGBAF RGBATar = CRGBAF(attr.x/255.0f, attr.y/255.0f, attr.z/255.0f, attr.w/255.0f);
+02285 CRGBAF deltaRGBA = RGBATar - RGBARef;
+02286 <font class="keywordflow">if</font> ((deltaRGBA.R*deltaRGBA.R + deltaRGBA.G*deltaRGBA.G +
+02287 deltaRGBA.B*deltaRGBA.B + deltaRGBA.A*deltaRGBA.A) &gt; 0.0001f)
+02288 {
+02289 rBS.deltaCol[i] = deltaRGBA;
+02290 rBS.VertRefs[i] = i;
+02291 bIsDeltaCol = <font class="keyword">true</font>;
+02292 }
+02293 attId++;
+02294 }
+02295
+02296 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::SecondaryColorFlag)
+02297 { <font class="comment">// Nothing to do !</font>
+02298 attId++;
+02299 }
+02300
+02301 <font class="comment">// Do that only for the UV0</font>
+02302 <font class="keywordflow">if</font> (vbFlags &amp; CVertexBuffer::TexCoord0Flag)
+02303 {
+02304 attr = rWedgeRef.Attributes[attId];
+02305 CUV UVRef = CUV(attr.x, attr.y);
+02306 attr = rWedgeTar.Attributes[attId];
+02307 CUV UVTar = CUV(attr.x, attr.y);
+02308 CUV deltaUV = UVTar - UVRef;
+02309 <font class="keywordflow">if</font> ((deltaUV.U*deltaUV.U + deltaUV.V*deltaUV.V) &gt; 0.0001f)
+02310 {
+02311 rBS.deltaUV[i] = deltaUV;
+02312 rBS.VertRefs[i] = i;
+02313 bIsDeltaUV = <font class="keyword">true</font>;
+02314 }
+02315 attId++;
+02316 }
+02317
+02318 <font class="keywordflow">if</font> (useTgSpace)
+02319 {
+02320 attr = rWedgeRef.Attributes[attId];
+02321 CVector TgSpaceRef = CVector(attr.x, attr.y, attr.z);
+02322 attr = rWedgeTar.Attributes[attId];
+02323 CVector TgSpaceTar = CVector(attr.x, attr.y, attr.z);
+02324 delta = TgSpaceTar - TgSpaceRef;
+02325 <font class="keywordflow">if</font> (delta.norm() &gt; 0.001f)
+02326 {
+02327 rBS.deltaTgSpace[i] = delta;
+02328 rBS.VertRefs[i] = i;
+02329 bIsDeltaTgSpace = <font class="keyword">true</font>;
+02330 }
+02331 attId++;
+02332 }
+02333
+02334 } <font class="comment">// End of all vertices added in blend shape</font>
+02335
+02336 <font class="comment">// Delete unused items and calculate the number of vertex used (blended)</font>
+02337
+02338 sint32 nNbVertUsed = nNbVertVB;
+02339 sint32 nDstPos = 0;
+02340 <font class="keywordflow">for</font> (j = 0; j &lt; nNbVertVB; ++j)
+02341 {
+02342 <font class="keywordflow">if</font> (rBS.VertRefs[j] == 0xffffffff) <font class="comment">// Is vertex UNused</font>
+02343 {
+02344 --nNbVertUsed;
+02345 }
+02346 <font class="keywordflow">else</font> <font class="comment">// Vertex used</font>
+02347 {
+02348 <font class="keywordflow">if</font> (nDstPos != j)
+02349 {
+02350 rBS.VertRefs[nDstPos] = rBS.VertRefs[j];
+02351 rBS.deltaPos[nDstPos] = rBS.deltaPos[j];
+02352 rBS.deltaNorm[nDstPos] = rBS.deltaNorm[j];
+02353 rBS.deltaUV[nDstPos] = rBS.deltaUV[j];
+02354 rBS.deltaCol[nDstPos] = rBS.deltaCol[j];
+02355 <font class="keywordflow">if</font> (useTgSpace)
+02356 {
+02357 rBS.deltaTgSpace[nDstPos] = rBS.deltaTgSpace[j];
+02358 }
+02359 }
+02360 ++nDstPos;
+02361 }
+02362 }
+02363
+02364 <font class="keywordflow">if</font> (bIsDeltaPos)
+02365 rBS.deltaPos.resize (nNbVertUsed);
+02366 <font class="keywordflow">else</font>
+02367 rBS.deltaPos.resize (0);
+02368
+02369 <font class="keywordflow">if</font> (bIsDeltaNorm)
+02370 rBS.deltaNorm.resize (nNbVertUsed);
+02371 <font class="keywordflow">else</font>
+02372 rBS.deltaNorm.resize (0);
+02373
+02374 <font class="keywordflow">if</font> (bIsDeltaUV)
+02375 rBS.deltaUV.resize (nNbVertUsed);
+02376 <font class="keywordflow">else</font>
+02377 rBS.deltaUV.resize (0);
+02378
+02379 <font class="keywordflow">if</font> (bIsDeltaCol)
+02380 rBS.deltaCol.resize (nNbVertUsed);
+02381 <font class="keywordflow">else</font>
+02382 rBS.deltaCol.resize (0);
+02383
+02384 <font class="keywordflow">if</font> (bIsDeltaTgSpace)
+02385 rBS.deltaTgSpace.resize (nNbVertUsed);
+02386 <font class="keywordflow">else</font>
+02387 rBS.deltaTgSpace.resize (0);
+02388
+02389
+02390 rBS.VertRefs.resize (nNbVertUsed);
+02391
+02392 }
+02393 }
+02394
+02395 <font class="comment">// ***************************************************************************</font>
+<a name="l02396"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z630_0">02396</a> <font class="keywordtype">void</font> CMRMBuilder::buildBlendShapes (CMRMMesh&amp; baseMesh,
+02397 std::vector&lt;CMesh::CMeshBuild*&gt; &amp;bsList, uint32 VertexFlags)
+02398 {
+02399 uint32 i, j, k, m, destIndex;
+02400 uint32 attId;
+02401 CVectorH vh;
+02402 vector&lt;CMRMBlendShape&gt; &amp;bsMeshes= baseMesh.BlendShapes;
+02403
+02404 bsMeshes.resize (bsList.size());
+02405
+02406 <font class="keywordflow">for</font> (i = 0; i &lt; bsList.size(); ++i)
+02407 {
+02408 <font class="comment">// Construct a blend shape like a mrm mesh</font>
+02409 <a class="code" href="debug_8h.html#a6">nlassert</a> (baseMesh.Vertices.size() == bsList[i]-&gt;Vertices.size());
+02410 bsMeshes[i].Vertices.resize (baseMesh.Vertices.size());
+02411 bsMeshes[i].Vertices = bsList[i]-&gt;Vertices;
+02412
+02413 bsMeshes[i].NumAttributes = baseMesh.NumAttributes;
+02414 <font class="keywordflow">for</font> (j = 0; j &lt; (uint32)bsMeshes[i].NumAttributes; ++j)
+02415 bsMeshes[i].Attributes[j].resize(baseMesh.Attributes[j].size());
+02416
+02417 <font class="comment">// For all corners parse the faces (given by the baseMesh) and construct blend shape mrm meshes</font>
+02418 <font class="keywordflow">for</font> (j = 0; j &lt; baseMesh.Faces.size(); ++j)
+02419 <font class="keywordflow">for</font> (k = 0; k &lt; 3; ++k)
+02420 {
+02421 <font class="keyword">const</font> CMesh::CCorner &amp;srcCorner = bsList[i]-&gt;Faces[j].Corner[k];
+02422 CMRMCorner &amp;neutralCorner = baseMesh.Faces[j].Corner[k];
+02423
+02424 attId= 0;
+02425
+02426 <font class="keywordflow">if</font> (VertexFlags &amp; CVertexBuffer::NormalFlag)
+02427 {
+02428 destIndex = neutralCorner.Attributes[attId];
+02429 vh.x = srcCorner.Normal.x;
+02430 vh.y = srcCorner.Normal.y;
+02431 vh.z = srcCorner.Normal.z;
+02432 vh.w = 0.0f;
+02433 bsMeshes[i].Attributes[attId].operator[](destIndex) = vh;
+02434 attId++;
+02435 }
+02436 <font class="keywordflow">if</font> (VertexFlags &amp; CVertexBuffer::PrimaryColorFlag)
+02437 {
+02438 destIndex = neutralCorner.Attributes[attId];
+02439 vh.x = srcCorner.Color.R;
+02440 vh.y = srcCorner.Color.G;
+02441 vh.z = srcCorner.Color.B;
+02442 vh.w = srcCorner.Color.A;
+02443 bsMeshes[i].Attributes[attId].operator[](destIndex) = vh;
+02444 attId++;
+02445 }
+02446 <font class="keywordflow">if</font> (VertexFlags &amp; CVertexBuffer::SecondaryColorFlag)
+02447 {
+02448 destIndex = neutralCorner.Attributes[attId];
+02449 vh.x = srcCorner.Specular.R;
+02450 vh.y = srcCorner.Specular.G;
+02451 vh.z = srcCorner.Specular.B;
+02452 vh.w = srcCorner.Specular.A;
+02453 bsMeshes[i].Attributes[attId].operator[](destIndex) = vh;
+02454 attId++;
+02455 }
+02456 <font class="keywordflow">for</font> (m = 0; m &lt; CVertexBuffer::MaxStage; ++m)
+02457 {
+02458 <font class="keywordflow">if</font> (VertexFlags &amp; (CVertexBuffer::TexCoord0Flag&lt;&lt;m))
+02459 {
+02460 destIndex = neutralCorner.Attributes[attId];
+02461 vh.x = srcCorner.Uvws[m].U;
+02462 vh.y = srcCorner.Uvws[m].V;
+02463 vh.z = srcCorner.Uvws[m].W;
+02464 vh.w = 0.0f;
+02465 bsMeshes[i].Attributes[attId].operator[](destIndex) = vh;
+02466 attId++;
+02467 }
+02468 }
+02469 }
+02470 }
+02471 }
+02472
+02473
+02474 <font class="comment">// ***************************************************************************</font>
+<a name="l02475"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#a1">02475</a> <font class="keywordtype">void</font> CMRMBuilder::compileMRM(<font class="keyword">const</font> CMesh::CMeshBuild &amp;mbuild, std::vector&lt;CMesh::CMeshBuild*&gt; &amp;bsList,
+02476 <font class="keyword">const</font> CMRMParameters &amp;<a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>, CMeshMRMGeom::CMeshBuildMRM &amp;mrmMesh,
+02477 uint numMaxMaterial)
+02478 {
+02479 <font class="comment">// Temp data.</font>
+02480 CMRMMesh baseMesh;
+02481 vector&lt;CMRMMeshGeom&gt; lodMeshs;
+02482 CMRMMeshFinal finalMRM;
+02483 vector&lt;CMRMMeshFinal&gt; finalBsMRM;
+02484 uint32 vbFlags;
+02485
+02486
+02487 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceFinest&gt;=0);
+02488 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceMiddle &gt; <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceFinest);
+02489 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceCoarsest &gt; <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceMiddle);
+02490
+02491
+02492 <font class="comment">// Copy some parameters.</font>
+02493 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_6">_SkinReduction</a>= <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.SkinReduction;
+02494
+02495 <font class="comment">// Skinning??</font>
+02496 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a>= ((mbuild.VertexFlags &amp; CVertexBuffer::PaletteSkinFlag)==CVertexBuffer::PaletteSkinFlag);
+02497 <font class="comment">// Skinning is OK only if SkinWeights are of same size as vertices.</font>
+02498 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a>= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_5">_Skinned</a> &amp;&amp; ( mbuild.Vertices.size()==mbuild.SkinWeights.size() );
+02499
+02500 <font class="comment">// MeshInterface setuped ?</font>
+02501 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_1">_HasMeshInterfaces</a>= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_0">buildMRMSewingMeshes</a>(mbuild, <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.NLods, <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.Divisor);
+02502
+02503 <font class="comment">// from mbuild, build an internal MRM mesh representation.</font>
+02504 <font class="comment">// vbFlags returned is the VBuffer format supported by CMRMBuilder.</font>
+02505 <font class="comment">// NB: skinning is removed because skinning is made in software in CMeshMRMGeom.</font>
+02506 vbFlags= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_7">buildMrmBaseMesh</a>(mbuild, baseMesh);
+02507
+02508 <font class="comment">// Construct all blend shapes in the same way we have constructed the basemesh mrm</font>
+02509 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z630_0">buildBlendShapes</a> (baseMesh, bsList, vbFlags);
+02510
+02511 <font class="comment">// If skinned, must ensure that skin weights have weights in ascending order.</font>
+02512 <font class="keywordflow">if</font>(_Skinned)
+02513 {
+02514 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_9">normalizeBaseMeshSkin</a>(baseMesh);
+02515 }
+02516
+02517 <font class="comment">// from this baseMesh, builds all LODs of the MRM, with geomorph info. NB: vertices/wedges are duplicated.</font>
+02518 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z630_1">buildAllLods</a> ( baseMesh, lodMeshs, <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.NLods, <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.Divisor );
+02519
+02520 <font class="comment">// From this array of LOD, build a finalMRM, by regrouping identical vertices/wedges, and compute index geomorphs.</font>
+02521 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z630_2">buildFinalMRM</a>(lodMeshs, finalMRM);
+02522
+02523 <font class="comment">// From this finalMRM, build output: a CMeshBuildMRM.</font>
+02524 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z631_8">buildMeshBuildMrm</a>(finalMRM, mrmMesh, vbFlags, numMaxMaterial, mbuild);
+02525
+02526 <font class="comment">// Copy degradation control params.</font>
+02527 mrmMesh.DistanceFinest= <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceFinest;
+02528 mrmMesh.DistanceMiddle= <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceMiddle;
+02529 mrmMesh.DistanceCoarsest= <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>.DistanceCoarsest;
+02530 }
+02531
+02532
+02533 <font class="comment">// ***************************************************************************</font>
+02534 <font class="comment">// ***************************************************************************</font>
+02535 <font class="comment">// MRM Interface system</font>
+02536 <font class="comment">// ***************************************************************************</font>
+02537 <font class="comment">// ***************************************************************************</font>
+02538
+02539 <font class="comment">// ***************************************************************************</font>
+<a name="l02540"></a><a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_0">02540</a> <font class="keywordtype">bool</font> CMRMBuilder::buildMRMSewingMeshes(<font class="keyword">const</font> CMesh::CMeshBuild &amp;mbuild, uint nWantedLods, uint divisor)
+02541 {
+02542 <a class="code" href="debug_8h.html#a6">nlassert</a>(nWantedLods&gt;=1);
+02543 <a class="code" href="debug_8h.html#a6">nlassert</a>(divisor&gt;=1);
+02544 <font class="keywordflow">if</font>(mbuild.Interfaces.size()==0)
+02545 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+02546 <font class="comment">// must have same size</font>
+02547 <font class="keywordflow">if</font>(mbuild.InterfaceLinks.size()!=mbuild.Vertices.size())
+02548 <font class="keywordflow">return</font> <font class="keyword">false</font>;
+02549
+02550 <font class="comment">// **** For each interface, MRM-ize it and store.</font>
+02551 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_2">_SewingMeshes</a>.resize(mbuild.Interfaces.size());
+02552 <font class="keywordflow">for</font>(uint i=0;i&lt;mbuild.Interfaces.size();i++)
+02553 {
+02554 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z628_2">_SewingMeshes</a>[i].build(mbuild.Interfaces[i], nWantedLods, divisor);
+02555 }
+02556
+02557
+02558 <font class="keywordflow">return</font> <font class="keyword">true</font>;
+02559 }
+02560
+02561
+02562 } <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>