diff options
Diffstat (limited to '')
-rw-r--r-- | docs/doxygen/nel/skeleton__model_8cpp-source.html | 1597 |
1 files changed, 1597 insertions, 0 deletions
diff --git a/docs/doxygen/nel/skeleton__model_8cpp-source.html b/docs/doxygen/nel/skeleton__model_8cpp-source.html new file mode 100644 index 00000000..5a9a416f --- /dev/null +++ b/docs/doxygen/nel/skeleton__model_8cpp-source.html @@ -0,0 +1,1597 @@ +<!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>skeleton_model.cpp</h1><a href="skeleton__model_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 +00007 <font class="comment">/* Copyright, 2001 Nevrax Ltd.</font> +00008 <font class="comment"> *</font> +00009 <font class="comment"> * This file is part of NEVRAX NEL.</font> +00010 <font class="comment"> * NEVRAX NEL is free software; you can redistribute it and/or modify</font> +00011 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> +00012 <font class="comment"> * the Free Software Foundation; either version 2, or (at your option)</font> +00013 <font class="comment"> * any later version.</font> +00014 <font class="comment"></font> +00015 <font class="comment"> * NEVRAX NEL is distributed in the hope that it will be useful, but</font> +00016 <font class="comment"> * WITHOUT ANY WARRANTY; without even the implied warranty of</font> +00017 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font> +00018 <font class="comment"> * General Public License for more details.</font> +00019 <font class="comment"></font> +00020 <font class="comment"> * You should have received a copy of the GNU General Public License</font> +00021 <font class="comment"> * along with NEVRAX NEL; see the file COPYING. If not, write to the</font> +00022 <font class="comment"> * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,</font> +00023 <font class="comment"> * MA 02111-1307, USA.</font> +00024 <font class="comment"> */</font> +00025 +00026 <font class="preprocessor">#include "<a class="code" href="std3d_8h.html">std3d.h</a>"</font> +00027 +00028 <font class="preprocessor">#include "<a class="code" href="hierarchical__timer_8h.html">nel/misc/hierarchical_timer.h</a>"</font> +00029 <font class="preprocessor">#include "<a class="code" href="skeleton__model_8h.html">3d/skeleton_model.h</a>"</font> +00030 <font class="preprocessor">#include "<a class="code" href="hrc__trav_8h.html">3d/hrc_trav.h</a>"</font> +00031 <font class="preprocessor">#include "<a class="code" href="clip__trav_8h.html">3d/clip_trav.h</a>"</font> +00032 <font class="preprocessor">#include "<a class="code" href="anim__detail__trav_8h.html">3d/anim_detail_trav.h</a>"</font> +00033 <font class="preprocessor">#include "<a class="code" href="render__trav_8h.html">3d/render_trav.h</a>"</font> +00034 <font class="preprocessor">#include "<a class="code" href="skeleton__shape_8h.html">3d/skeleton_shape.h</a>"</font> +00035 <font class="preprocessor">#include "<a class="code" href="scene_8h.html">3d/scene.h</a>"</font> +00036 <font class="preprocessor">#include "<a class="code" href="lod__character__manager_8h.html">3d/lod_character_manager.h</a>"</font> +00037 <font class="preprocessor">#include "<a class="code" href="lod__character__shape_8h.html">3d/lod_character_shape.h</a>"</font> +00038 <font class="preprocessor">#include "<a class="code" href="skip__model_8h.html">3d/skip_model.h</a>"</font> +00039 <font class="preprocessor">#include "<a class="code" href="rgba_8h.html">nel/misc/rgba.h</a>"</font> +00040 <font class="preprocessor">#include "<a class="code" href="aabbox_8h.html">nel/misc/aabbox.h</a>"</font> +00041 <font class="preprocessor">#include "<a class="code" href="mesh__skin__manager_8h.html">3d/mesh_skin_manager.h</a>"</font> +00042 <font class="preprocessor">#include "<a class="code" href="mesh__base__instance_8h.html">3d/mesh_base_instance.h</a>"</font> +00043 <font class="preprocessor">#include "<a class="code" href="async__texture__manager_8h.html">3d/async_texture_manager.h</a>"</font> +00044 +00045 +00046 +00047 <font class="keyword">using</font> <font class="keyword">namespace </font>std; +00048 <font class="keyword">using</font> <font class="keyword">namespace </font>NLMISC; +00049 +00050 <font class="keyword">namespace </font>NL3D +00051 { +00052 +00053 +00054 <font class="comment">// ***************************************************************************</font> +<a name="l00055"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#d0">00055</a> <font class="keywordtype">void</font> CSkeletonModel::registerBasic() +00056 { +00057 CMOT::registerModel(<a class="code" href="namespaceNL3D.html#a236">SkeletonModelId</a>, <a class="code" href="namespaceNL3D.html#a277">TransformShapeId</a>, CSkeletonModel::creator); +00058 CMOT::registerObs(<a class="code" href="namespaceNL3D.html#a3">AnimDetailTravId</a>, <a class="code" href="namespaceNL3D.html#a236">SkeletonModelId</a>, CSkeletonModelAnimDetailObs::creator); +00059 CMOT::registerObs(<a class="code" href="namespaceNL3D.html#a232">RenderTravId</a>, <a class="code" href="namespaceNL3D.html#a236">SkeletonModelId</a>, CSkeletonModelRenderObs::creator); +00060 } +00061 +00062 +00063 <font class="comment">// ***************************************************************************</font> +<a name="l00064"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z800_1">00064</a> <font class="keywordtype">void</font> CSkeletonModel::registerToChannelMixer(CChannelMixer *chanMixer, <font class="keyword">const</font> std::string &prefix) +00065 { +00066 CTransformShape::registerToChannelMixer(chanMixer, prefix); +00067 +00068 <font class="comment">// Add any bones.</font> +00069 <font class="keywordflow">for</font>(uint i=0;i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size();i++) +00070 { +00071 <font class="comment">// append bonename.</font> +00072 <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].registerToChannelMixer(chanMixer, prefix + <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getBoneName() + <font class="stringliteral">"."</font>); +00073 } +00074 +00075 } +00076 +00077 <font class="comment">// ***************************************************************************</font> +<a name="l00078"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#b0">00078</a> CSkeletonModel::CSkeletonModel() +00079 { +00080 IAnimatable::resize(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z800_0s1">AnimValueLast</a>); +00081 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a>= NULL; +00082 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>= NULL; +00083 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_2">_DisplayedAsLodCharacter</a>= <font class="keyword">false</font>; +00084 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_3">_LodCharacterDistance</a>= 0; +00085 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_4">_OOLodCharacterDistance</a>= 0; +00086 +00087 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o4">_DefaultMRMSetup</a>= <font class="keyword">true</font>; +00088 +00089 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o3">_SkinToRenderDirty</a>= <font class="keyword">false</font>; +00090 +00091 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_6">_CLodVertexColorDirty</a>= <font class="keyword">true</font>; +00092 +00093 <font class="comment">// Inform the transform that I am a skeleton</font> +00094 CTransform::setIsSkeleton(<font class="keyword">true</font>); +00095 +00096 <font class="comment">// By default, no skins, hence, impossible to have transparent pass. But opaque pass is always possible</font> +00097 <font class="comment">// because of CLod rendering</font> +00098 <a class="code" href="classNL3D_1_1CTransform.html#a1">setOpacity</a>(<font class="keyword">true</font>); +00099 <a class="code" href="classNL3D_1_1CTransform.html#a0">setTransparency</a>(<font class="keyword">false</font>); +00100 +00101 <font class="comment">// AnimDetail behavior: Must be traversed in AnimDetail, even if no channel mixer registered</font> +00102 CTransform::setIsForceAnimDetail(<font class="keyword">true</font>); +00103 +00104 <font class="comment">// LoadBalancing behavior. true because directly act on skins to draw all their MRM level</font> +00105 CTransform::setIsLoadbalancable(<font class="keyword">true</font>); +00106 +00107 <font class="comment">// Lighting behavior. Lightable because skins/stickedObjects may surely need its LightContribution</font> +00108 CTransform::setIsLightable(<font class="keyword">true</font>); +00109 +00110 <font class="comment">// Render behavior. Always renderable, because either render the skeleton as a CLod, or render skins</font> +00111 CTransform::setIsRenderable(<font class="keyword">true</font>); +00112 +00113 <font class="comment">// build a bug-free level detail</font> +00114 <a class="code" href="classNL3D_1_1CSkeletonModel.html#c0">buildDefaultLevelDetail</a>(); +00115 } +00116 +00117 +00118 <font class="comment">// ***************************************************************************</font> +<a name="l00119"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#b1">00119</a> CSkeletonModel::~CSkeletonModel() +00120 { +00121 <font class="comment">// if initModel() called</font> +00122 <font class="keywordflow">if</font>(ClipTrav) +00123 { +00124 <font class="comment">// remove from scene</font> +00125 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->Scene->eraseSkeletonModelToList(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o0">_ItSkeletonInScene</a>); +00126 } +00127 +00128 +00129 <font class="comment">// detach skeleton sons from skins.</font> +00130 <font class="keywordflow">while</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.begin()!=<a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.end()) +00131 { +00132 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_3">detachSkeletonSon</a>(*<a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.begin()); +00133 } +00134 +00135 <font class="comment">// detach skeleton sons from sticked objects.</font> +00136 <font class="keywordflow">while</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o2">_StickedObjects</a>.begin()!=<a class="code" href="classNL3D_1_1CSkeletonModel.html#o2">_StickedObjects</a>.end()) +00137 { +00138 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_3">detachSkeletonSon</a>(*<a class="code" href="classNL3D_1_1CSkeletonModel.html#o2">_StickedObjects</a>.begin()); +00139 } +00140 +00141 <font class="comment">// Free Lod instance</font> +00142 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_0">setLodCharacterShape</a>(-1); +00143 +00144 } +00145 +00146 +00147 <font class="comment">// ***************************************************************************</font> +<a name="l00148"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#b2">00148</a> <font class="keywordtype">void</font> CSkeletonModel::initModel() +00149 { +00150 <a class="code" href="classNL3D_1_1IModel.html#l1">IObs</a> *HrcObs= <a class="code" href="classNL3D_1_1IModel.html#b3">getObs</a>(NL3D::HrcTravId); +00151 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a>= (CHrcTrav*)HrcObs->Trav; +00152 <a class="code" href="classNL3D_1_1IModel.html#l1">IObs</a> *ClipObs= <a class="code" href="classNL3D_1_1IModel.html#b3">getObs</a>(NL3D::ClipTravId); +00153 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>= (CClipTrav*)ClipObs->Trav; +00154 +00155 <font class="comment">// Link this skeleton to the CScene.</font> +00156 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o0">_ItSkeletonInScene</a>= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->Scene->appendSkeletonModelToList(<font class="keyword">this</font>); +00157 +00158 <font class="comment">// Call base class</font> +00159 CTransformShape::initModel(); +00160 } +00161 +00162 +00163 <font class="comment">// ***************************************************************************</font> +<a name="l00164"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_0">00164</a> <font class="keywordtype">void</font> CSkeletonModel::initBoneUsages() +00165 { +00166 <font class="comment">// reset all to 0.</font> +00167 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>.resize(<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size()); +00168 <font class="keywordflow">for</font>(uint i=0; i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>.size(); i++) +00169 { +00170 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].Usage= 0; +00171 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ForcedUsage= 0; +00172 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].CLodForcedUsage= 0; +00173 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].MustCompute= 0; +00174 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ValidBoneSkinMatrix= 0; +00175 } +00176 <font class="comment">// reserve space for bone to compute</font> +00177 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_5">_BoneToCompute</a>.reserve(<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size()); +00178 +00179 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_6">_BoneToComputeDirty</a>= <font class="keyword">false</font>; +00180 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_7">_CurLod</a>= 0; +00181 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_8">_CurLodInterp</a>= 1.f; +00182 <font class="comment">// Default is 0.5 meters.</font> +00183 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_9">_LodInterpMultiplier</a>= 1.f / 0.5f; +00184 } +00185 +00186 +00187 <font class="comment">// ***************************************************************************</font> +<a name="l00188"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_1">00188</a> <font class="keywordtype">void</font> CSkeletonModel::incBoneUsage(uint i, TBoneUsageType boneUsageType) +00189 { +00190 <a class="code" href="debug_8h.html#a6">nlassert</a>(i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>.size()); +00191 +00192 <font class="comment">// Get ptr on according refCount</font> +00193 uint8 *usagePtr; +00194 <font class="keywordflow">if</font>(boneUsageType == <a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_0s2">UsageNormal</a>) +00195 usagePtr= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].Usage; +00196 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(boneUsageType == <a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_0s3">UsageForced</a>) +00197 usagePtr= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ForcedUsage; +00198 <font class="keywordflow">else</font> +00199 usagePtr= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].CLodForcedUsage; +00200 +00201 <font class="comment">// If the bone was not used before, must update MustCompute.</font> +00202 <font class="keywordflow">if</font>(*usagePtr==0) +00203 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_6">_BoneToComputeDirty</a>= <font class="keyword">true</font>; +00204 +00205 <font class="comment">// Inc the refCount of the bone.</font> +00206 <a class="code" href="debug_8h.html#a6">nlassert</a>(*usagePtr<255); +00207 (*usagePtr)++; +00208 } +00209 +00210 +00211 <font class="comment">// ***************************************************************************</font> +<a name="l00212"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_2">00212</a> <font class="keywordtype">void</font> CSkeletonModel::decBoneUsage(uint i, TBoneUsageType boneUsageType) +00213 { +00214 <a class="code" href="debug_8h.html#a6">nlassert</a>(i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>.size()); +00215 +00216 <font class="comment">// Get ptr on according refCount</font> +00217 uint8 *usagePtr; +00218 <font class="keywordflow">if</font>(boneUsageType == <a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_0s2">UsageNormal</a>) +00219 usagePtr= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].Usage; +00220 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(boneUsageType == <a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_0s3">UsageForced</a>) +00221 usagePtr= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ForcedUsage; +00222 <font class="keywordflow">else</font> +00223 usagePtr= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].CLodForcedUsage; +00224 +00225 <font class="comment">// If the bone was used before (and now won't be more), must update MustCompute.</font> +00226 <font class="keywordflow">if</font>(*usagePtr==1) +00227 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_6">_BoneToComputeDirty</a>= <font class="keyword">true</font>; +00228 +00229 <font class="comment">// Inc the refCount of the bone.</font> +00230 <a class="code" href="debug_8h.html#a6">nlassert</a>(*usagePtr>0); +00231 (*usagePtr)--; +00232 } +00233 +00234 +00235 <font class="comment">// ***************************************************************************</font> +<a name="l00236"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_3">00236</a> <font class="keywordtype">void</font> CSkeletonModel::flagBoneAndParents(uint32 boneId, std::vector<bool> &boneUsage)<font class="keyword"> const</font> +00237 <font class="keyword"></font>{ +00238 <a class="code" href="debug_8h.html#a6">nlassert</a>( boneUsage.size()==<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size() ); +00239 <a class="code" href="debug_8h.html#a6">nlassert</a>( boneId<<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size() ); +00240 +00241 <font class="comment">// Flag this bone.</font> +00242 boneUsage[boneId]= <font class="keyword">true</font>; +00243 +00244 <font class="comment">// if has father, flag it (recurs).</font> +00245 sint fatherId= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[boneId].getFatherId(); +00246 <font class="keywordflow">if</font>(fatherId>=0) +00247 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_3">flagBoneAndParents</a>(fatherId, boneUsage); +00248 } +00249 +00250 +00251 <font class="comment">// ***************************************************************************</font> +<a name="l00252"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_1">00252</a> <font class="keywordtype">void</font> CSkeletonModel::incForcedBoneUsageAndParents(uint i, <font class="keywordtype">bool</font> forceCLod) +00253 { +00254 <font class="comment">// inc forced.</font> +00255 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_1">incBoneUsage</a>(i, forceCLod?UsageCLodForced:UsageForced ); +00256 +00257 <font class="comment">// recurs to father</font> +00258 sint fatherId= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getFatherId(); +00259 <font class="comment">// if not a root bone...</font> +00260 <font class="keywordflow">if</font>(fatherId>=0) +00261 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_1">incForcedBoneUsageAndParents</a>(fatherId, forceCLod); +00262 } +00263 +00264 <font class="comment">// ***************************************************************************</font> +<a name="l00265"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_2">00265</a> <font class="keywordtype">void</font> CSkeletonModel::decForcedBoneUsageAndParents(uint i, <font class="keywordtype">bool</font> forceCLod) +00266 { +00267 <font class="comment">// dec forced</font> +00268 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z802_2">decBoneUsage</a>(i, forceCLod?UsageCLodForced:UsageForced); +00269 +00270 <font class="comment">// recurs to father</font> +00271 sint fatherId= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getFatherId(); +00272 <font class="comment">// if not a root bone...</font> +00273 <font class="keywordflow">if</font>(fatherId>=0) +00274 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_2">decForcedBoneUsageAndParents</a>(fatherId, forceCLod); +00275 } +00276 +00277 +00278 <font class="comment">// ***************************************************************************</font> +<a name="l00279"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_3">00279</a> <font class="keywordtype">void</font> CSkeletonModel::updateBoneToCompute() +00280 { +00281 <font class="comment">// If already computed, skip</font> +00282 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_6">_BoneToComputeDirty</a>) +00283 <font class="keywordflow">return</font>; +00284 +00285 <font class="comment">// get the channelMixer owned by CTransform.</font> +00286 CChannelMixer *chanMixer= <a class="code" href="classNL3D_1_1CTransform.html#b4">getChannelMixer</a>(); +00287 +00288 <font class="comment">// Get Lod infos from skeletonShape</font> +00289 <a class="code" href="classNL3D_1_1CSkeletonModel.html#l0">CSkeletonShape</a> *skeShape= (<a class="code" href="classNL3D_1_1CSkeletonModel.html#l0">CSkeletonShape</a>*)(IShape*)<a class="code" href="classNL3D_1_1CTransformShape.html#m0">Shape</a>; +00290 <font class="keyword">const</font> CSkeletonShape::CLod &lod= skeShape->getLod(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_7">_CurLod</a>); +00291 +00292 <font class="comment">// reset _BoneToCompute</font> +00293 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_5">_BoneToCompute</a>.clear(); +00294 +00295 <font class="comment">// For all bones</font> +00296 <font class="keywordflow">for</font>(uint i=0; i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>.size(); i++) +00297 { +00298 <font class="comment">// If we are in CLod mode</font> +00299 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_8">isDisplayedAsLodCharacter</a>()) +00300 <font class="comment">// don't compute the bone</font> +00301 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].MustCompute= 0; +00302 <font class="keywordflow">else</font> +00303 { +00304 <font class="comment">// set MustCompute to non 0 if (Usage && Lod) || ForcedUsage;</font> +00305 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].MustCompute= (<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].Usage & lod.ActiveBones[i]) | <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ForcedUsage; +00306 } +00307 <font class="comment">// if CLodForcedUsage for the bone, it must be computed, whatever _DisplayedAsLodCharacter state</font> +00308 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].MustCompute|= <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].CLodForcedUsage; +00309 +00310 <font class="comment">// If the bone must be computed (if !0)</font> +00311 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].MustCompute) +00312 { +00313 <font class="comment">// lodEnable the channels of this bone</font> +00314 <font class="keywordflow">if</font>(chanMixer) +00315 <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].lodEnableChannels(chanMixer, <font class="keyword">true</font>); +00316 +00317 <font class="comment">// This bone is computed => take his valid boneSkinMatrix.</font> +00318 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ValidBoneSkinMatrix= i; +00319 +00320 <font class="comment">// Append to the list to compute.</font> +00321 <font class="comment">//-------</font> +00322 CBoneCompute bc; +00323 bc.Bone= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i]; +00324 sint fatherId= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getFatherId(); +00325 <font class="comment">// if a root bone...</font> +00326 <font class="keywordflow">if</font>(fatherId==-1) +00327 bc.Father= NULL; +00328 <font class="keywordflow">else</font> +00329 bc.Father= &<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[fatherId]; +00330 <font class="comment">// MustInterpolate??</font> +00331 bc.MustInterpolate= <font class="keyword">false</font>; +00332 <font class="keyword">const</font> CSkeletonShape::CLod *lodNext= NULL; +00333 <font class="comment">// if a lod exist after current lod, and if lod interpolation enabled</font> +00334 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_7">_CurLod</a> < skeShape->getNumLods()-1 && <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_9">_LodInterpMultiplier</a>>0 ) +00335 { +00336 <font class="comment">// get next lod.</font> +00337 lodNext= &skeShape->getLod(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_7">_CurLod</a>+1); +00338 <font class="comment">// Lod interpolation on this bone ?? only if at next lod, the bone is disabled.</font> +00339 <font class="comment">// And only if it is not enabed because of a "Forced reason"</font> +00340 <font class="comment">// Must also have a father, esle can't interpolate.</font> +00341 <font class="keywordflow">if</font>(lodNext->ActiveBones[i]==0 && <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ForcedUsage==0 && <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].CLodForcedUsage==0 +00342 && bc.Father) +00343 bc.MustInterpolate= <font class="keyword">true</font>; +00344 } +00345 <font class="comment">// append</font> +00346 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_5">_BoneToCompute</a>.push_back(bc); +00347 } +00348 <font class="keywordflow">else</font> +00349 { +00350 <font class="comment">// lodDisable the channels of this bone</font> +00351 <font class="keywordflow">if</font>(chanMixer) +00352 <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].lodEnableChannels(chanMixer, <font class="keyword">false</font>); +00353 +00354 <font class="comment">// This bone is not computed => take the valid boneSkinMatrix of his father</font> +00355 sint fatherId= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getFatherId(); +00356 <font class="keywordflow">if</font>(fatherId<0) +00357 <font class="comment">// just take me, even if not computed.</font> +00358 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ValidBoneSkinMatrix= i; +00359 <font class="keywordflow">else</font> +00360 <font class="comment">// NB: father ValidBoneSkinMatrix already computed because of the hierarchy order of Bones array.</font> +00361 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ValidBoneSkinMatrix= <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[fatherId].ValidBoneSkinMatrix; +00362 } +00363 } +00364 +00365 <font class="comment">// For </font> +00366 +00367 <font class="comment">// computed</font> +00368 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_6">_BoneToComputeDirty</a>= <font class="keyword">false</font>; +00369 } +00370 +00371 +00372 <font class="comment">// ***************************************************************************</font> +<a name="l00373"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_1">00373</a> <font class="keywordtype">bool</font> CSkeletonModel::isBoneComputed(uint boneId)<font class="keyword"> const</font> +00374 <font class="keyword"></font>{ +00375 <font class="keywordflow">if</font>(boneId>=<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>.size()) +00376 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00377 <font class="keywordflow">else</font> +00378 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[boneId].MustCompute!=0; +00379 } +00380 +00381 +00382 <font class="comment">// ***************************************************************************</font> +<a name="l00383"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_5">00383</a> <font class="keyword">const</font> <a class="code" href="classNLMISC_1_1CMatrix.html">NLMISC::CMatrix</a> &CSkeletonModel::getActiveBoneSkinMatrix(uint boneId)<font class="keyword"> const</font> +00384 <font class="keyword"></font>{ +00385 <font class="comment">// Get me or first father with MustCompute==true.</font> +00386 uint validBoneId= <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[boneId].ValidBoneSkinMatrix; +00387 <font class="comment">// return his WorldMatrix.</font> +00388 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[validBoneId].getBoneSkinMatrix(); +00389 } +00390 +00391 +00392 <font class="comment">// ***************************************************************************</font> +<a name="l00393"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_0">00393</a> <font class="keywordtype">bool</font> CSkeletonModel::bindSkin(CTransform *mi) +00394 { +00395 <a class="code" href="debug_8h.html#a6">nlassert</a>(mi); +00396 <font class="keywordflow">if</font>( !mi->isSkinnable() ) +00397 <font class="keywordflow">return</font> <font class="keyword">false</font>; +00398 +00399 <font class="comment">// try to detach this object from any skeleton first (possibly me).</font> +00400 <font class="keywordflow">if</font>(mi->_FatherSkeletonModel) +00401 mi->_FatherSkeletonModel->detachSkeletonSon(mi); +00402 +00403 <font class="comment">// Then Add me.</font> +00404 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.insert(mi); +00405 +00406 <font class="comment">// advert skin transform it is skinned.</font> +00407 mi->_FatherSkeletonModel= <font class="keyword">this</font>; +00408 <font class="comment">// setApplySkin() use _FatherSkeletonModel to computeBonesId() and to update current skeleton bone usage.</font> +00409 mi->setApplySkin(<font class="keyword">true</font>); +00410 +00411 +00412 <font class="comment">// Unlink the Skin from Hrc and clip, because SkeletonModel now does the job for him.</font> +00413 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a> && <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>); +00414 <font class="comment">// First ensure that the transform is not frozen (unlink from some quadGrids etc...)</font> +00415 mi->unfreezeHRC(); +00416 <font class="comment">// then never re-parse in validateList/Hrc/Clip</font> +00417 mi->unlinkFromValidateList(); +00418 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a>->link(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a>->Scene->getSkipModelRoot(), mi); +00419 <font class="comment">// ClipTrav is a graph, so must unlink from ALL olds models.</font> +00420 <a class="code" href="classNL3D_1_1IModel.html#b0">IModel</a> *father= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->getFirstParent(mi); +00421 <font class="keywordflow">while</font>(father) +00422 { +00423 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->unlink(father, mi); +00424 father= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->getFirstParent(mi); +00425 } +00426 <font class="comment">// Ensure flag is correct</font> +00427 mi->_HrcObs->ClipLinkedInSonsOfAncestorSkeletonModelGroup= <font class="keyword">false</font>; +00428 <font class="comment">// link to the SkipModelRoot One.</font> +00429 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->link(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->Scene->getSkipModelRoot(), mi); +00430 +00431 +00432 <font class="comment">// must recompute lod vertex color when LodCharacter used</font> +00433 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_13">dirtLodVertexColor</a>(); +00434 <font class="comment">// must recompute list of skins.</font> +00435 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_4">dirtSkinRenderLists</a>(); +00436 +00437 <font class="comment">// Ok, skinned</font> +00438 <font class="keywordflow">return</font> <font class="keyword">true</font>; +00439 } +00440 <font class="comment">// ***************************************************************************</font> +<a name="l00441"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_1">00441</a> <font class="keywordtype">void</font> CSkeletonModel::stickObject(CTransform *mi, uint boneId) +00442 { +00443 <font class="comment">// by default don't force display of "mi" if the skeleton become in CLod state</font> +00444 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_2">stickObjectEx</a>(mi, boneId, <font class="keyword">false</font>); +00445 } +00446 <font class="comment">// ***************************************************************************</font> +<a name="l00447"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_2">00447</a> <font class="keywordtype">void</font> CSkeletonModel::stickObjectEx(CTransform *mi, uint boneId, <font class="keywordtype">bool</font> forceCLod) +00448 { +00449 <a class="code" href="debug_8h.html#a6">nlassert</a>(mi); +00450 +00451 <font class="comment">// if "mi" is a skeleton, forceCLod must be true, for correct animation purpose</font> +00452 <font class="keywordflow">if</font>(dynamic_cast<CSkeletonModel*>(mi)) +00453 forceCLod= <font class="keyword">true</font>; +00454 +00455 <font class="comment">// try to detach this object from any skeleton first (possibly me).</font> +00456 <font class="keywordflow">if</font>(mi->_FatherSkeletonModel) +00457 mi->_FatherSkeletonModel->detachSkeletonSon(mi); +00458 +00459 <font class="comment">// Then Add me.</font> +00460 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o2">_StickedObjects</a>.insert(mi); +00461 <font class="comment">// increment the refCount usage of the bone</font> +00462 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_1">incForcedBoneUsageAndParents</a>(boneId, forceCLod); +00463 +00464 <font class="comment">// advert transform of its sticked state.</font> +00465 mi->_FatherSkeletonModel= <font class="keyword">this</font>; +00466 mi->_FatherBoneId= boneId; +00467 <font class="comment">// advert him if it is "ForceCLod" sticked</font> +00468 mi->_ForceCLodSticked= forceCLod; +00469 +00470 <font class="comment">// link correctly Hrc only. ClipTrav grah updated in Hrc traversal.</font> +00471 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a> && <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>); +00472 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a>->link(<font class="keyword">this</font>, mi); +00473 +00474 <font class="comment">// must recompute lod vertex color when LodCharacter used</font> +00475 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_13">dirtLodVertexColor</a>(); +00476 } +00477 <font class="comment">// ***************************************************************************</font> +<a name="l00478"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_3">00478</a> <font class="keywordtype">void</font> CSkeletonModel::detachSkeletonSon(CTransform *tr) +00479 { +00480 <a class="code" href="debug_8h.html#a6">nlassert</a>(tr); +00481 +00482 <font class="comment">// If the instance is not binded/sticked to the skeleton, exit.</font> +00483 <font class="keywordflow">if</font>(tr->_FatherSkeletonModel!=<font class="keyword">this</font>) +00484 <font class="keywordflow">return</font>; +00485 +00486 <font class="comment">// try to erase from StickObject.</font> +00487 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o2">_StickedObjects</a>.erase(tr); +00488 <font class="comment">// try to erase from Skins.</font> +00489 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.erase(tr); +00490 +00491 <font class="comment">// If the instance is not skinned, then it is sticked</font> +00492 <font class="keywordtype">bool</font> wasSkinned= tr->isSkinned()!=0; +00493 <font class="keywordflow">if</font>( !wasSkinned ) +00494 { +00495 <font class="comment">// Then decrement Bone Usage RefCount. Decrement from CLodForcedUsage if was sticked with forceCLod==true</font> +00496 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_2">decForcedBoneUsageAndParents</a>(tr->_FatherBoneId, tr->_ForceCLodSticked); +00497 } +00498 <font class="keywordflow">else</font> +00499 { +00500 <font class="comment">// it is skinned, advert the skinning is no more OK.</font> +00501 <font class="comment">// setApplySkin() use _FatherSkeletonModel to update current skeleton bone usage.</font> +00502 tr->setApplySkin(<font class="keyword">false</font>); +00503 } +00504 +00505 <font class="comment">// advert transform it is no more sticked/skinned.</font> +00506 tr->_FatherSkeletonModel= NULL; +00507 tr->_ForceCLodSticked= <font class="keyword">false</font>; +00508 +00509 <font class="comment">// link correctly Hrc / Clip / ValidateList...</font> +00510 <a class="code" href="debug_8h.html#a6">nlassert</a>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a> && <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>); +00511 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o9">HrcTrav</a>->link(NULL, tr); +00512 <font class="keywordflow">if</font>( !wasSkinned ) +00513 { +00514 <font class="comment">// No-op. ClipTrav graph/ValidateList updated in Hrc traversal.</font> +00515 } +00516 <font class="keywordflow">else</font> +00517 { +00518 <font class="comment">// Skin case: must do the Job here.</font> +00519 <font class="comment">// Update ClipTrav here.</font> +00520 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->unlink(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->Scene->getSkipModelRoot(), tr); +00521 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->link(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->getRoot(), tr); +00522 <font class="comment">// Must re-add to the validate list.</font> +00523 tr->linkToValidateList(); +00524 } +00525 +00526 +00527 <font class="comment">// must recompute lod vertex color when LodCharacter used</font> +00528 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_13">dirtLodVertexColor</a>(); +00529 <font class="comment">// must recompute list of skins if was skinned</font> +00530 <font class="keywordflow">if</font>( wasSkinned ) +00531 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_4">dirtSkinRenderLists</a>(); +00532 } +00533 +00534 +00535 <font class="comment">// ***************************************************************************</font> +<a name="l00536"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_0">00536</a> sint32 CSkeletonModel::getBoneIdByName(<font class="keyword">const</font> std::string &name)<font class="keyword"> const</font> +00537 <font class="keyword"></font>{ +00538 <a class="code" href="classNL3D_1_1CSkeletonModel.html#l0">CSkeletonShape</a> *shp= safe_cast<CSkeletonShape*>((IShape*)<a class="code" href="classNL3D_1_1CTransformShape.html#m0">Shape</a>); +00539 <font class="keywordflow">return</font> shp->getBoneIdByName(name); +00540 } +00541 +00542 +00543 <font class="comment">// ***************************************************************************</font> +<a name="l00544"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_3">00544</a> <font class="keywordtype">void</font> CSkeletonModel::setInterpolationDistance(<font class="keywordtype">float</font> dist) +00545 { +00546 dist= std::max(0.f, dist); +00547 <font class="comment">// disable interpolation?</font> +00548 <font class="keywordflow">if</font>(dist==0) +00549 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_9">_LodInterpMultiplier</a>= 0.f; +00550 <font class="keywordflow">else</font> +00551 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_9">_LodInterpMultiplier</a>= 1.f / dist; +00552 } +00553 +00554 <font class="comment">// ***************************************************************************</font> +<a name="l00555"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_4">00555</a> <font class="keywordtype">float</font> CSkeletonModel::getInterpolationDistance()<font class="keyword"> const</font> +00556 <font class="keyword"></font>{ +00557 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_9">_LodInterpMultiplier</a>==0) +00558 <font class="keywordflow">return</font> 0.f; +00559 <font class="keywordflow">else</font> +00560 <font class="keywordflow">return</font> 1.f / <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_9">_LodInterpMultiplier</a>; +00561 } +00562 +00563 +00564 <font class="comment">// ***************************************************************************</font> +<a name="l00565"></a><a class="code" href="classNL3D_1_1CSkeletonModelAnimDetailObs.html#a0">00565</a> <font class="keywordtype">void</font> CSkeletonModelAnimDetailObs::traverse(IObs *caller) +00566 { +00567 CSkeletonModel *sm= (CSkeletonModel*)<a class="code" href="classNL3D_1_1IObs.html#m0">Model</a>; +00568 CSkeletonShape *skeShape= ((CSkeletonShape*)(IShape*)sm->Shape); +00569 +00570 <font class="comment">// Update Lod, and animate.</font> +00571 <font class="comment">//===============</font> +00572 +00573 <font class="comment">/*</font> +00574 <font class="comment"> CTransformAnimDetailObs::traverse() is torn in 2 here because </font> +00575 <font class="comment"> channels may be enabled/disabled by updateBoneToCompute()</font> +00576 <font class="comment"> */</font> +00577 +00578 <font class="comment">// First update Skeleton WorldMatrix (case where the skeleton is sticked).</font> +00579 CTransformAnimDetailObs::updateWorldMatrixFromFather(); +00580 <font class="comment">// get dist from camera.</font> +00581 <font class="keywordtype">float</font> dist= (<a class="code" href="classNL3D_1_1IBaseAnimDetailObs.html#m0">HrcObs</a>->WorldMatrix.getPos() - ((CClipTrav*)<a class="code" href="classNL3D_1_1IBaseAnimDetailObs.html#m1">ClipObs</a>->Trav)->CamPos).norm(); +00582 <font class="comment">// Use dist to get current lod to use for this skeleton</font> +00583 uint newLod= skeShape->getLodForDistance( dist ); +00584 <font class="keywordflow">if</font>(newLod != sm->_CurLod) +00585 { +00586 <font class="comment">// set new lod to use.</font> +00587 sm->_CurLod= newLod; +00588 <font class="comment">// dirt the skeleton.</font> +00589 sm->_BoneToComputeDirty= <font class="keyword">true</font>; +00590 } +00591 +00592 <font class="comment">// If needed, let's know which bone has to be computed, and enable / disable (lod) channels in channelMixer.</font> +00593 <font class="keywordtype">bool</font> forceUpdate= sm->_BoneToComputeDirty; +00594 sm->updateBoneToCompute(); +00595 +00596 <font class="comment">// Animate skeleton.</font> +00597 CTransformAnimDetailObs::traverseWithoutUpdateWorldMatrix(caller); +00598 +00599 +00600 <font class="comment">// Prepare Lod Bone interpolation.</font> +00601 <font class="comment">//===============</font> +00602 +00603 <font class="keywordtype">float</font> lodBoneInterp; +00604 <font class="keyword">const</font> CSkeletonShape::CLod *lodNext= NULL; +00605 <font class="comment">// if a lod exist after current lod, and if lod interpolation enabled</font> +00606 <font class="keywordflow">if</font>( sm->_CurLod < skeShape->getNumLods()-1 && sm->_LodInterpMultiplier>0 ) +00607 { +00608 <font class="comment">// get next lod.</font> +00609 lodNext= &skeShape->getLod(sm->_CurLod+1); +00610 <font class="comment">// get interp value to next.</font> +00611 lodBoneInterp= (lodNext->Distance - dist) * sm->_LodInterpMultiplier; +00612 <a class="code" href="namespaceNLMISC.html#a215">NLMISC::clamp</a>(lodBoneInterp, 0.f, 1.f); +00613 <font class="comment">// if still 1, keep cur matrix => disable interpolation</font> +00614 <font class="keywordflow">if</font>(lodBoneInterp==1.f) +00615 lodNext=NULL; +00616 } +00617 <font class="comment">// else, no interpolation</font> +00618 <font class="keywordflow">else</font> +00619 { +00620 lodBoneInterp=1.f; +00621 } +00622 <font class="comment">// If the interpolation value is different from last one, must update.</font> +00623 <font class="keywordflow">if</font>(lodBoneInterp != sm->_CurLodInterp) +00624 { +00625 <font class="comment">// set new one.</font> +00626 sm->_CurLodInterp= lodBoneInterp; +00627 <font class="comment">// must update bone compute.</font> +00628 forceUpdate= <font class="keyword">true</font>; +00629 } +00630 +00631 +00632 +00633 <font class="comment">// Compute bones</font> +00634 <font class="comment">//===============</font> +00635 +00636 <font class="comment">// test if bones must be updated. either if animation change or if BoneUsage change.</font> +00637 <font class="keywordflow">if</font>(sm->IAnimatable::isTouched(CSkeletonModel::OwnerBit) || forceUpdate) +00638 { +00639 <font class="comment">// Retrieve the WorldMatrix of the current CTransformShape.</font> +00640 CMatrix &modelWorldMatrix= <a class="code" href="classNL3D_1_1IBaseAnimDetailObs.html#m0">HrcObs</a>->WorldMatrix; +00641 +00642 <font class="comment">// must test / update the hierarchy of Bones.</font> +00643 <font class="comment">// Since they are orderd in depth-first order, we are sure that parent are computed before sons.</font> +00644 uint numBoneToCompute= sm->_BoneToCompute.size(); +00645 CSkeletonModel::CBoneCompute *pBoneCompute= numBoneToCompute? &sm->_BoneToCompute[0] : NULL; +00646 <font class="comment">// traverse only bones which need to be computed</font> +00647 <font class="keywordflow">for</font>(;numBoneToCompute>0;numBoneToCompute--, pBoneCompute++) +00648 { +00649 <font class="comment">// compute the bone with his father, if any</font> +00650 pBoneCompute->Bone->compute( pBoneCompute->Father, modelWorldMatrix); +00651 +00652 <font class="comment">// Lod interpolation on this bone .. only if interp is enabled now, and if bone wants it</font> +00653 <font class="keywordflow">if</font>(lodNext && pBoneCompute->MustInterpolate) +00654 { +00655 <font class="comment">// interpolate with my father matrix.</font> +00656 <font class="keyword">const</font> CMatrix &fatherMatrix= pBoneCompute->Father->getBoneSkinMatrix(); +00657 pBoneCompute->Bone->interpolateBoneSkinMatrix(fatherMatrix, lodBoneInterp); +00658 } +00659 } +00660 +00661 sm->IAnimatable::clearFlag(CSkeletonModel::OwnerBit); +00662 } +00663 +00664 <font class="comment">// Sticked Objects: </font> +00665 <font class="comment">// they will update their WorldMatrix after, because of the AnimDetail traverse scheme:</font> +00666 <font class="comment">// traverse visible ClipObs, and if skeleton, traverse Hrc sons.</font> +00667 +00668 +00669 <font class="comment">// Update Animated Skins.</font> +00670 <font class="comment">//===============</font> +00671 <font class="keywordflow">for</font>(uint i=0;i<sm->_AnimDetailSkins.size();i++) +00672 { +00673 <font class="comment">// get the detail Obs, via the clipObs</font> +00674 CTransformAnimDetailObs *adObs; +00675 adObs= safe_cast<CTransformAnimDetailObs*>(sm->_AnimDetailSkins[i]->_ClipObs->AnimDetailObs); +00676 +00677 <font class="comment">// traverse it. NB: updateWorldMatrixFromFather() is called but no-op because isSkinned()</font> +00678 adObs->traverse(NULL); +00679 } +00680 +00681 } +00682 +00683 +00684 <font class="comment">// ***************************************************************************</font> +<a name="l00685"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_6">00685</a> <font class="keywordtype">void</font> CSkeletonModel::computeAllBones(<font class="keyword">const</font> CMatrix &modelWorldMatrix) +00686 { +00687 <font class="comment">// must test / update the hierarchy of Bones.</font> +00688 <font class="comment">// Since they are orderd in depth-first order, we are sure that parent are computed before sons.</font> +00689 <font class="keywordflow">for</font>(uint i=0;i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size();i++) +00690 { +00691 sint fatherId= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getFatherId(); +00692 <font class="comment">// if a root bone...</font> +00693 <font class="keywordflow">if</font>(fatherId==-1) +00694 <font class="comment">// Compute root bone worldMatrix.</font> +00695 <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].compute( NULL, modelWorldMatrix); +00696 <font class="keywordflow">else</font> +00697 <font class="comment">// Compute bone worldMatrix.</font> +00698 <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].compute( &<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[fatherId], modelWorldMatrix); +00699 } +00700 +00701 } +00702 +00703 +00704 <font class="comment">// ***************************************************************************</font> +<a name="l00705"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_9">00705</a> <font class="keywordtype">void</font> CSkeletonModel::setLodCharacterDistance(<font class="keywordtype">float</font> dist) +00706 { +00707 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_3">_LodCharacterDistance</a>= max(dist, 0.f); +00708 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_3">_LodCharacterDistance</a>>0) +00709 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_4">_OOLodCharacterDistance</a>= 1.0f/<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_3">_LodCharacterDistance</a>; +00710 <font class="keywordflow">else</font> +00711 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_4">_OOLodCharacterDistance</a>= 0; +00712 } +00713 +00714 <font class="comment">// ***************************************************************************</font> +<a name="l00715"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_0">00715</a> <font class="keywordtype">void</font> CSkeletonModel::setLodCharacterShape(sint shapeId) +00716 { +00717 <font class="comment">// get a ptr on the scene which owns us, and so on the lodManager.</font> +00718 CScene *scene= static_cast<CScene*>(_OwnerMot); +00719 CLodCharacterManager *mngr= scene->getLodCharacterManager(); +00720 +00721 <font class="comment">// if mngr not setuped, noop (lod not possible).</font> +00722 <font class="keywordflow">if</font>(!mngr) +00723 <font class="keywordflow">return</font>; +00724 +00725 <font class="comment">// If a shape was setup, free the instance</font> +00726 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId>=0) +00727 { +00728 mngr->releaseInstance(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>); +00729 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId= -1; +00730 } +00731 +00732 <font class="comment">// assign</font> +00733 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId= shapeId; +00734 +00735 <font class="comment">// if a real shape is setuped, alloc an instance</font> +00736 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId>=0) +00737 { +00738 mngr->initInstance(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>); +00739 } +00740 } +00741 +00742 +00743 <font class="comment">// ***************************************************************************</font> +<a name="l00744"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_14">00744</a> <font class="keywordtype">void</font> CSkeletonModel::computeLodTexture() +00745 { +00746 <font class="comment">// is lod setuped</font> +00747 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId<0) +00748 <font class="keywordflow">return</font>; +00749 +00750 <font class="comment">// get a ptr on the scene which owns us, and so on the lodManager.</font> +00751 CScene *scene= static_cast<CScene*>(_OwnerMot); +00752 CLodCharacterManager *mngr= scene->getLodCharacterManager(); +00753 <font class="comment">// mngr must be setuped since shape Id is >-1</font> +00754 <a class="code" href="debug_8h.html#a6">nlassert</a>(mngr); +00755 <font class="comment">/* Get the asyncTextureManager. This is a Hack. We use the AsyncTextureManager to store very low version of Textures</font> +00756 <font class="comment"> (kept in DXTC1 format for minimum memory overhead).</font> +00757 <font class="comment"> HENCE Lod Texture can work only with Async Textured instances!!</font> +00758 <font class="comment"> */</font> +00759 CAsyncTextureManager *asyncMngr= scene->getAsyncTextureManager(); +00760 <font class="comment">// if not setuped, cancel</font> +00761 <font class="keywordflow">if</font>(!asyncMngr) +00762 <font class="keywordflow">return</font>; +00763 +00764 +00765 <font class="comment">// **** start process. If cannot (TextureId==no more texture space), just quit.</font> +00766 <font class="keywordflow">if</font>(!mngr->startTextureCompute(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>)) +00767 <font class="keywordflow">return</font>; +00768 uint maxNumBmpToReset= 0; +00769 +00770 <font class="comment">// **** For all skins which have a LodTexture setuped</font> +00771 <a class="code" href="classNL3D_1_1CSkeletonModel.html#u1">ItTransformSet</a> it= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.begin(); +00772 <font class="keywordflow">for</font>(;it!=<a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.end();it++) +00773 { +00774 <font class="comment">// the skin should be a meshBaseInstance setuped to asyncTexturing</font> +00775 CMeshBaseInstance *mbi= dynamic_cast<CMeshBaseInstance*>(*it); +00776 <font class="keywordflow">if</font>(mbi && mbi->getAsyncTextureMode() && mbi->Shape) +00777 { +00778 CMeshBase *mb= (CMeshBase*)(IShape*)(mbi->Shape); +00779 <font class="comment">// get the LodTexture info of this shape.</font> +00780 <font class="keyword">const</font> CLodCharacterTexture *lodText= mb->getLodCharacterTexture(); +00781 <font class="comment">// if setuped</font> +00782 <font class="keywordflow">if</font>(lodText) +00783 { +00784 <font class="comment">// Ok, compute influence of this instance on the Lod.</font> +00785 +00786 <font class="comment">// ---- Build all bmps of the instance with help of the asyncTextureManager</font> +00787 uint numMats= mbi->Materials.size(); +00788 <font class="comment">// 256 materials possibles for the lod Manager</font> +00789 numMats= <a class="code" href="bit__set_8cpp.html#a0">min</a>(numMats, 256U); +00790 <font class="comment">// for endTexturecompute</font> +00791 maxNumBmpToReset= max(maxNumBmpToReset, numMats); +00792 <font class="comment">// process each materials</font> +00793 <font class="keywordflow">for</font>(uint i=0;i<numMats;i++) +00794 { +00795 <font class="comment">// get the manager bitmap to write to</font> +00796 CLodCharacterTmpBitmap &dstBmp= mngr->getTmpBitmap(i); +00797 +00798 <font class="comment">// if the material stage 0 is not textured, or has not a valid async id, build the bitmap with a color.</font> +00799 sint asyncTextId= mbi->getAsyncTextureId(i,0); +00800 <font class="keyword">const</font> CBitmap *coarseBitmap= NULL; +00801 <font class="keywordflow">if</font>(asyncTextId!=-1) +00802 { +00803 <font class="comment">// get it from async manager</font> +00804 coarseBitmap= asyncMngr->getCoarseBitmap(asyncTextId); +00805 } +00806 +00807 <font class="comment">// So if we have no bmp here, build with material color, else build a texture</font> +00808 <font class="keywordflow">if</font>(!coarseBitmap) +00809 { +00810 dstBmp.build(mbi->Materials[i].getDiffuse()); +00811 } +00812 <font class="keywordflow">else</font> +00813 { +00814 dstBmp.build(*coarseBitmap); +00815 } +00816 } +00817 +00818 <font class="comment">// ---- add the lodTextureInfo to the current texture computed</font> +00819 mngr->addTextureCompute(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>, *lodText); +00820 } +00821 } +00822 } +00823 +00824 <font class="comment">// **** compile the process</font> +00825 mngr->endTextureCompute(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>, maxNumBmpToReset); +00826 +00827 } +00828 +00829 +00830 <font class="comment">// ***************************************************************************</font> +<a name="l00831"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_2">00831</a> <font class="keywordtype">void</font> CSkeletonModel::setLodCharacterAnimId(uint animId) +00832 { +00833 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.AnimId= animId; +00834 } +00835 +00836 <font class="comment">// ***************************************************************************</font> +<a name="l00837"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_4">00837</a> <font class="keywordtype">void</font> CSkeletonModel::setLodCharacterAnimTime(<a class="code" href="namespaceNL3D.html#a2">TGlobalAnimationTime</a> time) +00838 { +00839 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.AnimTime= time; +00840 } +00841 +00842 <font class="comment">// ***************************************************************************</font> +<a name="l00843"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_6">00843</a> <font class="keywordtype">void</font> CSkeletonModel::setLodCharacterWrapMode(<font class="keywordtype">bool</font> wrapMode) +00844 { +00845 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.WrapMode= wrapMode; +00846 } +00847 +00848 +00849 <font class="comment">// ***************************************************************************</font> +<a name="l00850"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_11">00850</a> <font class="keywordtype">float</font> CSkeletonModel::computeDisplayLodCharacterPriority()<font class="keyword"> const</font> +00851 <font class="keyword"></font>{ +00852 <font class="comment">// if enabled</font> +00853 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_3">_LodCharacterDistance</a>>0 && <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId>=0) +00854 { +00855 CVector globalPos; +00856 <font class="comment">/* \todo yoyo: bad test of visibility. If the skeleton is hidden but has a _AncestorSkeletonModel </font> +00857 <font class="comment"> wich is visible, then it is supposed to be visible (in this test), but only for The CLod LoadBalancing </font> +00858 <font class="comment"> (priority not 0). Not so important...</font> +00859 <font class="comment"> */</font> +00860 +00861 <font class="comment">// Get object position, test visibility;</font> +00862 <font class="comment">// If has a skeleton ancestor, take his world position instead, because ours is invalid.</font> +00863 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CTransform.html#n0">_HrcObs</a>->_AncestorSkeletonModel != NULL) +00864 { +00865 <font class="comment">// if the ancestore is clipped, quit</font> +00866 <font class="keywordflow">if</font>( !<a class="code" href="classNL3D_1_1CTransform.html#n0">_HrcObs</a>->_AncestorSkeletonModel->isClipVisible() ) +00867 <font class="keywordflow">return</font> 0; +00868 <font class="comment">// take ancestor world position</font> +00869 globalPos= <a class="code" href="classNL3D_1_1CTransform.html#n0">_HrcObs</a>->_AncestorSkeletonModel->getWorldMatrix().getPos(); +00870 } +00871 <font class="keywordflow">else</font> +00872 { +00873 <font class="comment">// if the skeleton is clipped, quit</font> +00874 <font class="keywordflow">if</font>( !<a class="code" href="classNL3D_1_1CSkeletonModel.html#a0">isClipVisible</a>() ) +00875 <font class="keywordflow">return</font> 0; +00876 <font class="comment">// take our world position</font> +00877 globalPos= <a class="code" href="classNL3D_1_1CTransform.html#n0">_HrcObs</a>->WorldMatrix.getPos(); +00878 } +00879 +00880 <font class="comment">// compute distance from camera.</font> +00881 <font class="keywordtype">float</font> dist= (<a class="code" href="classNL3D_1_1CSkeletonModel.html#o10">ClipTrav</a>->CamPos - globalPos).norm(); +00882 +00883 <font class="comment">// compute priority</font> +00884 <font class="keywordflow">return</font> dist*<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_4">_OOLodCharacterDistance</a>; +00885 } +00886 <font class="keywordflow">else</font> +00887 <font class="keywordflow">return</font> 0; +00888 } +00889 +00890 +00891 <font class="comment">// ***************************************************************************</font> +<a name="l00892"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_12">00892</a> <font class="keywordtype">void</font> CSkeletonModel::setDisplayLodCharacterFlag(<font class="keywordtype">bool</font> displayCLod) +00893 { +00894 <font class="comment">// if enabled</font> +00895 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_3">_LodCharacterDistance</a>>0 && <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId>=0) +00896 { +00897 <font class="comment">// If the flag has changed since last frame, must recompute bone Usage.</font> +00898 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_2">_DisplayedAsLodCharacter</a> != displayCLod) +00899 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_6">_BoneToComputeDirty</a>= <font class="keyword">true</font>; +00900 +00901 <font class="comment">// set new state</font> +00902 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_2">_DisplayedAsLodCharacter</a>= displayCLod; +00903 } +00904 } +00905 +00906 +00907 <font class="comment">// ***************************************************************************</font> +<a name="l00908"></a><a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a0">00908</a> <font class="keywordtype">void</font> CSkeletonModelRenderObs::traverse(IObs *caller) +00909 { +00910 <a class="code" href="hierarchical__timer_8h.html#a4">H_AUTO</a>( NL3D_Skeleton_Render ); +00911 +00912 CSkeletonModel *sm= (CSkeletonModel*)<a class="code" href="classNL3D_1_1IObs.html#m0">Model</a>; +00913 +00914 <font class="comment">// render as CLod, or render Skins.</font> +00915 <font class="keywordflow">if</font>(sm->isDisplayedAsLodCharacter()) +00916 <a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a1">renderCLod</a>(); +00917 <font class="keywordflow">else</font> +00918 <a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a2">renderSkins</a>(); +00919 } +00920 +00921 +00922 <font class="comment">// ***************************************************************************</font> +<a name="l00923"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_1">00923</a> <font class="keywordtype">void</font> CSkeletonModel::computeCLodVertexColors(CLodCharacterManager *mngr) +00924 { +00925 <font class="comment">// if shape id set.</font> +00926 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId<0) +00927 <font class="keywordflow">return</font>; +00928 <font class="comment">// get the lod shape,a nd check exist in the manager</font> +00929 <font class="keyword">const</font> CLodCharacterShape *lodShape= mngr->getShape(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.ShapeId); +00930 <font class="keywordflow">if</font>(lodShape) +00931 { +00932 <font class="keyword">static</font> vector<CRGBAF> tmpColors; +00933 tmpColors.clear(); +00934 +00935 <font class="comment">// start process.</font> +00936 <font class="comment">//-----------------</font> +00937 lodShape->startBoneColor(tmpColors); +00938 +00939 <font class="comment">// build an Id map, from Skeleton Ids to the lodShapes ids. (because may be differents)</font> +00940 <font class="keyword">static</font> vector<sint> boneMap; +00941 <font class="comment">// reset to -1 (ie not found)</font> +00942 boneMap.clear(); +00943 boneMap.resize(<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size(), -1); +00944 uint i; +00945 <font class="comment">// for all skeletons bones.</font> +00946 <font class="keywordflow">for</font>(i=0; i<boneMap.size(); i++) +00947 { +00948 boneMap[i]= lodShape->getBoneIdByName(<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getBoneName());; +00949 } +00950 +00951 <font class="comment">// Parse all skins</font> +00952 <font class="comment">//-----------------</font> +00953 <a class="code" href="classNL3D_1_1CSkeletonModel.html#u1">ItTransformSet</a> it; +00954 <font class="keywordflow">for</font>(it= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.begin(); it!=<a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.end(); it++) +00955 { +00956 <a class="code" href="classNL3D_1_1CTransform.html#b0">CTransform</a> *skin= *it; +00957 +00958 <font class="comment">// get color of this skin.</font> +00959 CRGBA color= skin->getMeanColor(); +00960 +00961 <font class="comment">// get array of bone used for this skin.</font> +00962 <font class="keyword">const</font> vector<sint32> *skinUsage= skin->getSkinBoneUsage(); +00963 <font class="comment">// check correct skin</font> +00964 <font class="keywordflow">if</font>(skinUsage) +00965 { +00966 <font class="comment">// For all bones used</font> +00967 <font class="keywordflow">for</font>(uint i=0; i<skinUsage->size(); i++) +00968 { +00969 <font class="comment">// the id in the vector point to a bone in the skeleton. Hence use the boneMap to translate it</font> +00970 <font class="comment">// in the lodShape ids.</font> +00971 sint idInLod= boneMap[(*skinUsage)[i]]; +00972 <font class="comment">// only if id found in the lod shape</font> +00973 <font class="keywordflow">if</font>(idInLod>=0) +00974 <font class="comment">// add color to this bone.</font> +00975 lodShape->addBoneColor(idInLod, color, tmpColors); +00976 } +00977 +00978 } +00979 } +00980 +00981 <font class="comment">// Parse all sticked objects</font> +00982 <font class="comment">//-----------------</font> +00983 <font class="keywordflow">for</font>(it= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o2">_StickedObjects</a>.begin(); it!=<a class="code" href="classNL3D_1_1CSkeletonModel.html#o2">_StickedObjects</a>.end(); it++) +00984 { +00985 <a class="code" href="classNL3D_1_1CTransform.html#b0">CTransform</a> *object= *it; +00986 +00987 <font class="comment">// get color of this object.</font> +00988 CRGBA color= object->getMeanColor(); +00989 +00990 <font class="comment">// get on which bone this object is linked.</font> +00991 <font class="comment">// use the boneMap to translate id to lodShape id.</font> +00992 sint idInLod= boneMap[object->_FatherBoneId]; +00993 +00994 <font class="comment">// only if id found in the lod shape</font> +00995 <font class="keywordflow">if</font>(idInLod>=0) +00996 <font class="comment">// add color to this bone.</font> +00997 lodShape->addBoneColor(idInLod, color, tmpColors); +00998 } +00999 +01000 +01001 <font class="comment">// compile colors</font> +01002 <font class="comment">//-----------------</font> +01003 lodShape->endBoneColor(tmpColors, <a class="code" href="classNL3D_1_1CSkeletonModel.html#z807_5">_CLodInstance</a>.VertexColors); +01004 } +01005 +01006 } +01007 +01008 +01009 <font class="comment">// ***************************************************************************</font> +<a name="l01010"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#a1">01010</a> <font class="keywordtype">void</font> CSkeletonModel::updateSkinRenderLists() +01011 { +01012 <font class="comment">// If need to update array of skins to compute</font> +01013 <font class="keywordflow">if</font>(_SkinToRenderDirty) +01014 { +01015 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o3">_SkinToRenderDirty</a>= <font class="keyword">false</font>; +01016 +01017 <font class="comment">// Reset the LevelDetail.</font> +01018 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.MinFaceUsed= 0; +01019 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.MaxFaceUsed= 0; +01020 <font class="comment">// If must follow default MRM setup from skins.</font> +01021 <font class="keywordflow">if</font>(_DefaultMRMSetup) +01022 { +01023 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceCoarsest= 0; +01024 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceMiddle= 0; +01025 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceFinest= 0; +01026 } +01027 +01028 <font class="comment">// Parse to count new size of the arrays, and to build MRM info</font> +01029 uint opaqueSize= 0; +01030 uint transparentSize= 0; +01031 uint animDetailSize= 0; +01032 <a class="code" href="classNL3D_1_1CSkeletonModel.html#u1">ItTransformSet</a> it; +01033 <font class="keywordflow">for</font>(it= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.begin();it!=<a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.end();it++) +01034 { +01035 <a class="code" href="classNL3D_1_1CTransform.html#b0">CTransform</a> *skin= *it; +01036 <font class="comment">// if transparent, then must fill in transparent list.</font> +01037 <font class="keywordflow">if</font>(skin->isTransparent()) +01038 transparentSize++; +01039 <font class="comment">// else may fill in opaquelist. NB: for optimisation, don't add in opaqueList </font> +01040 <font class="comment">// if added to the transperent list (all materials are rendered)</font> +01041 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(skin->isOpaque()) +01042 opaqueSize++; +01043 +01044 <font class="comment">// if animDetailable, then must fill list</font> +01045 <font class="keywordflow">if</font>(skin->isAnimDetailable()) +01046 animDetailSize++; +01047 +01048 <font class="comment">// if the skin support MRM, then must update levelDetal number of faces</font> +01049 <a class="code" href="classNL3D_1_1CTransformShape.html#b0">CTransformShape</a> *trShape= dynamic_cast<CTransformShape*>(skin); +01050 <font class="keywordflow">if</font>(trShape) +01051 { +01052 <font class="keyword">const</font> CMRMLevelDetail *skinLevelDetail= trShape->getMRMLevelDetail(); +01053 <font class="keywordflow">if</font>(skinLevelDetail) +01054 { +01055 <font class="comment">// Add Faces to the Skeleton level detail</font> +01056 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.MinFaceUsed+= skinLevelDetail->MinFaceUsed; +01057 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.MaxFaceUsed+= skinLevelDetail->MaxFaceUsed; +01058 <font class="comment">// MRM Max skin setup.</font> +01059 <font class="keywordflow">if</font>(_DefaultMRMSetup) +01060 { +01061 <font class="comment">// Get the maximum distance setup (ie the one which degrades the less)</font> +01062 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceCoarsest= max(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceCoarsest, skinLevelDetail->DistanceCoarsest); +01063 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceMiddle= max(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceMiddle, skinLevelDetail->DistanceMiddle); +01064 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceFinest= max(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceFinest, skinLevelDetail->DistanceFinest); +01065 } +01066 } +01067 } +01068 } +01069 +01070 <font class="comment">// MRM Max skin setup.</font> +01071 <font class="keywordflow">if</font>(_DefaultMRMSetup) +01072 { +01073 <font class="comment">// compile LevelDetail.</font> +01074 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.MaxFaceUsed==0) +01075 <font class="comment">// build a bug-free level detail</font> +01076 <a class="code" href="classNL3D_1_1CSkeletonModel.html#c0">buildDefaultLevelDetail</a>(); +01077 <font class="keywordflow">else</font> +01078 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.compileDistanceSetup(); +01079 } +01080 +01081 <font class="comment">// alloc array.</font> +01082 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o5">_OpaqueSkins</a>.<a class="code" href="classNLMISC_1_1CObjectVector.html#z301_0">clear</a>(); +01083 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o6">_TransparentSkins</a>.<a class="code" href="classNLMISC_1_1CObjectVector.html#z301_0">clear</a>(); +01084 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o7">_AnimDetailSkins</a>.<a class="code" href="classNLMISC_1_1CObjectVector.html#z301_0">clear</a>(); +01085 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o5">_OpaqueSkins</a>.<a class="code" href="classNLMISC_1_1CObjectVector.html#z301_1">resize</a>(opaqueSize); +01086 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o6">_TransparentSkins</a>.<a class="code" href="classNLMISC_1_1CObjectVector.html#z301_1">resize</a>(transparentSize); +01087 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o7">_AnimDetailSkins</a>.<a class="code" href="classNLMISC_1_1CObjectVector.html#z301_1">resize</a>(animDetailSize); +01088 +01089 <font class="comment">// ReParse, to fill array.</font> +01090 uint opaqueId= 0; +01091 uint transparentId= 0; +01092 uint animDetailId= 0; +01093 <font class="keywordflow">for</font>(it= <a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.begin();it!=<a class="code" href="classNL3D_1_1CSkeletonModel.html#o1">_Skins</a>.end();it++) +01094 { +01095 <a class="code" href="classNL3D_1_1CTransform.html#b0">CTransform</a> *skin= *it; +01096 <font class="comment">// if transparent, then must fill in transparent list.</font> +01097 <font class="keywordflow">if</font>(skin->isTransparent()) +01098 { +01099 <a class="code" href="debug_8h.html#a6">nlassert</a>(transparentId<transparentSize); +01100 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o6">_TransparentSkins</a>[transparentId++]= skin; +01101 } +01102 <font class="comment">// else may fill in opaquelist. NB: for optimisation, don't add in opaqueList </font> +01103 <font class="comment">// if added to the transperent list (all materials are rendered)</font> +01104 <font class="keywordflow">else</font> <font class="keywordflow">if</font>(skin->isOpaque()) +01105 { +01106 <a class="code" href="debug_8h.html#a6">nlassert</a>(opaqueId<opaqueSize); +01107 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o5">_OpaqueSkins</a>[opaqueId++]= skin; +01108 } +01109 +01110 <font class="comment">// if animDetailable, then must fill list</font> +01111 <font class="keywordflow">if</font>(skin->isAnimDetailable()) +01112 { +01113 <a class="code" href="debug_8h.html#a6">nlassert</a>(animDetailId<animDetailSize); +01114 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o7">_AnimDetailSkins</a>[animDetailId++]= skin; +01115 } +01116 } +01117 +01118 <font class="comment">// set the Transparency to the skeleton only if has at least one transparent skin</font> +01119 <a class="code" href="classNL3D_1_1CTransform.html#a0">setTransparency</a>( transparentSize>0 ); +01120 } +01121 } +01122 +01123 +01124 <font class="comment">// ***************************************************************************</font> +<a name="l01125"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#c0">01125</a> <font class="keywordtype">void</font> CSkeletonModel::buildDefaultLevelDetail() +01126 { +01127 <font class="comment">// Avoid divide by zero.</font> +01128 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.MinFaceUsed= 0; +01129 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.MaxFaceUsed= 0; +01130 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceFinest= 1; +01131 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceMiddle= 2; +01132 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceCoarsest= 3; +01133 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.compileDistanceSetup(); +01134 } +01135 +01136 +01137 <font class="comment">// ***************************************************************************</font> +<a name="l01138"></a><a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a1">01138</a> <font class="keywordtype">void</font> CSkeletonModelRenderObs::renderCLod() +01139 { +01140 CRenderTrav *trav= (CRenderTrav*)<a class="code" href="classNL3D_1_1IObs.html#m1">Trav</a>; +01141 CSkeletonModel *sm= (CSkeletonModel*)<a class="code" href="classNL3D_1_1IObs.html#m0">Model</a>; +01142 IDriver *drv= trav->getDriver(); +01143 CScene *scene= trav->Scene; +01144 <font class="comment">// the lod manager. no op if not here</font> +01145 CLodCharacterManager *mngr= trav->Scene->getLodCharacterManager(); +01146 <font class="keywordflow">if</font>(!mngr) +01147 <font class="keywordflow">return</font>; +01148 +01149 <font class="comment">// Get global lighting on the instance. Suppose SunAmbient only.</font> +01150 <font class="comment">//=================</font> +01151 <font class="keyword">const</font> CLightContribution *lightContrib; +01152 <font class="comment">// Get HrcObs.</font> +01153 CTransformHrcObs *hrcObs= (CTransformHrcObs*)<a class="code" href="classNL3D_1_1IBaseRenderObs.html#m0">HrcObs</a>; +01154 +01155 <font class="comment">// the std case is to take my model lightContribution</font> +01156 <font class="keywordflow">if</font>(hrcObs->_AncestorSkeletonModel==NULL) +01157 lightContrib= &sm->getSkeletonLightContribution(); +01158 <font class="comment">// but if skinned/sticked (directly or not) to a skeleton, take its.</font> +01159 <font class="keywordflow">else</font> +01160 lightContrib= &hrcObs->_AncestorSkeletonModel->getSkeletonLightContribution(); +01161 +01162 <font class="comment">// compute his main light contribution result. Try first with sun</font> +01163 CRGBA mainAmbient= scene->getSunAmbient(); +01164 CRGBA mainDiffuse= scene->getSunDiffuse(); +01165 <font class="comment">// modulate sun contribution</font> +01166 mainDiffuse.modulateFromuiRGBOnly(mainDiffuse, lightContrib->SunContribution ); +01167 CVector mainLightDir= scene->getSunDirection(); +01168 +01169 +01170 <font class="comment">/* During night, and in the buildings, it may be better to use one of the other Points lights</font> +01171 <font class="comment"> Test only with the first pointLight, for faster compute, even if It may fail in some cases.</font> +01172 <font class="comment"> */</font> +01173 CPointLight *mainPL= lightContrib->PointLight[0]; +01174 <font class="keywordflow">if</font>(mainPL) +01175 { +01176 CRGBA plDiffuse; +01177 <font class="comment">// get the diffuse of the pointLight, attenuated from distance and importance.</font> +01178 plDiffuse.modulateFromuiRGBOnly(mainPL->getDiffuse(), lightContrib->AttFactor[0]); +01179 <font class="comment">// compare the 2 diffuse</font> +01180 uint d0= mainDiffuse.R + mainDiffuse.G + mainDiffuse.B; +01181 uint d1= plDiffuse.R + plDiffuse.G + plDiffuse.B; +01182 <font class="comment">// if the pointLight is lighter, take it.</font> +01183 <font class="keywordflow">if</font>(d1>d0) +01184 { +01185 <font class="comment">// leave ambient, but take diffuse and pointLight fake Direction</font> +01186 mainDiffuse= plDiffuse; +01187 mainLightDir= hrcObs->WorldMatrix.getPos() - mainPL->getPosition(); +01188 mainLightDir.normalize(); +01189 } +01190 } +01191 +01192 +01193 <font class="comment">// compute colors of the lods.</font> +01194 <font class="comment">//=================</font> +01195 <font class="comment">// NB: even if texturing is sufficient, still important for AlphaTest.</font> +01196 +01197 <font class="comment">// If must recompute color because of change of skin color or if skin added/deleted</font> +01198 <font class="keywordflow">if</font>(sm->_CLodVertexColorDirty) +01199 { +01200 <font class="comment">// recompute vertex colors</font> +01201 sm->computeCLodVertexColors(mngr); +01202 <font class="comment">// set sm->_CLodVertexColorDirty to false.</font> +01203 sm->_CLodVertexColorDirty= <font class="keyword">false</font>; +01204 } +01205 +01206 <font class="comment">// render the Lod in the LodManager.</font> +01207 <font class="comment">//=================</font> +01208 <font class="comment">// render must have been intialized</font> +01209 <a class="code" href="debug_8h.html#a6">nlassert</a>(mngr->isRendering()); +01210 +01211 +01212 <font class="comment">// add the instance to the manager. </font> +01213 <font class="keywordflow">if</font>(!mngr->addRenderCharacterKey(sm->_CLodInstance, hrcObs->WorldMatrix, +01214 mainAmbient, mainDiffuse, mainLightDir) ) +01215 { +01216 <font class="comment">// If failed to add it because no more vertex space in the manager, retry.</font> +01217 +01218 <font class="comment">// close vertexBlock, compile render</font> +01219 mngr->endRender(); +01220 <font class="comment">// and restart.</font> +01221 mngr->beginRender(drv, trav->CamPos); +01222 +01223 <font class="comment">// retry. but no-op if refail.</font> +01224 mngr->addRenderCharacterKey(sm->_CLodInstance, hrcObs->WorldMatrix, +01225 mainAmbient, mainDiffuse, mainLightDir); +01226 } +01227 } +01228 +01229 +01230 <font class="comment">// ***************************************************************************</font> +<a name="l01231"></a><a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a2">01231</a> <font class="keywordtype">void</font> CSkeletonModelRenderObs::renderSkins() +01232 { +01233 <font class="comment">// Render skins according to the pass.</font> +01234 CRenderTrav *rdrTrav= (CRenderTrav*)<a class="code" href="classNL3D_1_1IObs.html#m1">Trav</a>; +01235 CSkeletonModel *sm= (CSkeletonModel*)<a class="code" href="classNL3D_1_1IObs.html#m0">Model</a>; +01236 CTransformHrcObs *hrcObs= (CTransformHrcObs*)<a class="code" href="classNL3D_1_1IBaseRenderObs.html#m0">HrcObs</a>; +01237 <font class="comment">// get a ptr on the driver</font> +01238 IDriver *drv= rdrTrav->getDriver(); +01239 <a class="code" href="debug_8h.html#a6">nlassert</a>(drv); +01240 +01241 +01242 <font class="comment">// Compute the levelOfDetail</font> +01243 <font class="keywordtype">float</font> alphaMRM= sm->_LevelDetail.getLevelDetailFromPolyCount(sm->getNumTrianglesAfterLoadBalancing()); +01244 +01245 <font class="comment">// force normalisation of normals..</font> +01246 <font class="keywordtype">bool</font> bkupNorm= drv->isForceNormalize(); +01247 drv->forceNormalize(<font class="keyword">true</font>); +01248 +01249 +01250 <font class="comment">// rdr good pass</font> +01251 <font class="keywordflow">if</font>(rdrTrav->isCurrentPassOpaque()) +01252 { +01253 <font class="comment">// Compute in Pass Opaque only the light contribution. </font> +01254 <font class="comment">// Easier for skeleton: suppose lightable, no local attenuation</font> +01255 +01256 <font class="comment">// the std case is to take my model lightContribution</font> +01257 <font class="keywordflow">if</font>(hrcObs->_AncestorSkeletonModel==NULL) +01258 sm->setupCurrentLightContribution(&sm->_LightContribution, <font class="keyword">false</font>); +01259 <font class="comment">// but if sticked (directly or not) to a skeleton, take its.</font> +01260 <font class="keywordflow">else</font> +01261 sm->setupCurrentLightContribution(&hrcObs->_AncestorSkeletonModel->_LightContribution, <font class="keyword">false</font>); +01262 +01263 +01264 <font class="comment">// Activate Driver setup: light and modelMatrix</font> +01265 sm->changeLightSetup( rdrTrav ); +01266 rdrTrav->getDriver()->setupModelMatrix(hrcObs->WorldMatrix); +01267 +01268 +01269 <font class="comment">// Render all totaly opaque skins.</font> +01270 <a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a3">renderSkinList</a>(sm->_OpaqueSkins, alphaMRM); +01271 } +01272 <font class="keywordflow">else</font> +01273 { +01274 <font class="comment">// NB: must have some transparent skins, since thee skeletonModel is traversed in the transparent pass.</font> +01275 +01276 <font class="comment">// Activate Driver setup: light and modelMatrix</font> +01277 sm->changeLightSetup( rdrTrav ); +01278 rdrTrav->getDriver()->setupModelMatrix(hrcObs->WorldMatrix); +01279 +01280 +01281 <font class="comment">// render all opaque/transparent skins</font> +01282 <a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a3">renderSkinList</a>(sm->_TransparentSkins, alphaMRM); +01283 } +01284 +01285 +01286 <font class="comment">// bkup force normalisation.</font> +01287 drv->forceNormalize(bkupNorm); +01288 } +01289 +01290 +01291 <font class="comment">// ***************************************************************************</font> +<a name="l01292"></a><a class="code" href="classNL3D_1_1CSkeletonModelRenderObs.html#a3">01292</a> <font class="keywordtype">void</font> CSkeletonModelRenderObs::renderSkinList(<a class="code" href="classNLMISC_1_1CObjectVector.html">NLMISC::CObjectVector<CTransform*, false></a> &skinList, <font class="keywordtype">float</font> alphaMRM) +01293 { +01294 CRenderTrav *rdrTrav= (CRenderTrav*)<a class="code" href="classNL3D_1_1IObs.html#m1">Trav</a>; +01295 +01296 <font class="comment">// if the SkinManager is not possible at all, just rendered the std way</font> +01297 <font class="keywordflow">if</font>( !rdrTrav->getMeshSkinManager() || !rdrTrav->getMeshSkinManager()->enabled() ) +01298 { +01299 <font class="keywordflow">for</font>(uint i=0;i<skinList.<a class="code" href="classNLMISC_1_1CObjectVector.html#z302_0">size</a>();i++) +01300 { +01301 skinList[i]->renderSkin(alphaMRM); +01302 } +01303 } +01304 <font class="keywordflow">else</font> +01305 { +01306 <font class="comment">// get the meshSkinManager</font> +01307 CMeshSkinManager &meshSkinManager= *rdrTrav->getMeshSkinManager(); +01308 +01309 <font class="comment">// array (rarely allocated) of skins with grouping support</font> +01310 <font class="keyword">static</font> std::vector<CTransform*> skinsToGroup; +01311 <font class="keyword">static</font> std::vector<uint> baseVertices; +01312 skinsToGroup.clear(); +01313 baseVertices.clear(); +01314 +01315 <font class="comment">// get the maxVertices the manager support</font> +01316 uint maxVertices= meshSkinManager.getMaxVertices(); +01317 uint vertexSize= meshSkinManager.getVertexSize(); +01318 +01319 <font class="comment">// render any skins which do not support SkinGrouping, and fill array of skins to group</font> +01320 <font class="keywordflow">for</font>(uint i=0;i<skinList.<a class="code" href="classNLMISC_1_1CObjectVector.html#z302_0">size</a>();i++) +01321 { +01322 <font class="comment">// If don't support, or if too big to fit in the manager, just renderSkin()</font> +01323 <font class="keywordflow">if</font>(!skinList[i]->supportSkinGrouping()) +01324 { +01325 <a class="code" href="hierarchical__timer_8h.html#a4">H_AUTO</a>( NL3D_Skin_NotGrouped ); +01326 skinList[i]->renderSkin(alphaMRM); +01327 } +01328 <font class="keywordflow">else</font> +01329 { +01330 skinsToGroup.push_back(skinList[i]); +01331 } +01332 } +01333 +01334 <a class="code" href="hierarchical__timer_8h.html#a4">H_AUTO</a>( NL3D_Skin_Grouped ); +01335 +01336 <font class="comment">// For each skin, have an index which gives the decal of the vertices in the buffer</font> +01337 baseVertices.resize(skinsToGroup.size()); +01338 +01339 <font class="comment">// while there is skin to render in group</font> +01340 uint skinId= 0; +01341 <font class="keywordflow">while</font>(skinId<skinsToGroup.size()) +01342 { +01343 <font class="comment">// space left in the manager</font> +01344 uint remainingVertices= maxVertices; +01345 uint currentBaseVertex= 0; +01346 +01347 <font class="comment">// First pass, fill The VB.</font> +01348 <font class="comment">//------------</font> +01349 <font class="comment">// lock buffer</font> +01350 uint8 *vbDest= meshSkinManager.lock(); +01351 +01352 <font class="comment">// For all skins until the buffer is full</font> +01353 uint startSkinId= skinId; +01354 <font class="keywordflow">while</font>(skinId<skinsToGroup.size()) +01355 { +01356 <font class="comment">// if success to fill the AGP</font> +01357 sint numVerticesAdded= skinsToGroup[skinId]->renderSkinGroupGeom(alphaMRM, remainingVertices, +01358 vbDest + vertexSize*currentBaseVertex ); +01359 <font class="comment">// -1 means that this skin can't render because no space left for her. Then stop for this block</font> +01360 <font class="keywordflow">if</font>(numVerticesAdded==-1) +01361 <font class="keywordflow">break</font>; +01362 <font class="comment">// Else ok, get the currentBaseVertex for this skin</font> +01363 baseVertices[skinId]= currentBaseVertex; +01364 <font class="comment">// and jump to the next place</font> +01365 currentBaseVertex+= numVerticesAdded; +01366 remainingVertices-= numVerticesAdded; +01367 +01368 <font class="comment">// go to the next skin</font> +01369 skinId++; +01370 } +01371 +01372 <font class="comment">// release buffer. ATI: release only vertices used.</font> +01373 meshSkinManager.unlock(currentBaseVertex); +01374 +01375 <font class="comment">// Second pass, render the primitives.</font> +01376 <font class="comment">//------------</font> +01377 meshSkinManager.activate(); +01378 <font class="keywordflow">for</font>(uint i=startSkinId;i<skinId;i++) +01379 { +01380 <font class="comment">// render the skin in the current buffer</font> +01381 skinsToGroup[i]->renderSkinGroupPrimitives(baseVertices[i]); +01382 } +01383 +01384 +01385 <font class="comment">// End of this block, swap to the next buffer</font> +01386 meshSkinManager.swapVBHard(); +01387 } +01388 } +01389 } +01390 +01391 +01392 <font class="comment">// ***************************************************************************</font> +<a name="l01393"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z805_0">01393</a> <font class="keywordtype">float</font> CSkeletonModel::getNumTriangles (<font class="keywordtype">float</font> distance) +01394 { +01395 <font class="comment">// If the skeleton is displayed as a CLod suppose 0 triangles.</font> +01396 <font class="keywordflow">if</font>( <a class="code" href="classNL3D_1_1CSkeletonModel.html#z804_8">isDisplayedAsLodCharacter</a>() ) +01397 <font class="keywordflow">return</font> 0; +01398 <font class="keywordflow">else</font> +01399 <font class="comment">// NB: this is an approximation, but this is continious.</font> +01400 <font class="keywordflow">return</font> <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.getNumTriangles(distance); +01401 } +01402 +01403 <font class="comment">// ***************************************************************************</font> +<a name="l01404"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z805_1">01404</a> <font class="keywordtype">void</font> CSkeletonModel::changeMRMDistanceSetup(<font class="keywordtype">float</font> distanceFinest, <font class="keywordtype">float</font> distanceMiddle, <font class="keywordtype">float</font> distanceCoarsest) +01405 { +01406 <font class="comment">// check input.</font> +01407 <font class="keywordflow">if</font>(distanceFinest<0) <font class="keywordflow">return</font>; +01408 <font class="keywordflow">if</font>(distanceMiddle<=distanceFinest) <font class="keywordflow">return</font>; +01409 <font class="keywordflow">if</font>(distanceCoarsest<=distanceMiddle) <font class="keywordflow">return</font>; +01410 +01411 <font class="comment">// Change.</font> +01412 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceFinest= distanceFinest; +01413 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceMiddle= distanceMiddle; +01414 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.DistanceCoarsest= distanceCoarsest; +01415 +01416 <font class="comment">// compile </font> +01417 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o8">_LevelDetail</a>.compileDistanceSetup(); +01418 +01419 <font class="comment">// Never more use MAX skin setup.</font> +01420 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o4">_DefaultMRMSetup</a>= <font class="keyword">false</font>; +01421 } +01422 +01423 +01424 <font class="comment">// ***************************************************************************</font> +<a name="l01425"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z805_2">01425</a> <font class="keywordtype">void</font> CSkeletonModel::resetDefaultMRMDistanceSetup() +01426 { +01427 <a class="code" href="classNL3D_1_1CSkeletonModel.html#o4">_DefaultMRMSetup</a>= <font class="keyword">true</font>; +01428 +01429 <font class="comment">// Must use Skins linked to know the MRM setup.</font> +01430 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z801_4">dirtSkinRenderLists</a>(); +01431 } +01432 +01433 +01434 <font class="comment">// ***************************************************************************</font> +<a name="l01435"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_7">01435</a> <font class="keywordtype">bool</font> CSkeletonModel::computeRenderedBBox(<a class="code" href="classNLMISC_1_1CAABBox.html">NLMISC::CAABBox</a> &bbox) +01436 { +01437 <font class="comment">// reset bbox</font> +01438 CAABBox tmpBBox; +01439 tmpBBox.setCenter(CVector::Null); +01440 tmpBBox.setHalfSize(CVector::Null); +01441 <font class="keywordtype">bool</font> empty= <font class="keyword">true</font>; +01442 +01443 <font class="comment">// Not visible => empty bbox</font> +01444 <font class="keywordflow">if</font>(!<a class="code" href="classNL3D_1_1CTransform.html#a19">getLastClippedState</a>()) +01445 <font class="keywordflow">return</font> <font class="keyword">false</font>; +01446 +01447 <font class="comment">// For all bones</font> +01448 uint i; +01449 <font class="keywordflow">for</font>(i=0;i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size();i++) +01450 { +01451 <font class="keywordflow">if</font>(<a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_1">isBoneComputed</a>(i)) +01452 { +01453 <font class="keyword">const</font> CVector &pos= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getLocalSkeletonMatrix().getPos(); +01454 <font class="keywordflow">if</font>(empty) +01455 { +01456 empty= <font class="keyword">false</font>; +01457 tmpBBox.setCenter(pos); +01458 } +01459 <font class="keywordflow">else</font> +01460 tmpBBox.extend(pos); +01461 } +01462 } +01463 +01464 <font class="comment">// End!</font> +01465 <font class="keywordflow">if</font>(!empty) +01466 { +01467 bbox= tmpBBox; +01468 <font class="keywordflow">return</font> <font class="keyword">true</font>; +01469 } +01470 <font class="keywordflow">else</font> +01471 <font class="keywordflow">return</font> <font class="keyword">false</font>; +01472 } +01473 +01474 +01475 <font class="comment">// ***************************************************************************</font> +<a name="l01476"></a><a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_8">01476</a> <font class="keywordtype">bool</font> CSkeletonModel::computeCurrentBBox(<a class="code" href="classNLMISC_1_1CAABBox.html">NLMISC::CAABBox</a> &bbox, <font class="keywordtype">bool</font> forceCompute <font class="comment">/* = false*/</font>) +01477 { +01478 <font class="comment">// animate all bones channels (detail only channels). don't bother cur lod state.</font> +01479 CChannelMixer *chanmix= <a class="code" href="classNL3D_1_1CTransform.html#b4">getChannelMixer</a>(); +01480 <font class="keywordflow">if</font> (chanmix) +01481 { +01482 <font class="comment">// Force detail evaluation.</font> +01483 chanmix->resetEvalDetailDate(); +01484 chanmix->eval(<font class="keyword">true</font>, 0); +01485 chanmix->resetEvalDetailDate(); +01486 } +01487 <font class="comment">// compute all skeleton bones</font> +01488 <a class="code" href="classNL3D_1_1CSkeletonModel.html#z803_6">computeAllBones</a>(CMatrix::Identity); +01489 +01490 <font class="comment">// reset bbox</font> +01491 CAABBox tmpBBox; +01492 tmpBBox.setCenter(CVector::Null); +01493 tmpBBox.setHalfSize(CVector::Null); +01494 <font class="keywordtype">bool</font> empty= <font class="keyword">true</font>; +01495 +01496 <font class="comment">// For all bones</font> +01497 uint i; +01498 <font class="keywordflow">for</font>(i=0;i<<a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>.size();i++) +01499 { +01500 <font class="comment">// Is the bone used ?? (whatever bone lod, or CLod state)</font> +01501 uint8 mustCompute = forceCompute ? 1 : <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].Usage | <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].ForcedUsage | <a class="code" href="classNL3D_1_1CSkeletonModel.html#z806_4">_BoneUsage</a>[i].CLodForcedUsage; +01502 +01503 <font class="comment">// If the bone is used.</font> +01504 <font class="keywordflow">if</font>(mustCompute) +01505 { +01506 <font class="keyword">const</font> CVector &pos= <a class="code" href="classNL3D_1_1CSkeletonModel.html#m0">Bones</a>[i].getLocalSkeletonMatrix().getPos(); +01507 <font class="keywordflow">if</font>(empty) +01508 { +01509 empty= <font class="keyword">false</font>; +01510 tmpBBox.setCenter(pos); +01511 } +01512 <font class="keywordflow">else</font> +01513 tmpBBox.extend(pos); +01514 } +01515 } +01516 +01517 <font class="comment">// End!</font> +01518 <font class="keywordflow">if</font>(!empty) +01519 { +01520 bbox= tmpBBox; +01521 <font class="keywordflow">return</font> <font class="keyword">true</font>; +01522 } +01523 <font class="keywordflow">else</font> +01524 <font class="keywordflow">return</font> <font class="keyword">false</font>; +01525 } +01526 +01527 +01528 } <font class="comment">// NL3D</font> +</pre></div> + +<!-- footer --> +<BR><FONT Size=+5> </FONT> +</TD> +<TD WIDTH=15><IMG SRC=http://www.nevrax.org/inc/img/pixel.gif WIDTH=15 HEIGHT=15 BORDER=0 ALT=""></TD> +</TR> +</TABLE> +</BODY> +</HTML> |