diff options
Diffstat (limited to '')
-rw-r--r-- | docs/doxygen/nel/mrm__builder_8cpp-source.html | 2630 |
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> <A CLASS=uplinks HREF=http://www.nevrax.org><b>Home</B></FONT></A> </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> <A CLASS=uplinks HREF=http://www.nevrax.com><b>nevrax.com</B></FONT></A> </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> + + +<!-- 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> </td> +</tr></table> +<!-- Generated by Doxygen 1.2.14 --> +<center> +<a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="hierarchy.html">Class Hierarchy</a> <a class="qindex" href="classes.html">Alphabetical List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="namespacemembers.html">Namespace Members</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="globals.html">File Members</a> <a class="qindex" href="pages.html">Related Pages</a> <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> </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<sint> &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<sint> &array, sint elt) +00052 { +00053 <font class="keywordtype">bool</font> found=<font class="keyword">false</font>; +00054 vector<sint>::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<> 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 &vert= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[numvertex]; +00077 <font class="keywordflow">for</font>(sint attId=0;attId<<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<(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>=0 && 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 &vert= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[numvertex]; +00094 <font class="keywordflow">for</font>(sint i=0;i<(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>=0 && 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) && <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 &vert= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[numvertex]; +00111 map<CMRMEdge, sint> EdgeShare; +00112 <font class="comment">// Init to 0.</font> +00113 sint i; +00114 <font class="keywordflow">for</font>(i=0;i<(sint)vert.SharedFaces.size();i++) +00115 { +00116 CMRMFaceBuild &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<(sint)vert.SharedFaces.size();i++) +00123 { +00124 CMRMFaceBuild &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<(sint)vert.SharedFaces.size();i++) +00131 { +00132 CMRMFaceBuild &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)]<2 && (v0==numvertex || v1==numvertex)) <font class="keywordflow">return</font> <font class="keyword">false</font>; +00137 <font class="keywordflow">if</font>(EdgeShare[f.getEdge(1)]<2 && (v1==numvertex || v2==numvertex)) <font class="keywordflow">return</font> <font class="keyword">false</font>; +00138 <font class="keywordflow">if</font>(EdgeShare[f.getEdge(2)]<2 && (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 &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<nfaces;i++) +00151 { +00152 CVector normal; +00153 CVector &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 &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 &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<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 &edge) +00170 { +00171 sint v0= edge.v0; +00172 sint v1= edge.v1; +00173 CMRMVertex &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<sint> deletedFaces; +00177 sint i; +00178 <font class="keywordflow">for</font>(i=0;i<(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<(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>=0 && 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<<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<(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>=0 && 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>=0 && 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 &edge) +00215 { +00216 sint v0= edge.v0; +00217 sint v1= edge.v1; +00218 CMRMVertex &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<sint> deletedFaces; +00222 sint i; +00223 <font class="keywordflow">for</font>(i=0;i<(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<(sint)deletedFaces.size();i++) +00232 { +00233 CMRMFaceBuild &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)) && +00235 !<a class="code" href="classNL3D_1_1CMRMBuilder.html#z625_5">edgeContinue</a>(f.getEdge(1)) && +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 &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) && !<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>=0 && 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 &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>=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->getAssociatedWedge(attribId, numVertex1); +00321 sint numWedge2= face->getAssociatedWedge(attribId, numVertex2); +00322 <font class="keywordflow">if</font>(numWedge1<0) <font class="keywordflow">return</font> <font class="keyword">false</font>; +00323 <font class="keywordflow">if</font>(numWedge2<0) <font class="keywordflow">return</font> <font class="keyword">false</font>; +00324 +00325 CMRMAttribute &w1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attribId][numWedge1]; +00326 CMRMAttribute &w2= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attribId][numWedge2]; +00327 <font class="keywordflow">return</font> w1.Shared && w2.Shared && w1.NbSharedFaces>0 && w2.NbSharedFaces>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 &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),&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),&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),&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 &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 &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<</a>(<font class="keyword">const</font> CTmpVertexWeight &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>>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 &sw1, <font class="keyword">const</font> CMesh::CSkinWeight &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<CTmpVertexWeight> 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<<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>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]>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<<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>0) +00426 { +00427 <font class="comment">// add it or add influence to the matrix.</font> +00428 vector<CTmpVertexWeight>::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->Weight+= vw.Weight; +00433 } +00434 <font class="comment">// For skinning reduction.</font> +00435 <font class="keywordflow">if</font>(sw2.Weights[i]>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<=<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<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<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 &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 &Vertex1=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[edgeV1], &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> && (Vertex1.InterfaceLink.InterfaceId>=0 || Vertex2.InterfaceLink.InterfaceId>=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 &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>=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>=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 && vc2) InterValue=0; +00560 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(vc1 && !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 && vc2) InterValue=0; +00568 <font class="keywordflow">if</font>(vc1 && !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 < (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<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<(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<(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<sint> neighboorFaces; +00604 <font class="keywordflow">for</font>(i=0;i<(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<(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<sint> deletedFaces; +00619 <font class="keywordflow">for</font>(i=0;i<(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<<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<(sint)deletedFaces.size();i++) +00637 { +00638 CMRMFaceBuild &face= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>[deletedFaces[i]]; +00639 +00640 CVectorH &w0= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][ face.getAssociatedWedge(attId, edgeV1) ].Current; +00641 CVectorH &w1= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][ face.getAssociatedWedge(attId, edgeV2) ].Current; +00642 +00643 CVectorH &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 < (sint)face.BSInterpolated.size(); ++j) +00650 { +00651 CVectorH &w0 = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][face.getAssociatedWedge(attId, edgeV1)].BSCurrent[j]; +00652 CVectorH &w1 = <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId][face.getAssociatedWedge(attId, edgeV2)].BSCurrent[j]; +00653 CVectorH &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<sint> wedges; +00665 +00666 <font class="keywordflow">for</font>(i=0;i<(sint)neighboorFaces.size();i++) +00667 { +00668 CMRMFaceBuild &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>=0 && !<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>=0 && !<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<(sint)wedges.size();i++) +00685 { +00686 sint numWedge= wedges[i]; +00687 CMRMAttribute &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<(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<(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<(sint)wedges.size();i++) +00717 { +00718 sint numWedge= wedges[i]; +00719 CMRMAttribute &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 => 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 &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) && +00746 <a class="code" href="classNL3D_1_1CMRMBuilder.html#z626_0">faceShareWedges</a>(&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<(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<(sint)neighboorFaces.size();i++) +00779 { +00780 CMRMFaceBuild &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<<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>=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>=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>=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 &vert=<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[i]; +00820 <font class="keywordflow">if</font>(vert.CollapsedTo>=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 &wedge= <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attribId][i]; +00829 <font class="keywordflow">if</font>(wedge.CollapsedTo>=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 &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<<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<<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<(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 <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<<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_2">NumAttributes</a>;attId++) +00890 { +00891 <font class="keywordflow">for</font>(i=0;i<(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 <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<(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<(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.size();i++) +00909 { +00910 CMRMFaceBuild &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<(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.size();i++) +00920 { +00921 CMRMFaceBuild &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>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>=0 +00951 || <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>[ edge.v1 ].CollapsedTo>=0) +00952 { +00953 <font class="comment">// \todo yoyo: TODO_BUG: potential bug here...</font> +00954 CMRMFaceBuild &f= *(EdgeIt->second.Face); +00955 <a class="code" href="debug_8h.html#a6">nlassert</a>(f.validEdgeIt(EdgeIt->second)); +00956 f.invalidEdgeIt(EdgeIt->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 &f= *(EdgeIt->second.Face); +00966 <a class="code" href="debug_8h.html#a6">nlassert</a>(f.validEdgeIt(EdgeIt->second)); +00967 f.invalidEdgeIt(EdgeIt->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 &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<(sint)vert.SharedFaces.size();i++) +00986 { +00987 CMRMFaceBuild &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 &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<<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<(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>.size();i++) +01013 { +01014 CMRMVertex &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<<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<(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId].size();i++) +01037 { +01038 CMRMAttribute &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<(sint)<a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_3">TmpFaces</a>.size();i++) +01063 { +01064 CMRMFaceBuild &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<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>=0); +01075 <font class="comment">// Attributes.</font> +01076 <font class="keywordflow">for</font>(attId=0;attId<<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]>=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 &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<(sint)lodMesh.CoarserFaces.size();i++) +01099 { +01100 CMRMFace &face= lodMesh.CoarserFaces[i]; +01101 +01102 <font class="comment">// For 3 corners.</font> +01103 <font class="keywordflow">for</font>(j=0;j<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>=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<<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>=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<CMRMMesh> &srcBsMeshs, vector<CMRMMesh> &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 < (sint)srcBsMeshs.size(); ++k)</font> +01149 <font class="comment"> {</font> +01150 <font class="comment"> CMRMMesh &rBsMesh = srcBsMeshs[k];</font> +01151 <font class="comment"> CMRMMesh &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 < (sint)rBsMesh.Vertices.size(); ++i)</font> +01156 <font class="comment"> {</font> +01157 <font class="comment"> CLinearEquation &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 < (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 < 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 < (sint)rBsMesh.Attributes[attId].size(); ++i)</font> +01171 <font class="comment"> {</font> +01172 <font class="comment"> CLinearEquation &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 < (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<CMRMBlendShape> &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 < <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 > 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 < csBsMeshs.size(); ++k) +01201 { +01202 CMRMBlendShape &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 < <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_0">TmpVertices</a>.size(); ++i) +01209 { +01210 CMRMVertex &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 < <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 < <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 > 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 < <a class="code" href="classNL3D_1_1CMRMBuilder.html#z624_1">TmpAttributes</a>[attId].size(); i++) +01229 { +01230 CMRMAttribute &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 &baseMesh, CMRMMeshGeom &lodMesh, CMRMMesh &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 &baseMesh, std::vector<CMRMMeshGeom> &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>=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>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<CMRMMeshGeom> &lodMeshs, CMRMMeshFinal &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<nLods; lodId++) +01341 { +01342 CMRMMeshGeom &lodMesh= lodMeshs[lodId]; +01343 CMRMMeshGeom &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<(sint)lodMesh.Faces.size();i++) +01346 { +01347 <font class="comment">// The current face.</font> +01348 CMRMFace &face= lodMesh.Faces[i]; +01349 <font class="comment">// the current face, but which points to the prec LOD vertices/attributes.</font> +01350 CMRMFace &faceCoarser= lodMesh.CoarserFaces[i]; +01351 <font class="comment">// for 3 corners.</font> +01352 <font class="keywordflow">for</font>(j=0;j<3;j++) +01353 { +01354 CMRMCorner &corner= face.Corner[j]; +01355 CMRMCorner &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<<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>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<<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<nLods; lodId++) +01411 { +01412 CMRMMeshGeom &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<(sint)lodMesh.Faces.size();i++) +01420 { +01421 <font class="comment">// The current face.</font> +01422 CMRMFace &face= lodMesh.Faces[i]; +01423 <font class="comment">// for 3 corners.</font> +01424 <font class="keywordflow">for</font>(j=0;j<3;j++) +01425 { +01426 CMRMCorner &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->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<nLods; lodId++) +01468 { +01469 CMRMMeshGeom &lodMesh= lodMeshs[lodId]; +01470 +01471 <font class="comment">// for all face corner.</font> +01472 <font class="keywordflow">for</font>(i=0; i<(sint)lodMesh.Faces.size();i++) +01473 { +01474 <font class="comment">// The current face.</font> +01475 CMRMFace &face= lodMesh.Faces[i]; +01476 <font class="comment">// for 3 corners.</font> +01477 <font class="keywordflow">for</font>(j=0;j<3;j++) +01478 { +01479 CMRMCorner &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<nLods; lodId++) +01496 { +01497 CMRMMeshGeom &lodMesh= lodMeshs[lodId]; +01498 CMRMMeshFinal::CLod &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<(sint)lodMesh.Faces.size();i++) +01508 { +01509 <font class="comment">// The current face.</font> +01510 CMRMFace &face= lodMesh.Faces[i]; +01511 <font class="comment">// The dest face.</font> +01512 CMRMMeshFinal::CFace &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<3;j++) +01518 { +01519 CMRMCorner &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<(sint)finalMRM.Wedges.size();i++) +01558 { +01559 CMRMMeshFinal::CWedge &wedge= finalMRM.Wedges[i]; +01560 <font class="keywordflow">for</font>(j=0; j<<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>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 < nLods; ++lodId) +01573 { +01574 CMRMMeshGeom &lodMesh= lodMeshs[lodId]; +01575 CMRMMeshGeom &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 < (sint)lodMesh.Faces.size(); ++i) +01579 { +01580 <font class="comment">// The current face.</font> +01581 CMRMFace &face = lodMesh.Faces[i]; +01582 <font class="comment">// the current face, but which points to the prec LOD vertices/attributes.</font> +01583 CMRMFace &faceCoarser = lodMesh.CoarserFaces[i]; +01584 <font class="comment">// for 3 corners.</font> +01585 <font class="keywordflow">for</font> (j = 0; j < 3; ++j) +01586 { +01587 CMRMCorner &corner = face.Corner[j]; +01588 CMRMCorner &cornerCoarser = faceCoarser.Corner[j]; +01589 +01590 sint startDestIndex = corner.WedgeStartId; +01591 +01592 <font class="keywordflow">for</font> (sint k = 0; k < (sint)finalMRM.MRMBlendShapesFinals.size(); ++k) +01593 { +01594 CMRMMeshFinal::CMRMBlendShapeFinal &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 < <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>0 && 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 < <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 &baseMesh, sint attId, sint vertexId, <font class="keyword">const</font> CVectorH &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->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 &baseMesh, sint attId, sint vertexId, <font class="keyword">const</font> CVector &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 &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 &baseMesh, sint attId, sint vertexId, <font class="keyword">const</font> <a class="code" href="classNLMISC_1_1CUVW.html">NLMISC::CUVW</a> &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 &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 &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 &mbuild, CMRMMesh &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<<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 & CVertexBuffer::NormalFlag) +01739 { +01740 baseMesh.NumAttributes++; +01741 retVbFlags|= CVertexBuffer::NormalFlag; +01742 } +01743 <font class="keywordflow">if</font>(mbuild.VertexFlags & CVertexBuffer::PrimaryColorFlag) +01744 { +01745 baseMesh.NumAttributes++; +01746 retVbFlags|= CVertexBuffer::PrimaryColorFlag; +01747 } +01748 <font class="keywordflow">if</font>(mbuild.VertexFlags & CVertexBuffer::SecondaryColorFlag) +01749 { +01750 baseMesh.NumAttributes++; +01751 retVbFlags|= CVertexBuffer::SecondaryColorFlag; +01752 } +01753 <font class="keywordflow">for</font>(k=0; k<CVertexBuffer::MaxStage;k++) +01754 { +01755 uint flag=CVertexBuffer::TexCoord0Flag<<k; +01756 <font class="keywordflow">if</font>(mbuild.VertexFlags & flag) +01757 { +01758 baseMesh.NumAttributes++; +01759 retVbFlags|=flag; +01760 } +01761 } +01762 <a class="code" href="debug_8h.html#a6">nlassert</a>(baseMesh.NumAttributes<=<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<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<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<nFaces; i++) +01793 { +01794 <font class="keywordflow">for</font>(j=0; j<3; j++) +01795 { +01796 <font class="keyword">const</font> CMesh::CCorner &srcCorner= mbuild.Faces[i].Corner[j]; +01797 CMRMCorner &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 & 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 & 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 & 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<CVertexBuffer::MaxStage;k++) +01819 { +01820 <font class="keywordflow">if</font>(mbuild.VertexFlags & (CVertexBuffer::TexCoord0Flag<<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<<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 &sw)<font class="keyword"> const</font> +01844 <font class="keyword"></font>{ +01845 uint nbMats= 0; +01846 <font class="keyword">static</font> vector<CTmpVertexWeight> 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<<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>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<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<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 &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<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 &finalMRM, CMeshMRMGeom::CMeshBuildMRM &mbuild, uint32 vbFlags, uint32 nbMats, <font class="keyword">const</font> CMesh::CMeshBuild &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 < CVertexBuffer::MaxStage; ++k) +01915 { +01916 <font class="keywordflow">if</font> ( +01917 (vbFlags & (CVertexBuffer::TexCoord0Flag << k)) +01918 && 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 < CVertexBuffer::MaxStage; ++k) +01929 { +01930 <font class="keywordflow">if</font> (vbFlags & (CVertexBuffer::TexCoord0Flag << 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 & CVertexBuffer::PositionFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3); +01945 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::NormalFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Normal, CVertexBuffer::Float3); +01946 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::PrimaryColorFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::PrimaryColor, CVertexBuffer::UChar4); +01947 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::SecondaryColorFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::SecondaryColor, CVertexBuffer::UChar4); +01948 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::WeightFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Weight, CVertexBuffer::Float4); +01949 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::PaletteSkinFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::PaletteSkin, CVertexBuffer::UChar4); +01950 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::FogFlag) mbuild.VBuffer.addValueEx(CVertexBuffer::Fog, CVertexBuffer::Float1); +01951 +01952 <font class="keywordflow">for</font> (k = 0; k < CVertexBuffer::MaxStage; ++k) +01953 { +01954 <font class="keywordflow">if</font> (vbFlags & (CVertexBuffer::TexCoord0Flag << 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<(sint)finalMRM.Wedges.size(); i++) +01986 { +01987 <font class="keyword">const</font> CMRMMeshFinal::CWedge &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 & CVertexBuffer::NormalFlag) +01997 { +01998 mbuild.VBuffer.setNormalCoord(i, wedge.Attributes[attId] ); +01999 attId++; +02000 } +02001 <font class="keywordflow">if</font>(vbFlags & 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 & 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<CVertexBuffer::MaxStage;k++) +02012 { +02013 <font class="keywordflow">if</font>(vbFlags & (CVertexBuffer::TexCoord0Flag<<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<(sint)finalMRM.Lods.size(); i++) +02048 { +02049 <font class="keyword">const</font> CMRMMeshFinal::CLod &srcLod= finalMRM.Lods[i]; +02050 CMeshMRMGeom::CLod &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<sint> 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<(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>=0); +02074 <a class="code" href="debug_8h.html#a6">nlassert</a>(matId<(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<sint> rdrPassIndex; <font class="comment">// material to rdrPass map.</font> +02081 rdrPassIndex.resize(nbMats); +02082 <font class="keywordflow">for</font>(j=0; j<(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<(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<<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<uint> 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<(sint)srcLod.Faces.size(); j++) +02127 { +02128 <font class="keywordflow">for</font>(k=0; k<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<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<<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 -> MatrixInfId.</font> +02168 map<uint, uint> 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<<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<(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 &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<<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<iSkinMat+1) +02187 { +02188 <a class="code" href="debug_8h.html#a6">nlassert</a>( matWeight>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>0) +02196 { +02197 uint matId= wedge.VertexSkin.MatrixId[k]; +02198 +02199 <font class="comment">// search/insert the matrixInfId.</font> +02200 map<uint, uint>::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->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 < (sint)mbuild.BlendShapes.size(); ++k) +02228 { +02229 CBlendShape &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 < nNbVertVB; i++) +02248 { +02249 <font class="keyword">const</font> CMRMMeshFinal::CWedge &rWedgeRef = finalMRM.Wedges[i]; +02250 <font class="keyword">const</font> CMRMMeshFinal::CWedge &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() > 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 & 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() > 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 & 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) > 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 & 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 & 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) > 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() > 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 < 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& baseMesh, +02397 std::vector<CMesh::CMeshBuild*> &bsList, uint32 VertexFlags) +02398 { +02399 uint32 i, j, k, m, destIndex; +02400 uint32 attId; +02401 CVectorH vh; +02402 vector<CMRMBlendShape> &bsMeshes= baseMesh.BlendShapes; +02403 +02404 bsMeshes.resize (bsList.size()); +02405 +02406 <font class="keywordflow">for</font> (i = 0; i < 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]->Vertices.size()); +02410 bsMeshes[i].Vertices.resize (baseMesh.Vertices.size()); +02411 bsMeshes[i].Vertices = bsList[i]->Vertices; +02412 +02413 bsMeshes[i].NumAttributes = baseMesh.NumAttributes; +02414 <font class="keywordflow">for</font> (j = 0; j < (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 < baseMesh.Faces.size(); ++j) +02419 <font class="keywordflow">for</font> (k = 0; k < 3; ++k) +02420 { +02421 <font class="keyword">const</font> CMesh::CCorner &srcCorner = bsList[i]->Faces[j].Corner[k]; +02422 CMRMCorner &neutralCorner = baseMesh.Faces[j].Corner[k]; +02423 +02424 attId= 0; +02425 +02426 <font class="keywordflow">if</font> (VertexFlags & 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 & 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 & 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 < CVertexBuffer::MaxStage; ++m) +02457 { +02458 <font class="keywordflow">if</font> (VertexFlags & (CVertexBuffer::TexCoord0Flag<<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 &mbuild, std::vector<CMesh::CMeshBuild*> &bsList, +02476 <font class="keyword">const</font> CMRMParameters &<a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>, CMeshMRMGeom::CMeshBuildMRM &mrmMesh, +02477 uint numMaxMaterial) +02478 { +02479 <font class="comment">// Temp data.</font> +02480 CMRMMesh baseMesh; +02481 vector<CMRMMeshGeom> lodMeshs; +02482 CMRMMeshFinal finalMRM; +02483 vector<CMRMMeshFinal> 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>=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 > <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 > <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 & 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> && ( 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 &mbuild, uint nWantedLods, uint divisor) +02541 { +02542 <a class="code" href="debug_8h.html#a6">nlassert</a>(nWantedLods>=1); +02543 <a class="code" href="debug_8h.html#a6">nlassert</a>(divisor>=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<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> </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> |