diff options
author | neodarz <neodarz@neodarz.net> | 2018-08-11 20:21:34 +0200 |
---|---|---|
committer | neodarz <neodarz@neodarz.net> | 2018-08-11 20:21:34 +0200 |
commit | 0ea5fc66924303d1bf73ba283a383e2aadee02f2 (patch) | |
tree | 2568e71a7ccc44ec23b8bb3f0ff97fb6bf2ed709 /docs/doxygen/nel/mesh__mrm_8cpp-source.html | |
download | nevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.tar.xz nevrax-website-self-hostable-0ea5fc66924303d1bf73ba283a383e2aadee02f2.zip |
Initial commit
Diffstat (limited to '')
-rw-r--r-- | docs/doxygen/nel/mesh__mrm_8cpp-source.html | 2867 |
1 files changed, 2867 insertions, 0 deletions
diff --git a/docs/doxygen/nel/mesh__mrm_8cpp-source.html b/docs/doxygen/nel/mesh__mrm_8cpp-source.html new file mode 100644 index 00000000..ce6580d5 --- /dev/null +++ b/docs/doxygen/nel/mesh__mrm_8cpp-source.html @@ -0,0 +1,2867 @@ +<!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>mesh_mrm.cpp</h1><a href="mesh__mrm_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 +00007 <font class="comment">/* Copyright, 2001 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="bsphere_8h.html">nel/misc/bsphere.h</a>"</font> +00029 <font class="preprocessor">#include "<a class="code" href="system__info_8h.html">nel/misc/system_info.h</a>"</font> +00030 <font class="preprocessor">#include "<a class="code" href="hierarchical__timer_8h.html">nel/misc/hierarchical_timer.h</a>"</font> +00031 <font class="preprocessor">#include "<a class="code" href="fast__mem_8h.html">nel/misc/fast_mem.h</a>"</font> +00032 <font class="preprocessor">#include "<a class="code" href="mesh__mrm_8h.html">3d/mesh_mrm.h</a>"</font> +00033 <font class="preprocessor">#include "<a class="code" href="mrm__builder_8h.html">3d/mrm_builder.h</a>"</font> +00034 <font class="preprocessor">#include "<a class="code" href="mrm__parameters_8h.html">3d/mrm_parameters.h</a>"</font> +00035 <font class="preprocessor">#include "<a class="code" href="mesh__mrm__instance_8h.html">3d/mesh_mrm_instance.h</a>"</font> +00036 <font class="preprocessor">#include "<a class="code" href="scene_8h.html">3d/scene.h</a>"</font> +00037 <font class="preprocessor">#include "<a class="code" href="skeleton__model_8h.html">3d/skeleton_model.h</a>"</font> +00038 <font class="preprocessor">#include "<a class="code" href="stripifier_8h.html">3d/stripifier.h</a>"</font> +00039 <font class="preprocessor">#include "<a class="code" href="mesh__blender_8h.html">3d/mesh_blender.h</a>"</font> +00040 <font class="preprocessor">#include "<a class="code" href="render__trav_8h.html">3d/render_trav.h</a>"</font> +00041 <font class="preprocessor">#include "<a class="code" href="fast__floor_8h.html">3d/fast_floor.h</a>"</font> +00042 <font class="preprocessor">#include "<a class="code" href="raw__skin_8h.html">3d/raw_skin.h</a>"</font> +00043 <font class="preprocessor">#include "<a class="code" href="shifted__triangle__cache_8h.html">3d/shifted_triangle_cache.h</a>"</font> +00044 +00045 +00046 <font class="keyword">using</font> <font class="keyword">namespace </font>NLMISC; +00047 <font class="keyword">using</font> <font class="keyword">namespace </font>std; +00048 +00049 +00050 <font class="keyword">namespace </font>NL3D +00051 { +00052 +00053 +00054 <a class="code" href="hierarchical__timer_8h.html#a6">H_AUTO_DECL</a>( NL3D_MeshMRMGeom_RenderSkinned ) +00055 +00056 +00057 <font class="comment">// ***************************************************************************</font> +00058 <font class="comment">// ***************************************************************************</font> +00059 <font class="comment">// CMeshMRMGeom::CLod</font> +00060 <font class="comment">// ***************************************************************************</font> +00061 <font class="comment">// ***************************************************************************</font> +00062 +00063 +00064 <font class="comment">// ***************************************************************************</font> +<a name="l00065"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#a1">00065</a> <font class="keywordtype">void</font> CMeshMRMGeom::CLod::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) +00066 { +00067 <font class="comment">/*</font> +00068 <font class="comment"> Version 2:</font> +00069 <font class="comment"> - precompute of triangle order. (nothing more to load).</font> +00070 <font class="comment"> Version 1:</font> +00071 <font class="comment"> - add VertexBlocks;</font> +00072 <font class="comment"> Version 0:</font> +00073 <font class="comment"> - base vdrsion.</font> +00074 <font class="comment"> */</font> +00075 +00076 sint ver= f.<a class="code" href="classNLMISC_1_1IStream.html#a29">serialVersion</a>(2); +00077 uint i; +00078 +00079 f.<a class="code" href="classNLMISC_1_1IStream.html#a5">serial</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m0">NWedges</a>); +00080 f.<a class="code" href="classNLMISC_1_1IStream.html#a7">serialCont</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m2">RdrPass</a>); +00081 f.<a class="code" href="classNLMISC_1_1IStream.html#a7">serialCont</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m1">Geomorphs</a>); +00082 f.<a class="code" href="classNLMISC_1_1IStream.html#a7">serialCont</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m4">MatrixInfluences</a>); +00083 +00084 <font class="comment">// Serial array of InfluencedVertices. NB: code written so far for NL3D_MESH_SKINNING_MAX_MATRIX==4 only.</font> +00085 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>==4); +00086 <font class="keywordflow">for</font>(i= 0; i<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; i++) +00087 { +00088 f.<a class="code" href="classNLMISC_1_1IStream.html#a7">serialCont</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m3">InfluencedVertices</a>[i]); +00089 } +00090 +00091 <font class="keywordflow">if</font>(ver>=1) +00092 f.<a class="code" href="classNLMISC_1_1IStream.html#a7">serialCont</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m6">SkinVertexBlocks</a>); +00093 <font class="keywordflow">else</font> +00094 <a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#a2">buildSkinVertexBlocks</a>(); +00095 +00096 <font class="comment">// if >= version 2, reorder of triangles is precomputed, else compute it now.</font> +00097 <font class="keywordflow">if</font>(ver<2) +00098 <a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#a3">optimizeTriangleOrder</a>(); +00099 +00100 } +00101 +00102 +00103 <font class="comment">// ***************************************************************************</font> +<a name="l00104"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#a2">00104</a> <font class="keywordtype">void</font> CMeshMRMGeom::CLod::buildSkinVertexBlocks() +00105 { +00106 <a class="code" href="namespaceNLMISC.html#a222">contReset</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m6">SkinVertexBlocks</a>); +00107 +00108 +00109 <font class="comment">// The list of vertices. true if used by this lod.</font> +00110 vector<bool> vertexMap; +00111 vertexMap.resize(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m0">NWedges</a>, <font class="keyword">false</font>); +00112 +00113 +00114 <font class="comment">// from InfluencedVertices, aknoledge what vertices are used.</font> +00115 uint i; +00116 <font class="keywordflow">for</font>(i=0;i<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;i++) +00117 { +00118 uint nInf= <a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m3">InfluencedVertices</a>[i].size(); +00119 <font class="keywordflow">if</font>( nInf==0 ) +00120 <font class="keywordflow">continue</font>; +00121 uint32 *infPtr= &(<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m3">InfluencedVertices</a>[i][0]); +00122 +00123 <font class="comment">// for all InfluencedVertices only.</font> +00124 <font class="keywordflow">for</font>(;nInf>0;nInf--, infPtr++) +00125 { +00126 uint <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>= *infPtr; +00127 vertexMap[<a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>]= <font class="keyword">true</font>; +00128 } +00129 } +00130 +00131 <font class="comment">// For all vertices, test if they are used, and build the according SkinVertexBlocks;</font> +00132 CVertexBlock *vBlock= NULL; +00133 <font class="keywordflow">for</font>(i=0; i<vertexMap.size();i++) +00134 { +00135 <font class="keywordflow">if</font>(vertexMap[i]) +00136 { +00137 <font class="comment">// preceding block?</font> +00138 <font class="keywordflow">if</font>(vBlock) +00139 { +00140 <font class="comment">// yes, extend it.</font> +00141 vBlock->NVertices++; +00142 } +00143 <font class="keywordflow">else</font> +00144 { +00145 <font class="comment">// no, append a new one.</font> +00146 <a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m6">SkinVertexBlocks</a>.push_back(CVertexBlock()); +00147 vBlock= &<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m6">SkinVertexBlocks</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m6">SkinVertexBlocks</a>.size()-1]; +00148 vBlock->VertexStart= i; +00149 vBlock->NVertices= 1; +00150 } +00151 } +00152 <font class="keywordflow">else</font> +00153 { +00154 <font class="comment">// Finish the preceding block (if any).</font> +00155 vBlock= NULL; +00156 } +00157 } +00158 +00159 } +00160 +00161 +00162 <font class="comment">// ***************************************************************************</font> +<a name="l00163"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#a3">00163</a> <font class="keywordtype">void</font> CMeshMRMGeom::CLod::optimizeTriangleOrder() +00164 { +00165 CStripifier stripifier; +00166 +00167 <font class="comment">// for all rdrpass</font> +00168 <font class="keywordflow">for</font>(uint rp=0; rp<<a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m2">RdrPass</a>.size(); rp++ ) +00169 { +00170 <font class="comment">// stripify list of triangles of this pass.</font> +00171 CRdrPass &pass= <a class="code" href="classNL3D_1_1CMeshMRMGeom_1_1CLod.html#m2">RdrPass</a>[rp]; +00172 stripifier.optimizeTriangles(pass.PBlock, pass.PBlock); +00173 } +00174 +00175 } +00176 +00177 +00178 <font class="comment">// ***************************************************************************</font> +00179 <font class="comment">// ***************************************************************************</font> +00180 <font class="comment">// CMeshMRMGeom.</font> +00181 <font class="comment">// ***************************************************************************</font> +00182 <font class="comment">// ***************************************************************************</font> +00183 +00184 +00185 +00186 +00187 <font class="comment">// ***************************************************************************</font> +00188 <font class="keyword">static</font> <a class="code" href="classNLMISC_1_1CAABBoxExt.html">NLMISC::CAABBoxExt</a> <a class="code" href="namespaceNL3D.html#a376">makeBBox</a>(<font class="keyword">const</font> std::vector<CVector> &Vertices) +00189 { +00190 <a class="code" href="classNLMISC_1_1CAABBox.html">NLMISC::CAABBox</a> ret; +00191 <a class="code" href="debug_8h.html#a6">nlassert</a>(Vertices.size()); +00192 ret.<a class="code" href="classNLMISC_1_1CAABBox.html#z263_0">setCenter</a>(Vertices[0]); +00193 <font class="keywordflow">for</font>(sint i=0;i<(sint)Vertices.size();i++) +00194 { +00195 ret.<a class="code" href="classNLMISC_1_1CAABBox.html#z263_4">extend</a>(Vertices[i]); +00196 } +00197 +00198 <font class="keywordflow">return</font> ret; +00199 } +00200 +00201 +00202 <font class="comment">// ***************************************************************************</font> +<a name="l00203"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#a0">00203</a> CMeshMRMGeom::CMeshMRMGeom() +00204 { +00205 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_5">_VertexBufferHardDirty</a>= <font class="keyword">true</font>; +00206 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a>= <font class="keyword">false</font>; +00207 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>= 0; +00208 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o7">_BoneIdComputed</a> = <font class="keyword">false</font>; +00209 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o8">_BoneIdExtended</a> = <font class="keyword">false</font>; +00210 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_6">_PreciseClipping</a>= <font class="keyword">false</font>; +00211 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o9">_SupportSkinGrouping</a>= <font class="keyword">false</font>; +00212 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_13">_MeshDataId</a>= 0; +00213 } +00214 +00215 +00216 <font class="comment">// ***************************************************************************</font> +<a name="l00217"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#a1">00217</a> CMeshMRMGeom::~CMeshMRMGeom() +00218 { +00219 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_1">deleteVertexBufferHard</a>(); +00220 } +00221 +00222 +00223 <font class="comment">// ***************************************************************************</font> +<a name="l00224"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#a4">00224</a> <font class="keywordtype">void</font> CMeshMRMGeom::changeMRMDistanceSetup(<font class="keywordtype">float</font> distanceFinest, <font class="keywordtype">float</font> distanceMiddle, <font class="keywordtype">float</font> distanceCoarsest) +00225 { +00226 <font class="comment">// check input.</font> +00227 <font class="keywordflow">if</font>(distanceFinest<0) <font class="keywordflow">return</font>; +00228 <font class="keywordflow">if</font>(distanceMiddle<=distanceFinest) <font class="keywordflow">return</font>; +00229 <font class="keywordflow">if</font>(distanceCoarsest<=distanceMiddle) <font class="keywordflow">return</font>; +00230 +00231 <font class="comment">// Change.</font> +00232 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceFinest= distanceFinest; +00233 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceMiddle= distanceMiddle; +00234 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceCoarsest= distanceCoarsest; +00235 +00236 <font class="comment">// compile </font> +00237 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.compileDistanceSetup(); +00238 } +00239 +00240 +00241 <font class="comment">// ***************************************************************************</font> +<a name="l00242"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#a2">00242</a> <font class="keywordtype">void</font> CMeshMRMGeom::build(CMesh::CMeshBuild &m, std::vector<CMesh::CMeshBuild*> &bsList, +00243 uint numMaxMaterial, <font class="keyword">const</font> CMRMParameters &<a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>) +00244 { +00245 +00246 <font class="comment">// Dirt the VBuffer.</font> +00247 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_5">_VertexBufferHardDirty</a>= <font class="keyword">true</font>; +00248 +00249 <font class="comment">// Empty geometry?</font> +00250 <font class="keywordflow">if</font>(m.Vertices.size()==0 || m.Faces.size()==0) +00251 { +00252 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.setNumVertices(0); +00253 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.reserve(0); +00254 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.clear(); +00255 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o15">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z267_0">setCenter</a>(CVector::Null); +00256 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o15">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z267_2">setSize</a>(CVector::Null); +00257 <font class="keywordflow">return</font>; +00258 } +00259 <a class="code" href="debug_8h.html#a6">nlassert</a>(numMaxMaterial>0); +00260 +00261 +00262 <font class="comment">// SmartPtr Copy VertexProgram effect.</font> +00263 <font class="comment">//================================================ </font> +00264 this-><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>= m.MeshVertexProgram; +00265 +00266 +00268 <font class="comment">//======================</font> +00269 <font class="comment">// NB: this is equivalent as building BBox from MRM VBuffer, because CMRMBuilder create new vertices </font> +00270 <font class="comment">// which are just interpolation of original vertices.</font> +00271 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o15">_BBox</a>= <a class="code" href="namespaceNL3D.html#a376">makeBBox</a>(m.Vertices); +00272 +00273 +00275 <font class="comment">//================================================</font> +00276 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#l0">CMRMBuilder</a> mrmBuilder; +00277 CMeshBuildMRM meshBuildMRM; +00278 +00279 mrmBuilder.compileMRM(m, bsList, <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>, meshBuildMRM, numMaxMaterial); +00280 +00281 <font class="comment">// Then just copy result!</font> +00282 <font class="comment">//================================================</font> +00283 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>= meshBuildMRM.VBuffer; +00284 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>= meshBuildMRM.Lods; +00285 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a>= meshBuildMRM.Skinned; +00286 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>= meshBuildMRM.SkinWeights; +00287 +00288 <font class="comment">// Compute degradation control.</font> +00289 <font class="comment">//================================================</font> +00290 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceFinest= meshBuildMRM.DistanceFinest; +00291 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceMiddle= meshBuildMRM.DistanceMiddle; +00292 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceCoarsest= meshBuildMRM.DistanceCoarsest; +00293 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceFinest>=0); +00294 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceMiddle > <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceFinest); +00295 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceCoarsest > <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.DistanceMiddle); +00296 <font class="comment">// Compute OODistDelta and DistancePow</font> +00297 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.compileDistanceSetup(); +00298 +00299 +00300 <font class="comment">// Build the _LodInfos.</font> +00301 <font class="comment">//================================================</font> +00302 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>.resize(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size()); +00303 uint32 precNWedges= 0; +00304 uint i; +00305 <font class="keywordflow">for</font>(i=0;i<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size();i++) +00306 { +00307 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>[i].StartAddWedge= precNWedges; +00308 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>[i].EndAddWedges= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[i].NWedges; +00309 precNWedges= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[i].NWedges; +00310 <font class="comment">// LodOffset is filled in serial() when stream is input.</font> +00311 } +00312 <font class="comment">// After build, all lods are present in memory. </font> +00313 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size(); +00314 +00315 +00316 <font class="comment">// For load balancing.</font> +00317 <font class="comment">//================================================</font> +00318 <font class="comment">// compute Max Face Used</font> +00319 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.MaxFaceUsed= 0; +00320 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.MinFaceUsed= 0; +00321 <font class="comment">// Count of primitive block</font> +00322 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size()>0) +00323 { +00324 uint pb; +00325 <font class="comment">// Compute MinFaces.</font> +00326 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &firstLod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[0]; +00327 <font class="keywordflow">for</font> (pb=0; pb<firstLod.RdrPass.size(); pb++) +00328 { +00329 CRdrPass &pass= firstLod.RdrPass[pb]; +00330 <font class="comment">// Sum tri</font> +00331 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.MinFaceUsed+= pass.PBlock.getNumTriangles (); +00332 } +00333 <font class="comment">// Compute MaxFaces.</font> +00334 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &lastLod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size()-1]; +00335 <font class="keywordflow">for</font> (pb=0; pb<lastLod.RdrPass.size(); pb++) +00336 { +00337 CRdrPass &pass= lastLod.RdrPass[pb]; +00338 <font class="comment">// Sum tri</font> +00339 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.MaxFaceUsed+= pass.PBlock.getNumTriangles (); +00340 } +00341 } +00342 +00343 +00344 <font class="comment">// For skinning.</font> +00345 <font class="comment">//================================================</font> +00346 <font class="keywordflow">if</font>( _Skinned ) +00347 { +00348 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c5">bkupOriginalSkinVertices</a>(); +00349 } +00350 <font class="comment">// Inform that the mesh data has changed</font> +00351 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_4">dirtMeshDataId</a>(); +00352 +00353 +00354 <font class="comment">// For AGP SKinning optim, and for Render optim</font> +00355 <font class="comment">//================================================</font> +00356 <font class="keywordflow">for</font>(i=0;i<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size();i++) +00357 { +00358 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[i].buildSkinVertexBlocks(); +00359 <font class="comment">// sort triangles for better cache use.</font> +00360 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[i].optimizeTriangleOrder(); +00361 } +00362 +00363 <font class="comment">// Copy Blend Shapes</font> +00364 <font class="comment">//================================================ </font> +00365 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.BlendShapes = meshBuildMRM.BlendShapes; +00366 +00367 +00368 <font class="comment">// Compact bone id and build a bone id names</font> +00369 <font class="comment">//================================================ </font> +00370 +00371 <font class="comment">// Skinned ?</font> +00372 <font class="keywordflow">if</font> (_Skinned) +00373 { +00374 <font class="comment">// Remap</font> +00375 std::map<uint, uint> remap; +00376 +00377 <font class="comment">// Current bone</font> +00378 uint currentBone = 0; +00379 +00380 <font class="comment">// Reserve memory</font> +00381 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o11">_BonesName</a>.reserve (m.BonesNames.size()); +00382 +00383 <font class="comment">// For each vertices</font> +00384 uint vert; +00385 <font class="keywordflow">for</font> (vert=0; vert<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>.size(); vert++) +00386 { +00387 <font class="comment">// Found one ?</font> +00388 <font class="keywordtype">bool</font> found=<font class="keyword">false</font>; +00389 +00390 <font class="comment">// For each weight</font> +00391 uint weight; +00392 <font class="keywordflow">for</font> (weight=0; weight<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; weight++) +00393 { +00394 <font class="comment">// Active ?</font> +00395 <font class="keywordflow">if</font> ((<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].Weights[weight]>0)||(weight==0)) +00396 { +00397 <font class="comment">// Look for it</font> +00398 std::map<uint, uint>::iterator ite = remap.find (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight]); +00399 +00400 <font class="comment">// Find ?</font> +00401 <font class="keywordflow">if</font> (ite == remap.end()) +00402 { +00403 <font class="comment">// Insert it</font> +00404 remap.insert (std::map<uint, uint>::value_type (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight], currentBone)); +00405 +00406 <font class="comment">// Check the id</font> +00407 <a class="code" href="debug_8h.html#a6">nlassert</a> (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight]<m.BonesNames.size()); +00408 +00409 <font class="comment">// Set the bone name</font> +00410 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o11">_BonesName</a>.push_back (m.BonesNames[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight]]); +00411 +00412 <font class="comment">// Set the local bone id</font> +00413 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight] = currentBone++; +00414 } +00415 <font class="keywordflow">else</font> +00416 { +00417 <font class="comment">// Set the local bone id</font> +00418 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight] = ite->second; +00419 } +00420 +00421 <font class="comment">// Found one</font> +00422 found = <font class="keyword">true</font>; +00423 } +00424 } +00425 +00426 <font class="comment">// Found one ?</font> +00427 <a class="code" href="debug_8h.html#a6">nlassert</a> (found); +00428 } +00429 +00430 <font class="comment">// Remap the vertex influence by lods</font> +00431 uint lod; +00432 <font class="keywordflow">for</font> (lod=0; lod<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size(); lod++) +00433 { +00434 <font class="comment">// For each matrix used</font> +00435 uint <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>; +00436 <font class="keywordflow">for</font> (<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>=0; <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a><<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].MatrixInfluences.size(); <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>++) +00437 { +00438 <font class="comment">// Remap</font> +00439 std::map<uint, uint>::iterator ite = remap.find (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].MatrixInfluences[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]); +00440 +00441 <font class="comment">// Find ?</font> +00442 <a class="code" href="debug_8h.html#a6">nlassert</a> (ite != remap.end()); +00443 +00444 <font class="comment">// Remap</font> +00445 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].MatrixInfluences[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>] = ite->second; +00446 } +00447 } +00448 } +00449 +00450 <font class="comment">// Misc.</font> +00451 <font class="comment">//===================</font> +00452 <font class="comment">// Some runtime not serialized compilation</font> +00453 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c20">compileRunTime</a>(); +00454 +00455 } +00456 +00457 <font class="comment">// ***************************************************************************</font> +<a name="l00458"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#a3">00458</a> <font class="keywordtype">void</font> CMeshMRMGeom::applyMaterialRemap(<font class="keyword">const</font> std::vector<sint> &remap) +00459 { +00460 <font class="keywordflow">for</font>(uint lod=0;lod<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z591_4">getNbLod</a>();lod++) +00461 { +00462 <font class="keywordflow">for</font>(uint rp=0;rp<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z591_5">getNbRdrPass</a>(lod);rp++) +00463 { +00464 <font class="comment">// remap</font> +00465 uint32 &matId= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].RdrPass[rp].MaterialId; +00466 <a class="code" href="debug_8h.html#a6">nlassert</a>(remap[matId]>=0); +00467 matId= remap[matId]; +00468 } +00469 } +00470 } +00471 +00472 <font class="comment">// ***************************************************************************</font> +<a name="l00473"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c2">00473</a> <font class="keywordtype">void</font> CMeshMRMGeom::applyGeomorph(std::vector<CMRMWedgeGeom> &geoms, <font class="keywordtype">float</font> alphaLod, IVertexBufferHard *currentVBHard) +00474 { +00475 <font class="keywordflow">if</font>(currentVBHard!=NULL) +00476 { +00477 <font class="comment">// must write into it</font> +00478 uint8 *vertexDestPtr= (uint8*)currentVBHard->lock(); +00479 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexSize() == currentVBHard->getVertexSize()); +00480 +00481 <font class="comment">// apply the geomorph</font> +00482 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c3">applyGeomorphWithVBHardPtr</a>(geoms, alphaLod, vertexDestPtr); +00483 +00484 <font class="comment">// unlock. ATI: copy only geomorphed vertices.</font> +00485 currentVBHard->unlock(0, geoms.size()); +00486 } +00487 <font class="keywordflow">else</font> +00488 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c3">applyGeomorphWithVBHardPtr</a>(geoms, alphaLod, NULL); +00489 +00490 } +00491 +00492 +00493 <font class="comment">// ***************************************************************************</font> +<a name="l00494"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c3">00494</a> <font class="keywordtype">void</font> CMeshMRMGeom::applyGeomorphWithVBHardPtr(std::vector<CMRMWedgeGeom> &geoms, <font class="keywordtype">float</font> alphaLod, uint8 *vertexDestPtr) +00495 { +00496 <font class="comment">// no geomorphs? quit.</font> +00497 <font class="keywordflow">if</font>(geoms.size()==0) +00498 <font class="keywordflow">return</font>; +00499 +00500 uint i; +00501 <a class="code" href="namespaceNLMISC.html#a215">clamp</a>(alphaLod, 0.f, 1.f); +00502 <font class="keywordtype">float</font> a= alphaLod; +00503 <font class="keywordtype">float</font> a1= 1 - alphaLod; +00504 uint ua= (uint)(a*256); +00505 <a class="code" href="namespaceNLMISC.html#a215">clamp</a>(ua, (uint)0, (uint)256); +00506 uint ua1= 256 - ua; +00507 +00508 +00509 <font class="comment">// info from VBuffer.</font> +00510 uint8 *vertexPtr= (uint8*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexCoordPointer(); +00511 uint flags= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat(); +00512 sint32 vertexSize= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexSize(); +00513 <font class="comment">// because of the unrolled code for 4 first UV, must assert this.</font> +00514 <a class="code" href="debug_8h.html#a6">nlassert</a>(CVertexBuffer::MaxStage>=4); +00515 <font class="comment">// must have XYZ.</font> +00516 <a class="code" href="debug_8h.html#a6">nlassert</a>(flags & CVertexBuffer::PositionFlag); +00517 +00518 +00519 <font class="comment">// If VBuffer Hard disabled</font> +00520 <font class="keywordflow">if</font>(vertexDestPtr==NULL) +00521 { +00522 <font class="comment">// write into vertexPtr.</font> +00523 vertexDestPtr= vertexPtr; +00524 } +00525 +00526 +00527 <font class="comment">// if it is a common format</font> +00528 <font class="keywordflow">if</font>( flags== (CVertexBuffer::PositionFlag | CVertexBuffer::NormalFlag | CVertexBuffer::TexCoord0Flag) && +00529 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getValueType(CVertexBuffer::TexCoord0) == CVertexBuffer::Float2 ) +00530 { +00531 <font class="comment">// use a faster method</font> +00532 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c4">applyGeomorphPosNormalUV0</a>(geoms, vertexPtr, vertexDestPtr, vertexSize, a, a1); +00533 } +00534 <font class="keywordflow">else</font> +00535 { +00536 <font class="comment">// if an offset is 0, it means that the component is not in the VBuffer.</font> +00537 sint32 normalOff; +00538 sint32 colorOff; +00539 sint32 specularOff; +00540 sint32 uvOff[CVertexBuffer::MaxStage]; +00541 <font class="keywordtype">bool</font> has3Coords[CVertexBuffer::MaxStage]; +00542 +00543 +00544 <font class="comment">// Compute offset of each component of the VB.</font> +00545 <font class="keywordflow">if</font>(flags & CVertexBuffer::NormalFlag) +00546 normalOff= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNormalOff(); +00547 <font class="keywordflow">else</font> +00548 normalOff= 0; +00549 <font class="keywordflow">if</font>(flags & CVertexBuffer::PrimaryColorFlag) +00550 colorOff= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getColorOff(); +00551 <font class="keywordflow">else</font> +00552 colorOff= 0; +00553 <font class="keywordflow">if</font>(flags & CVertexBuffer::SecondaryColorFlag) +00554 specularOff= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getSpecularOff(); +00555 <font class="keywordflow">else</font> +00556 specularOff= 0; +00557 +00558 <font class="keywordflow">for</font>(i= 0; i<CVertexBuffer::MaxStage;i++) +00559 { +00560 <font class="keywordflow">if</font>(flags & (CVertexBuffer::TexCoord0Flag<<i)) +00561 { +00562 uvOff[i]= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getTexCoordOff(i); +00563 has3Coords[i] = (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getValueType(i + CVertexBuffer::TexCoord0) == CVertexBuffer::Float3); +00564 } +00565 <font class="keywordflow">else</font> +00566 { +00567 uvOff[i]= 0; +00568 } +00569 } +00570 +00571 +00572 <font class="comment">// For all geomorphs.</font> +00573 uint nGeoms= geoms.size(); +00574 CMRMWedgeGeom *ptrGeom= &(geoms[0]); +00575 uint8 *destPtr= vertexDestPtr; +00576 <font class="comment">/* NB: optimisation: lot of "if" in this Loop, but because of BTB, they always cost nothing (prediction is good).</font> +00577 <font class="comment"> NB: this also is why we unroll the 4 1st Uv. The other (if any), are done in the other loop.</font> +00578 <font class="comment"> NB: optimisation for AGP write cominers: the order of write (vertex, normal, uvs...) is important for good</font> +00579 <font class="comment"> use of AGP write combiners.</font> +00580 <font class="comment"> We have 2 version : one that tests for 3 coordinates texture coords, and one that doesn't</font> +00581 <font class="comment"> */</font> +00582 +00583 <font class="keywordflow">if</font> (!has3Coords[0] && !has3Coords[1] && !has3Coords[2] && !has3Coords[3]) +00584 { +00585 <font class="comment">// there are no texture coordinate of dimension 3</font> +00586 <font class="keywordflow">for</font>(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize ) +00587 { +00588 uint8 *startPtr= vertexPtr + ptrGeom->Start*vertexSize; +00589 uint8 *endPtr= vertexPtr + ptrGeom->End*vertexSize; +00590 +00591 <font class="comment">// Vertex.</font> +00592 { +00593 CVector *start= (CVector*)startPtr; +00594 CVector *end= (CVector*)endPtr; +00595 CVector *dst= (CVector*)destPtr; +00596 *dst= *start * a + *end * a1; +00597 } +00598 +00599 <font class="comment">// Normal.</font> +00600 <font class="keywordflow">if</font>(normalOff) +00601 { +00602 CVector *start= (CVector*)(startPtr + normalOff); +00603 CVector *end= (CVector*)(endPtr + normalOff); +00604 CVector *dst= (CVector*)(destPtr + normalOff); +00605 *dst= *start * a + *end * a1; +00606 } +00607 +00608 +00609 <font class="comment">// Uvs.</font> +00610 <font class="comment">// uv[0].</font> +00611 <font class="keywordflow">if</font>(uvOff[0]) +00612 { +00613 <font class="comment">// Uv.</font> +00614 CUV *start= (CUV*)(startPtr + uvOff[0]); +00615 CUV *end= (CUV*)(endPtr + uvOff[0]); +00616 CUV *dst= (CUV*)(destPtr + uvOff[0]); +00617 *dst= *start * a + *end * a1; +00618 } +00619 <font class="comment">// uv[1].</font> +00620 <font class="keywordflow">if</font>(uvOff[1]) +00621 { +00622 <font class="comment">// Uv.</font> +00623 CUV *start= (CUV*)(startPtr + uvOff[1]); +00624 CUV *end= (CUV*)(endPtr + uvOff[1]); +00625 CUV *dst= (CUV*)(destPtr + uvOff[1]); +00626 *dst= *start * a + *end * a1; +00627 } +00628 <font class="comment">// uv[2].</font> +00629 <font class="keywordflow">if</font>(uvOff[2]) +00630 { +00631 CUV *start= (CUV*)(startPtr + uvOff[2]); +00632 CUV *end= (CUV*)(endPtr + uvOff[2]); +00633 CUV *dst= (CUV*)(destPtr + uvOff[2]); +00634 *dst= *start * a + *end * a1; +00635 } +00636 <font class="comment">// uv[3].</font> +00637 <font class="keywordflow">if</font>(uvOff[3]) +00638 { +00639 <font class="comment">// Uv.</font> +00640 CUV *start= (CUV*)(startPtr + uvOff[3]); +00641 CUV *end= (CUV*)(endPtr + uvOff[3]); +00642 CUV *dst= (CUV*)(destPtr + uvOff[3]); +00643 *dst= *start * a + *end * a1; +00644 } +00645 } +00646 } +00647 <font class="keywordflow">else</font> <font class="comment">// THERE ARE TEXTURE COORDINATES OF DIMENSION 3</font> +00648 { +00649 <font class="keywordflow">for</font>(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize ) +00650 { +00651 uint8 *startPtr= vertexPtr + ptrGeom->Start*vertexSize; +00652 uint8 *endPtr= vertexPtr + ptrGeom->End*vertexSize; +00653 +00654 <font class="comment">// Vertex.</font> +00655 { +00656 CVector *start= (CVector*)startPtr; +00657 CVector *end= (CVector*)endPtr; +00658 CVector *dst= (CVector*)destPtr; +00659 *dst= *start * a + *end * a1; +00660 } +00661 +00662 <font class="comment">// Normal.</font> +00663 <font class="keywordflow">if</font>(normalOff) +00664 { +00665 CVector *start= (CVector*)(startPtr + normalOff); +00666 CVector *end= (CVector*)(endPtr + normalOff); +00667 CVector *dst= (CVector*)(destPtr + normalOff); +00668 *dst= *start * a + *end * a1; +00669 } +00670 <font class="comment">// Uvs.</font> +00671 <font class="comment">// uv[0].</font> +00672 <font class="keywordflow">if</font>(uvOff[0]) +00673 { +00674 <font class="keywordflow">if</font> (!has3Coords[0]) +00675 { +00676 <font class="comment">// Uv.</font> +00677 CUV *start= (CUV*)(startPtr + uvOff[0]); +00678 CUV *end= (CUV*)(endPtr + uvOff[0]); +00679 CUV *dst= (CUV*)(destPtr + uvOff[0]); +00680 *dst= *start * a + *end * a1; +00681 } +00682 <font class="keywordflow">else</font> +00683 { +00684 <font class="comment">// Uv.</font> +00685 CUVW *start= (CUVW*)(startPtr + uvOff[0]); +00686 CUVW *end= (CUVW*)(endPtr + uvOff[0]); +00687 CUVW *dst= (CUVW*)(destPtr + uvOff[0]); +00688 *dst= *start * a + *end * a1; +00689 } +00690 } +00691 <font class="comment">// uv[1].</font> +00692 <font class="keywordflow">if</font>(uvOff[1]) +00693 { +00694 <font class="keywordflow">if</font> (!has3Coords[1]) +00695 { +00696 <font class="comment">// Uv.</font> +00697 CUV *start= (CUV*)(startPtr + uvOff[1]); +00698 CUV *end= (CUV*)(endPtr + uvOff[1]); +00699 CUV *dst= (CUV*)(destPtr + uvOff[1]); +00700 *dst= *start * a + *end * a1; +00701 } +00702 <font class="keywordflow">else</font> +00703 { +00704 <font class="comment">// Uv.</font> +00705 CUVW *start= (CUVW*)(startPtr + uvOff[1]); +00706 CUVW *end= (CUVW*)(endPtr + uvOff[1]); +00707 CUVW *dst= (CUVW*)(destPtr + uvOff[1]); +00708 *dst= *start * a + *end * a1; +00709 } +00710 } +00711 <font class="comment">// uv[2].</font> +00712 <font class="keywordflow">if</font>(uvOff[2]) +00713 { +00714 <font class="keywordflow">if</font> (!has3Coords[2]) +00715 { +00716 <font class="comment">// Uv.</font> +00717 CUV *start= (CUV*)(startPtr + uvOff[2]); +00718 CUV *end= (CUV*)(endPtr + uvOff[2]); +00719 CUV *dst= (CUV*)(destPtr + uvOff[2]); +00720 *dst= *start * a + *end * a1; +00721 } +00722 <font class="keywordflow">else</font> +00723 { +00724 <font class="comment">// Uv.</font> +00725 CUVW *start= (CUVW*)(startPtr + uvOff[2]); +00726 CUVW *end= (CUVW*)(endPtr + uvOff[2]); +00727 CUVW *dst= (CUVW*)(destPtr + uvOff[2]); +00728 *dst= *start * a + *end * a1; +00729 } +00730 } +00731 <font class="comment">// uv[3].</font> +00732 <font class="keywordflow">if</font>(uvOff[3]) +00733 { +00734 <font class="keywordflow">if</font> (!has3Coords[3]) +00735 { +00736 <font class="comment">// Uv.</font> +00737 CUV *start= (CUV*)(startPtr + uvOff[3]); +00738 CUV *end= (CUV*)(endPtr + uvOff[3]); +00739 CUV *dst= (CUV*)(destPtr + uvOff[3]); +00740 *dst= *start * a + *end * a1; +00741 } +00742 <font class="keywordflow">else</font> +00743 { +00744 <font class="comment">// Uv.</font> +00745 CUVW *start= (CUVW*)(startPtr + uvOff[3]); +00746 CUVW *end= (CUVW*)(endPtr + uvOff[3]); +00747 CUVW *dst= (CUVW*)(destPtr + uvOff[3]); +00748 *dst= *start * a + *end * a1; +00749 } +00750 } +00751 <font class="comment">// color.</font> +00752 <font class="keywordflow">if</font>(colorOff) +00753 { +00754 CRGBA *start= (CRGBA*)(startPtr + colorOff); +00755 CRGBA *end= (CRGBA*)(endPtr + colorOff); +00756 CRGBA *dst= (CRGBA*)(destPtr + colorOff); +00757 dst->blendFromui(*start, *end, ua1); +00758 } +00759 <font class="comment">// specular.</font> +00760 <font class="keywordflow">if</font>(specularOff) +00761 { +00762 CRGBA *start= (CRGBA*)(startPtr + specularOff); +00763 CRGBA *end= (CRGBA*)(endPtr + specularOff); +00764 CRGBA *dst= (CRGBA*)(destPtr + specularOff); +00765 dst->blendFromui(*start, *end, ua1); +00766 } +00767 } +00768 } +00769 +00770 +00771 <font class="comment">// Process extra UVs (maybe never, so don't bother optims :)).</font> +00772 <font class="comment">// For all stages after 4.</font> +00773 <font class="keywordflow">for</font>(i=4;i<CVertexBuffer::MaxStage;i++) +00774 { +00775 uint nGeoms= geoms.size(); +00776 CMRMWedgeGeom *ptrGeom= &(geoms[0]); +00777 uint8 *destPtr= vertexDestPtr; +00778 +00779 <font class="keywordflow">if</font>(uvOff[i]==0) +00780 <font class="keywordflow">continue</font>; +00781 +00782 <font class="comment">// For all geomorphs.</font> +00783 <font class="keywordflow">for</font>(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize ) +00784 { +00785 uint8 *startPtr= vertexPtr + ptrGeom->Start*vertexSize; +00786 uint8 *endPtr= vertexPtr + ptrGeom->End*vertexSize; +00787 +00788 <font class="comment">// uv[i].</font> +00789 <font class="comment">// Uv.</font> +00790 <font class="keywordflow">if</font> (!has3Coords[i]) +00791 { +00792 CUV *start= (CUV*)(startPtr + uvOff[i]); +00793 CUV *end= (CUV*)(endPtr + uvOff[i]); +00794 CUV *dst= (CUV*)(destPtr + uvOff[i]); +00795 *dst= *start * a + *end * a1; +00796 } +00797 <font class="keywordflow">else</font> +00798 { +00799 CUVW *start= (CUVW*)(startPtr + uvOff[i]); +00800 CUVW *end= (CUVW*)(endPtr + uvOff[i]); +00801 CUVW *dst= (CUVW*)(destPtr + uvOff[i]); +00802 *dst= *start * a + *end * a1; +00803 } +00804 } +00805 } +00806 } +00807 } +00808 +00809 +00810 <font class="comment">// ***************************************************************************</font> +<a name="l00811"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c4">00811</a> <font class="keywordtype">void</font> CMeshMRMGeom::applyGeomorphPosNormalUV0(std::vector<CMRMWedgeGeom> &geoms, uint8 *vertexPtr, uint8 *vertexDestPtr, sint32 vertexSize, <font class="keywordtype">float</font> a, <font class="keywordtype">float</font> a1) +00812 { +00813 <a class="code" href="debug_8h.html#a6">nlassert</a>(vertexSize==32); +00814 +00815 +00816 <font class="comment">// For all geomorphs.</font> +00817 uint nGeoms= geoms.size(); +00818 CMRMWedgeGeom *ptrGeom= &(geoms[0]); +00819 uint8 *destPtr= vertexDestPtr; +00820 <font class="keywordflow">for</font>(; nGeoms>0; nGeoms--, ptrGeom++, destPtr+= vertexSize ) +00821 { +00822 <font class="comment">// Consider the Pos/Normal/UV as an array of 8 float to interpolate.</font> +00823 <font class="keywordtype">float</font> *start= (<font class="keywordtype">float</font>*)(vertexPtr + (ptrGeom->Start<<5)); +00824 <font class="keywordtype">float</font> *end= (<font class="keywordtype">float</font>*)(vertexPtr + (ptrGeom->End<<5)); +00825 <font class="keywordtype">float</font> *dst= (<font class="keywordtype">float</font>*)(destPtr); +00826 +00827 <font class="comment">// unrolled</font> +00828 dst[0]= start[0] * a + end[0]* a1; +00829 dst[1]= start[1] * a + end[1]* a1; +00830 dst[2]= start[2] * a + end[2]* a1; +00831 dst[3]= start[3] * a + end[3]* a1; +00832 dst[4]= start[4] * a + end[4]* a1; +00833 dst[5]= start[5] * a + end[5]* a1; +00834 dst[6]= start[6] * a + end[6]* a1; +00835 dst[7]= start[7] * a + end[7]* a1; +00836 } +00837 } +00838 +00839 +00840 <font class="comment">// ***************************************************************************</font> +<a name="l00841"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z589_0">00841</a> <font class="keywordtype">void</font> CMeshMRMGeom::initInstance(CMeshBaseInstance *mbi) +00842 { +00843 <font class="comment">// init the instance with _MeshVertexProgram infos</font> +00844 <font class="keywordflow">if</font>(_MeshVertexProgram) +00845 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->initInstance(mbi); +00846 } +00847 +00848 +00849 <font class="comment">// ***************************************************************************</font> +<a name="l00850"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z589_1">00850</a> <font class="keywordtype">bool</font> CMeshMRMGeom::clip(<font class="keyword">const</font> std::vector<CPlane> &pyramid, <font class="keyword">const</font> CMatrix &worldMatrix) +00851 { +00852 <font class="comment">// Speed Clip: clip just the sphere.</font> +00853 CBSphere localSphere(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o15">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z268_2">getCenter</a>(), <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o15">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z268_5">getRadius</a>()); +00854 CBSphere worldSphere; +00855 +00856 <font class="comment">// transform the sphere in WorldMatrix (with nearly good scale info).</font> +00857 localSphere.applyTransform(worldMatrix, worldSphere); +00858 +00859 <font class="comment">// if out of only plane, entirely out.</font> +00860 <font class="keywordflow">for</font>(sint i=0;i<(sint)pyramid.size();i++) +00861 { +00862 <font class="comment">// We are sure that pyramid has normalized plane normals.</font> +00863 <font class="comment">// if SpherMax OUT return false.</font> +00864 <font class="keywordtype">float</font> d= pyramid[i]*worldSphere.Center; +00865 <font class="keywordflow">if</font>(d>worldSphere.Radius) +00866 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00867 } +00868 +00869 <font class="comment">// test if must do a precise clip, according to mesh size.</font> +00870 <font class="keywordflow">if</font>( _PreciseClipping ) +00871 { +00872 CPlane localPlane; +00873 +00874 <font class="comment">// if out of only plane, entirely out.</font> +00875 <font class="keywordflow">for</font>(sint i=0;i<(sint)pyramid.size();i++) +00876 { +00877 <font class="comment">// Transform the pyramid in Object space.</font> +00878 localPlane= pyramid[i]*worldMatrix; +00879 <font class="comment">// localPlane must be normalized, because worldMatrix mya have a scale.</font> +00880 localPlane.normalize(); +00881 <font class="comment">// if the box is not partially inside the plane, quit</font> +00882 <font class="keywordflow">if</font>( !<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o15">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z269_1">clipBack</a>(localPlane) ) +00883 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00884 } +00885 } +00886 +00887 <font class="keywordflow">return</font> <font class="keyword">true</font>; +00888 } +00889 +00890 +00891 <font class="comment">// ***************************************************************************</font> +<a name="l00892"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c1">00892</a> <font class="keyword">inline</font> sint CMeshMRMGeom::chooseLod(<font class="keywordtype">float</font> alphaMRM, <font class="keywordtype">float</font> &alphaLod) +00893 { +00894 <font class="comment">// Choose what Lod to draw.</font> +00895 alphaMRM*= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size()-1; +00896 sint numLod= (sint)ceil(alphaMRM); +00897 <font class="keywordflow">if</font>(numLod==0) +00898 { +00899 numLod= 0; +00900 alphaLod= 0; +00901 } +00902 <font class="keywordflow">else</font> +00903 { +00904 <font class="comment">// Lerp beetween lod i-1 and lod i.</font> +00905 alphaLod= alphaMRM-(numLod-1); +00906 } +00907 +00908 +00909 <font class="comment">// If lod chosen is not loaded, take the best loaded.</font> +00910 <font class="keywordflow">if</font>(numLod>=(sint)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>) +00911 { +00912 numLod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>-1; +00913 alphaLod= 1; +00914 } +00915 +00916 <font class="keywordflow">return</font> numLod; +00917 } +00918 +00919 +00920 <font class="comment">// ***************************************************************************</font> +<a name="l00921"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z589_2">00921</a> <font class="keywordtype">void</font> CMeshMRMGeom::render(IDriver *drv, CTransformShape *trans, <font class="keywordtype">float</font> polygonCount, uint32 rdrFlags, <font class="keywordtype">float</font> globalAlpha) +00922 { +00923 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +00924 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size()==0) +00925 <font class="keywordflow">return</font>; +00926 +00927 +00928 <font class="comment">// get the meshMRM instance.</font> +00929 CMeshBaseInstance *mi= safe_cast<CMeshBaseInstance*>(trans); +00930 <font class="comment">// get a ptr on scene</font> +00931 CScene *ownerScene= mi->getScene(); +00932 <font class="comment">// get a ptr on renderTrav</font> +00933 CRenderTrav *renderTrav= ownerScene->getRenderTrav(); +00934 +00935 +00936 <font class="comment">// get the result of the Load Balancing.</font> +00937 <font class="keywordtype">float</font> alphaMRM= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.getLevelDetailFromPolyCount(polygonCount); +00938 +00939 <font class="comment">// choose the lod.</font> +00940 <font class="keywordtype">float</font> alphaLod; +00941 sint numLod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c1">chooseLod</a>(alphaMRM, alphaLod); +00942 +00943 +00944 <font class="comment">// Render the choosen Lod.</font> +00945 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &lod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[numLod]; +00946 <font class="keywordflow">if</font>(lod.RdrPass.size()==0) +00947 <font class="keywordflow">return</font>; +00948 +00949 +00950 <font class="comment">// Update the vertexBufferHard (if possible).</font> +00951 <font class="comment">// \toto yoyo: TODO_OPTIMIZE: allocate only what is needed for the current Lod (Max of all instances, like</font> +00952 <font class="comment">// the loading....) (see loadHeader()).</font> +00953 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_0">updateVertexBufferHard</a>(drv, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices()); +00954 <font class="comment">/* currentVBHard is NULL if must disable it temporarily</font> +00955 <font class="comment"> For now, never disable it, but switch of VBHard may be VERY EXPENSIVE if NV_vertex_array_range2 is not</font> +00956 <font class="comment"> supported (old drivers).</font> +00957 <font class="comment"> */</font> +00958 IVertexBufferHard *currentVBHard= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>; +00959 +00960 +00961 <font class="comment">// get the skeleton model to which I am binded (else NULL).</font> +00962 CSkeletonModel *skeleton; +00963 skeleton = mi->getSkeletonModel(); +00964 <font class="comment">// The mesh must not be skinned for render()</font> +00965 <a class="code" href="debug_8h.html#a6">nlassert</a>(!(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a> && mi->isSkinned() && skeleton)); +00966 <font class="keywordtype">bool</font> bMorphApplied = <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.BlendShapes.size() > 0; +00967 <font class="keywordtype">bool</font> useTangentSpace = <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->needTangentSpace(); +00968 +00969 +00970 <font class="comment">// Profiling</font> +00971 <font class="comment">//===========</font> +00972 <a class="code" href="hierarchical__timer_8h.html#a4">H_AUTO</a>( NL3D_MeshMRMGeom_RenderNormal ); +00973 +00974 +00975 <font class="comment">// Morphing</font> +00976 <font class="comment">// ========</font> +00977 <font class="keywordflow">if</font> (bMorphApplied) +00978 { +00979 <font class="comment">// If _Skinned (NB: the skin is not applied) and if lod.OriginalSkinRestored, then restoreOriginalSkinPart is</font> +00980 <font class="comment">// not called but mush morpher write changed vertices into VBHard so its ok. The unchanged vertices</font> +00981 <font class="comment">// are written in the preceding call to restoreOriginalSkinPart.</font> +00982 <font class="keywordflow">if</font> (_Skinned) +00983 { +00984 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.initSkinned(&<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o4">_VBufferOriginal</a>, +00985 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>, +00986 currentVBHard, +00987 useTangentSpace, +00988 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>, +00989 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>, +00990 useTangentSpace ? &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o3">_OriginalTGSpace</a> : NULL, +00991 <font class="keyword">false</font> ); +00992 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.updateSkinned (mi->getBlendShapeFactors()); +00993 } +00994 <font class="keywordflow">else</font> <font class="comment">// Not even skinned so we have to do all the stuff</font> +00995 { +00996 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.init(&<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o4">_VBufferOriginal</a>, +00997 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>, +00998 currentVBHard, +00999 useTangentSpace); +01000 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.update (mi->getBlendShapeFactors()); +01001 } +01002 } +01003 +01004 <font class="comment">// Skinning.</font> +01005 <font class="comment">//===========</font> +01006 <font class="comment">// if mesh is skinned (but here skin not applied), we must copy vertices/normals from original vertices.</font> +01007 <font class="keywordflow">if</font> (_Skinned) +01008 { +01009 <font class="comment">// do it for this Lod only, and if cache say it is necessary.</font> +01010 <font class="keywordflow">if</font> (!lod.OriginalSkinRestored) +01011 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c15">restoreOriginalSkinPart</a>(lod, currentVBHard); +01012 } +01013 +01014 +01015 <font class="comment">// set the instance worldmatrix.</font> +01016 drv->setupModelMatrix(trans->getWorldMatrix()); +01017 +01018 +01019 <font class="comment">// Geomorph.</font> +01020 <font class="comment">//===========</font> +01021 <font class="comment">// Geomorph the choosen Lod (if not the coarser mesh).</font> +01022 <font class="keywordflow">if</font>(numLod>0) +01023 { +01024 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c2">applyGeomorph</a>(lod.Geomorphs, alphaLod, currentVBHard); +01025 } +01026 +01027 +01028 <font class="comment">// force normalisation of normals..</font> +01029 <font class="keywordtype">bool</font> bkupNorm= drv->isForceNormalize(); +01030 drv->forceNormalize(<font class="keyword">true</font>); +01031 +01032 +01033 <font class="comment">// Setup meshVertexProgram</font> +01034 <font class="comment">//===========</font> +01035 +01036 <font class="comment">// use MeshVertexProgram effect?</font> +01037 <font class="keywordtype">bool</font> useMeshVP= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a> != NULL; +01038 <font class="keywordflow">if</font>( useMeshVP ) +01039 { +01040 CMatrix invertedObjectMatrix; +01041 invertedObjectMatrix = trans->getWorldMatrix().inverted(); +01042 <font class="comment">// really ok if success to begin VP</font> +01043 useMeshVP= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->begin(drv, mi->getScene(), mi, invertedObjectMatrix, renderTrav->CamPos); +01044 } +01045 +01046 +01047 <font class="comment">// Render the lod.</font> +01048 <font class="comment">//===========</font> +01049 <font class="comment">// active VB.</font> +01050 <font class="keywordflow">if</font>(currentVBHard) +01051 drv->activeVertexBufferHard(currentVBHard); +01052 <font class="keywordflow">else</font> +01053 drv->activeVertexBuffer(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>); +01054 +01055 +01056 <font class="comment">// Global alpha used ?</font> +01057 uint32 globalAlphaUsed= rdrFlags & IMeshGeom::RenderGlobalAlpha; +01058 uint8 globalAlphaInt=(uint8)<a class="code" href="namespaceNL3D.html#a362">OptFastFloor</a>(globalAlpha*255); +01059 +01060 <font class="comment">// Render all pass.</font> +01061 <font class="keywordflow">if</font> (globalAlphaUsed) +01062 { +01063 <font class="keywordtype">bool</font> gaDisableZWrite= (rdrFlags & IMeshGeom::RenderGADisableZWrite)?<font class="keyword">true</font>:<font class="keyword">false</font>; +01064 +01065 <font class="comment">// for all passes</font> +01066 <font class="keywordflow">for</font>(uint i=0;i<lod.RdrPass.size();i++) +01067 { +01068 CRdrPass &rdrPass= lod.RdrPass[i]; +01069 +01070 <font class="keywordflow">if</font> ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">false</font>) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) || +01071 ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">true</font>) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) ) +01072 { +01073 <font class="comment">// CMaterial Ref</font> +01074 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +01075 +01076 <font class="comment">// Use a MeshBlender to modify material and driver.</font> +01077 CMeshBlender blender; +01078 blender.prepareRenderForGlobalAlpha(material, drv, globalAlpha, globalAlphaInt, gaDisableZWrite); +01079 +01080 <font class="comment">// Setup VP material</font> +01081 <font class="keywordflow">if</font> (useMeshVP) +01082 { +01083 <font class="keywordflow">if</font>(currentVBHard) +01084 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, currentVBHard); +01085 <font class="keywordflow">else</font> +01086 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>); +01087 } +01088 +01089 <font class="comment">// Render</font> +01090 drv->render(rdrPass.PBlock, material); +01091 +01092 <font class="comment">// Resetup material/driver</font> +01093 blender.restoreRender(material, drv, gaDisableZWrite); +01094 } +01095 } +01096 } +01097 <font class="keywordflow">else</font> +01098 { +01099 <font class="keywordflow">for</font>(uint i=0;i<lod.RdrPass.size();i++) +01100 { +01101 CRdrPass &rdrPass= lod.RdrPass[i]; +01102 +01103 <font class="keywordflow">if</font> ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">false</font>) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) || +01104 ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">true</font>) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) ) +01105 { +01106 <font class="comment">// CMaterial Ref</font> +01107 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +01108 +01109 <font class="comment">// Setup VP material</font> +01110 <font class="keywordflow">if</font> (useMeshVP) +01111 { +01112 <font class="keywordflow">if</font>(currentVBHard) +01113 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, currentVBHard); +01114 <font class="keywordflow">else</font> +01115 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>); +01116 } +01117 +01118 <font class="comment">// Render with the Materials of the MeshInstance.</font> +01119 drv->render(rdrPass.PBlock, material); +01120 } +01121 } +01122 } +01123 +01124 +01125 <font class="comment">// End VertexProgram effect</font> +01126 <font class="keywordflow">if</font>(useMeshVP) +01127 { +01128 <font class="comment">// end it.</font> +01129 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->end(drv); +01130 } +01131 +01132 +01133 <font class="comment">// bkup force normalisation.</font> +01134 drv->forceNormalize(bkupNorm); +01135 +01136 } +01137 +01138 +01139 <font class="comment">// ***************************************************************************</font> +<a name="l01140"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z589_3">01140</a> <font class="keywordtype">void</font> CMeshMRMGeom::renderSkin(CTransformShape *trans, <font class="keywordtype">float</font> alphaMRM) +01141 { +01142 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size()==0) +01143 <font class="keywordflow">return</font>; +01144 +01145 +01146 <font class="comment">// get the meshMRM instance. only CMeshMRMInstance is possible when skinned (not MultiLod)</font> +01147 CMeshMRMInstance *mi= safe_cast<CMeshMRMInstance*>(trans); +01148 <font class="comment">// get a ptr on scene</font> +01149 CScene *ownerScene= mi->getScene(); +01150 <font class="comment">// get a ptr on renderTrav</font> +01151 CRenderTrav *renderTrav= ownerScene->getRenderTrav(); +01152 <font class="comment">// get a ptr on the driver</font> +01153 IDriver *drv= renderTrav->getDriver(); +01154 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +01155 +01156 +01157 <font class="comment">// choose the lod.</font> +01158 <font class="keywordtype">float</font> alphaLod; +01159 sint numLod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c1">chooseLod</a>(alphaMRM, alphaLod); +01160 +01161 +01162 <font class="comment">// Render the choosen Lod.</font> +01163 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &lod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[numLod]; +01164 <font class="keywordflow">if</font>(lod.RdrPass.size()==0) +01165 <font class="keywordflow">return</font>; +01166 +01167 +01168 <font class="comment">/*</font> +01169 <font class="comment"> YOYO: renderSkin() no more support vertexBufferHard()!!! for AGP Memory optimisation concern.</font> +01170 <font class="comment"> AGP Skin rendering is made when supportSkinGrouping() is true</font> +01171 <font class="comment"> Hence if a skin is to be rendered here, because it doesn't have a good vertex format, or it has</font> +01172 <font class="comment"> MeshVertexProgram etc..., it will be rendered WITHOUT VBHard => slower.</font> +01173 <font class="comment"> */</font> +01174 +01175 +01176 <font class="comment">// get the skeleton model to which I am skinned</font> +01177 CSkeletonModel *skeleton; +01178 skeleton = mi->getSkeletonModel(); +01179 <font class="comment">// must be skinned for renderSkin()</font> +01180 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a> && mi->isSkinned() && skeleton); +01181 <font class="keywordtype">bool</font> bMorphApplied = <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.BlendShapes.size() > 0; +01182 <font class="keywordtype">bool</font> useNormal= (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() & CVertexBuffer::NormalFlag)!=0; +01183 <font class="keywordtype">bool</font> useTangentSpace = <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->needTangentSpace(); +01184 +01185 +01186 <font class="comment">// Profiling</font> +01187 <font class="comment">//===========</font> +01188 <a class="code" href="hierarchical__timer_8h.html#a7">H_AUTO_USE</a>( NL3D_MeshMRMGeom_RenderSkinned ); +01189 +01190 +01191 <font class="comment">// Morphing</font> +01192 <font class="comment">// ========</font> +01193 <font class="keywordflow">if</font> (bMorphApplied) +01194 { +01195 <font class="comment">// Since Skinned we must update original skin vertices and normals because skinning use it</font> +01196 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.initSkinned(&<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o4">_VBufferOriginal</a>, +01197 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>, +01198 NULL, +01199 useTangentSpace, +01200 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>, +01201 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>, +01202 useTangentSpace ? &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o3">_OriginalTGSpace</a> : NULL, +01203 <font class="keyword">true</font> ); +01204 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.updateSkinned (mi->getBlendShapeFactors()); +01205 } +01206 +01207 <font class="comment">// Skinning.</font> +01208 <font class="comment">//===========</font> +01209 +01210 <font class="comment">// Use RawSkin if possible: only if no morph, and only Vertex/Normal</font> +01211 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_3">updateRawSkinNormal</a>(!bMorphApplied && !useTangentSpace && useNormal, mi, numLod); +01212 +01213 <font class="comment">// applySkin.</font> +01214 <font class="comment">//--------</font> +01215 +01216 <font class="comment">// If skin without normal (rare/usefull?) always simple (slow) case.</font> +01217 <font class="keywordflow">if</font>(!useNormal) +01218 { +01219 <font class="comment">// skinning with just position</font> +01220 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c8">applySkin</a> (lod, skeleton); +01221 } +01222 <font class="keywordflow">else</font> +01223 { +01224 <font class="comment">// Use SSE when possible</font> +01225 <font class="keywordflow">if</font>( CSystemInfo::hasSSE() ) +01226 { +01227 <font class="comment">// apply skin for this Lod only.</font> +01228 <font class="keywordflow">if</font> (!useTangentSpace) +01229 { +01230 <font class="comment">// skinning with normal, but no tangent space</font> +01231 <font class="keywordflow">if</font>(mi->_RawSkinCache) +01232 <font class="comment">// Use faster RawSkin if possible.</font> +01233 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c12">applyRawSkinWithNormalSSE</a>(lod, *(mi->_RawSkinCache), skeleton); +01234 <font class="keywordflow">else</font> +01235 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c10">applySkinWithNormalSSE</a> (lod, skeleton); +01236 } +01237 <font class="keywordflow">else</font> +01238 { +01239 <font class="comment">// Tangent space stored in the last texture coordinate</font> +01240 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c14">applySkinWithTangentSpaceSSE</a>(lod, skeleton, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumTexCoordUsed() - 1); +01241 } +01242 } +01243 <font class="comment">// Standard FPU skinning</font> +01244 <font class="keywordflow">else</font> +01245 { +01246 <font class="comment">// apply skin for this Lod only.</font> +01247 <font class="keywordflow">if</font> (!useTangentSpace) +01248 { +01249 <font class="comment">// skinning with normal, but no tangent space</font> +01250 <font class="keywordflow">if</font>(mi->_RawSkinCache) +01251 <font class="comment">// Use faster RawSkin if possible.</font> +01252 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c11">applyRawSkinWithNormal</a> (lod, *(mi->_RawSkinCache), skeleton); +01253 <font class="keywordflow">else</font> +01254 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c9">applySkinWithNormal</a> (lod, skeleton); +01255 } +01256 <font class="keywordflow">else</font> +01257 { +01258 <font class="comment">// Tangent space stored in the last texture coordinate</font> +01259 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c13">applySkinWithTangentSpace</a>(lod, skeleton, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumTexCoordUsed() - 1); +01260 } +01261 } +01262 } +01263 +01264 <font class="comment">// endSkin.</font> +01265 <font class="comment">//--------</font> +01266 <font class="comment">// dirt this lod part. (NB: this is not optimal, but sufficient :) ).</font> +01267 lod.OriginalSkinRestored= <font class="keyword">false</font>; +01268 +01269 +01270 <font class="comment">// NB: the skeleton matrix has already been setuped by CSkeletonModel</font> +01271 <font class="comment">// NB: the normalize flag has already been setuped by CSkeletonModel</font> +01272 +01273 +01274 <font class="comment">// Geomorph.</font> +01275 <font class="comment">//===========</font> +01276 <font class="comment">// Geomorph the choosen Lod (if not the coarser mesh).</font> +01277 <font class="keywordflow">if</font>(numLod>0) +01278 { +01279 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c2">applyGeomorph</a>(lod.Geomorphs, alphaLod, NULL); +01280 } +01281 +01282 +01283 <font class="comment">// Setup meshVertexProgram</font> +01284 <font class="comment">//===========</font> +01285 +01286 <font class="comment">// use MeshVertexProgram effect?</font> +01287 <font class="keywordtype">bool</font> useMeshVP= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a> != NULL; +01288 <font class="keywordflow">if</font>( useMeshVP ) +01289 { +01290 CMatrix invertedObjectMatrix; +01291 invertedObjectMatrix = skeleton->getWorldMatrix().inverted(); +01292 <font class="comment">// really ok if success to begin VP</font> +01293 useMeshVP= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->begin(drv, mi->getScene(), mi, invertedObjectMatrix, renderTrav->CamPos); +01294 } +01295 +01296 +01297 <font class="comment">// Render the lod.</font> +01298 <font class="comment">//===========</font> +01299 <font class="comment">// active VB.</font> +01300 drv->activeVertexBuffer(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>); +01301 +01302 +01303 <font class="comment">// Render all pass.</font> +01304 <font class="keywordflow">for</font>(uint i=0;i<lod.RdrPass.size();i++) +01305 { +01306 CRdrPass &rdrPass= lod.RdrPass[i]; +01307 +01308 <font class="comment">// CMaterial Ref</font> +01309 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +01310 +01311 <font class="comment">// Setup VP material</font> +01312 <font class="keywordflow">if</font> (useMeshVP) +01313 { +01314 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>); +01315 } +01316 +01317 <font class="comment">// Render with the Materials of the MeshInstance.</font> +01318 drv->render(rdrPass.PBlock, material); +01319 } +01320 +01321 <font class="comment">// End VertexProgram effect</font> +01322 <font class="keywordflow">if</font>(useMeshVP) +01323 { +01324 <font class="comment">// end it.</font> +01325 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->end(drv); +01326 } +01327 } +01328 +01329 +01330 <font class="comment">// ***************************************************************************</font> +<a name="l01331"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z594_0">01331</a> <font class="keywordtype">bool</font> CMeshMRMGeom::supportSkinGrouping()<font class="keyword"> const</font> +01332 <font class="keyword"></font>{ +01333 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o9">_SupportSkinGrouping</a>; +01334 } +01335 +01336 <font class="comment">// ***************************************************************************</font> +<a name="l01337"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z594_1">01337</a> sint CMeshMRMGeom::renderSkinGroupGeom(CMeshMRMInstance *mi, <font class="keywordtype">float</font> alphaMRM, uint remainingVertices, uint8 *vbDest) +01338 { +01339 <font class="comment">// get a ptr on scene</font> +01340 CScene *ownerScene= mi->getScene(); +01341 <font class="comment">// get a ptr on renderTrav</font> +01342 CRenderTrav *renderTrav= ownerScene->getRenderTrav(); +01343 <font class="comment">// get a ptr on the driver</font> +01344 IDriver *drv= renderTrav->getDriver(); +01345 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +01346 +01347 +01348 <font class="comment">// choose the lod.</font> +01349 <font class="keywordtype">float</font> alphaLod; +01350 sint numLod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c1">chooseLod</a>(alphaMRM, alphaLod); +01351 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o10">_LastLodComputed</a>= numLod; +01352 +01353 +01354 <font class="comment">// Render the choosen Lod.</font> +01355 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &lod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[numLod]; +01356 <font class="keywordflow">if</font>(lod.RdrPass.size()==0) +01357 <font class="comment">// return no vertices added</font> +01358 <font class="keywordflow">return</font> 0; +01359 +01360 <font class="comment">// If the Lod is too big to render in the VBufferHard</font> +01361 <font class="keywordflow">if</font>(lod.NWedges>remainingVertices) +01362 <font class="comment">// return Failure</font> +01363 <font class="keywordflow">return</font> -1; +01364 +01365 <font class="comment">// get the skeleton model to which I am skinned</font> +01366 CSkeletonModel *skeleton; +01367 skeleton = mi->getSkeletonModel(); +01368 <font class="comment">// must be skinned for renderSkin()</font> +01369 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a> && mi->isSkinned() && skeleton); +01370 <font class="keywordtype">bool</font> bMorphApplied = <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.BlendShapes.size() > 0; +01371 <font class="keywordtype">bool</font> useNormal= (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() & CVertexBuffer::NormalFlag)!=0; +01372 <a class="code" href="debug_8h.html#a6">nlassert</a>(useNormal); +01373 +01374 +01375 <font class="comment">// Profiling</font> +01376 <font class="comment">//===========</font> +01377 <a class="code" href="hierarchical__timer_8h.html#a7">H_AUTO_USE</a>( NL3D_MeshMRMGeom_RenderSkinned ); +01378 +01379 +01380 <font class="comment">// Morphing</font> +01381 <font class="comment">// ========</font> +01382 <font class="keywordflow">if</font> (bMorphApplied) +01383 { +01384 <font class="comment">// Since Skinned we must update original skin vertices and normals because skinning use it</font> +01385 <font class="comment">// NB: no need to setup vertexBufferHard, because not update in SkinningMode, but if the skin is not applied,</font> +01386 <font class="comment">// which is not the case here</font> +01387 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.initSkinned(&<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o4">_VBufferOriginal</a>, +01388 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>, +01389 NULL, +01390 <font class="keyword">false</font>, +01391 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>, +01392 &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>, +01393 NULL, +01394 <font class="keyword">true</font> ); +01395 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.updateSkinned (mi->getBlendShapeFactors()); +01396 } +01397 +01398 <font class="comment">// Skinning.</font> +01399 <font class="comment">//===========</font> +01400 +01401 <font class="comment">// Use RawSkin if possible: only if no morph, and only Vertex/Normal</font> +01402 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_3">updateRawSkinNormal</a>(!bMorphApplied, mi, numLod); +01403 +01404 <font class="comment">// applySkin.</font> +01405 <font class="comment">//--------</font> +01406 +01407 <font class="comment">// Use SSE when possible</font> +01408 <font class="keywordflow">if</font>( CSystemInfo::hasSSE() ) +01409 { +01410 <font class="comment">// skinning with normal, but no tangent space</font> +01411 <font class="keywordflow">if</font>(mi->_RawSkinCache) +01412 <font class="comment">// Use faster RawSkin if possible.</font> +01413 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c12">applyRawSkinWithNormalSSE</a>(lod, *(mi->_RawSkinCache), skeleton); +01414 <font class="keywordflow">else</font> +01415 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c10">applySkinWithNormalSSE</a> (lod, skeleton); +01416 } +01417 <font class="comment">// Standard FPU skinning</font> +01418 <font class="keywordflow">else</font> +01419 { +01420 <font class="comment">// skinning with normal, but no tangent space</font> +01421 <font class="keywordflow">if</font>(mi->_RawSkinCache) +01422 <font class="comment">// Use faster RawSkin if possible.</font> +01423 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c11">applyRawSkinWithNormal</a> (lod, *(mi->_RawSkinCache), skeleton); +01424 <font class="keywordflow">else</font> +01425 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c9">applySkinWithNormal</a> (lod, skeleton); +01426 } +01427 +01428 <font class="comment">// endSkin.</font> +01429 <font class="comment">//--------</font> +01430 <font class="comment">// Fill the usefull AGP memory (if any one loaded/Used).</font> +01431 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_2">fillAGPSkinPartWithVBHardPtr</a>(lod, vbDest); +01432 <font class="comment">// dirt this lod part. (NB: this is not optimal, but sufficient :) ).</font> +01433 lod.OriginalSkinRestored= <font class="keyword">false</font>; +01434 +01435 +01436 <font class="comment">// NB: the skeleton matrix has already been setuped by CSkeletonModel</font> +01437 <font class="comment">// NB: the normalize flag has already been setuped by CSkeletonModel</font> +01438 +01439 +01440 <font class="comment">// Geomorph.</font> +01441 <font class="comment">//===========</font> +01442 <font class="comment">// Geomorph the choosen Lod (if not the coarser mesh).</font> +01443 <font class="keywordflow">if</font>(numLod>0) +01444 { +01445 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c3">applyGeomorphWithVBHardPtr</a>(lod.Geomorphs, alphaLod, vbDest); +01446 } +01447 +01448 <font class="comment">// How many vertices are added to the VBuffer ???</font> +01449 <font class="keywordflow">return</font> lod.NWedges; +01450 } +01451 +01452 <font class="comment">// ***************************************************************************</font> +<a name="l01453"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z594_2">01453</a> <font class="keywordtype">void</font> CMeshMRMGeom::renderSkinGroupPrimitives(CMeshMRMInstance *mi, uint baseVertex) +01454 { +01455 <font class="comment">// get a ptr on scene</font> +01456 CScene *ownerScene= mi->getScene(); +01457 <font class="comment">// get a ptr on renderTrav</font> +01458 CRenderTrav *renderTrav= ownerScene->getRenderTrav(); +01459 <font class="comment">// get a ptr on the driver</font> +01460 IDriver *drv= renderTrav->getDriver(); +01461 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +01462 +01463 <font class="comment">// Get the lod choosen in renderSkinGroupGeom()</font> +01464 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &lod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o10">_LastLodComputed</a>]; +01465 +01466 +01467 <font class="comment">// Profiling</font> +01468 <font class="comment">//===========</font> +01469 <a class="code" href="hierarchical__timer_8h.html#a7">H_AUTO_USE</a>( NL3D_MeshMRMGeom_RenderSkinned ); +01470 +01471 <font class="comment">// must update primitive cache</font> +01472 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c21">updateShiftedTriangleCache</a>(mi, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o10">_LastLodComputed</a>, baseVertex); +01473 <a class="code" href="debug_8h.html#a6">nlassert</a>(mi->_ShiftedTriangleCache); +01474 +01475 <font class="comment">// Render Quad or line, if needed (Yoyo: maybe never :/)</font> +01476 <font class="comment">//===========</font> +01477 <font class="keywordflow">if</font>(mi->_ShiftedTriangleCache->HasQuadOrLine) +01478 { +01479 <font class="keywordflow">for</font>(uint i=0;i<lod.RdrPass.size();i++) +01480 { +01481 CRdrPass &rdrPass= lod.RdrPass[i]; +01482 +01483 <font class="comment">// CMaterial Ref</font> +01484 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +01485 +01486 +01487 <font class="comment">// Compute a PBlock (static to avoid reallocation) shifted to baseVertex</font> +01488 <font class="keyword">static</font> CPrimitiveBlock dstPBlock; +01489 dstPBlock.setNumLine(0); +01490 dstPBlock.setNumQuad(0); +01491 <font class="comment">// Lines.</font> +01492 uint numLines= rdrPass.PBlock.getNumLine(); +01493 <font class="keywordflow">if</font>(numLines) +01494 { +01495 uint nIds= numLines*2; +01496 <font class="comment">// allocate, in the tmp buffer</font> +01497 dstPBlock.setNumLine(numLines); +01498 <font class="comment">// index, and fill</font> +01499 uint32 *pSrcLine= rdrPass.PBlock.getLinePointer(); +01500 uint32 *pDstLine= dstPBlock.getLinePointer(); +01501 <font class="keywordflow">for</font>(;nIds>0;nIds--,pSrcLine++,pDstLine++) +01502 *pDstLine= *pSrcLine + baseVertex; +01503 } +01504 <font class="comment">// Quads</font> +01505 uint numQuads= rdrPass.PBlock.getNumQuad(); +01506 <font class="keywordflow">if</font>(numQuads) +01507 { +01508 uint nIds= numQuads*4; +01509 <font class="comment">// allocate, in the tmp buffer</font> +01510 dstPBlock.setNumQuad(numQuads); +01511 <font class="comment">// index, and fill</font> +01512 uint32 *pSrcQuad= rdrPass.PBlock.getQuadPointer(); +01513 uint32 *pDstQuad= dstPBlock.getQuadPointer(); +01514 <font class="keywordflow">for</font>(;nIds>0;nIds--,pSrcQuad++,pDstQuad++) +01515 *pDstQuad= *pSrcQuad + baseVertex; +01516 } +01517 +01518 +01519 <font class="comment">// Render with the Materials of the MeshInstance.</font> +01520 drv->render(dstPBlock, material); +01521 } +01522 } +01523 +01524 <font class="comment">// Render Triangles with cache</font> +01525 <font class="comment">//===========</font> +01526 <font class="keywordflow">for</font>(uint i=0;i<lod.RdrPass.size();i++) +01527 { +01528 CRdrPass &rdrPass= lod.RdrPass[i]; +01529 +01530 <font class="comment">// CMaterial Ref</font> +01531 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +01532 +01533 <font class="comment">// Get the shifted triangles.</font> +01534 CShiftedTriangleCache::CRdrPass &shiftedRdrPass= mi->_ShiftedTriangleCache->RdrPass[i]; +01535 +01536 <font class="comment">// This speed up 4 ms for 80K polys.</font> +01537 uint memToCache= shiftedRdrPass.NumTriangles*12; +01538 memToCache= <a class="code" href="bit__set_8cpp.html#a0">min</a>(memToCache, 4096U); +01539 CFastMem::precache(shiftedRdrPass.Triangles, memToCache); +01540 +01541 <font class="comment">// Render with the Materials of the MeshInstance.</font> +01542 drv->renderTriangles(material, shiftedRdrPass.Triangles, shiftedRdrPass.NumTriangles); +01543 } +01544 } +01545 +01546 +01547 <font class="comment">// ***************************************************************************</font> +<a name="l01548"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c21">01548</a> <font class="keywordtype">void</font> CMeshMRMGeom::updateShiftedTriangleCache(CMeshMRMInstance *mi, sint curLodId, uint baseVertex) +01549 { +01550 <font class="comment">// if the instance has a cache, but not sync to us, delete it.</font> +01551 <font class="keywordflow">if</font>( mi->_ShiftedTriangleCache && ( +01552 mi->_ShiftedTriangleCache->MeshDataId != <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_13">_MeshDataId</a> || +01553 mi->_ShiftedTriangleCache->LodId != curLodId || +01554 mi->_ShiftedTriangleCache->BaseVertex != baseVertex) ) +01555 { +01556 mi->clearShiftedTriangleCache(); +01557 } +01558 +01559 <font class="comment">// If the instance has not a valid cache, must create it.</font> +01560 <font class="keywordflow">if</font>( !mi->_ShiftedTriangleCache ) +01561 { +01562 mi->_ShiftedTriangleCache= <font class="keyword">new</font> CShiftedTriangleCache; +01563 <font class="comment">// Fill the cache Key.</font> +01564 mi->_ShiftedTriangleCache->MeshDataId= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_13">_MeshDataId</a>; +01565 mi->_ShiftedTriangleCache->LodId= curLodId; +01566 mi->_ShiftedTriangleCache->BaseVertex= baseVertex; +01567 +01568 <font class="comment">// Default.</font> +01569 mi->_ShiftedTriangleCache->HasQuadOrLine= <font class="keyword">false</font>; +01570 +01571 <font class="comment">// Build RdrPass</font> +01572 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &lod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[curLodId]; +01573 mi->_ShiftedTriangleCache->RdrPass.resize(lod.RdrPass.size()); +01574 +01575 <font class="comment">// First pass, count number of triangles, and fill header info</font> +01576 uint totalTri= 0; +01577 uint i; +01578 <font class="keywordflow">for</font>(i=0;i<lod.RdrPass.size();i++) +01579 { +01580 CRdrPass &srcRdrPass= lod.RdrPass[i]; +01581 mi->_ShiftedTriangleCache->RdrPass[i].NumTriangles= srcRdrPass.PBlock.getNumTri(); +01582 totalTri+= srcRdrPass.PBlock.getNumTri(); +01583 <font class="comment">// Has quad or line??</font> +01584 <font class="keywordflow">if</font>( srcRdrPass.PBlock.getNumQuad() || srcRdrPass.PBlock.getNumLine() ) +01585 <font class="comment">// Yes => must inform the cache</font> +01586 mi->_ShiftedTriangleCache->HasQuadOrLine= <font class="keyword">true</font>; +01587 } +01588 +01589 <font class="comment">// Allocate triangles indices.</font> +01590 mi->_ShiftedTriangleCache->RawIndices.resize(totalTri*3); +01591 uint32 *rawPtr= mi->_ShiftedTriangleCache->RawIndices.getPtr(); +01592 +01593 <font class="comment">// Second pass, fill ptrs, and fill Arrays</font> +01594 uint indexTri= 0; +01595 <font class="keywordflow">for</font>(i=0;i<lod.RdrPass.size();i++) +01596 { +01597 CRdrPass &srcRdrPass= lod.RdrPass[i]; +01598 CShiftedTriangleCache::CRdrPass &dstRdrPass= mi->_ShiftedTriangleCache->RdrPass[i]; +01599 dstRdrPass.Triangles= rawPtr + indexTri*3; +01600 +01601 <font class="comment">// Fill the array</font> +01602 uint numTris= srcRdrPass.PBlock.getNumTri(); +01603 <font class="keywordflow">if</font>(numTris) +01604 { +01605 uint nIds= numTris*3; +01606 <font class="comment">// index, and fill</font> +01607 uint32 *pSrcTri= srcRdrPass.PBlock.getTriPointer(); +01608 uint32 *pDstTri= dstRdrPass.Triangles; +01609 <font class="keywordflow">for</font>(;nIds>0;nIds--,pSrcTri++,pDstTri++) +01610 *pDstTri= *pSrcTri + baseVertex; +01611 } +01612 +01613 <font class="comment">// Next</font> +01614 indexTri+= dstRdrPass.NumTriangles; +01615 } +01616 } +01617 } +01618 +01619 +01620 <font class="comment">// ***************************************************************************</font> +<a name="l01621"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z589_5">01621</a> <font class="keywordtype">void</font> CMeshMRMGeom::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +01622 { +01623 <font class="comment">// because of complexity, serial is separated in save / load.</font> +01624 +01625 <font class="keywordflow">if</font>(f.isReading()) +01626 load(f); +01627 <font class="keywordflow">else</font> +01628 save(f); +01629 +01630 } +01631 +01632 +01633 +01634 <font class="comment">// ***************************************************************************</font> +<a name="l01635"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c16">01635</a> sint CMeshMRMGeom::loadHeader(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +01636 { +01637 <font class="comment">/*</font> +01638 <font class="comment"> Version 4:</font> +01639 <font class="comment"> - serial SkinWeights per MRM, not per Lod</font> +01640 <font class="comment"> Version 3:</font> +01641 <font class="comment"> - Bones names.</font> +01642 <font class="comment"> Version 2:</font> +01643 <font class="comment"> - Mesh Vertex Program.</font> +01644 <font class="comment"> Version 1:</font> +01645 <font class="comment"> - added blend shapes</font> +01646 <font class="comment"> Version 0:</font> +01647 <font class="comment"> - base version.</font> +01648 <font class="comment"> */</font> +01649 sint ver= f.serialVersion(4); +01650 +01651 <font class="comment">// if >= version 3, serial boens names</font> +01652 <font class="keywordflow">if</font>(ver>=3) +01653 { +01654 f.serialCont (_BonesName); +01655 } +01656 +01657 <font class="comment">// Version3-: Bones index are in skeleton model id list</font> +01658 _BoneIdComputed = (ver < 3); +01659 <font class="comment">// Must always recompute usage of parents of bones used.</font> +01660 _BoneIdExtended = <font class="keyword">false</font>; +01661 +01662 <font class="comment">// Mesh Vertex Program.</font> +01663 <font class="keywordflow">if</font> (ver >= 2) +01664 { +01665 IMeshVertexProgram *mvp= NULL; +01666 f.serialPolyPtr(mvp); +01667 _MeshVertexProgram= mvp; +01668 } +01669 <font class="keywordflow">else</font> +01670 { +01671 <font class="comment">// release vp</font> +01672 _MeshVertexProgram= NULL; +01673 } +01674 +01675 <font class="comment">// blend shapes</font> +01676 <font class="keywordflow">if</font> (ver >= 1) +01677 f.serial (_MeshMorpher); +01678 +01679 <font class="comment">// serial Basic info.</font> +01680 <font class="comment">// ==================</font> +01681 f.serial(_Skinned); +01682 f.serial(_BBox); +01683 f.serial(_LevelDetail.MaxFaceUsed); +01684 f.serial(_LevelDetail.MinFaceUsed); +01685 f.serial(_LevelDetail.DistanceFinest); +01686 f.serial(_LevelDetail.DistanceMiddle); +01687 f.serial(_LevelDetail.DistanceCoarsest); +01688 f.serial(_LevelDetail.OODistanceDelta); +01689 f.serial(_LevelDetail.DistancePow); +01690 <font class="comment">// preload the Lods.</font> +01691 f.serialCont(_LodInfos); +01692 +01693 <font class="comment">// read/save number of wedges.</font> +01694 <font class="comment">/* NB: prepare memory space too for vertices.</font> +01695 <font class="comment"> \todo yoyo: TODO_OPTIMIZE. for now there is no Lod memory profit with vertices / skinWeights.</font> +01696 <font class="comment"> But resizing arrays is a problem because of reallocation...</font> +01697 <font class="comment"> */</font> +01698 uint32 nWedges; +01699 f.serial(nWedges); +01700 <font class="comment">// Prepare the VBuffer.</font> +01701 _VBufferFinal.serialHeader(f); +01702 <font class="comment">// If skinned, must allocate skinWeights.</font> +01703 <a class="code" href="namespaceNLMISC.html#a222">contReset</a>(_SkinWeights); +01704 <font class="keywordflow">if</font>(_Skinned) +01705 { +01706 _SkinWeights.resize(nWedges); +01707 } +01708 +01709 +01710 <font class="comment">// If new version, serial SkinWeights in header, not in lods.</font> +01711 <font class="keywordflow">if</font>(ver >= 4) +01712 { +01713 f.serialCont(_SkinWeights); +01714 } +01715 +01716 +01717 <font class="comment">// Serial lod offsets.</font> +01718 <font class="comment">// ==================</font> +01719 <font class="comment">// This is the reference pos, to load / save relative offsets.</font> +01720 sint32 startPos = f.getPos(); +01721 <font class="comment">// Those are the lodOffsets, relative to startPos.</font> +01722 vector<sint32> lodOffsets; +01723 lodOffsets.resize(_LodInfos.size(), 0); +01724 +01725 <font class="comment">// read all relative offsets, and build the absolute offset of LodInfos.</font> +01726 <font class="keywordflow">for</font>(uint i=0;i<_LodInfos.size(); i++) +01727 { +01728 f.serial(lodOffsets[i]); +01729 _LodInfos[i].LodOffset= startPos + lodOffsets[i]; +01730 } +01731 +01732 +01733 <font class="comment">// resest the Lod arrays. NB: each Lod is empty, and ready to receive Lod data.</font> +01734 <font class="comment">// ==================</font> +01735 <a class="code" href="namespaceNLMISC.html#a222">contReset</a>(_Lods); +01736 _Lods.resize(_LodInfos.size()); +01737 +01738 <font class="comment">// Flag the fact that no lod is loaded for now.</font> +01739 _NbLodLoaded= 0; +01740 +01741 <font class="comment">// Inform that the mesh data has changed</font> +01742 dirtMeshDataId(); +01743 +01744 +01745 <font class="comment">// Some runtime not serialized compilation</font> +01746 compileRunTime(); +01747 +01748 <font class="comment">// return version of the header</font> +01749 <font class="keywordflow">return</font> ver; +01750 } +01751 +01752 +01753 <font class="comment">// ***************************************************************************</font> +<a name="l01754"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c17">01754</a> <font class="keywordtype">void</font> CMeshMRMGeom::load(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +01755 { +01756 +01757 <font class="comment">// because loading, flag the VertexBufferHard.</font> +01758 _VertexBufferHardDirty= <font class="keyword">true</font>; +01759 +01760 +01761 <font class="comment">// Load the header of the stream.</font> +01762 <font class="comment">// ==================</font> +01763 sint verHeader= loadHeader(f); +01764 +01765 <font class="comment">// Read All lod subsets.</font> +01766 <font class="comment">// ==================</font> +01767 <font class="keywordflow">for</font>(uint i=0;i<_LodInfos.size(); i++) +01768 { +01769 <font class="comment">// read the lod face data.</font> +01770 f.serial(_Lods[i]); +01771 <font class="comment">// read the lod vertex data.</font> +01772 serialLodVertexData(f, _LodInfos[i].StartAddWedge, _LodInfos[i].EndAddWedges); +01773 <font class="comment">// if reading, must bkup all original vertices from VB.</font> +01774 <font class="comment">// this is done in serialLodVertexData(). by subset</font> +01775 } +01776 +01777 <font class="comment">// Now, all lods are loaded.</font> +01778 _NbLodLoaded= _Lods.size(); +01779 +01780 <font class="comment">// If version doen't have boneNames, must build BoneId now.</font> +01781 <font class="keywordflow">if</font>(verHeader <= 2) +01782 { +01783 buildBoneUsageVer2 (); +01784 } +01785 } +01786 +01787 +01788 <font class="comment">// ***************************************************************************</font> +<a name="l01789"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c18">01789</a> <font class="keywordtype">void</font> CMeshMRMGeom::save(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +01790 { +01791 <font class="comment">/*</font> +01792 <font class="comment"> Version 4:</font> +01793 <font class="comment"> - serial SkinWeights per MRM, not per Lod</font> +01794 <font class="comment"> Version 3:</font> +01795 <font class="comment"> - Bones names.</font> +01796 <font class="comment"> Version 2:</font> +01797 <font class="comment"> - Mesh Vertex Program.</font> +01798 <font class="comment"> Version 1:</font> +01799 <font class="comment"> - added blend shapes</font> +01800 <font class="comment"> Version 0:</font> +01801 <font class="comment"> - base version.</font> +01802 <font class="comment"> */</font> +01803 sint ver= f.serialVersion(4); +01804 uint i; +01805 +01806 <font class="comment">// if >= version 3, serial bones names</font> +01807 f.serialCont (_BonesName); +01808 +01809 <font class="comment">// Warning, if you have skinned this shape, you can't write it anymore because skinning id have been changed! </font> +01810 <a class="code" href="debug_8h.html#a6">nlassert</a> (_BoneIdComputed==<font class="keyword">false</font>); +01811 +01812 <font class="comment">// Mesh Vertex Program.</font> +01813 <font class="keywordflow">if</font> (ver >= 2) +01814 { +01815 IMeshVertexProgram *mvp= NULL; +01816 mvp= _MeshVertexProgram; +01817 f.serialPolyPtr(mvp); +01818 } +01819 +01820 <font class="comment">// blend shapes</font> +01821 <font class="keywordflow">if</font> (ver >= 1) +01822 f.serial (_MeshMorpher); +01823 +01824 <font class="comment">// must have good original Skinned Vertex before writing.</font> +01825 <font class="keywordflow">if</font>( _Skinned ) +01826 { +01827 restoreOriginalSkinVertices(); +01828 } +01829 +01830 +01831 <font class="comment">// serial Basic info.</font> +01832 <font class="comment">// ==================</font> +01833 f.serial(_Skinned); +01834 f.serial(_BBox); +01835 f.serial(_LevelDetail.MaxFaceUsed); +01836 f.serial(_LevelDetail.MinFaceUsed); +01837 f.serial(_LevelDetail.DistanceFinest); +01838 f.serial(_LevelDetail.DistanceMiddle); +01839 f.serial(_LevelDetail.DistanceCoarsest); +01840 f.serial(_LevelDetail.OODistanceDelta); +01841 f.serial(_LevelDetail.DistancePow); +01842 f.serialCont(_LodInfos); +01843 +01844 <font class="comment">// save number of wedges.</font> +01845 uint32 nWedges; +01846 nWedges= _VBufferFinal.getNumVertices(); +01847 f.serial(nWedges); +01848 <font class="comment">// Save the VBuffer header.</font> +01849 _VBufferFinal.serialHeader(f); +01850 +01851 +01852 <font class="comment">// If new version, serial SkinWeights in header, not in lods.</font> +01853 <font class="keywordflow">if</font>(ver >= 4) +01854 { +01855 f.serialCont(_SkinWeights); +01856 } +01857 +01858 +01859 <font class="comment">// Serial lod offsets.</font> +01860 <font class="comment">// ==================</font> +01861 <font class="comment">// This is the reference pos, to load / save relative offsets.</font> +01862 sint32 startPos = f.getPos(); +01863 <font class="comment">// Those are the lodOffsets, relative to startPos.</font> +01864 vector<sint32> lodOffsets; +01865 lodOffsets.resize(_LodInfos.size(), 0); +01866 +01867 <font class="comment">// write all dummy offset. For now (since we don't know what to set), compute the offset of </font> +01868 <font class="comment">// the sint32 to come back in serial lod parts below.</font> +01869 <font class="keywordflow">for</font>(i=0;i<_LodInfos.size(); i++) +01870 { +01871 lodOffsets[i]= f.getPos(); +01872 f.serial(lodOffsets[i]); +01873 } +01874 +01875 <font class="comment">// Serial lod subsets.</font> +01876 <font class="comment">// ==================</font> +01877 +01878 <font class="comment">// Save all the lods.</font> +01879 <font class="keywordflow">for</font>(i=0;i<_LodInfos.size(); i++) +01880 { +01881 <font class="comment">// get current absolute position.</font> +01882 sint32 absCurPos= f.getPos(); +01883 +01884 <font class="comment">// come back to "relative lodOffset" absolute position in the stream. (temp stored in lodOffset[i]).</font> +01885 f.seek(lodOffsets[i], IStream::begin); +01886 +01887 <font class="comment">// write the relative position of the lod to the stream.</font> +01888 sint32 relCurPos= absCurPos - startPos; +01889 f.serial(relCurPos); +01890 +01891 <font class="comment">// come back to absCurPos, to save the lod.</font> +01892 f.seek(absCurPos, IStream::begin); +01893 +01894 <font class="comment">// And so now, save the lod.</font> +01895 <font class="comment">// write the lod face data.</font> +01896 f.serial(_Lods[i]); +01897 <font class="comment">// write the lod vertex data.</font> +01898 serialLodVertexData(f, _LodInfos[i].StartAddWedge, _LodInfos[i].EndAddWedges); +01899 } +01900 +01901 +01902 } +01903 +01904 +01905 +01906 <font class="comment">// ***************************************************************************</font> +<a name="l01907"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c0">01907</a> <font class="keywordtype">void</font> CMeshMRMGeom::serialLodVertexData(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f, uint startWedge, uint endWedge) +01908 { +01909 <font class="comment">/*</font> +01910 <font class="comment"> Version 1:</font> +01911 <font class="comment"> - serial SkinWeights per MRM, not per Lod</font> +01912 <font class="comment"> */</font> +01913 sint ver= f.<a class="code" href="classNLMISC_1_1IStream.html#a29">serialVersion</a>(1); +01914 +01915 <font class="comment">// VBuffer part.</font> +01916 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.serialSubset(f, startWedge, endWedge); +01917 +01918 <font class="comment">// SkinWeights.</font> +01919 <font class="keywordflow">if</font>(_Skinned) +01920 { +01921 <font class="comment">// Serialize SkinWeight per lod only for old versions.</font> +01922 <font class="keywordflow">if</font>(ver<1) +01923 { +01924 <font class="keywordflow">for</font>(uint i= startWedge; i<endWedge; i++) +01925 { +01926 f.<a class="code" href="classNLMISC_1_1IStream.html#a5">serial</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[i]); +01927 } +01928 } +01929 <font class="comment">// if reading, must copy original vertices from VB.</font> +01930 <font class="keywordflow">if</font>( f.<a class="code" href="classNLMISC_1_1IStream.html#a4">isReading</a>()) +01931 { +01932 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c6">bkupOriginalSkinVerticesSubset</a>(startWedge, endWedge); +01933 } +01934 } +01935 } +01936 +01937 +01938 +01939 <font class="comment">// ***************************************************************************</font> +<a name="l01940"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z590_1">01940</a> <font class="keywordtype">void</font> CMeshMRMGeom::loadFirstLod(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) +01941 { +01942 +01943 <font class="comment">// because loading, flag the VertexBufferHard.</font> +01944 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_5">_VertexBufferHardDirty</a>= <font class="keyword">true</font>; +01945 +01946 <font class="comment">// Load the header of the stream.</font> +01947 <font class="comment">// ==================</font> +01948 sint verHeader= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c16">loadHeader</a>(f); +01949 +01950 +01951 <font class="comment">// If empty MRM, quit.</font> +01952 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>.size()==0) +01953 <font class="keywordflow">return</font>; +01954 +01955 <font class="comment">/* If the version is <4, then SkinWeights are serialised per Lod.</font> +01956 <font class="comment"> But for computebonesId(), we must have all SkinWeights RIGHT NOW.</font> +01957 <font class="comment"> Hence, if too old version (<4), serialize all the MRM....</font> +01958 <font class="comment"> */</font> +01959 uint numLodToLoad; +01960 <font class="keywordflow">if</font>(verHeader<4) +01961 numLodToLoad= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>.size(); +01962 <font class="keywordflow">else</font> +01963 numLodToLoad= 1; +01964 +01965 +01966 <font class="comment">// Read lod subset(s).</font> +01967 <font class="comment">// ==================</font> +01968 <font class="keywordflow">for</font>(uint i=0;i<numLodToLoad; i++) +01969 { +01970 <font class="comment">// read the lod face data.</font> +01971 f.<a class="code" href="classNLMISC_1_1IStream.html#a5">serial</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[i]); +01972 <font class="comment">// read the lod vertex data.</font> +01973 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c0">serialLodVertexData</a>(f, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>[i].StartAddWedge, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>[i].EndAddWedges); +01974 <font class="comment">// if reading, must bkup all original vertices from VB.</font> +01975 <font class="comment">// this is done in serialLodVertexData(). by subset</font> +01976 } +01977 +01978 <font class="comment">// Now, just first lod is loaded (but if too old file)</font> +01979 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>= numLodToLoad; +01980 +01981 <font class="comment">// If version doen't have boneNames, must build BoneId now.</font> +01982 <font class="keywordflow">if</font>(verHeader <= 2) +01983 { +01984 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c19">buildBoneUsageVer2</a> (); +01985 } +01986 } +01987 +01988 +01989 <font class="comment">// ***************************************************************************</font> +<a name="l01990"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z590_2">01990</a> <font class="keywordtype">void</font> CMeshMRMGeom::loadNextLod(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) +01991 { +01992 +01993 <font class="comment">// because loading, flag the VertexBufferHard.</font> +01994 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_5">_VertexBufferHardDirty</a>= <font class="keyword">true</font>; +01995 +01996 <font class="comment">// If all is loaded, quit.</font> +01997 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z590_0">getNbLodLoaded</a>() == <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z591_4">getNbLod</a>()) +01998 <font class="keywordflow">return</font>; +01999 +02000 <font class="comment">// Set pos to good lod.</font> +02001 f.<a class="code" href="classNLMISC_1_1IStream.html#a31">seek</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>].LodOffset, IStream::begin); +02002 +02003 <font class="comment">// Serial this lod data.</font> +02004 <font class="comment">// read the lod face data.</font> +02005 f.<a class="code" href="classNLMISC_1_1IStream.html#a5">serial</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>]); +02006 <font class="comment">// read the lod vertex data.</font> +02007 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c0">serialLodVertexData</a>(f, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>].StartAddWedge, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o16">_LodInfos</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>].EndAddWedges); +02008 <font class="comment">// if reading, must bkup all original vertices from VB.</font> +02009 <font class="comment">// this is done in serialLodVertexData(). by subset</font> +02010 +02011 +02012 <font class="comment">// Inc LodLoaded count.</font> +02013 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>++; +02014 } +02015 +02016 +02017 <font class="comment">// ***************************************************************************</font> +<a name="l02018"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z590_3">02018</a> <font class="keywordtype">void</font> CMeshMRMGeom::unloadNextLod(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) +02019 { +02020 <font class="comment">// If just first lod remain (or no lod), quit</font> +02021 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z590_0">getNbLodLoaded</a>() <= 1) +02022 <font class="keywordflow">return</font>; +02023 +02024 <font class="comment">// Reset the entire Lod object. (Free Memory).</font> +02025 <a class="code" href="namespaceNLMISC.html#a222">contReset</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>-1]); +02026 +02027 +02028 <font class="comment">// Dec LodLoaded count.</font> +02029 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o17">_NbLodLoaded</a>--; +02030 } +02031 +02032 +02033 <font class="comment">// ***************************************************************************</font> +<a name="l02034"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c5">02034</a> <font class="keywordtype">void</font> CMeshMRMGeom::bkupOriginalSkinVertices() +02035 { +02036 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a>); +02037 +02038 <font class="comment">// bkup the entire array.</font> +02039 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c6">bkupOriginalSkinVerticesSubset</a>(0, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices()); +02040 } +02041 +02042 +02043 <font class="comment">// ***************************************************************************</font> +<a name="l02044"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c6">02044</a> <font class="keywordtype">void</font> CMeshMRMGeom::bkupOriginalSkinVerticesSubset(uint wedgeStart, uint wedgeEnd) +02045 { +02046 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a>); +02047 +02048 <font class="comment">// Copy VBuffer content into Original vertices normals.</font> +02049 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() & CVertexBuffer::PositionFlag) +02050 { +02051 <font class="comment">// copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).</font> +02052 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>.resize(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices()); +02053 <font class="keywordflow">for</font>(uint i=wedgeStart; i<wedgeEnd;i++) +02054 { +02055 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>[i]= *(CVector*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexCoordPointer(i); +02056 } +02057 } +02058 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() & CVertexBuffer::NormalFlag) +02059 { +02060 <font class="comment">// copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).</font> +02061 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>.resize(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices()); +02062 <font class="keywordflow">for</font>(uint i=wedgeStart; i<wedgeEnd;i++) +02063 { +02064 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>[i]= *(CVector*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNormalCoordPointer(i); +02065 } +02066 } +02067 +02068 <font class="comment">// is there tangent space added ?</font> +02069 <font class="keywordflow">if</font> (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->needTangentSpace()) +02070 { +02071 <font class="comment">// yes, backup it</font> +02072 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumTexCoordUsed() > 0); +02073 uint tgSpaceStage = <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumTexCoordUsed() - 1; +02074 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o3">_OriginalTGSpace</a>.resize(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices()); +02075 <font class="keywordflow">for</font>(uint i=wedgeStart; i<wedgeEnd;i++) +02076 { +02077 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o3">_OriginalTGSpace</a>[i]= *(CVector*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getTexCoordPointer(i, tgSpaceStage); +02078 } +02079 } +02080 } +02081 +02082 +02083 <font class="comment">// ***************************************************************************</font> +<a name="l02084"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c7">02084</a> <font class="keywordtype">void</font> CMeshMRMGeom::restoreOriginalSkinVertices() +02085 { +02086 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a>); +02087 +02088 <font class="comment">// Copy VBuffer content into Original vertices normals.</font> +02089 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() & CVertexBuffer::PositionFlag) +02090 { +02091 <font class="comment">// copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).</font> +02092 <font class="keywordflow">for</font>(uint i=0; i<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices();i++) +02093 { +02094 *(CVector*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexCoordPointer(i)= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>[i]; +02095 } +02096 } +02097 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() & CVertexBuffer::NormalFlag) +02098 { +02099 <font class="comment">// copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).</font> +02100 <font class="keywordflow">for</font>(uint i=0; i<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices();i++) +02101 { +02102 *(CVector*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNormalCoordPointer(i)= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>[i]; +02103 } +02104 } +02105 <font class="keywordflow">if</font> (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>->needTangentSpace()) +02106 { +02107 uint numTexCoords = <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumTexCoordUsed(); +02108 <a class="code" href="debug_8h.html#a6">nlassert</a>(numTexCoords >= 2); +02109 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o3">_OriginalTGSpace</a>.size() == <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices()); +02110 <font class="comment">// copy tangent space vectors</font> +02111 <font class="keywordflow">for</font>(uint i = 0; i < <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices(); ++i) +02112 { +02113 *(CVector*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getTexCoordPointer(i, numTexCoords - 1)= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o3">_OriginalTGSpace</a>[i]; +02114 } +02115 } +02116 } +02117 +02118 +02119 <font class="comment">// ***************************************************************************</font> +<a name="l02120"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c15">02120</a> <font class="keywordtype">void</font> CMeshMRMGeom::restoreOriginalSkinPart(CLod &lod, IVertexBufferHard *currentVBHard) +02121 { +02122 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a>); +02123 +02124 +02125 <font class="comment">/*</font> +02126 <font class="comment"> YOYO: _Skinned mrms no more support vertexBufferHard</font> +02127 <font class="comment"> see note in renderSkin()</font> +02128 <font class="comment"> */</font> +02129 +02130 <font class="comment">// get vertexPtr / normalOff.</font> +02131 <font class="comment">//===========================</font> +02132 uint8 *destVertexPtr= (uint8*)<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexCoordPointer(); +02133 uint flags= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat(); +02134 sint32 vertexSize= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexSize(); +02135 <font class="comment">// must have XYZ.</font> +02136 <a class="code" href="debug_8h.html#a6">nlassert</a>(flags & CVertexBuffer::PositionFlag); +02137 +02138 <font class="comment">// Compute offset of each component of the VB.</font> +02139 sint32 normalOff; +02140 <font class="keywordflow">if</font>(flags & CVertexBuffer::NormalFlag) +02141 normalOff= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNormalOff(); +02142 <font class="keywordflow">else</font> +02143 normalOff= 0; +02144 +02145 +02146 <font class="comment">// compute src array.</font> +02147 CVector *srcVertexPtr; +02148 CVector *srcNormalPtr= NULL; +02149 srcVertexPtr= &<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>[0]; +02150 <font class="keywordflow">if</font>(normalOff) +02151 srcNormalPtr= &(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>[0]); +02152 +02153 +02154 <font class="comment">// copy skinning.</font> +02155 <font class="comment">//===========================</font> +02156 <font class="keywordflow">for</font>(uint i=0;i<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;i++) +02157 { +02158 uint nInf= lod.InfluencedVertices[i].size(); +02159 <font class="keywordflow">if</font>( nInf==0 ) +02160 <font class="keywordflow">continue</font>; +02161 uint32 *infPtr= &(lod.InfluencedVertices[i][0]); +02162 +02163 <font class="comment">// for all InfluencedVertices only.</font> +02164 <font class="keywordflow">for</font>(;nInf>0;nInf--, infPtr++) +02165 { +02166 uint <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>= *infPtr; +02167 CVector *srcVertex= srcVertexPtr + <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>; +02168 CVector *srcNormal= srcNormalPtr + <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a>; +02169 uint8 *dstVertexVB= destVertexPtr + <a class="code" href="driver__opengl__extension__def_8h.html#a358">index</a> * vertexSize; +02170 CVector *dstVertex= (CVector*)(dstVertexVB); +02171 CVector *dstNormal= (CVector*)(dstVertexVB + normalOff); +02172 +02173 +02174 <font class="comment">// Vertex.</font> +02175 *dstVertex= *srcVertex; +02176 <font class="comment">// Normal.</font> +02177 <font class="keywordflow">if</font>(normalOff) +02178 *dstNormal= *srcNormal; +02179 } +02180 } +02181 +02182 +02183 <font class="comment">// clean this lod part. (NB: this is not optimal, but sufficient :) ).</font> +02184 lod.OriginalSkinRestored= <font class="keyword">true</font>; +02185 } +02186 +02187 <font class="comment">// ***************************************************************************</font> +02188 +<a name="l02189"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z589_4">02189</a> <font class="keywordtype">float</font> CMeshMRMGeom::getNumTriangles (<font class="keywordtype">float</font> distance) +02190 { +02191 <font class="comment">// NB: this is an approximation, but this is continious.</font> +02192 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z596_0">_LevelDetail</a>.getNumTriangles(distance); +02193 } +02194 +02195 +02196 +02197 <font class="comment">// ***************************************************************************</font> +<a name="l02198"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_1">02198</a> <font class="keywordtype">void</font> CMeshMRMGeom::deleteVertexBufferHard() +02199 { +02200 <font class="comment">// test (refptr) if the object still exist in memory.</font> +02201 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>!=NULL) +02202 { +02203 <font class="comment">// A vbufferhard should still exist only if driver still exist.</font> +02204 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>!=NULL); +02205 +02206 <font class="comment">// delete it from driver.</font> +02207 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>->deleteVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>); +02208 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>= NULL; +02209 } +02210 } +02211 +02212 <font class="comment">// ***************************************************************************</font> +<a name="l02213"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_0">02213</a> <font class="keywordtype">void</font> CMeshMRMGeom::updateVertexBufferHard(IDriver *drv, uint32 numVertices) +02214 { +02215 <font class="keywordflow">if</font>(!drv->supportVertexBufferHard() || numVertices==0) +02216 <font class="keywordflow">return</font>; +02217 +02218 +02228 <font class="keywordtype">bool</font> avoidVBHard; +02229 avoidVBHard= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a> || ( <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o18">_MeshMorpher</a>.BlendShapes.size()>0 && drv->slowUnlockVertexBufferHard() ); +02230 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_5">_VertexBufferHardDirty</a> && avoidVBHard ) +02231 { +02232 <font class="comment">// delete possible old VBHard.</font> +02233 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>!=NULL) +02234 { +02235 <font class="comment">// VertexBufferHard lifetime < Driver lifetime.</font> +02236 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>!=NULL); +02237 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>->deleteVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>); +02238 } +02239 <font class="keywordflow">return</font>; +02240 } +02241 +02242 +02243 <font class="comment">// If the vbufferhard is not here, or if dirty, or if do not have enough vertices.</font> +02244 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>==NULL || <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_5">_VertexBufferHardDirty</a> || <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>->getNumVertices() < numVertices) +02245 { +02246 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_5">_VertexBufferHardDirty</a>= <font class="keyword">false</font>; +02247 +02248 <font class="comment">// delete possible old _VBHard.</font> +02249 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>!=NULL) +02250 { +02251 <font class="comment">// VertexBufferHard lifetime < Driver lifetime.</font> +02252 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>!=NULL); +02253 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>->deleteVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>); +02254 } +02255 +02256 <font class="comment">// bkup drv in a refptr. (so we know if the vbuffer hard has to be deleted).</font> +02257 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>= drv; +02258 <font class="comment">// try to create new one, in AGP Ram</font> +02259 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_4">_Driver</a>->createVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat(), <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getValueTypePointer (), numVertices, IDriver::VBHardAGP); +02260 +02261 +02262 <font class="comment">// If KO, use normal VertexBuffer, else, Fill it with VertexBuffer.</font> +02263 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>!=NULL) +02264 { +02265 <font class="keywordtype">void</font> *vertexPtr= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>->lock(); +02266 +02267 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() == <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>->getVertexFormat()); +02268 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices() >= numVertices); +02269 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexSize() == <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>->getVertexSize()); +02270 +02271 <font class="comment">// \todo yoyo: TODO_DX8 and DX8 ???</font> +02272 <font class="comment">// Because same internal format, just copy all block.</font> +02273 memcpy(vertexPtr, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexCoordPointer(), numVertices * <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexSize() ); +02274 +02275 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_3">_VBHard</a>->unlock(); +02276 } +02277 } +02278 +02279 } +02280 +02281 <font class="comment">// ***************************************************************************</font> +<a name="l02282"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z592_1">02282</a> <font class="keywordtype">void</font> CMeshMRMGeom::computeBonesId (CSkeletonModel *skeleton) +02283 { +02284 <font class="comment">// Already computed ?</font> +02285 <font class="keywordflow">if</font> (!<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o7">_BoneIdComputed</a>) +02286 { +02287 <font class="comment">// Get a pointer on the skeleton</font> +02288 <a class="code" href="debug_8h.html#a6">nlassert</a> (skeleton); +02289 <font class="keywordflow">if</font> (skeleton) +02290 { +02291 <font class="comment">// Resize boneId to the good size.</font> +02292 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o12">_BonesId</a>.resize(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o11">_BonesName</a>.size()); +02293 +02294 <font class="comment">// Remap bones id table</font> +02295 std::vector<uint> remap (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o11">_BonesName</a>.size()); +02296 +02297 <font class="comment">// For each bones</font> +02298 uint bone; +02299 <font class="keywordflow">for</font> (bone=0; bone<remap.size(); bone++) +02300 { +02301 <font class="comment">// Look for the bone</font> +02302 sint32 boneId = skeleton->getBoneIdByName (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o11">_BonesName</a>[bone]); +02303 +02304 <font class="comment">// Setup the _BoneId.</font> +02305 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o12">_BonesId</a>[bone]= boneId; +02306 +02307 <font class="comment">// Bones found ?</font> +02308 <font class="keywordflow">if</font> (boneId != -1) +02309 { +02310 <font class="comment">// Set the bone id</font> +02311 remap[bone] = (uint32)boneId; +02312 } +02313 <font class="keywordflow">else</font> +02314 { +02315 <font class="comment">// Put id 0</font> +02316 remap[bone] = 0; +02317 +02318 <font class="comment">// Error</font> +02319 <a class="code" href="debug_8h.html#a2">nlwarning</a> (<font class="stringliteral">"Bone %s not found in the skeleton."</font>, <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o11">_BonesName</a>[bone].c_str()); +02320 } +02321 } +02322 +02323 <font class="comment">// Remap the vertex</font> +02324 uint vert; +02325 <font class="keywordflow">for</font> (vert=0; vert<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>.size(); vert++) +02326 { +02327 <font class="comment">// For each weight</font> +02328 uint weight; +02329 <font class="keywordflow">for</font> (weight=0; weight<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; weight++) +02330 { +02331 <font class="comment">// Active ?</font> +02332 <font class="keywordflow">if</font> ((<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].Weights[weight]>0)||(weight==0)) +02333 { +02334 <font class="comment">// Check id</font> +02335 <a class="code" href="debug_8h.html#a6">nlassert</a> (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight] < remap.size()); +02336 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight] = remap[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight]]; +02337 } +02338 } +02339 } +02340 +02341 <font class="comment">// Remap the vertex influence by lods</font> +02342 uint lod; +02343 <font class="keywordflow">for</font> (lod=0; lod<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size(); lod++) +02344 { +02345 <font class="comment">// For each matrix used</font> +02346 uint <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>; +02347 <font class="keywordflow">for</font> (<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>=0; <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a><<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].MatrixInfluences.size(); <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>++) +02348 { +02349 <font class="comment">// Check</font> +02350 <a class="code" href="debug_8h.html#a6">nlassert</a> (<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].MatrixInfluences[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]<remap.size()); +02351 +02352 <font class="comment">// Remap</font> +02353 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].MatrixInfluences[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>] = remap[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[lod].MatrixInfluences[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]]; +02354 } +02355 } +02356 +02357 <font class="comment">// Computed</font> +02358 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o7">_BoneIdComputed</a> = <font class="keyword">true</font>; +02359 } +02360 } +02361 +02362 <font class="comment">// Already extended ?</font> +02363 <font class="keywordflow">if</font> (!<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o8">_BoneIdExtended</a>) +02364 { +02365 <a class="code" href="debug_8h.html#a6">nlassert</a> (skeleton); +02366 <font class="keywordflow">if</font> (skeleton) +02367 { +02368 <font class="comment">// the total bone Usage of the mesh.</font> +02369 vector<bool> boneUsage; +02370 boneUsage.resize(skeleton->Bones.size(), <font class="keyword">false</font>); +02371 +02372 <font class="comment">// for all Bones marked as valid.</font> +02373 uint i; +02374 <font class="keywordflow">for</font>(i=0; i<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o12">_BonesId</a>.size(); i++) +02375 { +02376 <font class="comment">// if not a valid boneId, skip it.</font> +02377 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o12">_BonesId</a>[i]<0) +02378 <font class="keywordflow">continue</font>; +02379 +02380 <font class="comment">// mark him and his father in boneUsage.</font> +02381 skeleton->flagBoneAndParents(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o12">_BonesId</a>[i], boneUsage); +02382 } +02383 +02384 <font class="comment">// fill _BonesIdExt with bones of _BonesId and their parents.</font> +02385 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o13">_BonesIdExt</a>.clear(); +02386 <font class="keywordflow">for</font>(i=0; i<boneUsage.size();i++) +02387 { +02388 <font class="comment">// if the bone is used by the mesh, add it to BoneIdExt.</font> +02389 <font class="keywordflow">if</font>(boneUsage[i]) +02390 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o13">_BonesIdExt</a>.push_back(i); +02391 } +02392 +02393 } +02394 +02395 <font class="comment">// Extended</font> +02396 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o8">_BoneIdExtended</a>= <font class="keyword">true</font>; +02397 } +02398 +02399 } +02400 +02401 +02402 <font class="comment">// ***************************************************************************</font> +<a name="l02403"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c19">02403</a> <font class="keywordtype">void</font> CMeshMRMGeom::buildBoneUsageVer2 () +02404 { +02405 <font class="keywordflow">if</font>(_Skinned) +02406 { +02407 <font class="comment">// parse all vertices, couting MaxBoneId used.</font> +02408 uint32 maxBoneId= 0; +02409 <font class="comment">// for each vertex</font> +02410 uint vert; +02411 <font class="keywordflow">for</font> (vert=0; vert<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>.size(); vert++) +02412 { +02413 <font class="comment">// For each weight</font> +02414 <font class="keywordflow">for</font> (uint weight=0; weight<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; weight++) +02415 { +02416 <font class="comment">// Active ?</font> +02417 <font class="keywordflow">if</font> ((<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].Weights[weight]>0)||(weight==0)) +02418 { +02419 maxBoneId= max(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight], maxBoneId); +02420 } +02421 } +02422 } +02423 +02424 <font class="comment">// alloc an array of maxBoneId+1, reset to 0.</font> +02425 std::vector<uint8> boneUsage; +02426 boneUsage.resize(maxBoneId+1, 0); +02427 +02428 <font class="comment">// reparse all vertices, counting usage for each bone.</font> +02429 <font class="keywordflow">for</font> (vert=0; vert<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>.size(); vert++) +02430 { +02431 <font class="comment">// For each weight</font> +02432 <font class="keywordflow">for</font> (uint weight=0; weight<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>; weight++) +02433 { +02434 <font class="comment">// Active ?</font> +02435 <font class="keywordflow">if</font> ((<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].Weights[weight]>0)||(weight==0)) +02436 { +02437 <font class="comment">// mark this bone as used.</font> +02438 boneUsage[<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vert].MatrixId[weight]]= 1; +02439 } +02440 } +02441 } +02442 +02443 <font class="comment">// For each bone used</font> +02444 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o12">_BonesId</a>.clear(); +02445 <font class="keywordflow">for</font>(uint i=0; i<boneUsage.size();i++) +02446 { +02447 <font class="comment">// if the bone is used by the mesh, add it to BoneId.</font> +02448 <font class="keywordflow">if</font>(boneUsage[i]) +02449 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o12">_BonesId</a>.push_back(i); +02450 } +02451 } +02452 } +02453 +02454 +02455 <font class="comment">// ***************************************************************************</font> +<a name="l02456"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z592_2">02456</a> <font class="keywordtype">void</font> CMeshMRMGeom::updateSkeletonUsage(CSkeletonModel *sm, <font class="keywordtype">bool</font> increment) +02457 { +02458 <font class="comment">// For all Bones used.</font> +02459 <font class="keywordflow">for</font>(uint i=0; i<<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o13">_BonesIdExt</a>.size();i++) +02460 { +02461 uint boneId= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o13">_BonesIdExt</a>[i]; +02462 <font class="comment">// Some explicit Error.</font> +02463 <font class="keywordflow">if</font>(boneId>=sm->Bones.size()) +02464 <a class="code" href="debug_8h.html#a3">nlerror</a>(<font class="stringliteral">" Skin is incompatible with Skeleton: tries to use bone %d"</font>, boneId); +02465 <font class="comment">// increment or decrement not Forced, because CMeshGeom use getActiveBoneSkinMatrix().</font> +02466 <font class="keywordflow">if</font>(increment) +02467 sm->incBoneUsage(boneId, CSkeletonModel::UsageNormal); +02468 <font class="keywordflow">else</font> +02469 sm->decBoneUsage(boneId, CSkeletonModel::UsageNormal); +02470 } +02471 } +02472 +02473 +02474 <font class="comment">// ***************************************************************************</font> +<a name="l02475"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#c20">02475</a> <font class="keywordtype">void</font> CMeshMRMGeom::compileRunTime() +02476 { +02477 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z597_6">_PreciseClipping</a>= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o15">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z268_5">getRadius</a>() >= <a class="code" href="mesh_8h.html#a1">NL3D_MESH_PRECISE_CLIP_THRESHOLD</a>; +02478 +02479 <font class="comment">// Compute if can support SkinGrouping rendering</font> +02480 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>.size()==0 || !<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o0">_Skinned</a>) +02481 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o9">_SupportSkinGrouping</a>= <font class="keyword">false</font>; +02482 <font class="keywordflow">else</font> +02483 { +02484 <font class="comment">// The Mesh must follow thos restrictions, to support group skinning</font> +02485 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o9">_SupportSkinGrouping</a>= +02486 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getVertexFormat() == <a class="code" href="render__trav_8h.html#a0">NL3D_MESH_SKIN_MANAGER_VERTEXFORMAT</a> && +02487 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o5">_VBufferFinal</a>.getNumVertices() < <a class="code" href="render__trav_8h.html#a1">NL3D_MESH_SKIN_MANAGER_MAXVERTICES</a> && +02488 !<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o19">_MeshVertexProgram</a>; +02489 } +02490 +02491 } +02492 +02493 +02494 <font class="comment">// ***************************************************************************</font> +02495 <font class="comment">// ***************************************************************************</font> +02496 <font class="comment">// Mesh Block Render Interface</font> +02497 <font class="comment">// ***************************************************************************</font> +02498 <font class="comment">// ***************************************************************************</font> +02499 +02500 +02501 <font class="comment">// ***************************************************************************</font> +<a name="l02502"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z593_0">02502</a> <font class="keywordtype">bool</font> CMeshMRMGeom::supportMeshBlockRendering ()<font class="keyword"> const</font> +02503 <font class="keyword"></font>{ +02504 <font class="comment">// \todo yoyo: TODO_OPTIMIZE support MeshBlockRendering with MRM</font> +02505 <font class="keywordflow">return</font> <font class="keyword">false</font>; +02506 } +02507 +02508 <font class="comment">// ***************************************************************************</font> +<a name="l02509"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z593_1">02509</a> <font class="keywordtype">bool</font> CMeshMRMGeom::sortPerMaterial()<font class="keyword"> const</font> +02510 <font class="keyword"></font>{ +02511 <font class="keywordflow">return</font> <font class="keyword">false</font>; +02512 } +02513 <font class="comment">// ***************************************************************************</font> +<a name="l02514"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z593_2">02514</a> uint CMeshMRMGeom::getNumRdrPasses()<font class="keyword"> const </font> +02515 <font class="keyword"></font>{ +02516 <font class="keywordflow">return</font> 0; +02517 } +02518 <font class="comment">// ***************************************************************************</font> +<a name="l02519"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z593_3">02519</a> <font class="keywordtype">void</font> CMeshMRMGeom::beginMesh(CMeshGeomRenderContext &rdrCtx) +02520 { +02521 } +02522 <font class="comment">// ***************************************************************************</font> +<a name="l02523"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z593_4">02523</a> <font class="keywordtype">void</font> CMeshMRMGeom::activeInstance(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, <font class="keywordtype">float</font> polygonCount) +02524 { +02525 } +02526 <font class="comment">// ***************************************************************************</font> +<a name="l02527"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z593_5">02527</a> <font class="keywordtype">void</font> CMeshMRMGeom::renderPass(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *mi, <font class="keywordtype">float</font> polygonCount, uint rdrPassId) +02528 { +02529 } +02530 <font class="comment">// ***************************************************************************</font> +<a name="l02531"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z593_6">02531</a> <font class="keywordtype">void</font> CMeshMRMGeom::endMesh(CMeshGeomRenderContext &rdrCtx) +02532 { +02533 } +02534 +02535 +02536 <font class="comment">// ***************************************************************************</font> +02537 <font class="comment">// ***************************************************************************</font> +02538 <font class="comment">// CMeshMRM.</font> +02539 <font class="comment">// ***************************************************************************</font> +02540 <font class="comment">// ***************************************************************************</font> +02541 +02542 +02543 +02544 <font class="comment">// ***************************************************************************</font> +<a name="l02545"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#a0">02545</a> CMeshMRM::CMeshMRM() +02546 { +02547 } +02548 <font class="comment">// ***************************************************************************</font> +<a name="l02549"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#a1">02549</a> <font class="keywordtype">void</font> CMeshMRM::build (CMeshBase::CMeshBaseBuild &mBase, CMesh::CMeshBuild &m, +02550 std::vector<CMesh::CMeshBuild*> &listBS, +02551 <font class="keyword">const</font> CMRMParameters &<a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>) +02552 { +02554 CMeshBase::buildMeshBase (mBase); +02555 +02556 <font class="comment">// Then build the geom.</font> +02557 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.build (m, listBS, mBase.Materials.size(), <a class="code" href="driver__opengl__extension__def_8h.html#a357">params</a>); +02558 } +02559 <font class="comment">// ***************************************************************************</font> +<a name="l02560"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#a2">02560</a> <font class="keywordtype">void</font> CMeshMRM::build (CMeshBase::CMeshBaseBuild &m, <font class="keyword">const</font> CMeshMRMGeom &mgeom) +02561 { +02563 CMeshBase::buildMeshBase(m); +02564 +02565 <font class="comment">// Then copy the geom.</font> +02566 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>= mgeom; +02567 } +02568 +02569 +02570 <font class="comment">// ***************************************************************************</font> +<a name="l02571"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#a3">02571</a> <font class="keywordtype">void</font> CMeshMRM::optimizeMaterialUsage(std::vector<sint> &remap) +02572 { +02573 <font class="comment">// For each material, count usage.</font> +02574 vector<bool> materialUsed; +02575 materialUsed.resize(CMeshBase::_Materials.<a class="code" href="cf__lexical_8cpp.html#a94">size</a>(), <font class="keyword">false</font>); +02576 <font class="keywordflow">for</font>(uint lod=0;lod<<a class="code" href="classNL3D_1_1CMeshMRM.html#z601_2">getNbLod</a>();lod++) +02577 { +02578 <font class="keywordflow">for</font>(uint rp=0;rp<<a class="code" href="classNL3D_1_1CMeshMRM.html#z601_3">getNbRdrPass</a>(lod);rp++) +02579 { +02580 uint matId= <a class="code" href="classNL3D_1_1CMeshMRM.html#z601_5">getRdrPassMaterial</a>(lod, rp); +02581 <font class="comment">// flag as used.</font> +02582 materialUsed[matId]= <font class="keyword">true</font>; +02583 } +02584 } +02585 +02586 <font class="comment">// Apply it to meshBase</font> +02587 CMeshBase::applyMaterialUsageOptim(materialUsed, remap); +02588 +02589 <font class="comment">// Apply lut to meshGeom.</font> +02590 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.applyMaterialRemap(remap); +02591 } +02592 +02593 +02594 <font class="comment">// ***************************************************************************</font> +<a name="l02595"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#z600_0">02595</a> CTransformShape *CMeshMRM::createInstance(CScene &scene) +02596 { +02597 <font class="comment">// Create a CMeshMRMInstance, an instance of a mesh.</font> +02598 <font class="comment">//===============================================</font> +02599 CMeshMRMInstance *mi= (CMeshMRMInstance*)scene.createModel(NL3D::MeshMRMInstanceId); +02600 mi->Shape= <font class="keyword">this</font>; +02601 +02602 +02603 <font class="comment">// instanciate the material part of the MeshMRM, ie the CMeshBase.</font> +02604 CMeshBase::instanciateMeshBase(mi, &scene); +02605 +02606 +02607 <font class="comment">// do some instance init for MeshGeom</font> +02608 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.initInstance(mi); +02609 +02610 <font class="keywordflow">return</font> mi; +02611 } +02612 +02613 +02614 <font class="comment">// ***************************************************************************</font> +<a name="l02615"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#z600_1">02615</a> <font class="keywordtype">bool</font> CMeshMRM::clip(<font class="keyword">const</font> std::vector<CPlane> &pyramid, <font class="keyword">const</font> CMatrix &worldMatrix) +02616 { +02617 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.clip(pyramid, worldMatrix); +02618 } +02619 +02620 +02621 <font class="comment">// ***************************************************************************</font> +<a name="l02622"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#z600_2">02622</a> <font class="keywordtype">void</font> CMeshMRM::render(IDriver *drv, CTransformShape *trans, <font class="keywordtype">bool</font> passOpaque) +02623 { +02624 <font class="comment">// 0 or 0xFFFFFFFF</font> +02625 uint32 mask= (0-(uint32)passOpaque); +02626 uint32 rdrFlags; +02627 <font class="comment">// select rdrFlags, without ifs.</font> +02628 rdrFlags= mask & (IMeshGeom::RenderOpaqueMaterial | IMeshGeom::RenderPassOpaque); +02629 rdrFlags|= ~mask & (IMeshGeom::RenderTransparentMaterial); +02630 <font class="comment">// render the mesh</font> +02631 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.render(drv, trans, trans->getNumTrianglesAfterLoadBalancing(), rdrFlags, 1); +02632 } +02633 +02634 +02635 <font class="comment">// ***************************************************************************</font> +<a name="l02636"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#z600_4">02636</a> <font class="keywordtype">void</font> CMeshMRM::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +02637 { +02638 <font class="comment">/*</font> +02639 <font class="comment"> Version 0:</font> +02640 <font class="comment"> - base version.</font> +02641 <font class="comment"> */</font> +02642 (void)f.serialVersion(0); +02643 +02644 <font class="comment">// serial Materials infos contained in CMeshBase.</font> +02645 CMeshBase::serialMeshBase(f); +02646 +02647 +02648 <font class="comment">// serial the geometry.</font> +02649 _MeshMRMGeom.serial(f); +02650 } +02651 +02652 +02653 <font class="comment">// ***************************************************************************</font> +<a name="l02654"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#z600_3">02654</a> <font class="keywordtype">float</font> CMeshMRM::getNumTriangles (<font class="keywordtype">float</font> distance) +02655 { +02656 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.getNumTriangles (distance); +02657 } +02658 +02659 +02660 <font class="comment">// ***************************************************************************</font> +<a name="l02661"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#z601_6">02661</a> <font class="keyword">const</font> CMeshMRMGeom& CMeshMRM::getMeshGeom ()<font class="keyword"> const</font> +02662 <font class="keyword"></font>{ +02663 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>; +02664 } +02665 +02666 +02667 <font class="comment">// ***************************************************************************</font> +<a name="l02668"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#a4">02668</a> <font class="keywordtype">void</font> CMeshMRM::computeBonesId (CSkeletonModel *skeleton) +02669 { +02670 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.computeBonesId (skeleton); +02671 } +02672 +02673 <font class="comment">// ***************************************************************************</font> +<a name="l02674"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#a5">02674</a> <font class="keywordtype">void</font> CMeshMRM::updateSkeletonUsage (CSkeletonModel *skeleton, <font class="keywordtype">bool</font> increment) +02675 { +02676 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.updateSkeletonUsage(skeleton, increment); +02677 } +02678 +02679 <font class="comment">// ***************************************************************************</font> +<a name="l02680"></a><a class="code" href="classNL3D_1_1CMeshMRM.html#a6">02680</a> <font class="keywordtype">void</font> CMeshMRM::changeMRMDistanceSetup(<font class="keywordtype">float</font> distanceFinest, <font class="keywordtype">float</font> distanceMiddle, <font class="keywordtype">float</font> distanceCoarsest) +02681 { +02682 <a class="code" href="classNL3D_1_1CMeshMRM.html#o0">_MeshMRMGeom</a>.changeMRMDistanceSetup(distanceFinest, distanceMiddle, distanceCoarsest); +02683 } +02684 +02685 <font class="comment">// ***************************************************************************</font> +02686 <font class="comment">// ***************************************************************************</font> +02687 <font class="comment">// CMeshMRMGeom RawSkin optimisation</font> +02688 <font class="comment">// ***************************************************************************</font> +02689 <font class="comment">// ***************************************************************************</font> +02690 +02691 +02692 <font class="comment">// ***************************************************************************</font> +<a name="l02693"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_4">02693</a> <font class="keywordtype">void</font> CMeshMRMGeom::dirtMeshDataId() +02694 { +02695 <font class="comment">// see updateRawSkinNormal()</font> +02696 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_13">_MeshDataId</a>++; +02697 } +02698 +02699 +02700 <font class="comment">// ***************************************************************************</font> +<a name="l02701"></a><a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_3">02701</a> <font class="keywordtype">void</font> CMeshMRMGeom::updateRawSkinNormal(<font class="keywordtype">bool</font> enabled, CMeshMRMInstance *mi, sint curLodId) +02702 { +02703 <font class="keywordflow">if</font>(!enabled) +02704 { +02705 <font class="comment">// if the instance cache is not cleared, must clear.</font> +02706 <font class="keywordflow">if</font>(mi->_RawSkinCache) +02707 mi->clearRawSkinCache(); +02708 } +02709 <font class="keywordflow">else</font> +02710 { +02711 <font class="comment">// If the instance has no RawSkin, or has a too old RawSkin cache, must delete it, and recreate</font> +02712 <font class="keywordflow">if</font>( !mi->_RawSkinCache || mi->_RawSkinCache->MeshDataId!=<a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_13">_MeshDataId</a>) +02713 { +02714 <font class="comment">// first delete if too old.</font> +02715 <font class="keywordflow">if</font>(mi->_RawSkinCache) +02716 mi->clearRawSkinCache(); +02717 <font class="comment">// Then recreate, and use _MeshDataId to verify that the instance works with same data.</font> +02718 mi->_RawSkinCache= <font class="keyword">new</font> CRawSkinNormalCache; +02719 mi->_RawSkinCache->MeshDataId= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z598_13">_MeshDataId</a>; +02720 mi->_RawSkinCache->LodId= -1; +02721 } +02722 +02723 +02724 <font class="comment">/* If the instance rawSkin has a different Lod (or if -1), then must recreate it.</font> +02725 <font class="comment"> NB: The lod may change each frame per instance, but suppose not so many change, so we can cache those data.</font> +02726 <font class="comment"> */</font> +02727 <font class="keywordflow">if</font>( mi->_RawSkinCache->LodId != curLodId ) +02728 { +02729 <a class="code" href="hierarchical__timer_8h.html#a4">H_AUTO</a>( NL3D_CMeshMRMGeom_updateRawSkinNormal ); +02730 +02731 CRawSkinNormalCache &skinLod= *mi->_RawSkinCache; +02732 <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#z595_0">CLod</a> &lod= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o14">_Lods</a>[curLodId]; +02733 uint i; +02734 +02735 <font class="comment">// Clear the raw skin mesh.</font> +02736 skinLod.clearArrays(); +02737 +02738 <font class="comment">// Cache this lod</font> +02739 mi->_RawSkinCache->LodId= curLodId; +02740 +02741 <font class="comment">// For each matrix influence.</font> +02742 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>==4); +02743 +02744 <font class="comment">// Resize the dest array.</font> +02745 skinLod.Vertices1.resize(lod.InfluencedVertices[0].size()); +02746 skinLod.Vertices2.resize(lod.InfluencedVertices[1].size()); +02747 skinLod.Vertices3.resize(lod.InfluencedVertices[2].size()); +02748 skinLod.Vertices4.resize(lod.InfluencedVertices[3].size()); +02749 +02750 <font class="comment">// 1 Matrix skinning.</font> +02751 <font class="comment">//========</font> +02752 <font class="keywordflow">for</font>(i=0;i<skinLod.Vertices1.size();i++) +02753 { +02754 <font class="comment">// get the dest vertex.</font> +02755 uint vid= lod.InfluencedVertices[0][i]; +02756 <font class="comment">// fill raw struct</font> +02757 skinLod.Vertices1[i].MatrixId[0]= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vid].MatrixId[0]; +02758 skinLod.Vertices1[i].Vertex= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>[vid]; +02759 skinLod.Vertices1[i].Normal= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>[vid]; +02760 skinLod.Vertices1[i].VertexId= vid; +02761 } +02762 +02763 <font class="comment">// 2 Matrix skinning.</font> +02764 <font class="comment">//========</font> +02765 <font class="keywordflow">for</font>(i=0;i<skinLod.Vertices2.size();i++) +02766 { +02767 <font class="comment">// get the dest vertex.</font> +02768 uint vid= lod.InfluencedVertices[1][i]; +02769 <font class="comment">// fill raw struct</font> +02770 skinLod.Vertices2[i].MatrixId[0]= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vid].MatrixId[0]; +02771 skinLod.Vertices2[i].MatrixId[1]= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vid].MatrixId[1]; +02772 skinLod.Vertices2[i].Weights[0]= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vid].Weights[0]; +02773 skinLod.Vertices2[i].Weights[1]= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vid].Weights[1]; +02774 skinLod.Vertices2[i].Vertex= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>[vid]; +02775 skinLod.Vertices2[i].Normal= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>[vid]; +02776 skinLod.Vertices2[i].VertexId= vid; +02777 } +02778 +02779 <font class="comment">// 3 Matrix skinning.</font> +02780 <font class="comment">//========</font> +02781 <font class="keywordflow">for</font>(i=0;i<skinLod.Vertices3.size();i++) +02782 { +02783 <font class="comment">// get the dest vertex.</font> +02784 uint vid= lod.InfluencedVertices[2][i]; +02785 <font class="comment">// fill raw struct</font> +02786 skinLod.Vertices3[i].SkinWeight= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vid]; +02787 skinLod.Vertices3[i].Vertex= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>[vid]; +02788 skinLod.Vertices3[i].Normal= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>[vid]; +02789 skinLod.Vertices3[i].VertexId= vid; +02790 } +02791 +02792 <font class="comment">// 4 Matrix skinning.</font> +02793 <font class="comment">//========</font> +02794 <font class="keywordflow">for</font>(i=0;i<skinLod.Vertices4.size();i++) +02795 { +02796 <font class="comment">// get the dest vertex.</font> +02797 uint vid= lod.InfluencedVertices[3][i]; +02798 <font class="comment">// fill raw struct</font> +02799 skinLod.Vertices4[i].SkinWeight= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o6">_SkinWeights</a>[vid]; +02800 skinLod.Vertices4[i].Vertex= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o1">_OriginalSkinVertices</a>[vid]; +02801 skinLod.Vertices4[i].Normal= <a class="code" href="classNL3D_1_1CMeshMRMGeom.html#o2">_OriginalSkinNormals</a>[vid]; +02802 skinLod.Vertices4[i].VertexId= vid; +02803 } +02804 +02805 } +02806 } +02807 } +02808 +02809 +02810 } <font class="comment">// NL3D</font> +02811 +</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> |