diff options
Diffstat (limited to 'docs/doxygen/nel/mesh_8cpp-source.html')
-rw-r--r-- | docs/doxygen/nel/mesh_8cpp-source.html | 2421 |
1 files changed, 2421 insertions, 0 deletions
diff --git a/docs/doxygen/nel/mesh_8cpp-source.html b/docs/doxygen/nel/mesh_8cpp-source.html new file mode 100644 index 00000000..a80456a6 --- /dev/null +++ b/docs/doxygen/nel/mesh_8cpp-source.html @@ -0,0 +1,2421 @@ +<!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.cpp</h1><a href="mesh_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 +00007 <font class="comment">/* Copyright, 2000 Nevrax Ltd.</font> +00008 <font class="comment"> *</font> +00009 <font class="comment"> * This file is part of NEVRAX NEL.</font> +00010 <font class="comment"> * NEVRAX NEL is free software; you can redistribute it and/or modify</font> +00011 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> +00012 <font class="comment"> * the Free Software Foundation; either version 2, or (at your option)</font> +00013 <font class="comment"> * any later version.</font> +00014 <font class="comment"></font> +00015 <font class="comment"> * NEVRAX NEL is distributed in the hope that it will be useful, but</font> +00016 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font> +00017 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font> +00018 <font class="comment"> * General Public License for more details.</font> +00019 <font class="comment"></font> +00020 <font class="comment"> * You should have received a copy of the GNU General Public License</font> +00021 <font class="comment"> * along with NEVRAX NEL; see the file COPYING. If not, write to the</font> +00022 <font class="comment"> * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,</font> +00023 <font class="comment"> * MA 02111-1307, USA.</font> +00024 <font class="comment"> */</font> +00025 +00026 <font class="preprocessor">#include "<a class="code" href="std3d_8h.html">std3d.h</a>"</font> +00027 +00028 <font class="preprocessor">#include "<a class="code" href="mesh_8h.html">3d/mesh.h</a>"</font> +00029 <font class="preprocessor">#include "<a class="code" href="mesh__instance_8h.html">3d/mesh_instance.h</a>"</font> +00030 <font class="preprocessor">#include "<a class="code" href="scene_8h.html">3d/scene.h</a>"</font> +00031 <font class="preprocessor">#include "<a class="code" href="skeleton__model_8h.html">3d/skeleton_model.h</a>"</font> +00032 <font class="preprocessor">#include "<a class="code" href="mesh__morpher_8h.html">3d/mesh_morpher.h</a>"</font> +00033 <font class="preprocessor">#include "<a class="code" href="bsphere_8h.html">nel/misc/bsphere.h</a>"</font> +00034 <font class="preprocessor">#include "<a class="code" href="stripifier_8h.html">3d/stripifier.h</a>"</font> +00035 <font class="preprocessor">#include "<a class="code" href="fast__floor_8h.html">3d/fast_floor.h</a>"</font> +00036 <font class="preprocessor">#include "<a class="code" href="hierarchical__timer_8h.html">nel/misc/hierarchical_timer.h</a>"</font> +00037 <font class="preprocessor">#include "<a class="code" href="mesh__blender_8h.html">3d/mesh_blender.h</a>"</font> +00038 <font class="preprocessor">#include "<a class="code" href="matrix__3x4_8h.html">3d/matrix_3x4.h</a>"</font> +00039 <font class="preprocessor">#include "<a class="code" href="render__trav_8h.html">3d/render_trav.h</a>"</font> +00040 +00041 +00042 <font class="keyword">using</font> <font class="keyword">namespace </font>std; +00043 <font class="keyword">using</font> <font class="keyword">namespace </font>NLMISC; +00044 +00045 +00046 <font class="keyword">namespace </font>NL3D +00047 { +00048 +00049 +00050 <font class="comment">// ***************************************************************************</font> +00051 <font class="comment">// ***************************************************************************</font> +00052 <font class="comment">// MeshGeom Tools.</font> +00053 <font class="comment">// ***************************************************************************</font> +00054 <font class="comment">// ***************************************************************************</font> +00055 +00056 +00057 <font class="comment">// ***************************************************************************</font> +00058 <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) +00059 { +00060 <a class="code" href="classNLMISC_1_1CAABBox.html">NLMISC::CAABBox</a> ret; +00061 <a class="code" href="debug_8h.html#a6">nlassert</a>(Vertices.size()); +00062 ret.<a class="code" href="classNLMISC_1_1CAABBox.html#z263_0">setCenter</a>(Vertices[0]); +00063 <font class="keywordflow">for</font>(sint i=0;i<(sint)Vertices.size();i++) +00064 { +00065 ret.<a class="code" href="classNLMISC_1_1CAABBox.html#z263_4">extend</a>(Vertices[i]); +00066 } +00067 +00068 <font class="keywordflow">return</font> ret; +00069 } +00070 +00071 +00072 <font class="comment">// ***************************************************************************</font> +<a name="l00073"></a><a class="code" href="structNL3D_1_1CMeshGeom_1_1CCornerTmp.html#p0">00073</a> sint CMeshGeom::CCornerTmp::Flags=0; +00074 +00075 +00076 <font class="comment">// ***************************************************************************</font> +<a name="l00077"></a><a class="code" href="structNL3D_1_1CMeshGeom_1_1CCornerTmp.html#a0">00077</a> <font class="keywordtype">bool</font> <a class="code" href="zone__lighter_8cpp.html#a13">CMeshGeom::CCornerTmp::operator<</a>(<font class="keyword">const</font> CCornerTmp &c)<font class="keyword"> const</font> +00078 <font class="keyword"></font>{ +00079 sint i; +00080 +00081 <font class="comment">// Vert first.</font> +00082 <font class="keywordflow">if</font>(<a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m0">Vertex</a>!=c.Vertex) +00083 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m0">Vertex</a><c.Vertex; +00084 +00085 <font class="comment">// Order: normal, uvs, color0, color1, skinning.</font> +00086 <font class="keywordflow">if</font>((CCornerTmp::Flags & CVertexBuffer::NormalFlag) && <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m1">Normal</a>!=c.Normal) +00087 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m1">Normal</a><c.Normal; +00088 <font class="keywordflow">for</font>(i=0; i<CVertexBuffer::MaxStage; i++) +00089 { +00090 <font class="keywordflow">if</font>((CCornerTmp::Flags & (CVertexBuffer::TexCoord0Flag<<i)) && <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m2">Uvws</a>[i]!=c.Uvws[i]) +00091 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m2">Uvws</a>[i]<c.Uvws[i]; +00092 } +00093 <font class="keywordflow">if</font>((CCornerTmp::Flags & CVertexBuffer::PrimaryColorFlag) && <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m3">Color</a>!=c.Color) +00094 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m3">Color</a><c.Color; +00095 <font class="keywordflow">if</font>((CCornerTmp::Flags & CVertexBuffer::SecondaryColorFlag) && <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m4">Specular</a>!=c.Specular) +00096 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m4">Specular</a><c.Specular; +00097 +00098 <font class="keywordflow">if</font> ((CCornerTmp::Flags & CVertexBuffer::PaletteSkinFlag)==CVertexBuffer::PaletteSkinFlag) +00099 { +00100 <font class="keywordflow">for</font>(i=0;i<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;i++) +00101 { +00102 <font class="keywordflow">if</font>(<a class="code" href="structNL3D_1_1CMeshGeom_1_1CCornerTmp.html#m0">Palette</a>.MatrixId[i] != c.Palette.MatrixId[i]) +00103 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CMeshGeom_1_1CCornerTmp.html#m0">Palette</a>.MatrixId[i] < c.Palette.MatrixId[i]; +00104 <font class="keywordflow">if</font>(<a class="code" href="structNL3D_1_1CMeshGeom_1_1CCornerTmp.html#m1">Weights</a>[i] != c.Weights[i]) +00105 <font class="keywordflow">return</font> <a class="code" href="structNL3D_1_1CMeshGeom_1_1CCornerTmp.html#m1">Weights</a>[i] < c.Weights[i]; +00106 } +00107 } +00108 +00109 +00110 <font class="comment">// All are equal!!</font> +00111 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00112 } +00113 +00114 +00115 <font class="comment">// ***************************************************************************</font> +00116 <font class="comment">// ***************************************************************************</font> +00117 <font class="comment">// CMeshGeom.</font> +00118 <font class="comment">// ***************************************************************************</font> +00119 <font class="comment">// ***************************************************************************</font> +00120 +00121 +00122 <font class="comment">// ***************************************************************************</font> +<a name="l00123"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#a0">00123</a> CMeshGeom::CMeshGeom() +00124 { +00125 <a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a>= <font class="keyword">false</font>; +00126 <a class="code" href="classNL3D_1_1CMeshGeom.html#o8">_OriginalSkinRestored</a>= <font class="keyword">true</font>; +00127 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_3">_VertexBufferHardDirty</a>= <font class="keyword">true</font>; +00128 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a> = <font class="keyword">new</font> CMeshMorpher; +00129 <a class="code" href="classNL3D_1_1CMeshGeom.html#o9">_BoneIdComputed</a> = <font class="keyword">false</font>; +00130 <a class="code" href="classNL3D_1_1CMeshGeom.html#o10">_BoneIdExtended</a>= <font class="keyword">false</font>; +00131 <a class="code" href="classNL3D_1_1CMeshGeom.html#o14">_PreciseClipping</a>= <font class="keyword">false</font>; +00132 } +00133 +00134 +00135 <font class="comment">// ***************************************************************************</font> +<a name="l00136"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#a1">00136</a> CMeshGeom::~CMeshGeom() +00137 { +00138 <font class="comment">// test (refptr) if the object still exist in memory.</font> +00139 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>!=NULL) +00140 { +00141 <font class="comment">// A vbufferhard should still exist only if driver still exist.</font> +00142 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>!=NULL); +00143 +00144 <font class="comment">// delete it from driver.</font> +00145 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>->deleteVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>); +00146 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>= NULL; +00147 } +00148 <font class="keyword">delete</font> <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>; +00149 } +00150 +00151 +00152 <font class="comment">// ***************************************************************************</font> +<a name="l00153"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#c1">00153</a> <font class="keywordtype">void</font> CMeshGeom::optimizeTriangleOrder() +00154 { +00155 CStripifier stripifier; +00156 +00157 <font class="comment">// for all rdrpass of all matrix blocks.</font> +00158 <font class="keywordflow">for</font>(uint mb= 0;mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();mb++) +00159 { +00160 <font class="keywordflow">for</font>(uint rp=0; rp<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass.size(); rp++ ) +00161 { +00162 <font class="comment">// stripify list of triangles of this pass.</font> +00163 CRdrPass &pass= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass[rp]; +00164 stripifier.optimizeTriangles(pass.PBlock, pass.PBlock); +00165 } +00166 } +00167 +00168 } +00169 +00170 +00171 <font class="comment">// ***************************************************************************</font> +<a name="l00172"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#a2">00172</a> <font class="keywordtype">void</font> CMeshGeom::build (CMesh::CMeshBuild &m, uint numMaxMaterial) +00173 { +00174 sint i; +00175 +00176 <font class="comment">// Dirt the VBuffer.</font> +00177 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_3">_VertexBufferHardDirty</a>= <font class="keyword">true</font>; +00178 +00179 <font class="comment">// Empty geometry?</font> +00180 <font class="keywordflow">if</font>(m.Vertices.size()==0 || m.Faces.size()==0) +00181 { +00182 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.setNumVertices(0); +00183 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.reserve(0); +00184 <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.clear(); +00185 <a class="code" href="classNL3D_1_1CMeshGeom.html#o6">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z267_0">setCenter</a>(CVector::Null); +00186 <a class="code" href="classNL3D_1_1CMeshGeom.html#o6">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z267_2">setSize</a>(CVector::Null); +00187 <font class="keywordflow">return</font>; +00188 } +00189 <a class="code" href="debug_8h.html#a6">nlassert</a>(numMaxMaterial>0); +00190 +00191 +00193 <font class="comment">//======================</font> +00194 <a class="code" href="classNL3D_1_1CMeshGeom.html#o6">_BBox</a>= <a class="code" href="namespaceNL3D.html#a376">makeBBox</a>(m.Vertices); +00195 +00196 +00198 <font class="comment">//================================================</font> +00199 +00200 <font class="comment">// First, copy Face array.</font> +00201 vector<CFaceTmp> tmpFaces; +00202 tmpFaces.resize(m.Faces.size()); +00203 <font class="keywordflow">for</font>(i=0;i<(sint)tmpFaces.size();i++) +00204 tmpFaces[i]= m.Faces[i]; +00205 +00206 <a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a>= ((m.VertexFlags & CVertexBuffer::PaletteSkinFlag)==CVertexBuffer::PaletteSkinFlag); +00207 <font class="comment">// Skinning is OK only if SkinWeights are of same size as vertices.</font> +00208 <a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a>= <a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a> && (m.Vertices.size()==m.SkinWeights.size()); +00209 +00210 <font class="comment">// If skinning is KO, remove the Skin option.</font> +00211 uint vbFlags= m.VertexFlags; +00212 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a>) +00213 vbFlags&= ~CVertexBuffer::PaletteSkinFlag; +00214 <font class="comment">// Force presence of vertex.</font> +00215 vbFlags|= CVertexBuffer::PositionFlag; +00216 +00217 +00218 <font class="comment">// If the mesh is not skinned, we have just 1 _MatrixBlocks.</font> +00219 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a>) +00220 { +00221 <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.resize(1); +00222 <font class="comment">// For each faces, assign it to the matrix block 0.</font> +00223 <font class="keywordflow">for</font>(i=0;i<(sint)tmpFaces.size();i++) +00224 tmpFaces[i].MatrixBlockId= 0; +00225 } +00226 <font class="comment">// Else We must group/compute the matrixs blocks.</font> +00227 <font class="keywordflow">else</font> +00228 { +00229 <font class="comment">// reset matrix blocks.</font> +00230 <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.clear(); +00231 <font class="comment">// build matrix blocks, and link faces to good matrix blocks.</font> +00232 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_1">buildSkin</a>(m, tmpFaces); +00233 } +00234 +00235 +00237 <font class="comment">//================================================</font> +00238 <font class="comment">// Setup VB.</font> +00239 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.setNumVertices(0); +00240 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.reserve(0); +00241 +00242 <font class="keywordtype">bool</font> useFormatExt = <font class="keyword">false</font>; +00246 <font class="keywordflow">for</font> (uint k = 0; k < CVertexBuffer::MaxStage; ++k) +00247 { +00248 <font class="keywordflow">if</font> ( +00249 (vbFlags & (CVertexBuffer::TexCoord0Flag << k)) +00250 && m.NumCoords[k] != 2) +00251 { +00252 useFormatExt = <font class="keyword">true</font>; +00253 <font class="keywordflow">break</font>; +00254 } +00255 } +00256 +00257 <font class="keywordflow">if</font> (!useFormatExt) +00258 { +00259 <font class="comment">// setup standard format</font> +00260 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.setVertexFormat(vbFlags); +00261 } +00262 <font class="keywordflow">else</font> <font class="comment">// setup extended format</font> +00263 { +00264 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.clearValueEx(); +00265 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::PositionFlag) <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx(CVertexBuffer::Position, CVertexBuffer::Float3); +00266 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::NormalFlag) <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx(CVertexBuffer::Normal, CVertexBuffer::Float3); +00267 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::PrimaryColorFlag) <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx(CVertexBuffer::PrimaryColor, CVertexBuffer::UChar4); +00268 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::SecondaryColorFlag) <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx(CVertexBuffer::SecondaryColor, CVertexBuffer::UChar4); +00269 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::WeightFlag) <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx(CVertexBuffer::Weight, CVertexBuffer::Float4); +00270 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::PaletteSkinFlag) <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx(CVertexBuffer::PaletteSkin, CVertexBuffer::UChar4); +00271 <font class="keywordflow">if</font> (vbFlags & CVertexBuffer::FogFlag) <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx(CVertexBuffer::Fog, CVertexBuffer::Float1); +00272 +00273 <font class="keywordflow">for</font> (uint k = 0; k < CVertexBuffer::MaxStage; ++k) +00274 { +00275 <font class="keywordflow">if</font> (vbFlags & (CVertexBuffer::TexCoord0Flag << k)) +00276 { +00277 <font class="keywordflow">switch</font>(m.NumCoords[k]) +00278 { +00279 <font class="keywordflow">case</font> 2: +00280 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + k), CVertexBuffer::Float2); +00281 <font class="keywordflow">break</font>; +00282 <font class="keywordflow">case</font> 3: +00283 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.addValueEx((CVertexBuffer::TValue) (CVertexBuffer::TexCoord0 + k), CVertexBuffer::Float3); +00284 <font class="keywordflow">break</font>; +00285 <font class="keywordflow">default</font>: +00286 <a class="code" href="debug_8h.html#a6">nlassert</a>(0); +00287 <font class="keywordflow">break</font>; +00288 } +00289 } +00290 } +00291 <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.initEx(); +00292 } +00293 +00294 <font class="comment">// Set local flags for corner comparison.</font> +00295 CCornerTmp::Flags= vbFlags; +00296 <font class="comment">// Setup locals.</font> +00297 <a class="code" href="classNL3D_1_1CMeshGeom.html#u2">TCornerSet</a> corners; +00298 <font class="keyword">const</font> CFaceTmp *pFace= &(*tmpFaces.begin()); +00299 uint32 nFaceMB = 0; +00300 sint N= tmpFaces.size(); +00301 sint currentVBIndex=0; +00302 +00303 m.VertLink.clear (); +00304 +00305 <font class="comment">// process each face, building up the VB.</font> +00306 <font class="keywordflow">for</font>(;N>0;N--, pFace++) +00307 { +00308 sint v0= pFace->Corner[0].Vertex; +00309 sint v1= pFace->Corner[1].Vertex; +00310 sint v2= pFace->Corner[2].Vertex; +00311 <a class="code" href="classNL3D_1_1CMeshGeom.html#c0">findVBId</a>(corners, &pFace->Corner[0], currentVBIndex, m.Vertices[v0], m); +00312 <a class="code" href="classNL3D_1_1CMeshGeom.html#c0">findVBId</a>(corners, &pFace->Corner[1], currentVBIndex, m.Vertices[v1], m); +00313 <a class="code" href="classNL3D_1_1CMeshGeom.html#c0">findVBId</a>(corners, &pFace->Corner[2], currentVBIndex, m.Vertices[v2], m); +00314 CMesh::CVertLink vl1(nFaceMB, 0, pFace->Corner[0].VBId); +00315 CMesh::CVertLink vl2(nFaceMB, 1, pFace->Corner[1].VBId); +00316 CMesh::CVertLink vl3(nFaceMB, 2, pFace->Corner[2].VBId); +00317 m.VertLink.push_back(vl1); +00318 m.VertLink.push_back(vl2); +00319 m.VertLink.push_back(vl3); +00320 ++nFaceMB; +00321 } +00322 +00323 +00325 <font class="comment">//================================</font> +00326 uint mb; +00327 +00328 <font class="comment">// For each _MatrixBlocks, point on those materials.</font> +00329 <font class="keywordflow">for</font>(mb= 0;mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();mb++) +00330 { +00331 <font class="comment">// Build RdrPass ids.</font> +00332 <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass.resize (numMaxMaterial); +00333 +00335 <font class="keywordflow">for</font>(i=0;i<(sint)<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass.size(); i++) +00336 { +00337 <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass[i].MaterialId= i; +00338 } +00339 } +00340 +00341 +00343 <font class="comment">//===================================================</font> +00344 pFace= &(*tmpFaces.begin()); +00345 N= tmpFaces.size(); +00346 <font class="keywordflow">for</font>(;N>0;N--, pFace++) +00347 { +00348 sint mbId= pFace->MatrixBlockId; +00349 <a class="code" href="debug_8h.html#a6">nlassert</a>(mbId>=0 && mbId<(sint)<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size()); +00350 <font class="comment">// Insert the face in good MatrixBlock/RdrPass.</font> +00351 <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mbId].RdrPass[pFace->MaterialId].PBlock.addTri(pFace->Corner[0].VBId, pFace->Corner[1].VBId, pFace->Corner[2].VBId); +00352 } +00353 +00354 +00356 <font class="comment">//============================</font> +00357 <font class="keywordflow">for</font>(mb= 0;mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();mb++) +00358 { +00359 <font class="comment">// NB: slow process (erase from a vector). Doens't matter since made at build.</font> +00360 vector<CRdrPass>::iterator itPass; +00361 <font class="keywordflow">for</font>( itPass=<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass.begin(); itPass!=<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass.end(); ) +00362 { +00363 <font class="comment">// If this pass is empty, remove it.</font> +00364 <font class="keywordflow">if</font>( itPass->PBlock.getNumTri()==0 ) +00365 itPass= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass.erase(itPass); +00366 <font class="keywordflow">else</font> +00367 itPass++; +00368 } +00369 } +00370 +00372 <font class="comment">//============================</font> +00373 <font class="comment">// BShapes</font> +00374 this-><a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->BlendShapes = m.BlendShapes; +00375 +00376 <font class="comment">// sort triangles for better cache use.</font> +00377 <a class="code" href="classNL3D_1_1CMeshGeom.html#c1">optimizeTriangleOrder</a>(); +00378 +00379 <font class="comment">// SmartPtr Copy VertexProgram effect.</font> +00380 this-><a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>= m.MeshVertexProgram; +00381 +00383 <font class="comment">//================================================= </font> +00384 +00385 <font class="comment">// If skinned</font> +00386 <font class="keywordflow">if</font>(_Skinned) +00387 { +00388 <font class="comment">// Reserve some space</font> +00389 <a class="code" href="classNL3D_1_1CMeshGeom.html#o11">_BonesName</a>.reserve (m.BonesNames.size ()); +00390 +00391 <font class="comment">// Current local bone</font> +00392 uint currentBone = 0; +00393 +00394 <font class="comment">// For each matrix block</font> +00395 uint matrixBlock; +00396 <font class="keywordflow">for</font> (matrixBlock=0; matrixBlock<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size(); matrixBlock++) +00397 { +00398 <font class="comment">// Ref on the matrix block</font> +00399 CMatrixBlock &mb = <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[matrixBlock]; +00400 +00401 <font class="comment">// Remap the skeleton index in model index</font> +00402 std::map<uint, uint> remap; +00403 +00404 <font class="comment">// For each matrix</font> +00405 uint <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>; +00406 <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><mb.NumMatrix; <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>++) +00407 { +00408 <font class="comment">// Get bone id in the skeleton</font> +00409 std::map<uint, uint>::iterator ite = remap.find (mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]); +00410 +00411 <font class="comment">// Not found</font> +00412 <font class="keywordflow">if</font> (ite == remap.end()) +00413 { +00414 <font class="comment">// Insert it</font> +00415 remap.insert (std::map<uint, uint>::value_type (mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>], currentBone)); +00416 +00417 <font class="comment">// Check the matrix id</font> +00418 <a class="code" href="debug_8h.html#a6">nlassert</a> (mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>] < m.BonesNames.size()); +00419 +00420 <font class="comment">// Set the bone name</font> +00421 <a class="code" href="classNL3D_1_1CMeshGeom.html#o11">_BonesName</a>.push_back (m.BonesNames[mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]]); +00422 +00423 <font class="comment">// Set the id in local</font> +00424 mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>] = currentBone++; +00425 } +00426 <font class="keywordflow">else</font> +00427 { +00428 <font class="comment">// Set the id in local</font> +00429 mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>] = ite->second; +00430 } +00431 } +00432 } +00433 +00434 <font class="comment">// Bone id in local</font> +00435 <a class="code" href="classNL3D_1_1CMeshGeom.html#o9">_BoneIdComputed</a> = <font class="keyword">false</font>; +00436 <a class="code" href="classNL3D_1_1CMeshGeom.html#o10">_BoneIdExtended</a> = <font class="keyword">false</font>; +00437 } +00438 +00439 +00440 <font class="comment">// End!!</font> +00441 <font class="comment">// Some runtime not serialized compilation</font> +00442 <a class="code" href="classNL3D_1_1CMeshGeom.html#c2">compileRunTime</a>(); +00443 } +00444 +00445 <font class="comment">// ***************************************************************************</font> +<a name="l00446"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#a3">00446</a> <font class="keywordtype">void</font> CMeshGeom::setBlendShapes(std::vector<CBlendShape>&bs) +00447 { +00448 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->BlendShapes = bs; +00449 <font class="comment">// must update some RunTime parameters</font> +00450 <a class="code" href="classNL3D_1_1CMeshGeom.html#c2">compileRunTime</a>(); +00451 } +00452 +00453 +00454 <font class="comment">// ***************************************************************************</font> +<a name="l00455"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#a4">00455</a> <font class="keywordtype">void</font> CMeshGeom::applyMaterialRemap(<font class="keyword">const</font> std::vector<sint> &remap) +00456 { +00457 <font class="keywordflow">for</font>(uint mb=0;mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#z565_2">getNbMatrixBlock</a>();mb++) +00458 { +00459 <font class="keywordflow">for</font>(uint rp=0;rp<<a class="code" href="classNL3D_1_1CMeshGeom.html#z565_3">getNbRdrPass</a>(mb);rp++) +00460 { +00461 <font class="comment">// remap</font> +00462 uint32 &matId= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb].RdrPass[rp].MaterialId; +00463 <a class="code" href="debug_8h.html#a6">nlassert</a>(remap[matId]>=0); +00464 matId= remap[matId]; +00465 } +00466 } +00467 } +00468 +00469 +00470 <font class="comment">// ***************************************************************************</font> +<a name="l00471"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z564_0">00471</a> <font class="keywordtype">void</font> CMeshGeom::initInstance(CMeshBaseInstance *mbi) +00472 { +00473 <font class="comment">// init the instance with _MeshVertexProgram infos</font> +00474 <font class="keywordflow">if</font>(_MeshVertexProgram) +00475 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->initInstance(mbi); +00476 } +00477 +00478 <font class="comment">// ***************************************************************************</font> +<a name="l00479"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z564_1">00479</a> <font class="keywordtype">bool</font> CMeshGeom::clip(<font class="keyword">const</font> std::vector<CPlane> &pyramid, <font class="keyword">const</font> CMatrix &worldMatrix) +00480 { +00481 <font class="comment">// Speed Clip: clip just the sphere.</font> +00482 CBSphere localSphere(<a class="code" href="classNL3D_1_1CMeshGeom.html#o6">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z268_2">getCenter</a>(), <a class="code" href="classNL3D_1_1CMeshGeom.html#o6">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z268_5">getRadius</a>()); +00483 CBSphere worldSphere; +00484 +00485 <font class="comment">// transform the sphere in WorldMatrix (with nearly good scale info).</font> +00486 localSphere.applyTransform(worldMatrix, worldSphere); +00487 +00488 <font class="comment">// if out of only plane, entirely out.</font> +00489 <font class="keywordflow">for</font>(sint i=0;i<(sint)pyramid.size();i++) +00490 { +00491 <font class="comment">// We are sure that pyramid has normalized plane normals.</font> +00492 <font class="comment">// if SpherMax OUT return false.</font> +00493 <font class="keywordtype">float</font> d= pyramid[i]*worldSphere.Center; +00494 <font class="keywordflow">if</font>(d>worldSphere.Radius) +00495 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00496 } +00497 +00498 <font class="comment">// test if must do a precise clip, according to mesh size.</font> +00499 <font class="keywordflow">if</font>( _PreciseClipping ) +00500 { +00501 CPlane localPlane; +00502 +00503 <font class="comment">// if out of only plane, entirely out.</font> +00504 <font class="keywordflow">for</font>(sint i=0;i<(sint)pyramid.size();i++) +00505 { +00506 <font class="comment">// Transform the pyramid in Object space.</font> +00507 localPlane= pyramid[i]*worldMatrix; +00508 <font class="comment">// localPlane must be normalized, because worldMatrix mya have a scale.</font> +00509 localPlane.normalize(); +00510 <font class="comment">// if the box is not partially inside the plane, quit</font> +00511 <font class="keywordflow">if</font>( !<a class="code" href="classNL3D_1_1CMeshGeom.html#o6">_BBox</a>.<a class="code" href="classNLMISC_1_1CAABBoxExt.html#z269_1">clipBack</a>(localPlane) ) +00512 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00513 } +00514 } +00515 +00516 <font class="keywordflow">return</font> <font class="keyword">true</font>; +00517 } +00518 +00519 <font class="comment">// ***************************************************************************</font> +<a name="l00520"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z568_0">00520</a> <font class="keywordtype">void</font> CMeshGeom::updateVertexBufferHard(IDriver *drv) +00521 { +00522 <font class="keywordflow">if</font>(!drv->supportVertexBufferHard()) +00523 <font class="keywordflow">return</font>; +00524 +00525 +00526 <font class="comment">/* If the mesh is skinned, still use normal CVertexBuffer.</font> +00527 <font class="comment"> * \todo yoyo: optimize. not done now because CMesh Skinned are not so used in game, </font> +00528 <font class="comment"> * and CMesh skinning is far not optimized (4 matrix mul all the time). Should use later the renderSkinGroupGeom()</font> +00529 <font class="comment"> * scheme</font> +00530 <font class="comment"> * Also, if the driver has slow VBhard unlock() (ie ATI gl extension), avoid use of them if MeshMorpher </font> +00531 <font class="comment"> * is used.</font> +00532 <font class="comment"> */</font> +00533 <font class="keywordtype">bool</font> avoidVBHard; +00534 avoidVBHard= <a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a> || ( <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->BlendShapes.size()>0 && drv->slowUnlockVertexBufferHard() ); +00535 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_3">_VertexBufferHardDirty</a> && avoidVBHard ) +00536 { +00537 <font class="comment">// delete possible old VBHard.</font> +00538 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>!=NULL) +00539 { +00540 <font class="comment">// VertexBufferHard lifetime < Driver lifetime.</font> +00541 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>!=NULL); +00542 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>->deleteVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>); +00543 } +00544 <font class="keywordflow">return</font>; +00545 } +00546 +00547 <font class="comment">// If the vbufferhard is not synced to the vbuffer.</font> +00548 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_3">_VertexBufferHardDirty</a> || <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>==NULL) +00549 { +00550 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_3">_VertexBufferHardDirty</a>= <font class="keyword">false</font>; +00551 +00552 <font class="comment">// delete possible old VBHard.</font> +00553 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>!=NULL) +00554 { +00555 <font class="comment">// VertexBufferHard lifetime < Driver lifetime.</font> +00556 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>!=NULL); +00557 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>->deleteVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>); +00558 } +00559 +00560 <font class="comment">// bkup drv in a refptr. (so we know if the vbuffer hard has to be deleted).</font> +00561 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>= drv; +00562 <font class="comment">// try to create new one, in AGP Ram</font> +00563 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>= <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_2">_Driver</a>->createVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexFormat(), <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getValueTypePointer (), <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumVertices(), IDriver::VBHardAGP); +00564 +00565 <font class="comment">// If KO, use normal VertexBuffer.</font> +00566 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>==NULL) +00567 <font class="keywordflow">return</font>; +00568 <font class="comment">// else, Fill it with VertexBuffer.</font> +00569 <font class="keywordflow">else</font> +00570 { +00571 <font class="keywordtype">void</font> *vertexPtr= <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>->lock(); +00572 +00573 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexFormat() == <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>->getVertexFormat()); +00574 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumVertices() == <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>->getNumVertices()); +00575 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexSize() == <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>->getVertexSize()); +00576 +00577 <font class="comment">// \todo yoyo: TODO_DX8 and DX8 ???</font> +00578 <font class="comment">// Because same internal format, just copy all block.</font> +00579 memcpy(vertexPtr, <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexCoordPointer(), <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumVertices() * <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexSize() ); +00580 +00581 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>->unlock(); +00582 } +00583 +00584 } +00585 } +00586 +00587 +00588 <font class="comment">// ***************************************************************************</font> +<a name="l00589"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z564_2">00589</a> <font class="keywordtype">void</font> CMeshGeom::render(IDriver *drv, CTransformShape *trans, <font class="keywordtype">float</font> polygonCount, uint32 rdrFlags, <font class="keywordtype">float</font> globalAlpha) +00590 { +00591 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +00592 <font class="comment">// get the mesh instance.</font> +00593 CMeshBaseInstance *mi= safe_cast<CMeshBaseInstance*>(trans); +00594 <font class="comment">// get a ptr on scene</font> +00595 CScene *ownerScene= mi->getScene(); +00596 <font class="comment">// get a ptr on renderTrav</font> +00597 CRenderTrav *renderTrav= ownerScene->getRenderTrav(); +00598 +00599 +00600 <font class="comment">// update the VBufferHard (create/delete), to maybe render in AGP memory.</font> +00601 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_0">updateVertexBufferHard</a> (drv); +00602 <font class="comment">/* currentVBHard is NULL if must disable it temporarily</font> +00603 <font class="comment"> For now, never disable it, but switch of VBHard may be VERY EXPENSIVE if NV_vertex_array_range2 is not</font> +00604 <font class="comment"> supported (old drivers).</font> +00605 <font class="comment"> */</font> +00606 IVertexBufferHard *currentVBHard= <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>; +00607 +00608 +00609 <font class="comment">// get the skeleton model to which I am binded (else NULL).</font> +00610 CSkeletonModel *skeleton; +00611 skeleton= mi->getSkeletonModel(); +00612 <font class="comment">// The mesh must not be skinned for render()</font> +00613 <a class="code" href="debug_8h.html#a6">nlassert</a>(!(<a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a> && mi->isSkinned() && skeleton)); +00614 <font class="keywordtype">bool</font> bMorphApplied = <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->BlendShapes.size() > 0; +00615 <font class="keywordtype">bool</font> useTangentSpace = <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->needTangentSpace(); +00616 +00617 +00618 <font class="comment">// Profiling</font> +00619 <font class="comment">//===========</font> +00620 <a class="code" href="hierarchical__timer_8h.html#a4">H_AUTO</a>( NL3D_MeshGeom_RenderNormal ); +00621 +00622 +00623 <font class="comment">// Morphing</font> +00624 <font class="comment">// ========</font> +00625 <font class="keywordflow">if</font> (bMorphApplied) +00626 { +00627 <font class="comment">// If _Skinned (NB: the skin is not applied) and if lod.OriginalSkinRestored, then restoreOriginalSkinPart is</font> +00628 <font class="comment">// not called but mush morpher write changed vertices into VBHard so its ok. The unchanged vertices</font> +00629 <font class="comment">// are written in the preceding call to restoreOriginalSkinPart.</font> +00630 <font class="keywordflow">if</font> (_Skinned) +00631 { +00632 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->initSkinned(&<a class="code" href="classNL3D_1_1CMeshGeom.html#o4">_VBufferOri</a>, +00633 &<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>, +00634 currentVBHard, +00635 useTangentSpace, +00636 &<a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>, +00637 &<a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>, +00638 useTangentSpace ? &<a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a> : NULL, +00639 <font class="keyword">false</font> ); +00640 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->updateSkinned (mi->getBlendShapeFactors()); +00641 } +00642 <font class="keywordflow">else</font> <font class="comment">// Not even skinned so we have to do all the stuff</font> +00643 { +00644 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->init(&<a class="code" href="classNL3D_1_1CMeshGeom.html#o4">_VBufferOri</a>, +00645 &<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>, +00646 currentVBHard, +00647 useTangentSpace); +00648 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->update (mi->getBlendShapeFactors()); +00649 } +00650 } +00651 +00652 +00653 <font class="comment">// Skinning</font> +00654 <font class="comment">// ========</font> +00655 +00656 <font class="comment">// else setup instance matrix</font> +00657 drv->setupModelMatrix(trans->getWorldMatrix()); +00658 +00659 +00660 <font class="comment">// since instance skin is invalid but mesh is skinned , we must copy vertices/normals from original vertices.</font> +00661 <font class="keywordflow">if</font> (_Skinned) +00662 { +00663 <font class="comment">// do it for this Lod only, and if cache say it is necessary.</font> +00664 <font class="keywordflow">if</font> (!<a class="code" href="classNL3D_1_1CMeshGeom.html#o8">_OriginalSkinRestored</a>) +00665 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_4">restoreOriginalSkinVertices</a>(); +00666 } +00667 +00668 +00669 <font class="comment">// Setup meshVertexProgram</font> +00670 <font class="comment">//===========</font> +00671 +00672 <font class="comment">// use MeshVertexProgram effect?</font> +00673 <font class="keywordtype">bool</font> useMeshVP= <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a> != NULL; +00674 <font class="keywordflow">if</font>( useMeshVP ) +00675 { +00676 CMatrix invertedObjectMatrix; +00677 invertedObjectMatrix = trans->getWorldMatrix().inverted(); +00678 <font class="comment">// really ok if success to begin VP</font> +00679 useMeshVP= <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->begin(drv, ownerScene, mi, invertedObjectMatrix, renderTrav->CamPos); +00680 } +00681 +00682 +00683 <font class="comment">// Render the mesh.</font> +00684 <font class="comment">//===========</font> +00685 <font class="comment">// active VB.</font> +00686 <font class="keywordflow">if</font>(currentVBHard != NULL) +00687 drv->activeVertexBufferHard(currentVBHard); +00688 <font class="keywordflow">else</font> +00689 drv->activeVertexBuffer(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>); +00690 +00691 +00692 <font class="comment">// Global alpha used ?</font> +00693 uint32 globalAlphaUsed= rdrFlags & IMeshGeom::RenderGlobalAlpha; +00694 uint8 globalAlphaInt=(uint8)<a class="code" href="namespaceNL3D.html#a362">OptFastFloor</a>(globalAlpha*255); +00695 +00696 +00697 <font class="comment">// For all _MatrixBlocks</font> +00698 <font class="keywordflow">for</font>(uint mb=0;mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();mb++) +00699 { +00700 CMatrixBlock &mBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb]; +00701 <font class="keywordflow">if</font>(mBlock.RdrPass.size()==0) +00702 <font class="keywordflow">continue</font>; +00703 +00704 <font class="comment">// Global alpha ?</font> +00705 <font class="keywordflow">if</font> (globalAlphaUsed) +00706 { +00707 <font class="keywordtype">bool</font> gaDisableZWrite= (rdrFlags & IMeshGeom::RenderGADisableZWrite)?<font class="keyword">true</font>:<font class="keyword">false</font>; +00708 +00709 <font class="comment">// Render all pass.</font> +00710 <font class="keywordflow">for</font> (uint i=0;i<mBlock.RdrPass.size();i++) +00711 { +00712 CRdrPass &rdrPass= mBlock.RdrPass[i]; +00713 <font class="comment">// Render with the Materials of the MeshInstance.</font> +00714 <font class="keywordflow">if</font> ( ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">false</font>) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) || +00715 ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">true</font>) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) ) +00716 { +00717 <font class="comment">// CMaterial Ref</font> +00718 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +00719 +00720 <font class="comment">// Use a MeshBlender to modify material and driver.</font> +00721 CMeshBlender blender; +00722 blender.prepareRenderForGlobalAlpha(material, drv, globalAlpha, globalAlphaInt, gaDisableZWrite); +00723 +00724 <font class="comment">// Setup VP material</font> +00725 <font class="keywordflow">if</font> (useMeshVP) +00726 { +00727 <font class="keywordflow">if</font>(currentVBHard) +00728 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, currentVBHard); +00729 <font class="keywordflow">else</font> +00730 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, &<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>); +00731 } +00732 +00733 <font class="comment">// Render</font> +00734 drv->render(rdrPass.PBlock, material); +00735 +00736 <font class="comment">// Resetup material/driver</font> +00737 blender.restoreRender(material, drv, gaDisableZWrite); +00738 } +00739 } +00740 } +00741 <font class="keywordflow">else</font> +00742 { +00743 <font class="comment">// Render all pass.</font> +00744 <font class="keywordflow">for</font>(uint i=0;i<mBlock.RdrPass.size();i++) +00745 { +00746 CRdrPass &rdrPass= mBlock.RdrPass[i]; +00747 <font class="comment">// Render with the Materials of the MeshInstance.</font> +00748 <font class="keywordflow">if</font>( ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">false</font>) && (rdrFlags & IMeshGeom::RenderOpaqueMaterial) ) || +00749 ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">true</font>) && (rdrFlags & IMeshGeom::RenderTransparentMaterial) ) ) +00750 { +00751 <font class="comment">// CMaterial Ref</font> +00752 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +00753 +00754 <font class="comment">// Setup VP material</font> +00755 <font class="keywordflow">if</font> (useMeshVP) +00756 { +00757 <font class="keywordflow">if</font>(currentVBHard) +00758 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, currentVBHard); +00759 <font class="keywordflow">else</font> +00760 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, &<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>); +00761 } +00762 +00763 <font class="comment">// render primitives</font> +00764 drv->render(rdrPass.PBlock, material); +00765 } +00766 } +00767 } +00768 } +00769 +00770 <font class="comment">// End VertexProgram effect</font> +00771 <font class="keywordflow">if</font>(useMeshVP) +00772 { +00773 <font class="comment">// Apply it.</font> +00774 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->end(drv); +00775 } +00776 } +00777 +00778 +00779 <font class="comment">// ***************************************************************************</font> +<a name="l00780"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z564_3">00780</a> <font class="keywordtype">void</font> CMeshGeom::renderSkin(CTransformShape *trans, <font class="keywordtype">float</font> alphaMRM) +00781 { +00782 <font class="comment">// get the mesh instance.</font> +00783 CMeshBaseInstance *mi= safe_cast<CMeshBaseInstance*>(trans); +00784 <font class="comment">// get a ptr on scene</font> +00785 CScene *ownerScene= mi->getScene(); +00786 <font class="comment">// get a ptr on renderTrav</font> +00787 CRenderTrav *renderTrav= ownerScene->getRenderTrav(); +00788 <font class="comment">// get a ptr on the driver</font> +00789 IDriver *drv= renderTrav->getDriver(); +00790 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +00791 +00792 +00793 <font class="comment">// update the VBufferHard (create/delete), to maybe render in AGP memory.</font> +00794 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_0">updateVertexBufferHard</a> (drv); +00795 <font class="comment">/* currentVBHard is NULL if must disable it temporarily</font> +00796 <font class="comment"> For now, never disable it, but switch of VBHard may be VERY EXPENSIVE if NV_vertex_array_range2 is not</font> +00797 <font class="comment"> supported (old drivers).</font> +00798 <font class="comment"> */</font> +00799 IVertexBufferHard *currentVBHard= <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>; +00800 +00801 +00802 <font class="comment">// get the skeleton model to which I am binded (else NULL).</font> +00803 CSkeletonModel *skeleton; +00804 skeleton= mi->getSkeletonModel(); +00805 <font class="comment">// must be skinned for renderSkin()</font> +00806 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a> && mi->isSkinned() && skeleton); +00807 <font class="keywordtype">bool</font> bMorphApplied = <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->BlendShapes.size() > 0; +00808 <font class="keywordtype">bool</font> useTangentSpace = <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->needTangentSpace(); +00809 +00810 +00811 <font class="comment">// Profiling</font> +00812 <font class="comment">//===========</font> +00813 <a class="code" href="hierarchical__timer_8h.html#a4">H_AUTO</a>( NL3D_MeshGeom_RenderSkinned ); +00814 +00815 +00816 <font class="comment">// Morphing</font> +00817 <font class="comment">// ========</font> +00818 <font class="keywordflow">if</font> (bMorphApplied) +00819 { +00820 <font class="comment">// Since Skinned we must update original skin vertices and normals because skinning use it</font> +00821 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->initSkinned(&<a class="code" href="classNL3D_1_1CMeshGeom.html#o4">_VBufferOri</a>, +00822 &<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>, +00823 currentVBHard, +00824 useTangentSpace, +00825 &<a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>, +00826 &<a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>, +00827 useTangentSpace ? &<a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a> : NULL, +00828 <font class="keyword">true</font> ); +00829 <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->updateSkinned (mi->getBlendShapeFactors()); +00830 } +00831 +00832 +00833 <font class="comment">// Skinning</font> +00834 <font class="comment">// ========</font> +00835 +00836 <font class="comment">// NB: the skeleton matrix has already been setuped by CSkeletonModel</font> +00837 <font class="comment">// NB: the normalize flag has already been setuped by CSkeletonModel</font> +00838 +00839 +00840 <font class="comment">// apply the skinning: _VBuffer is modified.</font> +00841 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_5">applySkin</a>(skeleton); +00842 +00843 +00844 <font class="comment">// Setup meshVertexProgram</font> +00845 <font class="comment">//===========</font> +00846 +00847 <font class="comment">// use MeshVertexProgram effect?</font> +00848 <font class="keywordtype">bool</font> useMeshVP= <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a> != NULL; +00849 <font class="keywordflow">if</font>( useMeshVP ) +00850 { +00851 CMatrix invertedObjectMatrix; +00852 invertedObjectMatrix = skeleton->getWorldMatrix().inverted(); +00853 <font class="comment">// really ok if success to begin VP</font> +00854 useMeshVP= <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->begin(drv, ownerScene, mi, invertedObjectMatrix, renderTrav->CamPos); +00855 } +00856 +00857 +00858 <font class="comment">// Render the mesh.</font> +00859 <font class="comment">//===========</font> +00860 <font class="comment">// active VB.</font> +00861 <font class="keywordflow">if</font>(currentVBHard != NULL) +00862 drv->activeVertexBufferHard(currentVBHard); +00863 <font class="keywordflow">else</font> +00864 drv->activeVertexBuffer(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>); +00865 +00866 +00867 <font class="comment">// For all _MatrixBlocks</font> +00868 <font class="keywordflow">for</font>(uint mb=0;mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();mb++) +00869 { +00870 CMatrixBlock &mBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb]; +00871 <font class="keywordflow">if</font>(mBlock.RdrPass.size()==0) +00872 <font class="keywordflow">continue</font>; +00873 +00874 <font class="comment">// Render all pass.</font> +00875 <font class="keywordflow">for</font>(uint i=0;i<mBlock.RdrPass.size();i++) +00876 { +00877 CRdrPass &rdrPass= mBlock.RdrPass[i]; +00878 +00879 <font class="comment">// CMaterial Ref</font> +00880 CMaterial &material=mi->Materials[rdrPass.MaterialId]; +00881 +00882 <font class="comment">// Setup VP material</font> +00883 <font class="keywordflow">if</font> (useMeshVP) +00884 { +00885 <font class="keywordflow">if</font>(currentVBHard) +00886 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, currentVBHard); +00887 <font class="keywordflow">else</font> +00888 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->setupForMaterial(material, drv, ownerScene, &<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>); +00889 } +00890 +00891 <font class="comment">// render primitives</font> +00892 drv->render(rdrPass.PBlock, material); +00893 } +00894 } +00895 +00896 <font class="comment">// End VertexProgram effect</font> +00897 <font class="keywordflow">if</font>(useMeshVP) +00898 { +00899 <font class="comment">// Apply it.</font> +00900 <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->end(drv); +00901 } +00902 +00903 } +00904 +00905 +00906 <font class="comment">// ***************************************************************************</font> +<a name="l00907"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#a5">00907</a> <font class="keywordtype">void</font> CMeshGeom::renderSimpleWithMaterial(IDriver *drv, <font class="keyword">const</font> CMatrix &worldMatrix, CMaterial &mat) +00908 { +00909 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +00910 +00911 <font class="comment">// setup matrix</font> +00912 drv->setupModelMatrix(worldMatrix); +00913 +00914 <font class="comment">// active VB.</font> +00915 drv->activeVertexBuffer(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>); +00916 +00917 <font class="comment">// For all _MatrixBlocks</font> +00918 <font class="keywordflow">for</font>(uint mb=0;mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();mb++) +00919 { +00920 CMatrixBlock &mBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb]; +00921 <font class="keywordflow">if</font>(mBlock.RdrPass.size()==0) +00922 <font class="keywordflow">continue</font>; +00923 +00924 <font class="comment">// Render all pass.</font> +00925 <font class="keywordflow">for</font>(uint i=0;i<mBlock.RdrPass.size();i++) +00926 { +00927 CRdrPass &rdrPass= mBlock.RdrPass[i]; +00928 +00929 <font class="comment">// render primitives</font> +00930 drv->render(rdrPass.PBlock, mat); +00931 } +00932 } +00933 +00934 } +00935 +00936 +00937 <font class="comment">// ***************************************************************************</font> +<a name="l00938"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z564_5">00938</a> <font class="keywordtype">void</font> CMeshGeom::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +00939 { +00940 <font class="comment">/*</font> +00941 <font class="comment"> Version 4:</font> +00942 <font class="comment"> - BonesName.</font> +00943 <font class="comment"> Version 3:</font> +00944 <font class="comment"> - MeshVertexProgram.</font> +00945 <font class="comment"> Version 2:</font> +00946 <font class="comment"> - precompute of triangle order. (nothing more to load).</font> +00947 <font class="comment"> Version 1:</font> +00948 <font class="comment"> - added blend shapes</font> +00949 <font class="comment"> Version 0:</font> +00950 <font class="comment"> - separate serialisation CMesh / CMeshGeom.</font> +00951 <font class="comment"> */</font> +00952 sint ver = f.serialVersion (4); +00953 +00954 +00955 <font class="comment">// must have good original Skinned Vertex before writing.</font> +00956 <font class="keywordflow">if</font>( !f.isReading() && _Skinned && !_OriginalSkinRestored ) +00957 { +00958 restoreOriginalSkinVertices(); +00959 } +00960 +00961 +00962 <font class="comment">// Version 4+: Array of bone name</font> +00963 <font class="keywordflow">if</font> (ver >= 4) +00964 { +00965 f.serialCont (_BonesName); +00966 } +00967 +00968 <font class="keywordflow">if</font> (f.isReading()) +00969 { +00970 <font class="comment">// Version3-: Bones index are in skeleton model id list</font> +00971 _BoneIdComputed = (ver < 4); +00972 <font class="comment">// In all case, must recompute usage of parents.</font> +00973 _BoneIdExtended= <font class="keyword">false</font>; +00974 } +00975 <font class="keywordflow">else</font> +00976 { +00977 <font class="comment">// Warning, if you have skinned this shape, you can't write it anymore because skinning id have been changed! </font> +00978 <a class="code" href="debug_8h.html#a6">nlassert</a> (_BoneIdComputed==<font class="keyword">false</font>); +00979 } +00980 +00981 <font class="comment">// Version3+: MeshVertexProgram.</font> +00982 <font class="keywordflow">if</font> (ver >= 3) +00983 { +00984 IMeshVertexProgram *mvp= NULL; +00985 <font class="keywordflow">if</font>(f.isReading()) +00986 { +00987 f.serialPolyPtr(mvp); +00988 _MeshVertexProgram= mvp; +00989 } +00990 <font class="keywordflow">else</font> +00991 { +00992 mvp= _MeshVertexProgram; +00993 f.serialPolyPtr(mvp); +00994 } +00995 } +00996 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(f.isReading()) +00997 { +00998 <font class="comment">// release vp</font> +00999 _MeshVertexProgram= NULL; +01000 } +01001 +01002 <font class="comment">// Version1+: _MeshMorpher.</font> +01003 <font class="keywordflow">if</font> (ver >= 1) +01004 f.serial (*_MeshMorpher); +01005 +01006 <font class="comment">// serial geometry.</font> +01007 f.serial (_VBuffer); +01008 f.serialCont (_MatrixBlocks); +01009 f.serial (_BBox); +01010 f.serial (_Skinned); +01011 +01012 +01013 <font class="comment">// If _VertexBuffer changed, flag the VertexBufferHard.</font> +01014 <font class="keywordflow">if</font>(f.isReading()) +01015 { +01016 _VertexBufferHardDirty = <font class="keyword">true</font>; +01017 +01018 <font class="comment">// if >= version 2, reorder of triangles is precomputed, else compute it now.</font> +01019 <font class="keywordflow">if</font>(ver < 2 ) +01020 { +01021 optimizeTriangleOrder(); +01022 } +01023 } +01024 +01025 <font class="comment">// Skinning: If Version < 4, _BonesName are not present, must compute _BonesId from localId</font> +01026 <font class="comment">// Else it is computed at first computeBonesId().</font> +01027 <font class="keywordflow">if</font>(ver < 4) +01028 buildBoneUsageVer3(); +01029 +01030 <font class="comment">// TestYoyo</font> +01031 <font class="comment">//_MeshVertexProgram= NULL;</font> +01032 <font class="comment">/*{</font> +01033 <font class="comment"> uint numTris= 0;</font> +01034 <font class="comment"> for(uint i=0;i<_MatrixBlocks.size();i++)</font> +01035 <font class="comment"> {</font> +01036 <font class="comment"> for(uint j=0;j<_MatrixBlocks[i].RdrPass.size();j++)</font> +01037 <font class="comment"> numTris+= _MatrixBlocks[i].RdrPass[j].PBlock.getNumTri();</font> +01038 <font class="comment"> }</font> +01039 <font class="comment"> nlinfo("YOYO: %d Vertices. %d Triangles.", _VBuffer.getNumVertices(), numTris);</font> +01040 <font class="comment"> }*/</font> +01041 +01042 <font class="comment">// Some runtime not serialized compilation</font> +01043 <font class="keywordflow">if</font>(f.isReading()) +01044 compileRunTime(); +01045 } +01046 +01047 +01048 <font class="comment">// ***************************************************************************</font> +<a name="l01049"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#c2">01049</a> <font class="keywordtype">void</font> CMeshGeom::compileRunTime() +01050 { +01051 <font class="comment">// if skinned, prepare skinning</font> +01052 <font class="keywordflow">if</font>(_Skinned) +01053 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_3">bkupOriginalSkinVertices</a>(); +01054 +01055 <font class="comment">// Do precise clipping for big object??</font> +01056 <a class="code" href="classNL3D_1_1CMeshGeom.html#o14">_PreciseClipping</a>= <a class="code" href="classNL3D_1_1CMeshGeom.html#o6">_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>; +01057 +01058 <font class="comment">// Support MeshBlockRendering only if not skinned/meshMorphed.</font> +01059 <a class="code" href="classNL3D_1_1CMeshGeom.html#z569_0">_SupportMeshBlockRendering</a>= !<a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o15">_MeshMorpher</a>->BlendShapes.size()==0; +01060 +01061 <font class="comment">// true only if one matrix block, and at least one rdrPass.</font> +01062 <a class="code" href="classNL3D_1_1CMeshGeom.html#z569_0">_SupportMeshBlockRendering</a>= <a class="code" href="classNL3D_1_1CMeshGeom.html#z569_0">_SupportMeshBlockRendering</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size()==1 && <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[0].RdrPass.size()>0; +01063 +01064 <font class="comment">// \todo yoyo: support later MeshVertexProgram </font> +01065 <a class="code" href="classNL3D_1_1CMeshGeom.html#z569_0">_SupportMeshBlockRendering</a>= <a class="code" href="classNL3D_1_1CMeshGeom.html#z569_0">_SupportMeshBlockRendering</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>==NULL; +01066 +01067 <font class="comment">// TestYoyo</font> +01068 <font class="comment">//_SupportMeshBlockRendering= false;</font> +01069 } +01070 +01071 +01072 <font class="comment">// ***************************************************************************</font> +01073 <font class="comment">// ***************************************************************************</font> +01074 <font class="comment">// Skinning.</font> +01075 <font class="comment">// ***************************************************************************</font> +01076 <font class="comment">// ***************************************************************************</font> +01077 +01078 +01079 <font class="comment">// ***************************************************************************</font> +<a name="l01080"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_1">01080</a> <font class="keywordtype">void</font> CMeshGeom::buildSkin(CMesh::CMeshBuild &m, std::vector<CFaceTmp> &tmpFaces) +01081 { +01082 sint i,j,k; +01083 <a class="code" href="classNL3D_1_1CMeshGeom.html#u0">TBoneMap</a> remainingBones; +01084 list<uint> remainingFaces; +01085 +01086 +01087 <font class="comment">// 0. normalize SkinWeights: for all weights at 0, copy the matrixId from 0th matrix => no random/bad use of matrix.</font> +01088 <font class="comment">//================================</font> +01089 <font class="keywordflow">for</font>(i=0;i<(sint)m.SkinWeights.size();i++) +01090 { +01091 CMesh::CSkinWeight &sw= m.SkinWeights[i]; +01092 +01093 <font class="comment">// 0th weight must not be 0.</font> +01094 <a class="code" href="debug_8h.html#a6">nlassert</a>(sw.Weights[0]!=0); +01095 +01096 <font class="comment">// Begin at 1, tests all other weights.</font> +01097 <font class="keywordflow">for</font>(j=1;j<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;j++) +01098 { +01099 <font class="comment">// We don't use this entry??</font> +01100 <font class="keywordflow">if</font>(sw.Weights[j]==0) +01101 { +01102 <font class="comment">// Setup MatrixId so that this vertex do no use more matrix than it really wants.</font> +01103 sw.MatrixId[j]= sw.MatrixId[0]; +01104 } +01105 } +01106 } +01107 +01108 +01109 <font class="comment">// 1. build the list of used/remaining bones, in ascending order. (so we use the depth-first topolgy of hierarchy).</font> +01110 <font class="comment">//================================</font> +01111 <font class="keywordflow">for</font>(i=0;i<(sint)tmpFaces.size();i++) +01112 { +01113 CFaceTmp &face= tmpFaces[i]; +01114 +01115 <font class="keywordflow">for</font>(j=0;j<3;j++) +01116 { +01117 CMesh::CSkinWeight &sw= m.SkinWeights[face.Corner[j].Vertex]; +01118 <font class="keywordflow">for</font>(k=0;k<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;k++) +01119 { +01120 <font class="comment">// insert (if not already here) the used bone in the set.</font> +01121 <font class="comment">// and insert his refcount. (NB: ctor() init it to 0 :) ).</font> +01122 remainingBones[sw.MatrixId[k]].RefCount++; +01123 } +01124 } +01125 } +01126 +01127 +01128 <font class="comment">// 2. Create the list of un-inserted faces.</font> +01129 <font class="comment">//================================</font> +01130 <font class="keywordflow">for</font>(i=0;i<(sint)tmpFaces.size();i++) +01131 { +01132 remainingFaces.push_back(i); +01133 } +01134 +01135 +01136 +01137 <font class="comment">// 3. Create as many Blocks as necessary.</font> +01138 <font class="comment">//================================</font> +01139 <font class="comment">// Which bones a face use (up to 12).</font> +01140 vector<uint> boneUse; +01141 boneUse.reserve(<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>*3); +01142 +01143 <font class="comment">// While still exist faces.</font> +01144 <font class="keywordflow">while</font>(!remainingFaces.empty()) +01145 { +01146 <font class="comment">// create a new matrix block.</font> +01147 <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.push_back(CMatrixBlock()); +01148 CMatrixBlock &matrixBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size()-1]; +01149 matrixBlock.NumMatrix=0; +01150 +01151 <font class="comment">// a. reset remainingBones as not inserted in the current matrixBlock.</font> +01152 <font class="comment">//============================</font> +01153 <a class="code" href="classNL3D_1_1CMeshGeom.html#u1">ItBoneMap</a> itBone; +01154 <font class="keywordflow">for</font>(itBone= remainingBones.begin();itBone!=remainingBones.end();itBone++) +01155 { +01156 itBone->second.Inserted= <font class="keyword">false</font>; +01157 } +01158 +01159 +01160 <font class="comment">// b. while still exist bones, try to insert faces which use them in matrixBlock.</font> +01161 <font class="comment">//============================</font> +01162 <font class="keywordflow">while</font>(!remainingBones.empty()) +01163 { +01164 <font class="comment">// get the first bone from the map. (remind: depth-first order).</font> +01165 uint currentBoneId= remainingBones.begin()->first; +01166 +01167 <font class="comment">// If no more faces in the remainingFace list use this bone, remove it, and continue.</font> +01168 <font class="keywordflow">if</font>(remainingBones.begin()->second.RefCount==0) +01169 { +01170 remainingBones.erase(remainingBones.begin()); +01171 <font class="keywordflow">continue</font>; +01172 } +01173 +01174 <font class="comment">// this is a marker, to know if a face insertion will occurs.</font> +01175 <font class="keywordtype">bool</font> faceAdded= <font class="keyword">false</font>; +01176 +01177 <font class="comment">// traverse all faces, trying to insert them in current MatrixBlock processed.</font> +01178 list<uint>::iterator itFace; +01179 <font class="keywordflow">for</font>(itFace= remainingFaces.begin(); itFace!=remainingFaces.end();) +01180 { +01181 <font class="keywordtype">bool</font> useCurrentBoneId; +01182 uint newBoneAdded; +01183 +01184 <font class="comment">// i/ Get info on current face.</font> +01185 <font class="comment">//-----------------------------</font> +01186 +01187 <font class="comment">// build which bones this face use.</font> +01188 tmpFaces[*itFace].buildBoneUse(boneUse, m.SkinWeights); +01189 +01190 <font class="comment">// test if this face use the currentBoneId.</font> +01191 useCurrentBoneId= <font class="keyword">false</font>; +01192 <font class="keywordflow">for</font>(i=0;i<(sint)boneUse.size();i++) +01193 { +01194 <font class="comment">// if this face use the currentBoneId</font> +01195 <font class="keywordflow">if</font>(boneUse[i]==currentBoneId) +01196 { +01197 useCurrentBoneId= <font class="keyword">true</font>; +01198 <font class="keywordflow">break</font>; +01199 } +01200 } +01201 <font class="comment">// compute how many bones that are not in the current matrixblock this face use.</font> +01202 newBoneAdded=0; +01203 <font class="keywordflow">for</font>(i=0;i<(sint)boneUse.size();i++) +01204 { +01205 <font class="comment">// if this bone is not inserted in the current matrix block, inform it.</font> +01206 <font class="keywordflow">if</font>(!remainingBones[boneUse[i]].Inserted) +01207 newBoneAdded++; +01208 } +01209 +01210 +01211 <font class="comment">// ii/ insert/reject face.</font> +01212 <font class="comment">//------------------------</font> +01213 +01214 <font class="comment">// If this face do not add any more bone, we can insert it into the current matrixblock.</font> +01215 <font class="comment">// If it use the currentBoneId, and do not explode max count, we allow insert it too in the current matrixblock.</font> +01216 <font class="keywordflow">if</font>( newBoneAdded==0 || +01217 (useCurrentBoneId && newBoneAdded+matrixBlock.NumMatrix < IDriver::MaxModelMatrix) ) +01218 { +01219 <font class="comment">// Insert this face in the current matrix block</font> +01220 +01221 CFaceTmp &face= tmpFaces[*itFace]; +01222 +01223 <font class="comment">// for all vertices of this face.</font> +01224 <font class="keywordflow">for</font>(j=0;j<3;j++) +01225 { +01226 CMesh::CSkinWeight &sw= m.SkinWeights[face.Corner[j].Vertex]; +01227 +01228 <font class="comment">// for each corner weight (4)</font> +01229 <font class="keywordflow">for</font>(k=0;k<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;k++) +01230 { +01231 <font class="comment">// get the global boneId this corner weight use.</font> +01232 uint boneId= sw.MatrixId[k]; +01233 <font class="comment">// get the CBoneTmp this corner weight use.</font> +01234 CBoneTmp &bone= remainingBones[boneId]; +01235 +01236 <font class="comment">// decRef the bone .</font> +01237 bone.RefCount--; +01238 +01239 <font class="comment">// Is this bone already inserted in the MatrixBlock ?</font> +01240 <font class="keywordflow">if</font>( !bone.Inserted ) +01241 { +01242 <font class="comment">// No, insert it.</font> +01243 bone.Inserted= <font class="keyword">true</font>; +01244 <font class="comment">// link it to the MatrixId in the current matrixBlock.</font> +01245 bone.MatrixIdInMB= matrixBlock.NumMatrix; +01246 +01247 <font class="comment">// modify the matrixBlock</font> +01248 matrixBlock.MatrixId[matrixBlock.NumMatrix]= boneId; +01249 <font class="comment">// increment the number of matrix in the matrixBlock.</font> +01250 matrixBlock.NumMatrix++; +01251 } +01252 +01253 <font class="comment">// Copy Weight info for this Corner.</font> +01254 <font class="comment">// Set what matrix in the current matrix block this corner use.</font> +01255 face.Corner[j].Palette.MatrixId[k]= bone.MatrixIdInMB; +01256 <font class="comment">// Set weight.</font> +01257 face.Corner[j].Weights[k]= sw.Weights[k]; +01258 } +01259 } +01260 +01261 <font class="comment">// to Which matrixblock this face is inserted.</font> +01262 face.MatrixBlockId= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size()-1; +01263 +01264 <font class="comment">// remove the face from remain face list.</font> +01265 itFace= remainingFaces.erase(itFace); +01266 +01267 <font class="comment">// inform the algorithm that a face has been added.</font> +01268 faceAdded= <font class="keyword">true</font>; +01269 } +01270 <font class="keywordflow">else</font> +01271 { +01272 <font class="comment">// do not append this face to the current matrix block, skip to the next</font> +01273 itFace++; +01274 } +01275 } +01276 +01277 <font class="comment">// If no faces have been added during this pass, we are blocked, and either the MatrixBlock may be full,</font> +01278 <font class="comment">// or there is no more face. So quit this block and process a new one.</font> +01279 <font class="keywordflow">if</font>(!faceAdded) +01280 <font class="keywordflow">break</font>; +01281 } +01282 +01283 } +01284 <font class="comment">// NB: at the end of this loop, remainingBones may not be empty(), but all remainingBones should have RefCount==0.</font> +01285 +01286 +01287 +01288 <font class="comment">// 4. Re-order matrix use in MatrixBlocks, for minimum matrix change between MatrixBlocks.</font> +01289 <font class="comment">//================================</font> +01290 vector<CMatrixBlockRemap> blockRemaps; +01291 blockRemaps.resize(<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size()); +01292 +01293 +01294 <font class="comment">// For all MatrixBlocks > first, try to "mirror" bones from previous.</font> +01295 <font class="keywordflow">for</font>(i=1;i<(sint)<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();i++) +01296 { +01297 CMatrixBlock &mBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[i]; +01298 CMatrixBlock &mPrevBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[i-1]; +01299 CMatrixBlockRemap &remap= blockRemaps[i]; +01300 +01301 <font class="comment">// First bkup the bone ids in remap table.</font> +01302 <font class="keywordflow">for</font>(j=0;j<(sint)mBlock.NumMatrix;j++) +01303 { +01304 remap.Remap[j]= mBlock.MatrixId[j]; +01305 } +01306 +01307 <font class="comment">// For all ids of this blocks, try to mirror them.</font> +01308 <font class="keywordflow">for</font>(j=0;j<(sint)mBlock.NumMatrix;j++) +01309 { +01310 <font class="comment">// get the location of this bone in the prev bone.</font> +01311 sint idLoc= mPrevBlock.getMatrixIdLocation(mBlock.MatrixId[j]); +01312 <font class="comment">// If not found, or if bigger than current array, fails (cant be mirrored).</font> +01313 <font class="comment">// Or if already mirrored.</font> +01314 <font class="keywordflow">if</font>(idLoc==-1 || idLoc>=(sint)mBlock.NumMatrix || idLoc==j) +01315 { +01316 <font class="comment">// next id.</font> +01317 j++; +01318 } +01319 <font class="keywordflow">else</font> +01320 { +01321 <font class="comment">// puts me on my mirrored location. and swap with the current one at this mirrored location.</font> +01322 swap(mBlock.MatrixId[j], mBlock.MatrixId[idLoc]); +01323 <font class="comment">// mBlock.MatrixId[j] is now a candidate for mirror.</font> +01324 } +01325 } +01326 +01327 <font class="comment">// Then build the Remap table, to re-order faces matrixId which use this matrix block.</font> +01328 <font class="keywordflow">for</font>(j=0;j<(sint)mBlock.NumMatrix;j++) +01329 { +01330 <font class="comment">// get the boneid which was at this position j before.</font> +01331 uint boneId= remap.Remap[j]; +01332 <font class="comment">// search his new position, and store the result in the remap table.</font> +01333 remap.Remap[j]= mBlock.getMatrixIdLocation(boneId); +01334 } +01335 +01336 <font class="comment">// NB: this matrixBlock is re-ordered. next matrixBlock use this state.</font> +01337 } +01338 +01339 +01340 <font class="comment">// For all faces/corners/weights, remap MatrixIds.</font> +01341 <font class="keywordflow">for</font>(i=0;i<(sint)tmpFaces.size();i++) +01342 { +01343 CFaceTmp &face= tmpFaces[i]; +01344 <font class="comment">// do it but for matrixblock0.</font> +01345 <font class="keywordflow">if</font>(face.MatrixBlockId!=0) +01346 { +01347 CMatrixBlockRemap &remap= blockRemaps[face.MatrixBlockId]; +01348 <font class="comment">// For all corners.</font> +01349 <font class="keywordflow">for</font>(j=0;j<3;j++) +01350 { +01351 <font class="keywordflow">for</font>(k=0;k<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;k++) +01352 { +01353 uint oldId= face.Corner[j].Palette.MatrixId[k]; +01354 face.Corner[j].Palette.MatrixId[k]= (uint8)remap.Remap[oldId]; +01355 } +01356 } +01357 } +01358 } +01359 +01360 } +01361 +01362 +01363 <font class="comment">// ***************************************************************************</font> +<a name="l01364"></a><a class="code" href="structNL3D_1_1CMeshGeom_1_1CFaceTmp.html#a2">01364</a> <font class="keywordtype">void</font> CMeshGeom::CFaceTmp::buildBoneUse(vector<uint> &boneUse, vector<CMesh::CSkinWeight> &skinWeights) +01365 { +01366 boneUse.clear(); +01367 +01368 <font class="comment">// For the 3 corners of the face.</font> +01369 <font class="keywordflow">for</font>(sint i=0;i<3;i++) +01370 { +01371 <font class="comment">// get the CSkinWeight of this vertex.</font> +01372 CMesh::CSkinWeight &sw= skinWeights[<a class="code" href="structNL3D_1_1CMeshGeom_1_1CFaceTmp.html#m0">Corner</a>[i].Vertex]; +01373 +01374 <font class="comment">// For all skin weights of this vertex,</font> +01375 <font class="keywordflow">for</font>(sint j=0;j<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;j++) +01376 { +01377 uint boneId= sw.MatrixId[j]; +01378 <font class="comment">// insert (if not in the array) this bone.</font> +01379 <font class="keywordflow">if</font>( find(boneUse.begin(), boneUse.end(), boneId)==boneUse.end() ) +01380 boneUse.push_back(boneId); +01381 } +01382 } +01383 +01384 +01385 } +01386 +01387 +01388 +01389 <font class="comment">// ***************************************************************************</font> +<a name="l01390"></a><a class="code" href="classNL3D_1_1CMeshGeom_1_1CMatrixBlock.html#a1">01390</a> sint CMeshGeom::CMatrixBlock::getMatrixIdLocation(uint32 boneId)<font class="keyword"> const</font> +01391 <font class="keyword"></font>{ +01392 <font class="keywordflow">for</font>(uint i=0;i<<a class="code" href="classNL3D_1_1CMeshGeom_1_1CMatrixBlock.html#m1">NumMatrix</a>;i++) +01393 { +01394 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom_1_1CMatrixBlock.html#m0">MatrixId</a>[i]==boneId) +01395 <font class="keywordflow">return</font> i; +01396 } +01397 +01398 <font class="comment">// not found.</font> +01399 <font class="keywordflow">return</font> -1; +01400 } +01401 +01402 +01403 <font class="comment">// ***************************************************************************</font> +<a name="l01404"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z564_4">01404</a> <font class="keywordtype">float</font> CMeshGeom::getNumTriangles (<font class="keywordtype">float</font> distance) +01405 { +01406 <font class="comment">// Sum of triangles</font> +01407 uint32 triCount=0; +01408 +01409 <font class="comment">// For each matrix block</font> +01410 uint mbCount=<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size(); +01411 <font class="keywordflow">for</font> (uint mb=0; mb<mbCount; mb++) +01412 { +01413 CMatrixBlock &block=<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb]; +01414 +01415 <font class="comment">// Count of primitive block</font> +01416 uint pCount=block.RdrPass.size(); +01417 <font class="keywordflow">for</font> (uint pb=0; pb<pCount; pb++) +01418 { +01419 <font class="comment">// Ref on the primitive block</font> +01420 CRdrPass &pass=block.RdrPass[pb]; +01421 +01422 <font class="comment">// Sum tri</font> +01423 triCount+=pass.PBlock.getNumTriangles (); +01424 } +01425 } +01426 <font class="keywordflow">return</font> (float)triCount; +01427 } +01428 +01429 +01430 <font class="comment">// ***************************************************************************</font> +<a name="l01431"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z566_1">01431</a> <font class="keywordtype">void</font> CMeshGeom::computeBonesId (CSkeletonModel *skeleton) +01432 { +01433 <font class="comment">// Already computed ?</font> +01434 <font class="keywordflow">if</font> (!<a class="code" href="classNL3D_1_1CMeshGeom.html#o9">_BoneIdComputed</a>) +01435 { +01436 <font class="comment">// Get a pointer on the skeleton</font> +01437 <a class="code" href="debug_8h.html#a6">nlassert</a> (skeleton); +01438 <font class="keywordflow">if</font> (skeleton) +01439 { +01440 <font class="comment">// Resize boneId to the good size.</font> +01441 <a class="code" href="classNL3D_1_1CMeshGeom.html#o12">_BonesId</a>.resize(<a class="code" href="classNL3D_1_1CMeshGeom.html#o11">_BonesName</a>.size()); +01442 +01443 <font class="comment">// For each matrix block</font> +01444 uint matrixBlock; +01445 <font class="keywordflow">for</font> (matrixBlock=0; matrixBlock<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size(); matrixBlock++) +01446 { +01447 <font class="comment">// Ref on the matrix block</font> +01448 CMatrixBlock &mb = <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[matrixBlock]; +01449 +01450 <font class="comment">// For each matrix</font> +01451 uint <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>; +01452 <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><mb.NumMatrix; <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>++) +01453 { +01454 <font class="comment">// Get bone id in the skeleton</font> +01455 <a class="code" href="debug_8h.html#a6">nlassert</a> (mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]<<a class="code" href="classNL3D_1_1CMeshGeom.html#o11">_BonesName</a>.size()); +01456 sint32 boneId = skeleton->getBoneIdByName (<a class="code" href="classNL3D_1_1CMeshGeom.html#o11">_BonesName</a>[mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]]); +01457 +01458 <font class="comment">// Setup the _BoneId.</font> +01459 <a class="code" href="classNL3D_1_1CMeshGeom.html#o12">_BonesId</a>[mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]]= boneId; +01460 +01461 <font class="comment">// Bones found ?</font> +01462 <font class="keywordflow">if</font> (boneId != -1) +01463 { +01464 <font class="comment">// Set the bone id</font> +01465 mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>] = (uint32)boneId; +01466 } +01467 <font class="keywordflow">else</font> +01468 { +01469 <font class="comment">// Put id 0</font> +01470 mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>] = 0; +01471 +01472 <font class="comment">// Error</font> +01473 <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_1CMeshGeom.html#o11">_BonesName</a>[mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]].c_str()); +01474 } +01475 } +01476 } +01477 +01478 <font class="comment">// Computed</font> +01479 <a class="code" href="classNL3D_1_1CMeshGeom.html#o9">_BoneIdComputed</a> = <font class="keyword">true</font>; +01480 } +01481 } +01482 +01483 <font class="comment">// Already extended ?</font> +01484 <font class="keywordflow">if</font> (!<a class="code" href="classNL3D_1_1CMeshGeom.html#o10">_BoneIdExtended</a>) +01485 { +01486 <a class="code" href="debug_8h.html#a6">nlassert</a> (skeleton); +01487 <font class="keywordflow">if</font> (skeleton) +01488 { +01489 <font class="comment">// the total bone Usage of the mesh.</font> +01490 vector<bool> boneUsage; +01491 boneUsage.resize(skeleton->Bones.size(), <font class="keyword">false</font>); +01492 +01493 <font class="comment">// for all Bones marked as valid.</font> +01494 uint i; +01495 <font class="keywordflow">for</font>(i=0; i<<a class="code" href="classNL3D_1_1CMeshGeom.html#o12">_BonesId</a>.size(); i++) +01496 { +01497 <font class="comment">// if not a valid boneId, skip it.</font> +01498 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o12">_BonesId</a>[i]<0) +01499 <font class="keywordflow">continue</font>; +01500 +01501 <font class="comment">// mark him and his father in boneUsage.</font> +01502 skeleton->flagBoneAndParents(<a class="code" href="classNL3D_1_1CMeshGeom.html#o12">_BonesId</a>[i], boneUsage); +01503 } +01504 +01505 <font class="comment">// fill _BonesIdExt with bones of _BonesId and their parents.</font> +01506 <a class="code" href="classNL3D_1_1CMeshGeom.html#o13">_BonesIdExt</a>.clear(); +01507 <font class="keywordflow">for</font>(i=0; i<boneUsage.size();i++) +01508 { +01509 <font class="comment">// if the bone is used by the mesh, add it to BoneIdExt.</font> +01510 <font class="keywordflow">if</font>(boneUsage[i]) +01511 <a class="code" href="classNL3D_1_1CMeshGeom.html#o13">_BonesIdExt</a>.push_back(i); +01512 } +01513 +01514 } +01515 +01516 <font class="comment">// Extended</font> +01517 <a class="code" href="classNL3D_1_1CMeshGeom.html#o10">_BoneIdExtended</a>= <font class="keyword">true</font>; +01518 } +01519 +01520 } +01521 +01522 +01523 <font class="comment">// ***************************************************************************</font> +<a name="l01524"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_2">01524</a> <font class="keywordtype">void</font> CMeshGeom::buildBoneUsageVer3 () +01525 { +01526 <font class="keywordflow">if</font>(_Skinned) +01527 { +01528 <font class="comment">// parse all matrixBlocks, couting MaxBoneId used.</font> +01529 uint32 maxBoneId= 0; +01530 <font class="comment">// For each matrix block</font> +01531 uint matrixBlock; +01532 <font class="keywordflow">for</font> (matrixBlock=0; matrixBlock<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size(); matrixBlock++) +01533 { +01534 CMatrixBlock &mb = <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[matrixBlock]; +01535 <font class="comment">// For each matrix</font> +01536 <font class="keywordflow">for</font> (uint <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><mb.NumMatrix; <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>++) +01537 { +01538 maxBoneId= max(mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>], maxBoneId); +01539 } +01540 } +01541 +01542 <font class="comment">// alloc an array of maxBoneId+1, reset to 0.</font> +01543 std::vector<uint8> boneUsage; +01544 boneUsage.resize(maxBoneId+1, 0); +01545 +01546 <font class="comment">// reparse all matrixBlocks, counting usage for each bone.</font> +01547 <font class="keywordflow">for</font> (matrixBlock=0; matrixBlock<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size(); matrixBlock++) +01548 { +01549 CMatrixBlock &mb = <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[matrixBlock]; +01550 <font class="comment">// For each matrix</font> +01551 <font class="keywordflow">for</font> (uint <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><mb.NumMatrix; <a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>++) +01552 { +01553 <font class="comment">// mark this bone as used.</font> +01554 boneUsage[mb.MatrixId[<a class="code" href="driver__opengl__extension__def_8h.html#a370">matrix</a>]]= 1; +01555 } +01556 } +01557 +01558 <font class="comment">// For each bone used</font> +01559 <a class="code" href="classNL3D_1_1CMeshGeom.html#o12">_BonesId</a>.clear(); +01560 <font class="keywordflow">for</font>(uint i=0; i<boneUsage.size();i++) +01561 { +01562 <font class="comment">// if the bone is used by the mesh, add it to BoneId.</font> +01563 <font class="keywordflow">if</font>(boneUsage[i]) +01564 <a class="code" href="classNL3D_1_1CMeshGeom.html#o12">_BonesId</a>.push_back(i); +01565 } +01566 } +01567 } +01568 +01569 +01570 <font class="comment">// ***************************************************************************</font> +<a name="l01571"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z566_2">01571</a> <font class="keywordtype">void</font> CMeshGeom::updateSkeletonUsage(CSkeletonModel *sm, <font class="keywordtype">bool</font> increment) +01572 { +01573 <font class="comment">// For all Bones used by this mesh.</font> +01574 <font class="keywordflow">for</font>(uint i=0; i<<a class="code" href="classNL3D_1_1CMeshGeom.html#o13">_BonesIdExt</a>.size();i++) +01575 { +01576 uint boneId= <a class="code" href="classNL3D_1_1CMeshGeom.html#o13">_BonesIdExt</a>[i]; +01577 <font class="comment">// Some explicit Error.</font> +01578 <font class="keywordflow">if</font>(boneId>=sm->Bones.size()) +01579 <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); +01580 <font class="comment">// increment or decrement not Forced, because CMeshGeom use getActiveBoneSkinMatrix().</font> +01581 <font class="keywordflow">if</font>(increment) +01582 sm->incBoneUsage(boneId, CSkeletonModel::UsageNormal); +01583 <font class="keywordflow">else</font> +01584 sm->decBoneUsage(boneId, CSkeletonModel::UsageNormal); +01585 } +01586 } +01587 +01588 +01589 <font class="comment">// ***************************************************************************</font> +<a name="l01590"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_3">01590</a> <font class="keywordtype">void</font> CMeshGeom::bkupOriginalSkinVertices() +01591 { +01592 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a>); +01593 +01594 <font class="comment">// reset</font> +01595 <a class="code" href="namespaceNLMISC.html#a222">contReset</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>); +01596 <a class="code" href="namespaceNLMISC.html#a222">contReset</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>); +01597 <a class="code" href="namespaceNLMISC.html#a222">contReset</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a>); +01598 +01599 <font class="comment">// get num of vertices</font> +01600 uint numVertices= <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumVertices(); +01601 +01602 <font class="comment">// Copy VBuffer content into Original vertices normals.</font> +01603 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexFormat() & CVertexBuffer::PositionFlag) +01604 { +01605 <font class="comment">// copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).</font> +01606 <a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>.resize(numVertices); +01607 <font class="keywordflow">for</font>(uint i=0; i<numVertices;i++) +01608 { +01609 <a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>[i]= *(CVector*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexCoordPointer(i); +01610 } +01611 } +01612 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexFormat() & CVertexBuffer::NormalFlag) +01613 { +01614 <font class="comment">// copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).</font> +01615 <a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>.resize(numVertices); +01616 <font class="keywordflow">for</font>(uint i=0; i<numVertices;i++) +01617 { +01618 <a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>[i]= *(CVector*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNormalCoordPointer(i); +01619 } +01620 } +01621 +01622 <font class="comment">// is there tangent space added ?</font> +01623 <font class="keywordflow">if</font> (<a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->needTangentSpace()) +01624 { +01625 <font class="comment">// yes, backup it</font> +01626 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumTexCoordUsed() > 0); +01627 uint tgSpaceStage = <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumTexCoordUsed() - 1; +01628 <a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a>.resize(numVertices); +01629 <font class="keywordflow">for</font>(uint i=0; i<numVertices;i++) +01630 { +01631 <a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a>[i]= *(CVector*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getTexCoordPointer(i, tgSpaceStage); +01632 } +01633 } +01634 } +01635 +01636 +01637 <font class="comment">// ***************************************************************************</font> +<a name="l01638"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_4">01638</a> <font class="keywordtype">void</font> CMeshGeom::restoreOriginalSkinVertices() +01639 { +01640 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o7">_Skinned</a>); +01641 +01642 <font class="comment">// get num of vertices</font> +01643 uint numVertices= <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumVertices(); +01644 +01645 <font class="comment">// Copy VBuffer content into Original vertices normals.</font> +01646 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexFormat() & CVertexBuffer::PositionFlag) +01647 { +01648 <font class="comment">// copy vertices from VBuffer. (NB: unusefull geomorphed vertices are still copied, but doesn't matter).</font> +01649 <font class="keywordflow">for</font>(uint i=0; i<numVertices;i++) +01650 { +01651 *(CVector*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexCoordPointer(i)= <a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>[i]; +01652 } +01653 } +01654 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexFormat() & CVertexBuffer::NormalFlag) +01655 { +01656 <font class="comment">// copy normals from VBuffer. (NB: unusefull geomorphed normals are still copied, but doesn't matter).</font> +01657 <font class="keywordflow">for</font>(uint i=0; i<numVertices;i++) +01658 { +01659 *(CVector*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNormalCoordPointer(i)= <a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>[i]; +01660 } +01661 } +01662 <font class="keywordflow">if</font> (<a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a> && <a class="code" href="classNL3D_1_1CMeshGeom.html#o16">_MeshVertexProgram</a>->needTangentSpace()) +01663 { +01664 uint numTexCoords = <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumTexCoordUsed(); +01665 <a class="code" href="debug_8h.html#a6">nlassert</a>(numTexCoords >= 2); +01666 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a>.size() == numVertices); +01667 <font class="comment">// copy tangent space vectors</font> +01668 <font class="keywordflow">for</font>(uint i = 0; i < numVertices; ++i) +01669 { +01670 *(CVector*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getTexCoordPointer(i, numTexCoords - 1)= <a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a>[i]; +01671 } +01672 } +01673 +01674 <font class="comment">// cleared</font> +01675 <a class="code" href="classNL3D_1_1CMeshGeom.html#o8">_OriginalSkinRestored</a>= <font class="keyword">true</font>; +01676 } +01677 +01678 +01679 <font class="comment">// ***************************************************************************</font> +01680 <font class="comment">// Flags for software vertex skinning.</font> +<a name="l01681"></a><a class="code" href="mesh_8cpp.html#a0">01681</a> <font class="preprocessor">#define NL3D_SOFTSKIN_VNEEDCOMPUTE 3</font> +<a name="l01682"></a><a class="code" href="mesh_8cpp.html#a1">01682</a> <font class="preprocessor"></font><font class="preprocessor">#define NL3D_SOFTSKIN_VMUSTCOMPUTE 1</font> +<a name="l01683"></a><a class="code" href="mesh_8cpp.html#a2">01683</a> <font class="preprocessor"></font><font class="preprocessor">#define NL3D_SOFTSKIN_VCOMPUTED 0</font> +01684 <font class="preprocessor"></font><font class="comment">// 3 means "vertex may need compute".</font> +01685 <font class="comment">// 1 means "Primitive say vertex must be computed".</font> +01686 <font class="comment">// 0 means "vertex is computed".</font> +01687 +01688 +01689 <font class="comment">// ***************************************************************************</font> +<a name="l01690"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_5">01690</a> <font class="keywordtype">void</font> CMeshGeom::applySkin(CSkeletonModel *skeleton) +01691 { +01692 <font class="comment">// init.</font> +01693 <font class="comment">//===================</font> +01694 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>.empty()) +01695 <font class="keywordflow">return</font>; +01696 +01697 <font class="comment">// Use correct skinning</font> +01698 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0">TSkinType</a> skinType; +01699 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>.empty() ) +01700 skinType= <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u4">SkinPosOnly</a>; +01701 <font class="keywordflow">else</font> <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a>.empty() ) +01702 skinType= <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u5">SkinWithNormal</a>; +01703 <font class="keywordflow">else</font> +01704 skinType= <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u6">SkinWithTgSpace</a>; +01705 +01706 <font class="comment">// Get VB src/dst info/ptrs.</font> +01707 uint numVertices= <a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>.size(); +01708 uint dstStride= <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexSize(); +01709 <font class="comment">// Get dst TgSpace.</font> +01710 uint tgSpaceStage = 0; +01711 <font class="keywordflow">if</font>( skinType>= <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u6">SkinWithTgSpace</a>) +01712 { +01713 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumTexCoordUsed() > 0); +01714 tgSpaceStage= <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumTexCoordUsed() - 1; +01715 } +01716 +01717 <font class="comment">// Mark all vertices flag to not computed.</font> +01718 <font class="keyword">static</font> vector<uint8> skinFlags; +01719 skinFlags.resize(numVertices); +01720 <font class="comment">// reset all flags</font> +01721 memset(&skinFlags[0], <a class="code" href="mesh_8cpp.html#a0">NL3D_SOFTSKIN_VNEEDCOMPUTE</a>, numVertices ); +01722 +01723 +01724 <font class="comment">// For all MatrixBlocks</font> +01725 <font class="comment">//===================</font> +01726 <font class="keywordflow">for</font>(uint mb= 0; mb<<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size();mb++) +01727 { +01728 <font class="comment">// compute matrixes for this block.</font> +01729 <font class="keyword">static</font> CMatrix3x4 matrixes[IDriver::MaxModelMatrix]; +01730 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_7">computeSkinMatrixes</a>(skeleton, matrixes, mb==0?NULL:&<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb-1], <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb]); +01731 +01732 <font class="comment">// check what vertex to skin for this PB.</font> +01733 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_6">flagSkinVerticesForMatrixBlock</a>(&skinFlags[0], <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[mb]); +01734 +01735 <font class="comment">// Get VB src/dst ptrs.</font> +01736 uint8 *pFlag= &skinFlags[0]; +01737 CVector *srcVector= &<a class="code" href="classNL3D_1_1CMeshGeom.html#o0">_OriginalSkinVertices</a>[0]; +01738 uint8 *srcPal= (uint8*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getPaletteSkinPointer(0); +01739 uint8 *srcWgt= (uint8*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getWeightPointer(0); +01740 uint8 *dstVector= (uint8*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexCoordPointer(0); +01741 <font class="comment">// Normal.</font> +01742 CVector *srcNormal= NULL; +01743 uint8 *dstNormal= NULL; +01744 <font class="keywordflow">if</font>(skinType>=<a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u5">SkinWithNormal</a>) +01745 { +01746 srcNormal= &<a class="code" href="classNL3D_1_1CMeshGeom.html#o1">_OriginalSkinNormals</a>[0]; +01747 dstNormal= (uint8*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNormalCoordPointer(0); +01748 } +01749 <font class="comment">// TgSpace.</font> +01750 CVector *srcTgSpace= NULL; +01751 uint8 *dstTgSpace= NULL; +01752 <font class="keywordflow">if</font>(skinType>=<a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u6">SkinWithTgSpace</a>) +01753 { +01754 srcTgSpace= &<a class="code" href="classNL3D_1_1CMeshGeom.html#o2">_OriginalTGSpace</a>[0]; +01755 dstTgSpace= (uint8*)<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getTexCoordPointer(0, tgSpaceStage); +01756 } +01757 +01758 +01759 <font class="comment">// For all vertices that need to be computed.</font> +01760 uint size= numVertices; +01761 <font class="keywordflow">for</font>(;size>0;size--) +01762 { +01763 <font class="comment">// If we must compute this vertex.</font> +01764 <font class="keywordflow">if</font>(*pFlag==<a class="code" href="mesh_8cpp.html#a1">NL3D_SOFTSKIN_VMUSTCOMPUTE</a>) +01765 { +01766 <font class="comment">// Flag this vertex as computed.</font> +01767 *pFlag=<a class="code" href="mesh_8cpp.html#a2">NL3D_SOFTSKIN_VCOMPUTED</a>; +01768 +01769 CPaletteSkin *psPal= (CPaletteSkin*)srcPal; +01770 +01771 <font class="comment">// checks indices.</font> +01772 <a class="code" href="debug_8h.html#a6">nlassert</a>(psPal->MatrixId[0]<IDriver::MaxModelMatrix); +01773 <a class="code" href="debug_8h.html#a6">nlassert</a>(psPal->MatrixId[1]<IDriver::MaxModelMatrix); +01774 <a class="code" href="debug_8h.html#a6">nlassert</a>(psPal->MatrixId[2]<IDriver::MaxModelMatrix); +01775 <a class="code" href="debug_8h.html#a6">nlassert</a>(psPal->MatrixId[3]<IDriver::MaxModelMatrix); +01776 +01777 <font class="comment">// compute vertex part.</font> +01778 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_8">computeSoftwarePointSkinning</a>(matrixes, srcVector, psPal, (<font class="keywordtype">float</font>*)srcWgt, (CVector*)dstVector); +01779 +01780 <font class="comment">// compute normal part.</font> +01781 <font class="keywordflow">if</font>(skinType>=<a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u5">SkinWithNormal</a>) +01782 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_9">computeSoftwareVectorSkinning</a>(matrixes, srcNormal, psPal, (<font class="keywordtype">float</font>*)srcWgt, (CVector*)dstNormal); +01783 +01784 <font class="comment">// compute tg part.</font> +01785 <font class="keywordflow">if</font>(skinType>=<a class="code" href="classNL3D_1_1CMeshGeom.html#z570_0u6">SkinWithTgSpace</a>) +01786 <a class="code" href="classNL3D_1_1CMeshGeom.html#z570_9">computeSoftwareVectorSkinning</a>(matrixes, srcTgSpace, psPal, (<font class="keywordtype">float</font>*)srcWgt, (CVector*)dstTgSpace); +01787 } +01788 +01789 <font class="comment">// inc flags.</font> +01790 pFlag++; +01791 <font class="comment">// inc src (all whatever skin type used...)</font> +01792 srcVector++; +01793 srcNormal++; +01794 srcTgSpace++; +01795 <font class="comment">// inc paletteSkin and dst (all whatever skin type used...)</font> +01796 srcPal+= dstStride; +01797 srcWgt+= dstStride; +01798 dstVector+= dstStride; +01799 dstNormal+= dstStride; +01800 dstTgSpace+= dstStride; +01801 } +01802 } +01803 +01804 +01805 <font class="comment">// dirt</font> +01806 <a class="code" href="classNL3D_1_1CMeshGeom.html#o8">_OriginalSkinRestored</a>= <font class="keyword">false</font>; +01807 } +01808 +01809 +01810 <font class="comment">// ***************************************************************************</font> +<a name="l01811"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_6">01811</a> <font class="keywordtype">void</font> CMeshGeom::flagSkinVerticesForMatrixBlock(uint8 *skinFlags, CMatrixBlock &mb) +01812 { +01813 <font class="keywordflow">for</font>(uint i=0; i<mb.RdrPass.size(); i++) +01814 { +01815 CPrimitiveBlock &PB= mb.RdrPass[i].PBlock; +01816 +01817 uint32 *pIndex; +01818 uint nIndex; +01819 +01820 <font class="comment">// This may be better to flags in 2 pass (first traverse primitives, then test vertices).</font> +01821 <font class="comment">// Better sol for BTB..., because number of tests are divided by 6 (for triangles).</font> +01822 +01823 <font class="comment">// for all prims, indicate which vertex we must compute.</font> +01824 <font class="comment">// nothing if not already computed (ie 0), because 0&1==0.</font> +01825 <font class="comment">// Lines.</font> +01826 pIndex= (uint32*)PB.getLinePointer(); +01827 nIndex= PB.getNumLine()*2; +01828 <font class="keywordflow">for</font>(;nIndex>0;nIndex--, pIndex++) +01829 skinFlags[*pIndex]&= <a class="code" href="mesh_8cpp.html#a1">NL3D_SOFTSKIN_VMUSTCOMPUTE</a>; +01830 <font class="comment">// Tris.</font> +01831 pIndex= (uint32*)PB.getTriPointer(); +01832 nIndex= PB.getNumTri()*3; +01833 <font class="keywordflow">for</font>(;nIndex>0;nIndex--, pIndex++) +01834 skinFlags[*pIndex]&= <a class="code" href="mesh_8cpp.html#a1">NL3D_SOFTSKIN_VMUSTCOMPUTE</a>; +01835 <font class="comment">// Quads.</font> +01836 pIndex= (uint32*)PB.getQuadPointer(); +01837 nIndex= PB.getNumQuad()*4; +01838 <font class="keywordflow">for</font>(;nIndex>0;nIndex--, pIndex++) +01839 skinFlags[*pIndex]&= <a class="code" href="mesh_8cpp.html#a1">NL3D_SOFTSKIN_VMUSTCOMPUTE</a>; +01840 } +01841 } +01842 +01843 +01844 <font class="comment">// ***************************************************************************</font> +<a name="l01845"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_8">01845</a> <font class="keywordtype">void</font> CMeshGeom::computeSoftwarePointSkinning(CMatrix3x4 *matrixes, CVector *srcVec, CPaletteSkin *srcPal, <font class="keywordtype">float</font> *srcWgt, CVector *pDst) +01846 { +01847 CMatrix3x4 *pMat; +01848 +01849 <font class="comment">// \todo yoyo: TODO_OPTIMIZE: SSE verion...</font> +01850 +01851 <font class="comment">// 0th matrix influence.</font> +01852 pMat= matrixes + srcPal->MatrixId[0]; +01853 pMat->mulSetPoint(*srcVec, srcWgt[0], *pDst); +01854 <font class="comment">// 1th matrix influence.</font> +01855 pMat= matrixes + srcPal->MatrixId[1]; +01856 pMat->mulAddPoint(*srcVec, srcWgt[1], *pDst); +01857 <font class="comment">// 2th matrix influence.</font> +01858 pMat= matrixes + srcPal->MatrixId[2]; +01859 pMat->mulAddPoint(*srcVec, srcWgt[2], *pDst); +01860 <font class="comment">// 3th matrix influence.</font> +01861 pMat= matrixes + srcPal->MatrixId[3]; +01862 pMat->mulAddPoint(*srcVec, srcWgt[3], *pDst); +01863 } +01864 +01865 +01866 <font class="comment">// ***************************************************************************</font> +<a name="l01867"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_9">01867</a> <font class="keywordtype">void</font> CMeshGeom::computeSoftwareVectorSkinning(CMatrix3x4 *matrixes, CVector *srcVec, CPaletteSkin *srcPal, <font class="keywordtype">float</font> *srcWgt, CVector *pDst) +01868 { +01869 CMatrix3x4 *pMat; +01870 +01871 <font class="comment">// \todo yoyo: TODO_OPTIMIZE: SSE verion...</font> +01872 +01873 <font class="comment">// 0th matrix influence.</font> +01874 pMat= matrixes + srcPal->MatrixId[0]; +01875 pMat->mulSetVector(*srcVec, srcWgt[0], *pDst); +01876 <font class="comment">// 1th matrix influence.</font> +01877 pMat= matrixes + srcPal->MatrixId[1]; +01878 pMat->mulAddVector(*srcVec, srcWgt[1], *pDst); +01879 <font class="comment">// 2th matrix influence.</font> +01880 pMat= matrixes + srcPal->MatrixId[2]; +01881 pMat->mulAddVector(*srcVec, srcWgt[2], *pDst); +01882 <font class="comment">// 3th matrix influence.</font> +01883 pMat= matrixes + srcPal->MatrixId[3]; +01884 pMat->mulAddVector(*srcVec, srcWgt[3], *pDst); +01885 } +01886 +01887 +01888 <font class="comment">// ***************************************************************************</font> +<a name="l01889"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z570_7">01889</a> <font class="keywordtype">void</font> CMeshGeom::computeSkinMatrixes(CSkeletonModel *skeleton, CMatrix3x4 *matrixes, CMatrixBlock *prevBlock, CMatrixBlock &mBlock) +01890 { +01891 <font class="comment">// For all matrix of this mBlock.</font> +01892 <font class="keywordflow">for</font>(uint idMat=0;idMat<mBlock.NumMatrix;idMat++) +01893 { +01894 uint curBoneId= mBlock.MatrixId[idMat]; +01895 +01896 <font class="comment">// If same matrix binded as previous block, no need to bind!!</font> +01897 <font class="keywordflow">if</font>(prevBlock && idMat<prevBlock->NumMatrix && prevBlock->MatrixId[idMat]== curBoneId) +01898 <font class="keywordflow">continue</font>; +01899 +01900 <font class="comment">// Else, we must setup the matrix </font> +01901 matrixes[idMat].set(skeleton->getActiveBoneSkinMatrix(curBoneId)); +01902 } +01903 } +01904 +01905 +01906 <font class="comment">// ***************************************************************************</font> +01907 <font class="comment">// ***************************************************************************</font> +01908 <font class="comment">// Mesh Block Render Interface</font> +01909 <font class="comment">// ***************************************************************************</font> +01910 <font class="comment">// ***************************************************************************</font> +01911 +01912 +01913 <font class="comment">// ***************************************************************************</font> +<a name="l01914"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_0">01914</a> <font class="keywordtype">bool</font> CMeshGeom::supportMeshBlockRendering ()<font class="keyword"> const</font> +01915 <font class="keyword"></font>{ +01916 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshGeom.html#z569_0">_SupportMeshBlockRendering</a>; +01917 } +01918 +01919 <font class="comment">// ***************************************************************************</font> +<a name="l01920"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_1">01920</a> <font class="keywordtype">bool</font> CMeshGeom::sortPerMaterial()<font class="keyword"> const</font> +01921 <font class="keyword"></font>{ +01922 <font class="keywordflow">return</font> <font class="keyword">true</font>; +01923 } +01924 <font class="comment">// ***************************************************************************</font> +<a name="l01925"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_2">01925</a> uint CMeshGeom::getNumRdrPasses()<font class="keyword"> const </font> +01926 <font class="keyword"></font>{ +01927 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[0].RdrPass.size(); +01928 } +01929 <font class="comment">// ***************************************************************************</font> +<a name="l01930"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_3">01930</a> <font class="keywordtype">void</font> CMeshGeom::beginMesh(CMeshGeomRenderContext &rdrCtx) +01931 { +01932 <font class="keywordflow">if</font>(rdrCtx.RenderThroughVBHeap) +01933 { +01934 <font class="comment">// Don't setup VB in this case, since use the VBHeap setuped one.</font> +01935 } +01936 <font class="keywordflow">else</font> +01937 { +01938 <font class="comment">// update the VBufferHard (create/delete), to maybe render in AGP memory.</font> +01939 <a class="code" href="classNL3D_1_1CMeshGeom.html#z568_0">updateVertexBufferHard</a> ( rdrCtx.Driver ); +01940 +01941 +01942 <font class="comment">// if VB Hard is here, use it.</font> +01943 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a> != NULL) +01944 { +01945 <font class="comment">// active VB Hard.</font> +01946 rdrCtx.Driver->activeVertexBufferHard(<a class="code" href="classNL3D_1_1CMeshGeom.html#z568_1">_VertexBufferHard</a>); +01947 } +01948 <font class="keywordflow">else</font> +01949 { +01950 <font class="comment">// active VB. SoftwareSkinning: reset flags for skinning.</font> +01951 rdrCtx.Driver->activeVertexBuffer(<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>); +01952 } +01953 } +01954 } +01955 <font class="comment">// ***************************************************************************</font> +<a name="l01956"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_4">01956</a> <font class="keywordtype">void</font> CMeshGeom::activeInstance(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *inst, <font class="keywordtype">float</font> polygonCount) +01957 { +01958 <font class="comment">// setup instance matrix</font> +01959 rdrCtx.Driver->setupModelMatrix(inst->getWorldMatrix()); +01960 +01961 <font class="comment">// setupLighting.</font> +01962 inst->changeLightSetup(rdrCtx.RenderTrav); +01963 +01964 <font class="comment">// \todo yoyo: MeshVertexProgram.</font> +01965 } +01966 <font class="comment">// ***************************************************************************</font> +<a name="l01967"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_5">01967</a> <font class="keywordtype">void</font> CMeshGeom::renderPass(CMeshGeomRenderContext &rdrCtx, CMeshBaseInstance *mi, <font class="keywordtype">float</font> polygonCount, uint rdrPassId) +01968 { +01969 CMatrixBlock &mBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[0]; +01970 +01971 CRdrPass &rdrPass= mBlock.RdrPass[rdrPassId]; +01972 <font class="comment">// Render with the Materials of the MeshInstance, only if not blended.</font> +01973 <font class="keywordflow">if</font>( ( (mi->Materials[rdrPass.MaterialId].getBlend() == <font class="keyword">false</font>) ) ) +01974 { +01975 <font class="comment">// \todo yoyo: MeshVertexProgram.</font> +01976 +01977 <font class="keywordflow">if</font>(rdrCtx.RenderThroughVBHeap) +01978 <font class="comment">// render shifted primitives</font> +01979 rdrCtx.Driver->render(rdrPass.VBHeapPBlock, mi->Materials[rdrPass.MaterialId]); +01980 <font class="keywordflow">else</font> +01981 <font class="comment">// render primitives</font> +01982 rdrCtx.Driver->render(rdrPass.PBlock, mi->Materials[rdrPass.MaterialId]); +01983 } +01984 } +01985 <font class="comment">// ***************************************************************************</font> +<a name="l01986"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_6">01986</a> <font class="keywordtype">void</font> CMeshGeom::endMesh(CMeshGeomRenderContext &rdrCtx) +01987 { +01988 <font class="comment">// nop.</font> +01989 <font class="comment">// \todo yoyo: MeshVertexProgram.</font> +01990 } +01991 +01992 <font class="comment">// ***************************************************************************</font> +<a name="l01993"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_7">01993</a> <font class="keywordtype">bool</font> CMeshGeom::getVBHeapInfo(uint &vertexFormat, uint &numVertices) +01994 { +01995 <font class="comment">// CMeshGeom support VBHeap rendering, assuming _SupportMeshBlockRendering is true</font> +01996 vertexFormat= <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexFormat(); +01997 numVertices= <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumVertices(); +01998 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMeshGeom.html#z569_0">_SupportMeshBlockRendering</a>; +01999 } +02000 +02001 <font class="comment">// ***************************************************************************</font> +<a name="l02002"></a><a class="code" href="classNL3D_1_1CMeshGeom.html#z567_8">02002</a> <font class="keywordtype">void</font> CMeshGeom::computeMeshVBHeap(<font class="keywordtype">void</font> *dst, uint indexStart) +02003 { +02004 <font class="comment">// Fill dst with Buffer content.</font> +02005 memcpy(dst, <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexCoordPointer(), <a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getNumVertices()*<a class="code" href="classNL3D_1_1CMeshGeom.html#o3">_VBuffer</a>.getVertexSize() ); +02006 +02007 <font class="comment">// NB: only 1 MB is possible ...</font> +02008 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>.size()==1); +02009 CMatrixBlock &mBlock= <a class="code" href="classNL3D_1_1CMeshGeom.html#o5">_MatrixBlocks</a>[0]; +02010 <font class="comment">// For all rdrPass.</font> +02011 <font class="keywordflow">for</font>(uint i=0;i<mBlock.RdrPass.size();i++) +02012 { +02013 <font class="comment">// shift the PB</font> +02014 CPrimitiveBlock &srcPb= mBlock.RdrPass[i].PBlock; +02015 CPrimitiveBlock &dstPb= mBlock.RdrPass[i].VBHeapPBlock; +02016 uint j; +02017 +02018 <font class="comment">// Lines.</font> +02019 dstPb.setNumLine(srcPb.getNumLine()); +02020 uint32 *srcLinePtr= srcPb.getLinePointer(); +02021 uint32 *dstLinePtr= dstPb.getLinePointer(); +02022 <font class="keywordflow">for</font>(j=0; j<dstPb.getNumLine()*2;j++) +02023 { +02024 dstLinePtr[j]= srcLinePtr[j]+indexStart; +02025 } +02026 <font class="comment">// Tris.</font> +02027 dstPb.setNumTri(srcPb.getNumTri()); +02028 uint32 *srcTriPtr= srcPb.getTriPointer(); +02029 uint32 *dstTriPtr= dstPb.getTriPointer(); +02030 <font class="keywordflow">for</font>(j=0; j<dstPb.getNumTri()*3;j++) +02031 { +02032 dstTriPtr[j]= srcTriPtr[j]+indexStart; +02033 } +02034 <font class="comment">// Quads.</font> +02035 dstPb.setNumQuad(srcPb.getNumQuad()); +02036 uint32 *srcQuadPtr= srcPb.getQuadPointer(); +02037 uint32 *dstQuadPtr= dstPb.getQuadPointer(); +02038 <font class="keywordflow">for</font>(j=0; j<dstPb.getNumQuad()*4;j++) +02039 { +02040 dstQuadPtr[j]= srcQuadPtr[j]+indexStart; +02041 } +02042 } +02043 } +02044 +02045 +02046 <font class="comment">// ***************************************************************************</font> +02047 <font class="comment">// ***************************************************************************</font> +02048 <font class="comment">// CMeshBuild components.</font> +02049 <font class="comment">// ***************************************************************************</font> +02050 <font class="comment">// ***************************************************************************</font> +02051 +02052 +02053 +02054 <font class="comment">// ***************************************************************************</font> +<a name="l02055"></a><a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#a0">02055</a> CMesh::CCorner::CCorner() +02056 { +02057 sint i; +02058 <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m0">Vertex</a>= 0; +02059 <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m1">Normal</a>= CVector::Null; +02060 <font class="keywordflow">for</font>(i=0;i<CVertexBuffer::MaxStage;i++) +02061 { +02062 <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m2">Uvws</a>[i]= CUVW(0, 0, 0); +02063 } +02064 <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m3">Color</a>.set(255,255,255,255); +02065 <a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#m4">Specular</a>.set(0,0,0,0); +02066 } +02067 +02068 +02069 <font class="comment">// ***************************************************************************</font> +<a name="l02070"></a><a class="code" href="structNL3D_1_1CMesh_1_1CCorner.html#a1">02070</a> <font class="keywordtype">void</font> CMesh::CCorner::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +02071 { +02072 <a class="code" href="debug_8h.html#a6">nlassert</a>(0); <font class="comment">// not used</font> +02073 f.serial(Vertex); +02074 f.serial(Normal); +02075 <font class="keywordflow">for</font>(<font class="keywordtype">int</font> i=0;i<CVertexBuffer::MaxStage;++i) f.serial(Uvws[i]); +02076 f.serial(Color); +02077 f.serial(Specular); +02078 } +02079 +02080 <font class="comment">// ***************************************************************************</font> +<a name="l02081"></a><a class="code" href="structNL3D_1_1CMesh_1_1CFace.html#a0">02081</a> <font class="keywordtype">void</font> CMesh::CFace::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +02082 { +02083 <font class="keywordflow">for</font>(<font class="keywordtype">int</font> i=0;i<3;++i) +02084 f.serial(Corner[i]); +02085 f.serial(MaterialId); +02086 f.serial(SmoothGroup); +02087 } +02088 +02089 <font class="comment">// ***************************************************************************</font> +<a name="l02090"></a><a class="code" href="structNL3D_1_1CMesh_1_1CSkinWeight.html#a1">02090</a> <font class="keywordtype">void</font> CMesh::CSkinWeight::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +02091 { +02092 <font class="keywordflow">for</font>(<font class="keywordtype">int</font> i=0;i<<a class="code" href="mesh_8h.html#a0">NL3D_MESH_SKINNING_MAX_MATRIX</a>;++i) +02093 { +02094 f.serial(MatrixId[i]); +02095 f.serial(Weights[i]); +02096 } +02097 } +02098 +02099 <font class="comment">// ***************************************************************************</font> +02100 <font class="comment">/* Serialization is not used.</font> +02101 <font class="comment">void CMesh::CMeshBuild::serial(NLMISC::IStream &f) throw(NLMISC::EStream)</font> +02102 <font class="comment">{</font> +02103 <font class="comment"> sint ver= f.serialVersion(0);</font> +02104 <font class="comment"></font> +02105 <font class="comment"> // Serial mesh base (material info).</font> +02106 <font class="comment"> CMeshBaseBuild::serial(f);</font> +02107 <font class="comment"></font> +02108 <font class="comment"> // Serial Geometry.</font> +02109 <font class="comment"> f.serial( VertexFlags );</font> +02110 <font class="comment"> f.serialCont( Vertices );</font> +02111 <font class="comment"> f.serialCont( SkinWeights );</font> +02112 <font class="comment"> f.serialCont( Faces );</font> +02113 <font class="comment"></font> +02114 <font class="comment">}*/</font> +02115 +02116 +02117 <font class="comment">//************************************</font> +<a name="l02118"></a><a class="code" href="structNL3D_1_1CMesh_1_1CMeshBuild.html#a0">02118</a> CMesh::CMeshBuild::CMeshBuild() +02119 { +02120 <font class="keywordflow">for</font> (uint k = 0; k < CVertexBuffer::MaxStage; ++k) +02121 { +02122 <a class="code" href="structNL3D_1_1CMesh_1_1CMeshBuild.html#m1">NumCoords</a>[k] = 2; +02123 } +02124 } +02125 +02126 +02127 <font class="comment">// ***************************************************************************</font> +02128 <font class="comment">// ***************************************************************************</font> +02129 <font class="comment">// CMesh.</font> +02130 <font class="comment">// ***************************************************************************</font> +02131 <font class="comment">// ***************************************************************************</font> +02132 +02133 +02134 +02135 <font class="comment">// ***************************************************************************</font> +<a name="l02136"></a><a class="code" href="classNL3D_1_1CMesh.html#a0">02136</a> CMesh::CMesh() +02137 { +02138 <font class="comment">// create the MeshGeom</font> +02139 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>= <font class="keyword">new</font> CMeshGeom; +02140 } +02141 <font class="comment">// ***************************************************************************</font> +<a name="l02142"></a><a class="code" href="classNL3D_1_1CMesh.html#a1">02142</a> CMesh::~CMesh() +02143 { +02144 <font class="comment">// delete the MeshGeom</font> +02145 <font class="keyword">delete</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>; +02146 } +02147 +02148 +02149 <font class="comment">// ***************************************************************************</font> +<a name="l02150"></a><a class="code" href="classNL3D_1_1CMesh.html#a2">02150</a> CMesh::CMesh(<font class="keyword">const</font> CMesh &mesh) +02151 { +02152 <font class="comment">// create the MeshGeom</font> +02153 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>= <font class="keyword">new</font> CMeshGeom(*mesh._MeshGeom); +02154 } +02155 +02156 +02157 <font class="comment">// ***************************************************************************</font> +<a name="l02158"></a><a class="code" href="classNL3D_1_1CMesh.html#a3">02158</a> CMesh &CMesh::operator=(<font class="keyword">const</font> CMesh &mesh) +02159 { +02160 <font class="comment">// Copy CMeshBase part</font> +02161 (<a class="code" href="classNL3D_1_1CMeshBase.html#a0">CMeshBase</a>&)*<font class="keyword">this</font>= (<a class="code" href="classNL3D_1_1CMeshBase.html#a0">CMeshBase</a>&)mesh; +02162 +02163 <font class="comment">// copy content of meshGeom.</font> +02164 *<a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>= *mesh._MeshGeom; +02165 +02166 +02167 <font class="keywordflow">return</font> *<font class="keyword">this</font>; +02168 } +02169 +02170 +02171 +02172 <font class="comment">// ***************************************************************************</font> +<a name="l02173"></a><a class="code" href="classNL3D_1_1CMesh.html#a4">02173</a> <font class="keywordtype">void</font> CMesh::build (CMeshBase::CMeshBaseBuild &mbase, CMeshBuild &m) +02174 { +02176 CMeshBase::buildMeshBase (mbase); +02177 +02178 <font class="comment">// build the geometry.</font> +02179 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->build (m, mbase.Materials.size()); +02180 } +02181 +02182 +02183 <font class="comment">// ***************************************************************************</font> +<a name="l02184"></a><a class="code" href="classNL3D_1_1CMesh.html#a6">02184</a> <font class="keywordtype">void</font> CMesh::optimizeMaterialUsage(std::vector<sint> &remap) +02185 { +02186 <font class="comment">// For each material, count usage.</font> +02187 vector<bool> materialUsed; +02188 materialUsed.resize(CMeshBase::_Materials.<a class="code" href="cf__lexical_8cpp.html#a94">size</a>(), <font class="keyword">false</font>); +02189 <font class="keywordflow">for</font>(uint mb=0;mb<<a class="code" href="classNL3D_1_1CMesh.html#z562_2">getNbMatrixBlock</a>();mb++) +02190 { +02191 <font class="keywordflow">for</font>(uint rp=0;rp<<a class="code" href="classNL3D_1_1CMesh.html#z562_3">getNbRdrPass</a>(mb);rp++) +02192 { +02193 uint matId= <a class="code" href="classNL3D_1_1CMesh.html#z562_5">getRdrPassMaterial</a>(mb, rp); +02194 <font class="comment">// flag as used.</font> +02195 materialUsed[matId]= <font class="keyword">true</font>; +02196 } +02197 } +02198 +02199 <font class="comment">// Apply it to meshBase</font> +02200 CMeshBase::applyMaterialUsageOptim(materialUsed, remap); +02201 +02202 <font class="comment">// Apply lut to meshGeom.</font> +02203 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->applyMaterialRemap(remap); +02204 } +02205 +02206 +02207 <font class="comment">// ***************************************************************************</font> +<a name="l02208"></a><a class="code" href="classNL3D_1_1CMesh.html#a7">02208</a> <font class="keywordtype">void</font> CMesh::setBlendShapes(std::vector<CBlendShape>&bs) +02209 { +02210 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->setBlendShapes (bs); +02211 } +02212 +02213 <font class="comment">// ***************************************************************************</font> +<a name="l02214"></a><a class="code" href="classNL3D_1_1CMesh.html#a5">02214</a> <font class="keywordtype">void</font> CMesh::build(CMeshBase::CMeshBaseBuild &mbuild, CMeshGeom &meshGeom) +02215 { +02217 CMeshBase::buildMeshBase(mbuild); +02218 +02219 <font class="comment">// build the geometry.</font> +02220 *<a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>= meshGeom; +02221 } +02222 +02223 +02224 <font class="comment">// ***************************************************************************</font> +<a name="l02225"></a><a class="code" href="classNL3D_1_1CMesh.html#z561_0">02225</a> CTransformShape *CMesh::createInstance(CScene &scene) +02226 { +02227 <font class="comment">// Create a CMeshInstance, an instance of a mesh.</font> +02228 <font class="comment">//===============================================</font> +02229 CMeshInstance *mi= (CMeshInstance*)scene.createModel(NL3D::MeshInstanceId); +02230 mi->Shape= <font class="keyword">this</font>; +02231 +02232 +02233 <font class="comment">// instanciate the material part of the Mesh, ie the CMeshBase.</font> +02234 CMeshBase::instanciateMeshBase(mi, &scene); +02235 +02236 +02237 <font class="comment">// do some instance init for MeshGeom</font> +02238 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->initInstance(mi); +02239 +02240 +02241 <font class="keywordflow">return</font> mi; +02242 } +02243 +02244 +02245 <font class="comment">// ***************************************************************************</font> +<a name="l02246"></a><a class="code" href="classNL3D_1_1CMesh.html#z561_1">02246</a> <font class="keywordtype">bool</font> CMesh::clip(<font class="keyword">const</font> std::vector<CPlane> &pyramid, <font class="keyword">const</font> CMatrix &worldMatrix) +02247 { +02248 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->clip(pyramid, worldMatrix); +02249 } +02250 +02251 +02252 <font class="comment">// ***************************************************************************</font> +<a name="l02253"></a><a class="code" href="classNL3D_1_1CMesh.html#z561_2">02253</a> <font class="keywordtype">void</font> CMesh::render(IDriver *drv, CTransformShape *trans, <font class="keywordtype">bool</font> passOpaque) +02254 { +02255 <font class="comment">// 0 or 0xFFFFFFFF</font> +02256 uint32 mask= (0-(uint32)passOpaque); +02257 uint32 rdrFlags; +02258 <font class="comment">// select rdrFlags, without ifs.</font> +02259 rdrFlags= mask & (IMeshGeom::RenderOpaqueMaterial | IMeshGeom::RenderPassOpaque); +02260 rdrFlags|= ~mask & (IMeshGeom::RenderTransparentMaterial); +02261 <font class="comment">// render the mesh</font> +02262 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->render(drv, trans, 0, rdrFlags, 1); +02263 } +02264 +02265 +02266 <font class="comment">// ***************************************************************************</font> +<a name="l02267"></a><a class="code" href="classNL3D_1_1CMesh.html#z561_3">02267</a> <font class="keywordtype">void</font> CMesh::serial(<a class="code" href="classNLMISC_1_1IStream.html">NLMISC::IStream</a> &f) <font class="keywordflow">throw</font>(NLMISC::EStream) +02268 { +02269 <font class="comment">/*</font> +02270 <font class="comment"> Version 6:</font> +02271 <font class="comment"> - cut in serialisation, because of:</font> +02272 <font class="comment"> - bad ITexture serialisation (with no version....) => must cut. (see CMeshBase serial).</font> +02273 <font class="comment"> - because of this and to simplify, make a cut too in CMesh serialisation.</font> +02274 <font class="comment"> NB : all old version code is dropped.</font> +02275 <font class="comment"> */</font> +02276 sint ver= f.serialVersion(6); +02277 +02278 +02279 <font class="keywordflow">if</font>(ver<6) +02280 <font class="keywordflow">throw</font> <a class="code" href="structNLMISC_1_1EStream.html">NLMISC::EStream</a>(f, <font class="stringliteral">"Mesh in Stream is too old (Mesh version < 6)"</font>); +02281 +02282 +02283 <font class="comment">// serial Materials infos contained in CMeshBase.</font> +02284 CMeshBase::serialMeshBase(f); +02285 +02286 +02287 <font class="comment">// serial geometry.</font> +02288 _MeshGeom->serial(f); +02289 +02290 } +02291 +02292 +02293 <font class="comment">// ***************************************************************************</font> +<a name="l02294"></a><a class="code" href="classNL3D_1_1CMesh.html#z562_0">02294</a> <font class="keyword">const</font> <a class="code" href="classNLMISC_1_1CAABBoxExt.html">NLMISC::CAABBoxExt</a>& CMesh::getBoundingBox()<font class="keyword"> const</font> +02295 <font class="keyword"></font>{ +02296 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->getBoundingBox(); +02297 } +02298 <font class="comment">// ***************************************************************************</font> +<a name="l02299"></a><a class="code" href="classNL3D_1_1CMesh.html#z562_1">02299</a> <font class="keyword">const</font> CVertexBuffer &CMesh::getVertexBuffer()<font class="keyword"> const </font> +02300 <font class="keyword"></font>{ +02301 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->getVertexBuffer() ; +02302 } +02303 <font class="comment">// ***************************************************************************</font> +<a name="l02304"></a><a class="code" href="classNL3D_1_1CMesh.html#z562_2">02304</a> uint CMesh::getNbMatrixBlock()<font class="keyword"> const </font> +02305 <font class="keyword"></font>{ +02306 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->getNbMatrixBlock(); +02307 } +02308 <font class="comment">// ***************************************************************************</font> +<a name="l02309"></a><a class="code" href="classNL3D_1_1CMesh.html#z562_3">02309</a> uint CMesh::getNbRdrPass(uint matrixBlockIndex)<font class="keyword"> const </font> +02310 <font class="keyword"></font>{ +02311 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->getNbRdrPass(matrixBlockIndex) ; +02312 } +02313 <font class="comment">// ***************************************************************************</font> +<a name="l02314"></a><a class="code" href="classNL3D_1_1CMesh.html#z562_4">02314</a> <font class="keyword">const</font> CPrimitiveBlock &CMesh::getRdrPassPrimitiveBlock(uint matrixBlockIndex, uint renderingPassIndex)<font class="keyword"> const</font> +02315 <font class="keyword"></font>{ +02316 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->getRdrPassPrimitiveBlock(matrixBlockIndex, renderingPassIndex) ; +02317 } +02318 <font class="comment">// ***************************************************************************</font> +<a name="l02319"></a><a class="code" href="classNL3D_1_1CMesh.html#z562_5">02319</a> uint32 CMesh::getRdrPassMaterial(uint matrixBlockIndex, uint renderingPassIndex)<font class="keyword"> const</font> +02320 <font class="keyword"></font>{ +02321 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->getRdrPassMaterial(matrixBlockIndex, renderingPassIndex) ; +02322 } +02323 <font class="comment">// ***************************************************************************</font> +<a name="l02324"></a><a class="code" href="classNL3D_1_1CMesh.html#z561_5">02324</a> <font class="keywordtype">float</font> CMesh::getNumTriangles (<font class="keywordtype">float</font> distance) +02325 { +02326 <font class="comment">// A CMesh do not degrad himself, so return 0, to not be taken into account.</font> +02327 <font class="keywordflow">return</font> 0; +02328 } +02329 <font class="comment">// ***************************************************************************</font> +<a name="l02330"></a><a class="code" href="classNL3D_1_1CMesh.html#z562_6">02330</a> <font class="keyword">const</font> CMeshGeom& CMesh::getMeshGeom ()<font class="keyword"> const</font> +02331 <font class="keyword"></font>{ +02332 <font class="keywordflow">return</font> *<a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>; +02333 } +02334 <font class="comment">// ***************************************************************************</font> +<a name="l02335"></a><a class="code" href="classNL3D_1_1CMesh.html#a8">02335</a> <font class="keywordtype">void</font> CMesh::computeBonesId (CSkeletonModel *skeleton) +02336 { +02337 <a class="code" href="debug_8h.html#a6">nlassert</a> (<a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>); +02338 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->computeBonesId (skeleton); +02339 } +02340 +02341 +02342 <font class="comment">// ***************************************************************************</font> +<a name="l02343"></a><a class="code" href="classNL3D_1_1CMesh.html#a9">02343</a> <font class="keywordtype">void</font> CMesh::updateSkeletonUsage(CSkeletonModel *sm, <font class="keywordtype">bool</font> increment) +02344 { +02345 <a class="code" href="debug_8h.html#a6">nlassert</a> (<a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>); +02346 <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->updateSkeletonUsage(sm, increment); +02347 } +02348 +02349 <font class="comment">// ***************************************************************************</font> +<a name="l02350"></a><a class="code" href="classNL3D_1_1CMesh.html#z563_0">02350</a> IMeshGeom *CMesh::supportMeshBlockRendering (CTransformShape *trans, <font class="keywordtype">float</font> &polygonCount )<font class="keyword"> const</font> +02351 <font class="keyword"></font>{ +02352 <font class="comment">// Ok if meshGeom is ok.</font> +02353 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>->supportMeshBlockRendering()) +02354 { +02355 polygonCount= 0; +02356 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CMesh.html#o0">_MeshGeom</a>; +02357 } +02358 <font class="keywordflow">else</font> +02359 <font class="keywordflow">return</font> NULL; +02360 } +02361 +02362 +02363 } <font class="comment">// NL3D</font> +02364 +02365 +02366 +</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> |