diff options
Diffstat (limited to '')
-rw-r--r-- | docs/doxygen/nel/a04624.html | 2169 |
1 files changed, 2169 insertions, 0 deletions
diff --git a/docs/doxygen/nel/a04624.html b/docs/doxygen/nel/a04624.html new file mode 100644 index 00000000..18ad80a6 --- /dev/null +++ b/docs/doxygen/nel/a04624.html @@ -0,0 +1,2169 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> +<title>NeL: move_container.cpp File Reference</title> +<link href="doxygen.css" rel="stylesheet" type="text/css"> +</head><body> +<!-- Generated by Doxygen 1.3.6 --> +<div class="qindex"> <form class="search" action="search.php" method="get"> +<a class="qindex" href="main.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">Data Structures</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">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related Pages</a> | <span class="search"><u>S</u>earch for <input class="search" type="text" name="query" value="" size="20" accesskey="s"/></span></form></div> +<h1>move_container.cpp File Reference</h1><hr><a name="_details"></a><h2>Detailed Description</h2> +<dl compact><dt><b>Id</b></dt><dd><a class="el" href="a04624.html">move_container.cpp</a>,v 1.45 2004/02/09 14:57:33 legros Exp </dd></dl> + +<p> +Definition in file <a class="el" href="a06047.html">move_container.cpp</a>. +<p> +<code>#include "<a class="el" href="a06452.html">stdpacs.h</a>"</code><br> +<code>#include "<a class="el" href="a06054.html">pacs/move_primitive.h</a>"</code><br> +<code>#include "<a class="el" href="a06051.html">pacs/move_element.h</a>"</code><br> +<code>#include "<a class="el" href="a06199.html">pacs/primitive_block.h</a>"</code><br> +<code>#include "<a class="el" href="a05788.html">nel/misc/hierarchical_timer.h</a>"</code><br> +<code>#include "<a class="el" href="a05801.html">nel/misc/i_xml.h</a>"</code><br> +<code>#include <math.h></code><br> +<code>#include <float.h></code><br> + +<p> +<a href="a06047.html">Go to the source code of this file.</a><table border=0 cellpadding=0 cellspacing=0> +<tr><td></td></tr> +<tr><td colspan=2><br><h2>Defines</h2></td></tr> +<tr><td class="memItemLeft" nowrap align=right valign=top>#define </td><td class="memItemRight" valign=bottom><a class="el" href="a04624.html#a0">NELPACS_ALLOC_DYNAMIC_INFO</a> 100</td></tr> + +<tr><td class="memItemLeft" nowrap align=right valign=top>#define </td><td class="memItemRight" valign=bottom><a class="el" href="a04624.html#a1">NELPACS_ALLOC_STATIC_INFO</a> 100</td></tr> + +<tr><td class="memItemLeft" nowrap align=right valign=top>#define </td><td class="memItemRight" valign=bottom><a class="el" href="a04624.html#a2">NLPACS_HAUTO_EVAL_COLLISION</a> H_AUTO_USE ( NLPACS_Eval_Collision )</td></tr> + +<tr><td colspan=2><br><h2>Functions</h2></td></tr> +<tr><td class="memItemLeft" nowrap align=right valign=top> </td><td class="memItemRight" valign=bottom><a class="el" href="a04624.html#a3">H_AUTO_DECL</a> (NLPACS_Eval_Collision) namespace NLPACS</td></tr> + +</table> +<hr><h2>Define Documentation</h2> +<a class="anchor" name="a0" doxytag="move_container.cpp::NELPACS_ALLOC_DYNAMIC_INFO" ></a><p> +<table class="mdTable" width="100%" cellpadding="2" cellspacing="0"> + <tr> + <td class="mdRow"> + <table cellpadding="0" cellspacing="0" border="0"> + <tr> + <td class="md" nowrap valign="top"> #define NELPACS_ALLOC_DYNAMIC_INFO 100 + </table> + </td> + </tr> +</table> +<table cellspacing=5 cellpadding=0 border=0> + <tr> + <td> + + </td> + <td> + +<p> + +<p> +Definition at line <a class="el" href="a06047.html#l00040">40</a> of file <a class="el" href="a06047.html">move_container.cpp</a>. </td> + </tr> +</table> +<a class="anchor" name="a1" doxytag="move_container.cpp::NELPACS_ALLOC_STATIC_INFO" ></a><p> +<table class="mdTable" width="100%" cellpadding="2" cellspacing="0"> + <tr> + <td class="mdRow"> + <table cellpadding="0" cellspacing="0" border="0"> + <tr> + <td class="md" nowrap valign="top"> #define NELPACS_ALLOC_STATIC_INFO 100 + </table> + </td> + </tr> +</table> +<table cellspacing=5 cellpadding=0 border=0> + <tr> + <td> + + </td> + <td> + +<p> + +<p> +Definition at line <a class="el" href="a06047.html#l00041">41</a> of file <a class="el" href="a06047.html">move_container.cpp</a>. </td> + </tr> +</table> +<a class="anchor" name="a2" doxytag="move_container.cpp::NLPACS_HAUTO_EVAL_COLLISION" ></a><p> +<table class="mdTable" width="100%" cellpadding="2" cellspacing="0"> + <tr> + <td class="mdRow"> + <table cellpadding="0" cellspacing="0" border="0"> + <tr> + <td class="md" nowrap valign="top"> #define NLPACS_HAUTO_EVAL_COLLISION H_AUTO_USE ( NLPACS_Eval_Collision ) + </table> + </td> + </tr> +</table> +<table cellspacing=5 cellpadding=0 border=0> + <tr> + <td> + + </td> + <td> + +<p> + +<p> +Referenced by <a class="el" href="a06047.html#l00043">H_AUTO_DECL()</a>. </td> + </tr> +</table> +<hr><h2>Function Documentation</h2> +<a class="anchor" name="a3" doxytag="move_container.cpp::H_AUTO_DECL" ></a><p> +<table class="mdTable" width="100%" cellpadding="2" cellspacing="0"> + <tr> + <td class="mdRow"> + <table cellpadding="0" cellspacing="0" border="0"> + <tr> + <td class="md" nowrap valign="top"> H_AUTO_DECL </td> + <td class="md" valign="top">( </td> + <td class="md" nowrap valign="top">NLPACS_Eval_Collision </td> + <td class="mdname1" valign="top" nowrap> </td> + <td class="md" valign="top"> ) </td> + <td class="md" nowrap></td> + </tr> + + </table> + </td> + </tr> +</table> +<table cellspacing=5 cellpadding=0 border=0> + <tr> + <td> + + </td> + <td> + +<p> + +<p> +Definition at line <a class="el" href="a06047.html#l00043">43</a> of file <a class="el" href="a06047.html">move_container.cpp</a>. +<p> +References <a class="el" href="a05538.html#l02654">file</a>, <a class="el" href="a05973.html#l00198">NLMISC::CMatrix::getPos()</a>, <a class="el" href="a05788.html#l00056">H_AUTO</a>, <a class="el" href="a05646.html#l01013">height</a>, <a class="el" href="a05646.html#l00225">index</a>, <a class="el" href="a05484.html#l00038">min</a>, <a class="el" href="a05972.html#l01244">NLMISC::CMatrix::mulVector()</a>, <a class="el" href="a06048.html#l00036">NELPACS_CONTAINER_TRIGGER_DEFAULT_SIZE</a>, <a class="el" href="a06054.html#l00038">NELPACS_DIST_BACK</a>, <a class="el" href="a05622.html#l00290">nlassert</a>, <a class="el" href="a04624.html#a2">NLPACS_HAUTO_EVAL_COLLISION</a>, <a class="el" href="a05622.html#l00135">nlwarning</a>, <a class="el" href="a06682.html#l00119">NLMISC::CVector::normalize()</a>, <a class="el" href="a05587.html#l00079">NLMISC::Pi</a>, <a class="el" href="a05646.html#l00993">r</a>, <a class="el" href="a06462.html#l00232">NLMISC::IStream::serial()</a>, <a class="el" href="a05981.html#l00104">sint</a>, <a class="el" href="a05646.html#l00645">size</a>, <a class="el" href="a05981.html#l00105">uint</a>, <a class="el" href="a05981.html#l00098">uint16</a>, <a class="el" href="a05981.html#l00096">uint8</a>, <a class="el" href="a05646.html#l01013">width</a>, <a class="el" href="a05646.html#l00236">x</a>, <a class="el" href="a06673.html#l00051">NLMISC::CVector::x</a>, <a class="el" href="a05646.html#l00236">y</a>, <a class="el" href="a06673.html#l00051">NLMISC::CVector::y</a>, and <a class="el" href="a06673.html#l00051">NLMISC::CVector::z</a>. +<p> +<div class="fragment"><pre>00048 : +00049 +00050 <span class="comment">// Non collisionnable primitive</span> +00051 Their moves are evaluate one by one with evalNCPrimitiveCollision(). +00052 If a collision is found, reaction() is called. +00053 +00054 <span class="comment">// Collisionnable primitives</span> +00055 Each primitive must be moved first with the move() method. +00056 Their moves are evaluate all at once. All the collisions found are time sorted <a class="code" href="a04223.html#a647">in</a> a time orderin table (_TimeOT). +00057 While the table is not empty, the first collision occured <a class="code" href="a04223.html#a647">in</a> time is solved and +00058 If a collision is found, reaction() is called. +00059 +00060 +00061 ****************************************************************************/ +00062 +00063 <span class="keyword">namespace </span>NLPACS +00064 { +00065 +00066 <span class="comment">// ***************************************************************************</span> +00067 +00068 CMoveContainer::~CMoveContainer () +00069 { +00070 clear (); +00071 } +00072 +00073 <span class="comment">// ***************************************************************************</span> +00074 +00075 <span class="keywordtype">void</span> CMoveContainer::clear () +00076 { +00077 <span class="comment">// Clear all primitives</span> +00078 std::set<CMovePrimitive*>::iterator ite=_PrimitiveSet.begin(); +00079 <span class="keywordflow">while</span> (ite!=_PrimitiveSet.end ()) +00080 { +00081 freePrimitive (*ite); +00082 ite++; +00083 } +00084 +00085 <span class="comment">// Clear primitive set</span> +00086 _PrimitiveSet.clear (); +00087 +00088 <span class="comment">// Clear root changed</span> +00089 _ChangedRoot.clear (); +00090 +00091 <span class="comment">// Clear static world image set</span> +00092 _StaticWorldImage.clear (); +00093 +00094 <span class="comment">// Clear cell array</span> +00095 _VectorCell.clear (); +00096 +00097 <span class="comment">// Clear time ot</span> +00098 _TimeOT.clear (); +00099 } +00100 +00101 <span class="comment">// ***************************************************************************</span> +00102 +00103 <span class="keywordtype">void</span> CMoveContainer::init (<span class="keywordtype">double</span> xmin, <span class="keywordtype">double</span> ymin, <span class="keywordtype">double</span> xmax, <span class="keywordtype">double</span> ymax, <a class="code" href="a04558.html#a15">uint</a> widthCellCount, <a class="code" href="a04558.html#a15">uint</a> heightCellCount, +00104 <span class="keywordtype">double</span> primitiveMaxSize, <a class="code" href="a04558.html#a7">uint8</a> numWorldImage, <a class="code" href="a04558.html#a15">uint</a> maxIteration, <a class="code" href="a04558.html#a15">uint</a> otSize) +00105 { +00106 <span class="comment">// Clear arrays</span> +00107 clear (); +00108 +00109 <span class="comment">// Create world images</span> +00110 _ChangedRoot.resize (numWorldImage); +00111 <span class="keywordflow">for</span> (<a class="code" href="a04558.html#a15">uint</a> i=0; i<numWorldImage; i++) +00112 _ChangedRoot[i]=NULL; +00113 +00114 <span class="comment">// Not in test mode</span> +00115 _Retriever=NULL; +00116 +00117 <span class="comment">// Element size</span> +00118 _PrimitiveMaxSize=primitiveMaxSize; +00119 +00120 <span class="comment">// BB</span> +00121 _Xmin=xmin; +00122 _Ymin=ymin; +00123 _Xmax=xmax; +00124 _Ymax=ymax; +00125 +00126 <span class="comment">// Cells count</span> +00127 _CellCountWidth=widthCellCount; +00128 _CellCountHeight=heightCellCount; +00129 +00130 <span class="comment">// Cells size</span> +00131 _CellWidth=(_Xmax - _Xmin)/(<span class="keywordtype">double</span>)_CellCountWidth; +00132 _CellHeight=(_Ymax - _Ymin)/(<span class="keywordtype">double</span>)_CellCountHeight; +00133 +00134 <span class="comment">// Cell array</span> +00135 _VectorCell.resize (numWorldImage); +00136 <span class="keywordflow">for</span> (<a class="code" href="a04558.html#a15">uint</a> j=0; j<numWorldImage; j++) +00137 _VectorCell[j].resize (_CellCountWidth * _CellCountHeight); +00138 +00139 <span class="comment">// resize OT</span> +00140 _OtSize=otSize; +00141 _TimeOT.resize (otSize); +00142 +00143 <span class="comment">// Clear the OT</span> +00144 clearOT (); +00145 +00146 <span class="comment">// Clear test time</span> +00147 _TestTime=0xffffffff; +00148 _MaxTestIteration=maxIteration; +00149 +00150 <span class="comment">// Resize trigger array</span> +00151 _Triggers.resize (NELPACS_CONTAINER_TRIGGER_DEFAULT_SIZE); +00152 } +00153 +00154 <span class="comment">// ***************************************************************************</span> +00155 +00156 <span class="keywordtype">void</span> CMoveContainer::init (CGlobalRetriever* retriever, <a class="code" href="a04558.html#a15">uint</a> widthCellCount, <a class="code" href="a04558.html#a15">uint</a> heightCellCount, <span class="keywordtype">double</span> primitiveMaxSize, +00157 <a class="code" href="a04558.html#a7">uint8</a> numWorldImage, <a class="code" href="a04558.html#a15">uint</a> maxIteration, <a class="code" href="a04558.html#a15">uint</a> otSize) +00158 { +00159 <span class="comment">// Get min max of the global retriever BB</span> +00160 CVector <a class="code" href="a04061.html#a0">min</a>=retriever->getBBox().getMin(); +00161 CVector max=retriever->getBBox().getMax(); +00162 +00163 <span class="comment">// Setup min max</span> +00164 <span class="keywordtype">double</span> xmin=<a class="code" href="a04061.html#a0">min</a>.x; +00165 <span class="keywordtype">double</span> ymin=<a class="code" href="a04061.html#a0">min</a>.y; +00166 <span class="keywordtype">double</span> xmax=max.x; +00167 <span class="keywordtype">double</span> ymax=max.y; +00168 +00169 <span class="comment">// Init</span> +00170 init (xmin, ymin, xmax, ymax, widthCellCount, heightCellCount, primitiveMaxSize, numWorldImage, maxIteration, otSize); +00171 +00172 <span class="comment">// Init the retriever</span> +00173 _Retriever=retriever; +00174 } +00175 +00176 <span class="comment">// ***************************************************************************</span> +00177 +00178 <span class="keywordtype">void</span> CMoveContainer::evalCollision (<span class="keywordtype">double</span> deltaTime, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +00179 { +00180 NL_ALLOC_CONTEXT( Pacs ) +00181 <a class="code" href="a04624.html#a2">NLPACS_HAUTO_EVAL_COLLISION</a> +00182 +00183 <span class="comment">// H_AUTO(PACS_MC_evalCollision);</span> +00184 +00185 <span class="comment">// New test time</span> +00186 _TestTime++; +00187 +00188 <span class="comment">// Delta time</span> +00189 _DeltaTime=deltaTime; +00190 +00191 <span class="comment">// Clear triggers</span> +00192 _Triggers.clear (); +00193 +00194 <span class="comment">// Update the bounding box and position of modified primitives</span> +00195 updatePrimitives (0.f, worldImage); +00196 +00197 <span class="preprocessor">#ifdef NL_DEBUG</span> +00198 <span class="preprocessor"></span> <span class="comment">// Check list integrity</span> +00199 <span class="comment">//checkSortedList ();</span> +00200 <span class="preprocessor">#endif // NL_DEBUG</span> +00201 <span class="preprocessor"></span> +00202 <span class="comment">// Get first collision</span> +00203 _PreviousCollisionNode = &_TimeOT[0]; +00204 +00205 <span class="comment">// Eval all collisions</span> +00206 evalAllCollisions (0.f, worldImage); +00207 +00208 <span class="comment">// Clear modified list</span> +00209 clearModifiedList (worldImage); +00210 +00211 <span class="comment">// Modified list is empty at this point</span> +00212 <a class="code" href="a04199.html#a6">nlassert</a> (_ChangedRoot[worldImage]==NULL); +00213 +00214 <span class="comment">// Previous node is a 'hard' OT node</span> +00215 <a class="code" href="a04199.html#a6">nlassert</a> (!_PreviousCollisionNode->isInfo()); +00216 +00217 <span class="comment">// Get next collision</span> +00218 CCollisionOTInfo *nextCollision; +00219 { +00220 <a class="code" href="a04365.html#a4">H_AUTO</a> (NLPACS_Get_Next_Info); +00221 nextCollision=_PreviousCollisionNode->getNextInfo (); +00222 } +00223 +00224 <span class="comment">// Collision ?</span> +00225 <span class="keywordflow">while</span> (nextCollision) +00226 { +00227 <span class="comment">// Get new previous OT hard node</span> +00228 _PreviousCollisionNode=nextCollision->getPrevious (); +00229 +00230 <span class="comment">// Previous node is a 'hard' OT node</span> +00231 <a class="code" href="a04199.html#a6">nlassert</a> (!_PreviousCollisionNode->isInfo()); +00232 +00233 <span class="comment">// Keep this collision</span> +00234 reaction (*nextCollision); +00235 +00236 <span class="comment">// Remove this collision from ot</span> +00237 <span class="keywordflow">if</span> (!nextCollision->isCollisionAgainstStatic ()) +00238 { +00239 <span class="comment">// Remove the primitive from OT</span> +00240 nextCollision->unlink(); +00241 +00242 CCollisionOTDynamicInfo *info = static_cast<CCollisionOTDynamicInfo*>(nextCollision); +00243 <span class="keywordflow">if</span> (info->getFirstPrimitive()) +00244 info->getFirstPrimitive()->removeCollisionOTInfo(info); +00245 <span class="keywordflow">if</span> (info->getSecondPrimitive()) +00246 info->getSecondPrimitive()->removeCollisionOTInfo(info); +00247 } +00248 +00249 <span class="comment">// Last time</span> +00250 <span class="keywordtype">double</span> newTime=nextCollision->getCollisionTime (); +00251 +00252 <span class="comment">// Remove modified objects from the OT</span> +00253 removeModifiedFromOT (worldImage); +00254 +00255 <span class="comment">// Must have been removed</span> +00256 <a class="code" href="a04199.html#a6">nlassert</a> (nextCollision->getPrevious ()==NULL); +00257 <a class="code" href="a04199.html#a6">nlassert</a> (nextCollision->CCollisionOT::getNext ()==NULL); +00258 +00259 <span class="comment">// Update the bounding box and position of modified primitives</span> +00260 updatePrimitives (newTime, worldImage); +00261 +00262 <span class="comment">// Eval all collisions of modified objects for the new delta t</span> +00263 evalAllCollisions (newTime, worldImage); +00264 +00265 <span class="comment">// Clear modified list</span> +00266 clearModifiedList (worldImage); +00267 +00268 <span class="comment">// Get next collision</span> +00269 nextCollision=_PreviousCollisionNode->getNextInfo (); +00270 } +00271 +00272 <span class="preprocessor">#ifdef NL_DEBUG</span> +00273 <span class="preprocessor"></span> <span class="comment">// OT must be cleared</span> +00274 checkOT (); +00275 <span class="preprocessor">#endif // NL_DEBUG</span> +00276 <span class="preprocessor"></span> +00277 <span class="comment">// Free ordered table info</span> +00278 freeAllOTInfo (); +00279 +00280 <span class="comment">// Some init</span> +00281 _PreviousCollisionNode=NULL; +00282 } +00283 +00284 <span class="comment">// ***************************************************************************</span> +00285 +00286 <span class="keywordtype">bool</span> CMoveContainer::testMove (UMovePrimitive* primitive, <span class="keyword">const</span> <a class="code" href="a03664.html">CVectorD</a>& speed, <span class="keywordtype">double</span> deltaTime, <a class="code" href="a04558.html#a7">uint8</a> worldImage, <a class="code" href="a03664.html">CVectorD</a> *contactNormal) +00287 { +00288 NL_ALLOC_CONTEXT( Pacs ) +00289 +00290 <span class="comment">// H_AUTO(PACS_MC_testMove);</span> +00291 +00292 <span class="keywordflow">if</span> (contactNormal) +00293 *contactNormal = CVectorD::Null; +00294 +00295 <span class="comment">// Cast</span> +00296 <a class="code" href="a04199.html#a6">nlassert</a> (dynamic_cast<CMovePrimitive*>(primitive)); +00297 CMovePrimitive* prim=static_cast<CMovePrimitive*>(primitive); +00298 +00299 <span class="comment">// New test time</span> +00300 _TestTime++; +00301 +00302 <span class="comment">// Delta time</span> +00303 _DeltaTime=deltaTime; +00304 +00305 <span class="comment">// Get the world image primitive</span> +00306 <a class="code" href="a04558.html#a7">uint8</a> primitiveWorldImage; +00307 CPrimitiveWorldImage *wI; +00308 <span class="keywordflow">if</span> (prim->isNonCollisionable ()) +00309 { +00310 wI=prim->getWorldImage (0); +00311 primitiveWorldImage=worldImage; +00312 } +00313 <span class="keywordflow">else</span> +00314 { +00315 wI=prim->getWorldImage (worldImage); +00316 primitiveWorldImage=worldImage; +00317 } +00318 +00319 <span class="comment">// Backup speed</span> +00320 <a class="code" href="a03664.html">CVectorD</a> oldSpeed=wI->getSpeed (); +00321 +00322 <span class="comment">// Set speed</span> +00323 wI->move (speed, *<span class="keyword">this</span>, *prim, primitiveWorldImage); +00324 +00325 <span class="comment">// Update the bounding box and position of the primitive</span> +00326 wI->update (0, _DeltaTime, *prim); +00327 +00328 <span class="comment">// Compute cells overlaped by the primitive</span> +00329 <span class="keywordflow">if</span> (!prim->isNonCollisionable ()) +00330 updateCells (prim, worldImage); +00331 +00332 <span class="preprocessor">#ifdef NL_DEBUG</span> +00333 <span class="preprocessor"></span> <span class="comment">// Check list integrity</span> +00334 <span class="comment">// checkSortedList ();</span> +00335 <span class="preprocessor">#endif // NL_DEBUG</span> +00336 <span class="preprocessor"></span> +00337 <span class="comment">// Result</span> +00338 <span class="keywordtype">bool</span> result=<span class="keyword">false</span>; +00339 <span class="keywordtype">bool</span> testMoveValid; +00340 +00341 <span class="comment">// Eval first each static world images</span> +00342 result=evalOneTerrainCollision (0, prim, primitiveWorldImage, <span class="keyword">true</span>, testMoveValid, NULL, contactNormal); +00343 +00344 <span class="comment">// Eval first each static world images</span> +00345 <span class="keywordflow">if</span> (!result) +00346 { +00347 std::set<uint8>::iterator ite=_StaticWorldImage.begin(); +00348 <span class="keywordflow">while</span> (ite!=_StaticWorldImage.end()) +00349 { +00350 +00351 <span class="comment">// Eval in this world image</span> +00352 result=evalOnePrimitiveCollision (0, prim, *ite, primitiveWorldImage, <span class="keyword">true</span>, <span class="keyword">true</span>, testMoveValid, NULL, contactNormal); +00353 +00354 <span class="comment">// If found, abort</span> +00355 <span class="keywordflow">if</span> (result) +00356 <span class="keywordflow">break</span>; +00357 +00358 <span class="comment">// Next world image</span> +00359 ite++; +00360 } +00361 } +00362 +00363 <span class="comment">// Eval collisions if not found and not tested</span> +00364 <span class="keywordflow">if</span> ((!result) && (_StaticWorldImage.find (worldImage)==_StaticWorldImage.end())) +00365 result=evalOnePrimitiveCollision (0, prim, worldImage, primitiveWorldImage, <span class="keyword">true</span>, <span class="keyword">false</span>, testMoveValid, NULL, contactNormal); +00366 +00367 <span class="comment">// Backup speed only if the primitive is inserted in the world image</span> +00368 <span class="keywordflow">if</span> (prim->isInserted (primitiveWorldImage)) +00369 wI->move (oldSpeed, *<span class="keyword">this</span>, *prim, primitiveWorldImage); +00370 +00371 <span class="preprocessor">#ifdef NL_DEBUG</span> +00372 <span class="preprocessor"></span> <span class="comment">// OT must be cleared</span> +00373 checkOT (); +00374 <span class="preprocessor">#endif // NL_DEBUG</span> +00375 <span class="preprocessor"></span> +00376 <span class="comment">// Free ordered table info</span> +00377 freeAllOTInfo (); +00378 +00379 <span class="comment">// Some init</span> +00380 _PreviousCollisionNode=NULL; +00381 +00382 <span class="comment">// Return result</span> +00383 <span class="keywordflow">return</span> !result; +00384 } +00385 +00386 <span class="comment">// ***************************************************************************</span> +00387 +00388 <span class="keywordtype">void</span> CMoveContainer::updatePrimitives (<span class="keywordtype">double</span> beginTime, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +00389 { +00390 <a class="code" href="a04365.html#a4">H_AUTO</a> (NLPACS_Update_Primitives); +00391 +00392 <span class="comment">// For each changed primitives</span> +00393 CMovePrimitive *changed=_ChangedRoot[worldImage]; +00394 <span class="keywordflow">while</span> (changed) +00395 { +00396 <span class="comment">// Get the primitive world image</span> +00397 CPrimitiveWorldImage *wI; +00398 <span class="keywordflow">if</span> (changed->isNonCollisionable()) +00399 wI=changed->getWorldImage (0); +00400 <span class="keywordflow">else</span> +00401 wI=changed->getWorldImage (worldImage); +00402 +00403 <span class="comment">// Force the build of the bounding box</span> +00404 wI->update (beginTime, _DeltaTime, *changed); +00405 +00406 <span class="comment">// Is inserted in this world image ?</span> +00407 <span class="keywordflow">if</span> (changed->isInserted (worldImage)) +00408 { +00409 +00410 <span class="comment">// Compute cells overlaped by the primitive</span> +00411 updateCells (changed, worldImage); +00412 } +00413 +00414 <span class="comment">// Next primitive</span> +00415 changed=wI->getNextModified (); +00416 } +00417 } +00418 +00419 <span class="comment">// ***************************************************************************</span> +00420 +00421 <span class="keywordtype">void</span> CMoveContainer::updateCells (CMovePrimitive *primitive, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +00422 { +00423 <span class="comment">// H_AUTO(PACS_MC_updateCells);</span> +00424 +00425 <span class="comment">// Get the primitive world image</span> +00426 CPrimitiveWorldImage *wI=primitive->getWorldImage (worldImage); +00427 +00428 <span class="comment">// Check BB width not too large</span> +00429 <span class="keywordflow">if</span> (wI->getBBXMax() - wI->getBBXMin() > _CellWidth) +00430 { +00431 <a class="code" href="a04199.html#a2">nlwarning</a> (<span class="stringliteral">"Primitives have moved more than a cell."</span>); +00432 } +00433 +00434 <span class="comment">// Check BB height not too large</span> +00435 <span class="keywordflow">if</span> (wI->getBBYMax() - wI->getBBYMin() > _CellHeight) +00436 { +00437 <a class="code" href="a04199.html#a2">nlwarning</a> (<span class="stringliteral">"Primitives have moved more than a cell."</span>); +00438 } +00439 +00440 <span class="comment">// Get coordinate in the cell array</span> +00441 <a class="code" href="a04558.html#a14">sint</a> minx=(<span class="keywordtype">int</span>)floor ((wI->getBBXMin() - _Xmin) / _CellWidth); +00442 <a class="code" href="a04558.html#a14">sint</a> miny=(<span class="keywordtype">int</span>)floor ((wI->getBBYMin() - _Ymin) / _CellHeight); +00443 <a class="code" href="a04558.html#a14">sint</a> maxx=(<span class="keywordtype">int</span>)floor ((wI->getBBXMax() - _Xmin) / _CellWidth); +00444 <a class="code" href="a04558.html#a14">sint</a> maxy=(<span class="keywordtype">int</span>)floor ((wI->getBBYMax() - _Ymin) / _CellHeight); +00445 +00446 <span class="comment">// Born</span> +00447 <span class="keywordflow">if</span> (minx<0) +00448 minx=0; +00449 <span class="keywordflow">if</span> (miny<0) +00450 miny=0; +00451 <span class="keywordflow">if</span> (maxx>=(<span class="keywordtype">int</span>)_CellCountWidth) +00452 maxx=(<span class="keywordtype">int</span>)_CellCountWidth-1; +00453 <span class="keywordflow">if</span> (maxy>=(<span class="keywordtype">int</span>)_CellCountHeight) +00454 maxy=(<span class="keywordtype">int</span>)_CellCountHeight-1; +00455 +00456 maxx=<a class="code" href="a04061.html#a0">std::min</a> (minx+1, maxx); +00457 maxy=<a class="code" href="a04061.html#a0">std::min</a> (miny+1, maxy); +00458 +00459 <span class="comment">// flags founded</span> +00460 <span class="keywordtype">bool</span> found[4]={<span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span>}; +00461 +00462 <span class="comment">// For each old cells</span> +00463 <a class="code" href="a04558.html#a15">uint</a> i; +00464 <span class="keywordflow">for</span> (i=0; i<4; i++) +00465 { +00466 <span class="comment">// Element</span> +00467 CMoveElement *elm = wI->getMoveElement (i); +00468 +00469 <span class="comment">// Old element in this cell ?</span> +00470 <span class="keywordflow">if</span> ( elm ) +00471 { +00472 <span class="comment">// Check</span> +00473 <a class="code" href="a04199.html#a6">nlassert</a> (elm->X<_CellCountWidth); +00474 <a class="code" href="a04199.html#a6">nlassert</a> (elm->Y<_CellCountHeight); +00475 +00476 <span class="comment">// Must remove it ?</span> +00477 <span class="keywordflow">if</span> ( (elm->X < minx) || (elm->X > maxx) || (elm->Y < miny) || (elm->Y > maxy) ) +00478 { +00479 <span class="comment">// Yes remove it</span> +00480 wI->removeMoveElement (i, *<span class="keyword">this</span>, worldImage); +00481 } +00482 <span class="keywordflow">else</span> +00483 { +00484 <span class="comment">// Checks</span> +00485 <a class="code" href="a04199.html#a6">nlassert</a> (((elm->X - minx)==0)||((elm->X - minx)==1)); +00486 <a class="code" href="a04199.html#a6">nlassert</a> (((elm->Y - miny)==0)||((elm->Y - miny)==1)); +00487 +00488 <span class="comment">// Update position</span> +00489 <span class="preprocessor">#ifndef TEST_CELL</span> +00490 <span class="preprocessor"></span> _VectorCell[worldImage][elm->X+elm->Y*_CellCountWidth].updateSortedLists (elm, worldImage); +00491 <span class="preprocessor">#endif</span> +00492 <span class="preprocessor"></span> +00493 <span class="comment">// Check found cells</span> +00494 found[ elm->X - minx + ((elm->Y - miny) << (maxx-minx)) ]=<span class="keyword">true</span>; +00495 } +00496 } +00497 } +00498 +00499 <span class="comment">// For each case selected</span> +00500 <span class="keywordtype">int</span> <a class="code" href="a04223.html#a572">x</a>, <a class="code" href="a04223.html#a573">y</a>; +00501 i=0; +00502 <span class="keywordflow">for</span> (<a class="code" href="a04223.html#a573">y</a>=miny; <a class="code" href="a04223.html#a573">y</a><=(<span class="keywordtype">int</span>)maxy; <a class="code" href="a04223.html#a573">y</a>++) +00503 <span class="keywordflow">for</span> (<a class="code" href="a04223.html#a572">x</a>=minx; <a class="code" href="a04223.html#a572">x</a><=(<span class="keywordtype">int</span>)maxx; <a class="code" href="a04223.html#a572">x</a>++) +00504 { +00505 <span class="comment">// Check the formula</span> +00506 <a class="code" href="a04199.html#a6">nlassert</a> ((<span class="keywordtype">int</span>)i == (x - minx + ((y - miny) << (maxx-minx)) )); +00507 +00508 <span class="comment">// If the cell is not found</span> +00509 <span class="keywordflow">if</span> (!found[i]) +00510 { +00511 <span class="comment">// Center of the cell</span> +00512 <span class="keywordtype">double</span> cx=((<span class="keywordtype">double</span>)<a class="code" href="a04223.html#a572">x</a>+0.5f)*_CellWidth+_Xmin; +00513 <span class="keywordtype">double</span> cy=((<span class="keywordtype">double</span>)<a class="code" href="a04223.html#a573">y</a>+0.5f)*_CellHeight+_Ymin; +00514 +00515 <span class="comment">// Add it in the list</span> +00516 wI->addMoveElement (_VectorCell[worldImage][x+y*_CellCountWidth], (<a class="code" href="a04558.html#a9">uint16</a>)x, (<a class="code" href="a04558.html#a9">uint16</a>)y, cx, cy, primitive, *<span class="keyword">this</span>, worldImage); +00517 } +00518 +00519 <span class="comment">// Next cell</span> +00520 i++; +00521 } +00522 } +00523 +00524 <span class="comment">// ***************************************************************************</span> +00525 +00526 <span class="keywordtype">void</span> CMoveContainer::getCells (CMovePrimitive *primitive, <a class="code" href="a04558.html#a7">uint8</a> worldImage, <a class="code" href="a04558.html#a7">uint8</a> primitiveWorldImage, CMoveElement **elementArray) +00527 { +00528 <span class="comment">// H_AUTO(PACS_MC_getCells);</span> +00529 +00530 <span class="comment">// Get the primitive world image</span> +00531 CPrimitiveWorldImage *wI; +00532 <span class="keywordflow">if</span> (primitive->isNonCollisionable()) +00533 wI=primitive->getWorldImage (0); +00534 <span class="keywordflow">else</span> +00535 wI=primitive->getWorldImage (primitiveWorldImage); +00536 +00537 <span class="comment">// Check BB width not too large</span> +00538 <span class="keywordflow">if</span> (wI->getBBXMax() - wI->getBBXMin() > _CellWidth) +00539 { +00540 <a class="code" href="a04199.html#a2">nlwarning</a> (<span class="stringliteral">"Primitives have moved more than a cell."</span>); +00541 } +00542 +00543 <span class="comment">// Check BB height not too large</span> +00544 <span class="keywordflow">if</span> (wI->getBBYMax() - wI->getBBYMin() > _CellHeight) +00545 { +00546 <a class="code" href="a04199.html#a2">nlwarning</a> (<span class="stringliteral">"Primitives have moved more than a cell."</span>); +00547 } +00548 +00549 <span class="comment">// Get coordinate in the cell array</span> +00550 <span class="keywordtype">int</span> minx=(<span class="keywordtype">int</span>)floor ((wI->getBBXMin() - _Xmin) / _CellWidth); +00551 <span class="keywordtype">int</span> miny=(<span class="keywordtype">int</span>)floor ((wI->getBBYMin() - _Ymin) / _CellHeight); +00552 <span class="keywordtype">int</span> maxx=(<span class="keywordtype">int</span>)floor ((wI->getBBXMax() - _Xmin) / _CellWidth); +00553 <span class="keywordtype">int</span> maxy=(<span class="keywordtype">int</span>)floor ((wI->getBBYMax() - _Ymin) / _CellHeight); +00554 +00555 <span class="comment">// Born</span> +00556 <span class="keywordflow">if</span> (minx<0) +00557 minx=0; +00558 <span class="keywordflow">if</span> (miny<0) +00559 miny=0; +00560 <span class="keywordflow">if</span> (maxx>=(<span class="keywordtype">int</span>)_CellCountWidth) +00561 maxx=(<span class="keywordtype">int</span>)_CellCountWidth-1; +00562 <span class="keywordflow">if</span> (maxy>=(<span class="keywordtype">int</span>)_CellCountHeight) +00563 maxy=(<span class="keywordtype">int</span>)_CellCountHeight-1; +00564 +00565 maxx=<a class="code" href="a04061.html#a0">std::min</a> (minx+1, maxx); +00566 maxy=<a class="code" href="a04061.html#a0">std::min</a> (miny+1, maxy); +00567 +00568 <span class="comment">// For each case selected</span> +00569 <span class="keywordtype">int</span> <a class="code" href="a04223.html#a572">x</a>, <a class="code" href="a04223.html#a573">y</a>; +00570 <span class="keywordtype">int</span> i=0; +00571 <span class="keywordflow">for</span> (<a class="code" href="a04223.html#a573">y</a>=miny; <a class="code" href="a04223.html#a573">y</a><=(<span class="keywordtype">int</span>)maxy; <a class="code" href="a04223.html#a573">y</a>++) +00572 <span class="keywordflow">for</span> (<a class="code" href="a04223.html#a572">x</a>=minx; <a class="code" href="a04223.html#a572">x</a><=(<span class="keywordtype">int</span>)maxx; <a class="code" href="a04223.html#a572">x</a>++) +00573 { +00574 <span class="comment">// Check the formula</span> +00575 <a class="code" href="a04199.html#a6">nlassert</a> ((<span class="keywordtype">int</span>)i == (x - minx + ((y - miny) << (maxx-minx)) )); +00576 +00577 <span class="comment">// Center of the cell</span> +00578 <span class="keywordtype">double</span> cx=((<span class="keywordtype">double</span>)<a class="code" href="a04223.html#a572">x</a>+0.5f)*_CellWidth+_Xmin; +00579 +00580 <span class="comment">// Primitive center</span> +00581 <span class="keywordtype">double</span> pcx=(wI->getBBXMin()+wI->getBBXMax())/2.f; +00582 +00583 elementArray[i]->Primitive=primitive; +00584 elementArray[i]->X=<a class="code" href="a04223.html#a572">x</a>; +00585 elementArray[i]->Y=<a class="code" href="a04223.html#a573">y</a>; +00586 <span class="comment">// Insert in left or right ?</span> +00587 <span class="keywordflow">if</span> (pcx<cx) +00588 { +00589 <span class="comment">// In the left</span> +00590 elementArray[i]->NextX=_VectorCell[worldImage][<a class="code" href="a04223.html#a572">x</a>+<a class="code" href="a04223.html#a573">y</a>*_CellCountWidth].getFirstX (); +00591 elementArray[i]->PreviousX=NULL; +00592 } +00593 <span class="keywordflow">else</span> +00594 { +00595 <span class="comment">// In the right</span> +00596 elementArray[i]->PreviousX=_VectorCell[worldImage][<a class="code" href="a04223.html#a572">x</a>+<a class="code" href="a04223.html#a573">y</a>*_CellCountWidth].getLastX (); +00597 elementArray[i]->NextX=NULL; +00598 } +00599 +00600 <span class="comment">// Next cell</span> +00601 i++; +00602 } +00603 +00604 <span class="comment">// Erase last array element</span> +00605 <span class="keywordflow">for</span> (; i<4; i++) +00606 { +00607 elementArray[i]=NULL; +00608 } +00609 } +00610 +00611 <span class="comment">// ***************************************************************************</span> +00612 +00613 <span class="keywordtype">void</span> CMoveContainer::clearModifiedList (<a class="code" href="a04558.html#a7">uint8</a> worldImage) +00614 { +00615 <a class="code" href="a04365.html#a4">H_AUTO</a> (NLPACS_Clear_Modified_List); +00616 +00617 <span class="comment">// For each changed primitives</span> +00618 CMovePrimitive *changed=_ChangedRoot[worldImage]; +00619 <span class="keywordflow">while</span> (changed) +00620 { +00621 <span class="comment">// Get the world image primitive</span> +00622 CPrimitiveWorldImage *wI; +00623 <span class="keywordflow">if</span> (changed->isNonCollisionable()) +00624 wI=changed->getWorldImage (0); +00625 <span class="keywordflow">else</span> +00626 wI=changed->getWorldImage (worldImage); +00627 +00628 <span class="comment">// Next primitive</span> +00629 changed=wI->getNextModified (); +00630 +00631 <span class="comment">// Remove it from the list</span> +00632 wI->setInModifiedListFlag (<span class="keyword">false</span>); +00633 } +00634 +00635 <span class="comment">// Empty list</span> +00636 _ChangedRoot[worldImage]=NULL; +00637 } +00638 +00639 <span class="comment">// ***************************************************************************</span> +00640 +00641 <span class="keywordtype">void</span> CMoveContainer::checkSortedList () +00642 { +00643 <span class="comment">// Check each primitives in the set</span> +00644 std::set<CMovePrimitive*>::iterator ite=_PrimitiveSet.begin(); +00645 <span class="keywordflow">while</span> (ite!=_PrimitiveSet.end()) +00646 { +00647 <span class="comment">// Check</span> +00648 (*ite)->checkSortedList (); +00649 +00650 ite++; +00651 } +00652 } +00653 +00654 <span class="comment">// ***************************************************************************</span> +00655 +00656 <span class="keywordtype">bool</span> CMoveContainer::evalOneTerrainCollision (<span class="keywordtype">double</span> beginTime, CMovePrimitive *primitive, <a class="code" href="a04558.html#a7">uint8</a> primitiveWorldImage, +00657 <span class="keywordtype">bool</span> testMove, <span class="keywordtype">bool</span> &testMoveValid, CCollisionOTStaticInfo *staticColInfo, <a class="code" href="a03664.html">CVectorD</a> *contactNormal) +00658 { +00659 <span class="comment">// H_AUTO(PACS_MC_evalOneCollision);</span> +00660 <a class="code" href="a04365.html#a4">H_AUTO</a>(NLPACS_Eval_One_Terrain_Collision); +00661 +00662 <span class="comment">// Find its collisions</span> +00663 <span class="keywordtype">bool</span> found=<span class="keyword">false</span>; +00664 +00665 <span class="comment">// Get the primitive world image</span> +00666 CPrimitiveWorldImage *wI; +00667 <span class="keywordflow">if</span> (primitive->isNonCollisionable()) +00668 wI=primitive->getWorldImage (0); +00669 <span class="keywordflow">else</span> +00670 wI=primitive->getWorldImage (primitiveWorldImage); +00671 +00672 <span class="comment">// Begin time must be the same as beginTime</span> +00673 <span class="comment">//nlassert (wI->getInitTime()==beginTime);</span> +00674 <span class="keywordflow">if</span> (wI->getInitTime() != beginTime) +00675 { +00676 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: evalOneTerrainCollision() failure, wI->getInitTime() [%f] != beginTime [%f]"</span>, wI->getInitTime(), beginTime); +00677 <span class="keywordflow">return</span> <span class="keyword">false</span>; +00678 } +00679 +00680 <span class="comment">// Test its static collision</span> +00681 <span class="keywordflow">if</span> (_Retriever) +00682 { +00683 <span class="comment">// Delta pos..</span> +00684 <span class="comment">// Test retriever with the primitive</span> +00685 <span class="keyword">const</span> <a class="code" href="a05380.html#a0">TCollisionSurfaceDescVector</a> *result=wI->evalCollision (*_Retriever, _SurfaceTemp, _TestTime, _MaxTestIteration, *primitive); +00686 <span class="keywordflow">if</span> (result) +00687 { +00688 <span class="comment">// TEST MOVE MUST BE OK !!</span> +00689 testMoveValid=<span class="keyword">true</span>; +00690 +00691 <span class="comment">// Size of the array</span> +00692 <a class="code" href="a04558.html#a15">uint</a> <a class="code" href="a04223.html#a587">size</a>=result->size(); +00693 +00694 <span class="comment">// For each detected collisions</span> +00695 <span class="keywordflow">for</span> (<a class="code" href="a04558.html#a15">uint</a> c=0; c<<a class="code" href="a04223.html#a587">size</a>; c++) +00696 { +00697 <span class="comment">// Ref on the collision</span> +00698 CCollisionSurfaceDesc desc=(*result)[c]; +00699 <span class="keywordtype">double</span> contactTime = (_DeltaTime-beginTime)*desc.ContactTime+beginTime; +00700 +00701 <span class="comment">/*</span> +00702 <span class="comment"> * If beginTime is 0.999999999 and desc.ContactTime<1.0, contactTime will be 1.0.</span> +00703 <span class="comment"> * In this case, we force contactTime to be beginTime to avoid collision at time == 1.0.</span> +00704 <span class="comment"> **/</span> +00705 <span class="keywordflow">if</span> ((contactTime >= 1.0) && (beginTime < 1.0) && (desc.ContactTime < 1.0)) +00706 contactTime = beginTime; +00707 +00708 <span class="comment">// Set the container's time space contact time</span> +00709 desc.ContactTime = contactTime; +00710 +00711 <span class="comment">// ptr on the surface</span> +00712 <span class="keyword">const</span> CRetrievableSurface *surf= _Retriever->getSurfaceById (desc.ContactSurface); +00713 +00714 <span class="comment">// TODO: check surface flags against primitive flags HERE:</span> +00715 <span class="comment">// Is a wall ?</span> +00716 <span class="keywordtype">bool</span> isWall; +00717 <span class="keywordflow">if</span>(!surf) +00718 isWall= <span class="keyword">true</span>; +00719 <span class="keywordflow">else</span> +00720 isWall= !(surf->isFloor() || surf->isCeiling()); +00721 +00722 <span class="comment">// stop on a wall.</span> +00723 <span class="keywordflow">if</span>(isWall) +00724 { +00725 <span class="comment">// Test move ?</span> +00726 <span class="keywordflow">if</span> (testMove) +00727 { +00728 <span class="comment">// return contact normal only when testmove and vector provided</span> +00729 <span class="keywordflow">if</span> (contactNormal) +00730 *contactNormal = desc.ContactNormal; +00731 <span class="keywordflow">return</span> <span class="keyword">true</span>; +00732 } +00733 <span class="keywordflow">else</span> +00734 { +00735 <span class="comment">// OK, collision if we are a collisionable primitive</span> +00736 newCollision (primitive, desc, primitiveWorldImage, beginTime, staticColInfo); +00737 +00738 <span class="comment">// One collision found</span> +00739 found=<span class="keyword">true</span>; +00740 <span class="keywordflow">break</span>; +00741 } +00742 } +00743 } +00744 } +00745 <span class="keywordflow">else</span> +00746 <span class="comment">// More than maxtest made, exit</span> +00747 <span class="keywordflow">return</span> <span class="keyword">false</span>; +00748 } +00749 <span class="keywordflow">return</span> found; +00750 } +00751 +00752 <span class="comment">// ***************************************************************************</span> +00753 +00754 <span class="keywordtype">bool</span> CMoveContainer::evalOnePrimitiveCollision (<span class="keywordtype">double</span> beginTime, CMovePrimitive *primitive, <a class="code" href="a04558.html#a7">uint8</a> worldImage, <a class="code" href="a04558.html#a7">uint8</a> primitiveWorldImage, +00755 <span class="keywordtype">bool</span> testMove, <span class="keywordtype">bool</span> secondIsStatic, <span class="keywordtype">bool</span> &testMoveValid, CCollisionOTDynamicInfo *dynamicColInfo, +00756 <a class="code" href="a03664.html">CVectorD</a> *contactNormal) +00757 { +00758 <span class="comment">// H_AUTO(PACS_MC_evalOneCollision);</span> +00759 <a class="code" href="a04365.html#a4">H_AUTO</a>(NLPACS_Eval_One_Primitive_Collision); +00760 +00761 <span class="comment">// Find its collisions</span> +00762 <span class="keywordtype">bool</span> found=<span class="keyword">false</span>; +00763 +00764 <span class="comment">// Get the primitive world image</span> +00765 CPrimitiveWorldImage *wI; +00766 <span class="keywordflow">if</span> (primitive->isNonCollisionable()) +00767 wI=primitive->getWorldImage (0); +00768 <span class="keywordflow">else</span> +00769 wI=primitive->getWorldImage (primitiveWorldImage); +00770 +00771 <span class="comment">// Begin time must be the same as beginTime</span> +00772 <span class="comment">//nlassert (wI->getInitTime()==beginTime);</span> +00773 <span class="keywordflow">if</span> (wI->getInitTime() != beginTime) +00774 { +00775 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: evalOnePrimitiveCollision() failure, wI->getInitTime() [%f] != beginTime [%f]"</span>, wI->getInitTime(), beginTime); +00776 <span class="keywordflow">return</span> <span class="keyword">false</span>; +00777 } +00778 +00779 <span class="comment">// Element table</span> +00780 CMoveElement tableNotInserted[4]; +00781 CMoveElement *table[4]; +00782 +00783 <span class="comment">// Single test ?</span> +00784 <span class="keywordtype">bool</span> singleTest=testMove; +00785 +00786 <span class="comment">// Is in world image</span> +00787 <span class="keywordflow">if</span> ((worldImage==primitiveWorldImage) && wI->isInWorldImageFlag()) +00788 { +00789 <span class="comment">// Get move element table from the primitive</span> +00790 table[0]=wI->getMoveElement (0); +00791 table[1]=wI->getMoveElement (1); +00792 table[2]=wI->getMoveElement (2); +00793 table[3]=wI->getMoveElement (3); +00794 } +00795 <span class="keywordflow">else</span> +00796 { +00797 <span class="comment">// Set table pointers</span> +00798 table[0]=tableNotInserted+0; +00799 table[1]=tableNotInserted+1; +00800 table[2]=tableNotInserted+2; +00801 table[3]=tableNotInserted+3; +00802 +00803 <span class="comment">// Get cells</span> +00804 getCells (primitive, worldImage, primitiveWorldImage, table); +00805 +00806 <span class="comment">// Force the test</span> +00807 singleTest=<span class="keyword">true</span>; +00808 } +00809 +00810 <span class="comment">// For each move element</span> +00811 <span class="keywordflow">for</span> (<a class="code" href="a04558.html#a15">uint</a> i=0; i<4; i++) +00812 { +00813 <span class="comment">// Get the element</span> +00814 CMoveElement *elm=table[i]; +00815 +00816 <span class="comment">// Element valid ?</span> +00817 <span class="keywordflow">if</span> (elm) +00818 { +00819 <span class="comment">// Check</span> +00820 <a class="code" href="a04199.html#a6">nlassert</a> (elm->Primitive==primitive); +00821 <span class="comment">// Primitive to the left</span> +00822 +00823 <span class="comment">// Lookup in X sorted list on the left</span> +00824 CMoveElement *other=elm->PreviousX; +00825 <a class="code" href="a04199.html#a6">nlassert</a> (other!=elm); +00826 +00827 <span class="keywordflow">while</span> (other && (wI->getBBXMin() - other->Primitive->getWorldImage(worldImage)->getBBXMin() < _PrimitiveMaxSize) ) +00828 { +00829 <span class="comment">// Other primitive</span> +00830 CMovePrimitive *otherPrimitive=other->Primitive; +00831 CPrimitiveWorldImage *otherWI=otherPrimitive->getWorldImage (worldImage); +00832 <a class="code" href="a04199.html#a6">nlassert</a> (otherPrimitive!=primitive); +00833 +00834 <span class="comment">// Continue the check if the other primitive is not int the modified list or if its pointer is higher than primitive</span> +00835 <span class="keywordflow">if</span> ( singleTest || ( (!otherWI->isInModifiedListFlag ()) || (primitive<otherPrimitive) ) ) +00836 { +00837 <span class="comment">// Look if valid in X</span> +00838 <span class="keywordflow">if</span> (wI->getBBXMin() < otherWI->getBBXMax()) +00839 { +00840 <span class="comment">// Look if valid in Y</span> +00841 <span class="keywordflow">if</span> ( (wI->getBBYMin() < otherWI->getBBYMax()) && (otherWI->getBBYMin() < wI->getBBYMax()) ) +00842 { +00843 <span class="comment">// If not already in collision with this primitive</span> +00844 <span class="keywordflow">if</span> (!primitive->isInCollision (otherPrimitive)) +00845 { +00846 <span class="keywordflow">if</span> (evalPrimAgainstPrimCollision (beginTime, primitive, otherPrimitive, wI, otherWI, testMove, +00847 primitiveWorldImage, worldImage, secondIsStatic, dynamicColInfo, contactNormal)) +00848 { +00849 <span class="keywordflow">if</span> (testMove) +00850 <span class="keywordflow">return</span> <span class="keyword">true</span>; +00851 found=<span class="keyword">true</span>; +00852 } +00853 } +00854 } +00855 } +00856 } +00857 +00858 <span class="comment">// Next primitive to the left</span> +00859 other = other->PreviousX; +00860 } +00861 +00862 <span class="comment">// Lookup in X sorted list on the right</span> +00863 other=elm->NextX; +00864 +00865 <span class="comment">// Primitive to the right</span> +00866 <span class="keywordflow">while</span> (other && (other->Primitive->getWorldImage(worldImage)->getBBXMin() < wI->getBBXMax()) ) +00867 { +00868 <span class="comment">// Other primitive</span> +00869 CMovePrimitive *otherPrimitive=other->Primitive; +00870 CPrimitiveWorldImage *otherWI=otherPrimitive->getWorldImage (worldImage); +00871 <a class="code" href="a04199.html#a6">nlassert</a> (otherPrimitive!=primitive); +00872 +00873 <span class="comment">// Continue the check if the other primitive is not in the modified list or if its pointer is higher than primitive</span> +00874 <span class="keywordflow">if</span> ( singleTest || ( (!otherWI->isInModifiedListFlag ()) || (primitive<otherPrimitive) ) ) +00875 { +00876 <span class="comment">// Look if valid in Y</span> +00877 <span class="keywordflow">if</span> ( (wI->getBBYMin() < otherWI->getBBYMax()) && (otherWI->getBBYMin() < wI->getBBYMax()) ) +00878 { +00879 <span class="comment">// If not already in collision with this primitive</span> +00880 <span class="keywordflow">if</span> (!primitive->isInCollision (otherPrimitive)) +00881 { +00882 <span class="keywordflow">if</span> (evalPrimAgainstPrimCollision (beginTime, primitive, otherPrimitive, wI, otherWI, testMove, +00883 primitiveWorldImage, worldImage, secondIsStatic, dynamicColInfo, contactNormal)) +00884 { +00885 <span class="keywordflow">if</span> (testMove) +00886 <span class="keywordflow">return</span> <span class="keyword">true</span>; +00887 found=<span class="keyword">true</span>; +00888 } +00889 } +00890 } +00891 } +00892 +00893 <span class="comment">// Next primitive to the left</span> +00894 other = other->NextX; +00895 } +00896 } +00897 } +00898 +00899 <span class="keywordflow">return</span> found; +00900 } +00901 +00902 <span class="comment">// ***************************************************************************</span> +00903 +00904 <span class="keywordtype">bool</span> CMoveContainer::evalPrimAgainstPrimCollision (<span class="keywordtype">double</span> beginTime, CMovePrimitive *primitive, CMovePrimitive *otherPrimitive, +00905 CPrimitiveWorldImage *wI, CPrimitiveWorldImage *otherWI, <span class="keywordtype">bool</span> testMove, +00906 <a class="code" href="a04558.html#a7">uint8</a> firstWorldImage, <a class="code" href="a04558.html#a7">uint8</a> secondWorldImage, <span class="keywordtype">bool</span> secondIsStatic, CCollisionOTDynamicInfo *dynamicColInfo, +00907 <a class="code" href="a03664.html">CVectorD</a> *contactNormal) +00908 { +00909 <span class="comment">// H_AUTO(PACS_MC_evalPrimAgainstPrimCollision);</span> +00910 +00911 <span class="comment">// Test the primitive</span> +00912 <span class="keywordtype">double</span> firstTime, lastTime; +00913 +00914 <span class="comment">// Collision</span> +00915 CCollisionDesc desc; +00916 <span class="keywordflow">if</span> (wI->evalCollision (*otherWI, desc, beginTime, _DeltaTime, _TestTime, _MaxTestIteration, +00917 firstTime, lastTime, *primitive, *otherPrimitive)) +00918 { +00919 <span class="comment">// Enter or exit</span> +00920 <span class="keywordtype">bool</span> enter = (beginTime<=firstTime) && (firstTime<_DeltaTime) && ((primitive->getTriggerType()&UMovePrimitive::EnterTrigger) +00921 || (otherPrimitive->getTriggerType()&UMovePrimitive::EnterTrigger)); +00922 <span class="keywordtype">bool</span> exit = (beginTime<=lastTime) && (lastTime<_DeltaTime) && ((primitive->getTriggerType()&UMovePrimitive::ExitTrigger) +00923 || (otherPrimitive->getTriggerType()&UMovePrimitive::ExitTrigger)); +00924 <span class="keywordtype">bool</span> overlap = (firstTime<=beginTime) && (lastTime>_DeltaTime) && ((primitive->getTriggerType()&UMovePrimitive::OverlapTrigger) +00925 || (otherPrimitive->getTriggerType()&UMovePrimitive::OverlapTrigger)); +00926 <span class="keywordtype">bool</span> contact = ( beginTime<((firstTime+lastTime)/2) ) && (firstTime<=_DeltaTime); +00927 <span class="keywordtype">bool</span> collision = contact && (primitive->isObstacle() && otherPrimitive->isObstacle ()); +00928 +00929 <span class="comment">// Return collision time</span> +00930 +00931 <span class="keywordflow">if</span> (testMove) +00932 <span class="keywordflow">return</span> contact; +00933 +00942 <span class="keywordflow">if</span> (primitive->isNonCollisionable () && (enter || exit || overlap)) +00943 { +00944 <span class="keywordflow">if</span> (primitive->isTriggered (*otherPrimitive, enter, exit)) +00945 { +00946 <span class="comment">// Add a trigger</span> +00947 <span class="keywordflow">if</span> (enter) +00948 newTrigger (primitive, otherPrimitive, desc, UTriggerInfo::In); +00949 <span class="keywordflow">if</span> (exit) +00950 newTrigger (primitive, otherPrimitive, desc, UTriggerInfo::Out); +00951 <span class="keywordflow">if</span> (overlap) +00952 newTrigger (primitive, otherPrimitive, desc, UTriggerInfo::Inside); +00953 } +00954 +00955 <span class="comment">// If the other primitive is not an obstacle, skip it because it will re-generate collisions.</span> +00956 <span class="keywordflow">if</span> (!collision) +00957 <span class="keywordflow">return</span> <span class="keyword">false</span>; +00958 } +00959 +00960 <span class="comment">// OK, collision</span> +00961 <span class="keywordflow">if</span> (contact || enter || exit || overlap) +00962 newCollision (primitive, otherPrimitive, desc, contact, enter, exit, overlap, firstWorldImage, secondWorldImage, secondIsStatic, +00963 dynamicColInfo); +00964 +00965 <span class="comment">// Collision</span> +00966 <span class="keywordflow">return</span> collision; +00967 } +00968 <span class="keywordflow">return</span> <span class="keyword">false</span>; +00969 } +00970 +00971 <span class="comment">// ***************************************************************************</span> +00972 +00973 <span class="keywordtype">void</span> CMoveContainer::evalAllCollisions (<span class="keywordtype">double</span> beginTime, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +00974 { +00975 <a class="code" href="a04365.html#a4">H_AUTO</a>(NLPACS_Eval_All_Collisions); +00976 +00977 <span class="comment">// First primitive</span> +00978 CMovePrimitive *primitive=_ChangedRoot[worldImage]; +00979 +00980 <span class="comment">// For each modified primitive</span> +00981 <span class="keywordflow">while</span> (primitive) +00982 { +00983 <span class="comment">// Get the primitive world image</span> +00984 <a class="code" href="a04558.html#a7">uint8</a> primitiveWorldImage; +00985 CPrimitiveWorldImage *wI; +00986 <span class="keywordflow">if</span> (primitive->isNonCollisionable ()) +00987 { +00988 wI=primitive->getWorldImage (0); +00989 primitiveWorldImage=worldImage; +00990 } +00991 <span class="keywordflow">else</span> +00992 { +00993 wI=primitive->getWorldImage (worldImage); +00994 primitiveWorldImage=worldImage; +00995 } +00996 +00997 <a class="code" href="a03664.html">CVectorD</a> d0=wI->getDeltaPosition(); +00998 +00999 <span class="comment">// Find a collision</span> +01000 <span class="keywordtype">bool</span> found=<span class="keyword">false</span>; +01001 <span class="keywordtype">bool</span> testMoveValid=<span class="keyword">false</span>; +01002 +01003 <span class="comment">// Eval collision on the terrain</span> +01004 found|=evalOneTerrainCollision (beginTime, primitive, primitiveWorldImage, <span class="keyword">false</span>, testMoveValid, NULL, NULL); +01005 +01006 <span class="comment">// If the primitive can collid other primitive..</span> +01007 <span class="keywordflow">if</span> (primitive->getCollisionMask()) +01008 { +01009 <span class="comment">// Eval collision in each static world image</span> +01010 std::set<uint8>::iterator ite=_StaticWorldImage.begin(); +01011 <span class="keywordflow">while</span> (ite!=_StaticWorldImage.end()) +01012 { +01013 <span class="comment">// Eval in this world image</span> +01014 found|=evalOnePrimitiveCollision (beginTime, primitive, *ite, primitiveWorldImage, <span class="keyword">false</span>, <span class="keyword">true</span>, testMoveValid, NULL, NULL); +01015 +01016 <span class="comment">// Next world image</span> +01017 ite++; +01018 } +01019 } +01020 +01021 <a class="code" href="a03664.html">CVectorD</a> d1=wI->getDeltaPosition(); +01022 +01023 <span class="comment">// If the primitive can collid other primitive..</span> +01024 <span class="keywordflow">if</span> (primitive->getCollisionMask()) +01025 { +01026 <span class="comment">// Eval collision in the world image if not already tested</span> +01027 <span class="keywordflow">if</span> (_StaticWorldImage.find (worldImage)==_StaticWorldImage.end()) +01028 found|=evalOnePrimitiveCollision (beginTime, primitive, worldImage, primitiveWorldImage, <span class="keyword">false</span>, <span class="keyword">false</span>, testMoveValid, NULL, NULL); +01029 } +01030 +01031 <a class="code" href="a03664.html">CVectorD</a> d2=wI->getDeltaPosition(); +01032 +01033 <span class="comment">// No collision ?</span> +01034 <span class="keywordflow">if</span> (!found) +01035 { +01036 <span class="comment">//nlassert ((d0==d1)&&(d0==d2));</span> +01037 <span class="comment">//nlassert (f1==f2);</span> +01038 +01039 <span class="keywordflow">if</span> (_Retriever&&testMoveValid) +01040 { +01041 <span class="comment">// Do move</span> +01042 wI->doMove (*_Retriever, _SurfaceTemp, _DeltaTime, _DeltaTime, primitive->getDontSnapToGround()); +01043 } +01044 <span class="keywordflow">else</span> +01045 { +01046 <span class="comment">// Do move</span> +01047 wI->doMove (_DeltaTime); +01048 } +01049 } +01050 +01051 <span class="comment">// Next primitive</span> +01052 primitive=wI->getNextModified (); +01053 } +01054 } +01055 +01056 <span class="comment">// ***************************************************************************</span> +01057 +01058 <span class="keywordtype">void</span> CMoveContainer::newCollision (CMovePrimitive* first, CMovePrimitive* second, <span class="keyword">const</span> CCollisionDesc& desc, <span class="keywordtype">bool</span> collision, <span class="keywordtype">bool</span> enter, <span class="keywordtype">bool</span> exit, <span class="keywordtype">bool</span> inside, +01059 <a class="code" href="a04558.html#a15">uint</a> firstWorldImage, <a class="code" href="a04558.html#a15">uint</a> secondWorldImage, <span class="keywordtype">bool</span> secondIsStatic, CCollisionOTDynamicInfo *dynamicColInfo) +01060 { +01061 <span class="comment">// H_AUTO(PACS_MC_newCollision_short);</span> +01062 +01063 <a class="code" href="a04199.html#a6">nlassert</a> ((dynamicColInfo && first->isNonCollisionable ()) || (!dynamicColInfo && first->isCollisionable ())); +01064 +01065 <span class="keywordflow">if</span> (dynamicColInfo) +01066 { +01067 dynamicColInfo->init (first, second, desc, collision, enter, exit, inside, firstWorldImage, secondWorldImage, secondIsStatic); +01068 } +01069 <span class="keywordflow">else</span> +01070 { +01071 <span class="comment">// Get an ordered time index. Always round to the future.</span> +01072 <span class="keywordtype">int</span> <a class="code" href="a04223.html#a566">index</a>=(<span class="keywordtype">int</span>)(ceil (desc.ContactTime*(<span class="keywordtype">double</span>)_OtSize/_DeltaTime) ); +01073 +01074 <span class="comment">// Clamp left.</span> +01075 <span class="keywordflow">if</span> (<a class="code" href="a04223.html#a566">index</a><0) +01076 <a class="code" href="a04223.html#a566">index</a>=0; +01077 +01078 <span class="comment">// If in time</span> +01079 <span class="keywordflow">if</span> (<a class="code" href="a04223.html#a566">index</a><(<span class="keywordtype">int</span>)_OtSize) +01080 { +01081 <span class="comment">// Build info</span> +01082 CCollisionOTDynamicInfo *info = allocateOTDynamicInfo (); +01083 info->init (first, second, desc, collision, enter, exit, inside, firstWorldImage, secondWorldImage, secondIsStatic); +01084 +01085 <span class="comment">// Add in the primitive list</span> +01086 first->addCollisionOTInfo (info); +01087 second->addCollisionOTInfo (info); +01088 +01089 <span class="comment">// Insert in the time ordered table</span> +01090 <span class="comment">//nlassert (index<(int)_TimeOT.size());</span> +01091 <span class="keywordflow">if</span> (<a class="code" href="a04223.html#a566">index</a> >= (<span class="keywordtype">int</span>)_TimeOT.size()) +01092 { +01093 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: newCollision() failure, index [%d] >= (int)_TimeOT.size() [%d], clamped to max"</span>, index, (<span class="keywordtype">int</span>)_TimeOT.size()); +01094 <a class="code" href="a04223.html#a566">index</a> = _TimeOT.size()-1; +01095 } +01096 _TimeOT[<a class="code" href="a04223.html#a566">index</a>].link (info); +01097 +01098 <span class="comment">// Check it is after the last hard collision</span> +01099 <a class="code" href="a04199.html#a6">nlassert</a> (_PreviousCollisionNode<=&_TimeOT[index]); +01100 } +01101 } +01102 } +01103 +01104 <span class="comment">// ***************************************************************************</span> +01105 +01106 <span class="keywordtype">void</span> CMoveContainer::newCollision (CMovePrimitive* first, <span class="keyword">const</span> CCollisionSurfaceDesc& desc, <a class="code" href="a04558.html#a7">uint8</a> worldImage, <span class="keywordtype">double</span> beginTime, CCollisionOTStaticInfo *staticColInfo) +01107 { +01108 <span class="comment">// H_AUTO(PACS_MC_newCollision_long);</span> +01109 +01110 <span class="comment">// Check</span> +01111 <a class="code" href="a04199.html#a6">nlassert</a> (_Retriever); +01112 <a class="code" href="a04199.html#a6">nlassert</a> ((staticColInfo && first->isNonCollisionable ()) || (!staticColInfo && first->isCollisionable ())); +01113 +01114 <span class="comment">// Get the world image</span> +01115 CPrimitiveWorldImage *wI; +01116 <span class="keywordflow">if</span> (first->isNonCollisionable()) +01117 wI=first->getWorldImage (0); +01118 <span class="keywordflow">else</span> +01119 wI=first->getWorldImage (worldImage); +01120 +01121 <span class="comment">// Time</span> +01122 <span class="keywordtype">double</span> time=desc.ContactTime; +01123 <span class="comment">/*</span> +01124 <span class="comment"> if (time == _DeltaTime)</span> +01125 <span class="comment"> time -= _DeltaTime*FLT_EPSILON;</span> +01126 <span class="comment">*/</span> +01127 +01128 <span class="comment">// Check time interval</span> +01129 +01130 <span class="comment">//nlassertex (beginTime<=time, ("beginTime=%f, time=%f", beginTime, time));</span> +01131 <span class="comment">//nlassertex (time<_DeltaTime, ("time=%f, _DeltaTime=%f", time, _DeltaTime));</span> +01132 +01133 <span class="keywordflow">if</span> (beginTime > time) +01134 { +01135 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: beginTime=%f > time=%f"</span>, beginTime, time); +01136 } +01137 +01138 <span class="keywordflow">if</span> (time >= _DeltaTime) +01139 { +01140 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: time=%f >= _DeltaTime=%f"</span>, time, _DeltaTime); +01141 } +01142 +01143 +01144 <span class="comment">// Time of the collision.</span> +01145 time-=<a class="code" href="a04631.html#a0">NELPACS_DIST_BACK</a>/wI->getSpeed().norm(); +01146 time=std::max(time, beginTime); +01147 <span class="keywordtype">double</span> ratio=(time-beginTime)/(_DeltaTime-beginTime); +01148 +01149 <span class="comment">/*</span> +01150 <span class="comment"> nlassert (ratio>=0);</span> +01151 <span class="comment"> nlassert (ratio<=1);</span> +01152 <span class="comment">*/</span> +01153 +01154 <span class="keywordflow">if</span> (ratio < 0.0) +01155 { +01156 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: ratio=%f < 0.0"</span>, ratio); +01157 ratio = 0.0; +01158 } +01159 +01160 <span class="keywordflow">if</span> (ratio > 1.0) +01161 { +01162 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: ratio=%f > 1.0"</span>, ratio); +01163 ratio = 1.0; +01164 } +01165 +01166 <span class="keywordflow">if</span> (staticColInfo) +01167 { +01168 <span class="comment">// Make a new globalposition</span> +01169 UGlobalPosition endPosition=_Retriever->doMove (wI->getGlobalPosition(), wI->getDeltaPosition(), +01170 (<span class="keywordtype">float</span>)ratio, _SurfaceTemp, <span class="keyword">false</span>); +01171 +01172 <span class="comment">// Init the info descriptor</span> +01173 staticColInfo->init (first, desc, endPosition, ratio, worldImage); +01174 } +01175 <span class="keywordflow">else</span> +01176 { +01177 <span class="comment">// Get an ordered time index. Always round to the future.</span> +01178 <span class="keywordtype">int</span> <a class="code" href="a04223.html#a566">index</a>=(<span class="keywordtype">int</span>)(ceil (time*(<span class="keywordtype">double</span>)_OtSize/_DeltaTime) ); +01179 +01180 <span class="comment">// Clamp left.</span> +01181 <span class="keywordflow">if</span> (<a class="code" href="a04223.html#a566">index</a><0) +01182 <a class="code" href="a04223.html#a566">index</a>=0; +01183 +01184 <span class="comment">// If in time</span> +01185 <span class="keywordflow">if</span> (<a class="code" href="a04223.html#a566">index</a><(<span class="keywordtype">int</span>)_OtSize) +01186 { +01187 <span class="comment">// Build info</span> +01188 CCollisionOTStaticInfo *info = allocateOTStaticInfo (); +01189 +01190 <span class="comment">// Make a new globalposition</span> +01191 UGlobalPosition endPosition=_Retriever->doMove (wI->getGlobalPosition(), wI->getDeltaPosition(), +01192 (<span class="keywordtype">float</span>)ratio, _SurfaceTemp, <span class="keyword">false</span>); +01193 +01194 <span class="comment">// Init the info descriptor</span> +01195 info->init (first, desc, endPosition, ratio, worldImage); +01196 +01197 <span class="comment">// Add in the primitive list</span> +01198 first->addCollisionOTInfo (info); +01199 +01200 <span class="comment">// Insert in the time ordered table</span> +01201 <span class="comment">//nlassert (index<(int)_TimeOT.size());</span> +01202 <span class="keywordflow">if</span> (<a class="code" href="a04223.html#a566">index</a> >= (<span class="keywordtype">int</span>)_TimeOT.size()) +01203 { +01204 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: newCollision() failure, index [%d] >= (int)_TimeOT.size() [%d], clamped to max"</span>, index, (<span class="keywordtype">int</span>)_TimeOT.size()); +01205 <a class="code" href="a04223.html#a566">index</a> = _TimeOT.size()-1; +01206 } +01207 _TimeOT[<a class="code" href="a04223.html#a566">index</a>].link (info); +01208 +01209 <span class="comment">// Check it is after the last hard collision</span> +01210 <a class="code" href="a04199.html#a6">nlassert</a> (_PreviousCollisionNode<=&_TimeOT[index]); +01211 } +01212 } +01213 } +01214 +01215 <span class="comment">// ***************************************************************************</span> +01216 +01217 <span class="keywordtype">void</span> CMoveContainer::newTrigger (CMovePrimitive* first, CMovePrimitive* second, <span class="keyword">const</span> CCollisionDesc& desc, <a class="code" href="a04558.html#a15">uint</a> triggerType) +01218 { +01219 <span class="comment">// Element index</span> +01220 <a class="code" href="a04558.html#a15">uint</a> <a class="code" href="a04223.html#a566">index</a>=_Triggers.size(); +01221 +01222 <span class="comment">// Add one element</span> +01223 _Triggers.resize (index+1); +01224 +01225 <span class="comment">// Fill info</span> +01226 _Triggers[<a class="code" href="a04223.html#a566">index</a>].Object0=first->UserData; +01227 _Triggers[<a class="code" href="a04223.html#a566">index</a>].Object1=second->UserData; +01228 _Triggers[<a class="code" href="a04223.html#a566">index</a>].CollisionDesc=desc; +01229 _Triggers[<a class="code" href="a04223.html#a566">index</a>].CollisionType = triggerType; +01230 } +01231 +01232 <span class="comment">// ***************************************************************************</span> +01233 +01234 <span class="keywordtype">void</span> CMoveContainer::checkOT () +01235 { +01236 <span class="comment">// Check</span> +01237 <a class="code" href="a04199.html#a6">nlassert</a> (_OtSize==_TimeOT.size()); +01238 +01239 <span class="comment">// Check linked list</span> +01240 <span class="keywordflow">for</span> (<a class="code" href="a04558.html#a15">uint</a> i=0; i<_OtSize-1; i++) +01241 { +01242 <span class="comment">// Check link</span> +01243 <a class="code" href="a04199.html#a6">nlassert</a> ( _TimeOT[i].getNext() == (&(_TimeOT[i+1])) ); +01244 <a class="code" href="a04199.html#a6">nlassert</a> ( _TimeOT[i+1].getPrevious() == (&(_TimeOT[i])) ); +01245 } +01246 +01247 <span class="comment">// Check first and last</span> +01248 <a class="code" href="a04199.html#a6">nlassert</a> ( _TimeOT[0].getPrevious() == NULL ); +01249 <a class="code" href="a04199.html#a6">nlassert</a> ( _TimeOT[_OtSize-1].getNext() == NULL ); +01250 } +01251 +01252 <span class="comment">// ***************************************************************************</span> +01253 +01254 <span class="keywordtype">void</span> CMoveContainer::clearOT () +01255 { +01256 <span class="comment">// Check</span> +01257 <a class="code" href="a04199.html#a6">nlassert</a> (_OtSize==_TimeOT.size()); +01258 +01259 <span class="comment">// clear the list</span> +01260 <a class="code" href="a04558.html#a15">uint</a> i; +01261 <span class="keywordflow">for</span> (i=0; i<_OtSize; i++) +01262 _TimeOT[i].clear (); +01263 +01264 <span class="comment">// Relink the list</span> +01265 <span class="keywordflow">for</span> (i=0; i<_OtSize-1; i++) +01266 <span class="comment">// Link the two cells</span> +01267 _TimeOT[i].link (&(_TimeOT[i+1])); +01268 } +01269 +01270 <span class="comment">// ***************************************************************************</span> +01271 +01272 <span class="keywordtype">void</span> CMoveContainer::removeModifiedFromOT (<a class="code" href="a04558.html#a7">uint8</a> worldImage) +01273 { +01274 <span class="comment">// For each changed primitives</span> +01275 CMovePrimitive *changed=_ChangedRoot[worldImage]; +01276 <span class="keywordflow">while</span> (changed) +01277 { +01278 <span class="comment">// Remove from ot list</span> +01279 changed->removeCollisionOTInfo (); +01280 +01281 <span class="comment">// Get the primitive world image</span> +01282 CPrimitiveWorldImage *wI; +01283 <span class="keywordflow">if</span> (changed->isNonCollisionable()) +01284 wI=changed->getWorldImage (0); +01285 <span class="keywordflow">else</span> +01286 wI=changed->getWorldImage (worldImage); +01287 +01288 <span class="comment">// Next primitive</span> +01289 changed=wI->getNextModified (); +01290 } +01291 } +01292 +01293 <span class="comment">// ***************************************************************************</span> +01294 +01295 CCollisionOTDynamicInfo *CMoveContainer::allocateOTDynamicInfo () +01296 { +01297 <span class="keywordflow">return</span> _AllocOTDynamicInfo.allocate (); +01298 } +01299 +01300 <span class="comment">// ***************************************************************************</span> +01301 +01302 CCollisionOTStaticInfo *CMoveContainer::allocateOTStaticInfo () +01303 { +01304 <span class="keywordflow">return</span> _AllocOTStaticInfo.allocate (); +01305 } +01306 +01307 <span class="comment">// ***************************************************************************</span> +01308 +01309 <span class="comment">// Free all ordered table info</span> +01310 <span class="keywordtype">void</span> CMoveContainer::freeAllOTInfo () +01311 { +01312 <a class="code" href="a04365.html#a4">H_AUTO</a> (NLPACS_Free_All_OT_Info); +01313 +01314 _AllocOTDynamicInfo.free (); +01315 _AllocOTStaticInfo.free (); +01316 } +01317 +01318 <span class="comment">// ***************************************************************************</span> +01319 +01320 CMovePrimitive *CMoveContainer::allocatePrimitive (<a class="code" href="a04558.html#a7">uint8</a> firstWorldImage, <a class="code" href="a04558.html#a7">uint8</a> numWorldImage) +01321 { +01322 <span class="comment">// Simply allocate</span> +01323 <span class="keywordflow">return</span> <span class="keyword">new</span> CMovePrimitive (<span class="keyword">this</span>, firstWorldImage, numWorldImage); +01324 } +01325 +01326 <span class="comment">// ***************************************************************************</span> +01327 +01328 <span class="keywordtype">void</span> CMoveContainer::freePrimitive (CMovePrimitive *primitive) +01329 { +01330 <span class="comment">// Simply deallocate</span> +01331 <span class="keyword">delete</span> primitive; +01332 } +01333 +01334 <span class="comment">// ***************************************************************************</span> +01335 +01336 CPrimitiveWorldImage **CMoveContainer::allocateWorldImagesPtrs (<a class="code" href="a04558.html#a15">uint</a> numPtrs) +01337 { +01338 <span class="keywordflow">return</span> <span class="keyword">new</span> CPrimitiveWorldImage*[numPtrs]; +01339 } +01340 +01341 <span class="comment">// ***************************************************************************</span> +01342 +01343 <span class="keywordtype">void</span> CMoveContainer::freeWorldImagesPtrs (CPrimitiveWorldImage **ptrs) +01344 { +01345 <span class="keyword">delete</span> [] ptrs; +01346 } +01347 +01348 <span class="comment">// ***************************************************************************</span> +01349 +01350 CPrimitiveWorldImage *CMoveContainer::allocateWorldImage () +01351 { +01352 <span class="keywordflow">return</span> <span class="keyword">new</span> CPrimitiveWorldImage; +01353 } +01354 +01355 <span class="comment">// ***************************************************************************</span> +01356 +01357 <span class="keywordtype">void</span> CMoveContainer::freeWorldImage (CPrimitiveWorldImage *worldImage) +01358 { +01359 <span class="keyword">delete</span> worldImage; +01360 } +01361 +01362 <span class="comment">// ***************************************************************************</span> +01363 +01364 CMoveElement *CMoveContainer::allocateMoveElement () +01365 { +01366 <span class="comment">// Simply allocate</span> +01367 <span class="keywordflow">return</span> <span class="keyword">new</span> CMoveElement; +01368 } +01369 +01370 <span class="comment">// ***************************************************************************</span> +01371 +01372 <span class="keywordtype">void</span> CMoveContainer::freeMoveElement (CMoveElement *element) +01373 { +01374 <span class="comment">// Simply deallocate</span> +01375 <span class="keyword">delete</span> element; +01376 } +01377 +01378 <span class="comment">// ***************************************************************************</span> +01379 +01380 <span class="keywordtype">void</span> UMoveContainer::deleteMoveContainer (UMoveContainer *container) +01381 { +01382 <span class="keyword">delete</span> (CMoveContainer*)container; +01383 } +01384 +01385 <span class="comment">// ***************************************************************************</span> +01386 +01387 UMovePrimitive *CMoveContainer::addCollisionablePrimitive (<a class="code" href="a04558.html#a7">uint8</a> firstWorldImage, <a class="code" href="a04558.html#a7">uint8</a> numWorldImage, <span class="keyword">const</span> UMovePrimitive *copyFrom) +01388 { +01389 NL_ALLOC_CONTEXT( Pacs ) +01390 +01391 <span class="comment">// Allocate primitive</span> +01392 CMovePrimitive *primitive=allocatePrimitive (firstWorldImage, numWorldImage); +01393 +01394 <span class="comment">// Add into the set</span> +01395 _PrimitiveSet.insert (primitive); +01396 +01397 <span class="comment">// if copy from primitive is not null, copy attributes</span> +01398 <span class="keywordflow">if</span> (copyFrom != NULL) +01399 { +01400 primitive->setPrimitiveType(copyFrom->getPrimitiveType()); +01401 primitive->setReactionType(copyFrom->getReactionType()); +01402 primitive->setTriggerType(copyFrom->getTriggerType()); +01403 primitive->setCollisionMask(copyFrom->getCollisionMask()); +01404 primitive->setOcclusionMask(copyFrom->getOcclusionMask()); +01405 primitive->setObstacle(copyFrom->getObstacle()); +01406 primitive->setAbsorbtion(copyFrom->getAbsorbtion()); +01407 primitive->setHeight(copyFrom->getHeight()); +01408 <span class="keywordflow">if</span> (primitive->getPrimitiveType() == UMovePrimitive::_2DOrientedBox) +01409 { +01410 <span class="keywordtype">float</span> <a class="code" href="a04223.html#a632">width</a>=0.0f, <a class="code" href="a04223.html#a633">height</a>=0.0f; +01411 copyFrom->getSize(width, <a class="code" href="a04223.html#a633">height</a>); +01412 primitive->setSize(width, <a class="code" href="a04223.html#a633">height</a>); +01413 } +01414 <span class="keywordflow">else</span> +01415 { +01416 primitive->setRadius(copyFrom->getRadius()); +01417 } +01418 } +01419 +01420 <span class="comment">// Return it</span> +01421 <span class="keywordflow">return</span> primitive; +01422 } +01423 +01424 <span class="comment">// ***************************************************************************</span> +01425 +01426 UMovePrimitive *CMoveContainer::addNonCollisionablePrimitive (<span class="keyword">const</span> UMovePrimitive *copyFrom) +01427 { +01428 NL_ALLOC_CONTEXT( Pacs ) +01429 +01430 <span class="comment">// Allocate primitive</span> +01431 CMovePrimitive *primitive=allocatePrimitive (0, 1); +01432 +01433 <span class="comment">// Set as noncollisionable</span> +01434 primitive->setNonCollisionable (<span class="keyword">true</span>); +01435 +01436 <span class="comment">// Add into the set</span> +01437 _PrimitiveSet.insert (primitive); +01438 +01439 <span class="comment">// if copy from primitive is not null, copy attributes</span> +01440 <span class="keywordflow">if</span> (copyFrom != NULL) +01441 { +01442 primitive->setPrimitiveType(copyFrom->getPrimitiveType()); +01443 primitive->setReactionType(copyFrom->getReactionType()); +01444 primitive->setTriggerType(copyFrom->getTriggerType()); +01445 primitive->setCollisionMask(copyFrom->getCollisionMask()); +01446 primitive->setOcclusionMask(copyFrom->getOcclusionMask()); +01447 primitive->setObstacle(copyFrom->getObstacle()); +01448 primitive->setAbsorbtion(copyFrom->getAbsorbtion()); +01449 primitive->setHeight(copyFrom->getHeight()); +01450 <span class="keywordflow">if</span> (primitive->getPrimitiveType() == UMovePrimitive::_2DOrientedBox) +01451 { +01452 <span class="keywordtype">float</span> <a class="code" href="a04223.html#a632">width</a>=0.0f, <a class="code" href="a04223.html#a633">height</a>=0.0f; +01453 copyFrom->getSize(width, <a class="code" href="a04223.html#a633">height</a>); +01454 primitive->setSize(width, <a class="code" href="a04223.html#a633">height</a>); +01455 } +01456 <span class="keywordflow">else</span> +01457 { +01458 primitive->setRadius(copyFrom->getRadius()); +01459 } +01460 } +01461 +01462 <span class="comment">// Return it</span> +01463 <span class="keywordflow">return</span> primitive; +01464 } +01465 +01466 <span class="comment">// ***************************************************************************</span> +01467 +01468 <span class="keywordtype">void</span> CMoveContainer::removePrimitive (UMovePrimitive* primitive) +01469 { +01470 NL_ALLOC_CONTEXT( Pacs ) +01471 +01472 <span class="comment">// CMovePrimitive pointer</span> +01473 CMovePrimitive *prim=(CMovePrimitive*)primitive; +01474 +01475 <span class="comment">// Get the primitive world image</span> +01476 <span class="keywordflow">for</span> (<a class="code" href="a04558.html#a7">uint8</a> i=0; i<prim->getNumWorldImage (); i++) +01477 { +01478 <span class="comment">// World image</span> +01479 <a class="code" href="a04558.html#a7">uint8</a> worldImage=prim->getFirstWorldImage ()+i; +01480 +01481 <span class="comment">// Get primitive world image</span> +01482 CPrimitiveWorldImage *wI=prim->getWorldImage (worldImage); +01483 +01484 <span class="comment">// In modified list ?</span> +01485 <span class="keywordflow">if</span> (wI->isInModifiedListFlag ()) +01486 { +01487 <span class="comment">// Non collisionable primitive ?</span> +01488 <span class="keywordflow">if</span> (prim->isNonCollisionable()) +01489 { +01490 <span class="comment">// Remove from all world image</span> +01491 removeNCFromModifiedList (prim, worldImage); +01492 } +01493 <span class="keywordflow">else</span> +01494 { +01495 <span class="comment">// Remove from modified list</span> +01496 removeFromModifiedList (prim, worldImage); +01497 } +01498 } +01499 } +01500 +01501 <span class="comment">// Remove from the set</span> +01502 _PrimitiveSet.erase (prim); +01503 +01504 <span class="comment">// Erase it</span> +01505 freePrimitive (prim); +01506 } +01507 +01508 <span class="comment">// ***************************************************************************</span> +01509 +01510 <span class="keywordtype">void</span> CMoveContainer::removeNCFromModifiedList (CMovePrimitive* primitive, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +01511 { +01512 <span class="comment">// For each world image</span> +01513 <a class="code" href="a04558.html#a15">uint</a> i; +01514 <a class="code" href="a04558.html#a15">uint</a> worldImageCount = _ChangedRoot.size(); +01515 <span class="keywordflow">for</span> (i=0; i<worldImageCount; i++) +01516 { +01517 <span class="comment">// For each changed primitives</span> +01518 CMovePrimitive *changed=_ChangedRoot[i]; +01519 CPrimitiveWorldImage *previous=NULL; +01520 CPrimitiveWorldImage *wI=primitive->getWorldImage (worldImage); +01521 +01522 <span class="keywordflow">while</span> (changed) +01523 { +01524 <span class="comment">// Get the primitive world image</span> +01525 CPrimitiveWorldImage *changedWI=changed->getWorldImage (worldImage); +01526 +01527 <span class="comment">// Remove from ot list</span> +01528 <span class="keywordflow">if</span> (changed==primitive) +01529 { +01530 <span class="comment">// There is a previous primitive ?</span> +01531 <span class="keywordflow">if</span> (previous) +01532 previous->linkInModifiedList (wI->getNextModified ()); +01533 <span class="keywordflow">else</span> +01534 _ChangedRoot[i]=wI->getNextModified (); +01535 +01536 <span class="comment">// Unlink</span> +01537 wI->linkInModifiedList (NULL); +01538 wI->setInModifiedListFlag (<span class="keyword">false</span>); +01539 <span class="keywordflow">break</span>; +01540 } +01541 +01542 <span class="comment">// Next primitive</span> +01543 previous=changedWI; +01544 changed=changedWI->getNextModified (); +01545 } +01546 +01547 <span class="comment">// Breaked ?</span> +01548 <span class="keywordflow">if</span> (changed==primitive) +01549 <span class="keywordflow">break</span>; +01550 } +01551 } +01552 +01553 <span class="comment">// ***************************************************************************</span> +01554 +01555 <span class="keywordtype">void</span> CMoveContainer::removeFromModifiedList (CMovePrimitive* primitive, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +01556 { +01557 <span class="comment">// For each changed primitives</span> +01558 CMovePrimitive *changed=_ChangedRoot[worldImage]; +01559 CPrimitiveWorldImage *previous=NULL; +01560 CPrimitiveWorldImage *wI=primitive->getWorldImage (worldImage); +01561 +01562 <span class="keywordflow">while</span> (changed) +01563 { +01564 <span class="comment">// Get the primitive world image</span> +01565 CPrimitiveWorldImage *changedWI=changed->getWorldImage (worldImage); +01566 +01567 <span class="comment">// Remove from ot list</span> +01568 <span class="keywordflow">if</span> (changed==primitive) +01569 { +01570 <span class="comment">// There is a previous primitive ?</span> +01571 <span class="keywordflow">if</span> (previous) +01572 previous->linkInModifiedList (wI->getNextModified ()); +01573 <span class="keywordflow">else</span> +01574 _ChangedRoot[worldImage]=wI->getNextModified (); +01575 +01576 <span class="comment">// Unlink</span> +01577 wI->linkInModifiedList (NULL); +01578 wI->setInModifiedListFlag (<span class="keyword">false</span>); +01579 <span class="keywordflow">break</span>; +01580 } +01581 +01582 <span class="comment">// Next primitive</span> +01583 previous=changedWI; +01584 changed=changedWI->getNextModified (); +01585 } +01586 } +01587 +01588 <span class="comment">// ***************************************************************************</span> +01589 +01590 <span class="keywordtype">void</span> CMoveContainer::unlinkMoveElement (CMoveElement *element, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +01591 { +01592 <span class="comment">// Some checks</span> +01593 <a class="code" href="a04199.html#a6">nlassert</a> (element->X<_CellCountWidth); +01594 <a class="code" href="a04199.html#a6">nlassert</a> (element->Y<_CellCountHeight); +01595 +01596 <span class="comment">// Unlink it</span> +01597 CMoveCell &cell=_VectorCell[worldImage][element->X+element->Y*_CellCountWidth]; +01598 cell.unlinkX (element); +01599 <span class="comment">//cell.unlinkY (element);</span> +01600 } +01601 +01602 <span class="comment">// ***************************************************************************</span> +01603 +01604 <span class="keywordtype">void</span> CMoveContainer::reaction (<span class="keyword">const</span> CCollisionOTInfo& first) +01605 { +01606 <span class="comment">// H_AUTO(PACS_MC_reaction);</span> +01607 +01608 <span class="comment">// Static collision ?</span> +01609 <span class="keywordflow">if</span> (first.isCollisionAgainstStatic()) +01610 { +01611 <span class="comment">// Check mode</span> +01612 <a class="code" href="a04199.html#a6">nlassert</a> (_Retriever); +01613 +01614 <span class="comment">// Cast</span> +01615 <span class="keyword">const</span> CCollisionOTStaticInfo *staticInfo=safe_cast<const CCollisionOTStaticInfo*> (&first); +01616 +01617 <span class="comment">// Get the primitive world image</span> +01618 CMovePrimitive *movePrimitive=staticInfo->getPrimitive (); +01619 CPrimitiveWorldImage *wI; +01620 <span class="keywordflow">if</span> (movePrimitive->isNonCollisionable ()) +01621 wI=movePrimitive->getWorldImage (0); +01622 <span class="keywordflow">else</span> +01623 wI=movePrimitive->getWorldImage (staticInfo->getWorldImage()); +01624 +01625 <span class="comment">// Dynamic collision</span> +01626 wI->reaction ( staticInfo->getCollisionDesc (), staticInfo->getGlobalPosition (), +01627 *_Retriever, staticInfo->getDeltaTime(), _DeltaTime, *staticInfo->getPrimitive (), *<span class="keyword">this</span>, staticInfo->getWorldImage()); +01628 } +01629 <span class="keywordflow">else</span> +01630 { +01631 <span class="comment">// Cast</span> +01632 <span class="keyword">const</span> CCollisionOTDynamicInfo *dynInfo=safe_cast<const CCollisionOTDynamicInfo*> (&first); +01633 +01634 <span class="comment">// Get the primitives world image</span> +01635 CPrimitiveWorldImage *firstWI; +01636 <span class="keywordflow">if</span> (dynInfo->getFirstPrimitive ()->isNonCollisionable ()) +01637 firstWI=dynInfo->getFirstPrimitive ()->getWorldImage (0); +01638 <span class="keywordflow">else</span> +01639 firstWI=dynInfo->getFirstPrimitive ()->getWorldImage (dynInfo->getFirstWorldImage()); +01640 +01641 CPrimitiveWorldImage *secondWI; +01642 <span class="keywordflow">if</span> (dynInfo->getSecondPrimitive ()->isNonCollisionable ()) +01643 secondWI=dynInfo->getSecondPrimitive ()->getWorldImage (0); +01644 <span class="keywordflow">else</span> +01645 secondWI=dynInfo->getSecondPrimitive ()->getWorldImage (dynInfo->getSecondWorldImage()); +01646 +01647 <span class="comment">// Dynamic collision</span> +01648 firstWI->reaction ( *secondWI, dynInfo->getCollisionDesc (), _Retriever, _SurfaceTemp, dynInfo->isCollision(), +01649 *dynInfo->getFirstPrimitive (), *dynInfo->getSecondPrimitive (), <span class="keyword">this</span>, dynInfo->getFirstWorldImage(), +01650 dynInfo->getSecondWorldImage(), dynInfo->isSecondStatic()); +01651 +01660 <span class="keywordflow">if</span> (dynInfo->getFirstPrimitive ()->isCollisionable ()) +01661 { +01662 <span class="keywordflow">if</span> (dynInfo->getFirstPrimitive ()->isTriggered (*dynInfo->getSecondPrimitive (), dynInfo->isEnter(), dynInfo->isExit())) +01663 { +01664 <span class="keywordflow">if</span> (dynInfo->isEnter()) +01665 newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::In); +01666 <span class="keywordflow">if</span> (dynInfo->isExit()) +01667 newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::Out); +01668 <span class="keywordflow">if</span> (dynInfo->isInside()) +01669 newTrigger (dynInfo->getFirstPrimitive (), dynInfo->getSecondPrimitive (), dynInfo->getCollisionDesc (), UTriggerInfo::Inside); +01670 } +01671 } +01672 } +01673 } +01674 +01675 <span class="comment">// ***************************************************************************</span> +01676 +01677 <span class="keywordtype">void</span> CMoveContainer::setAsStatic (<a class="code" href="a04558.html#a7">uint8</a> worldImage) +01678 { +01679 NL_ALLOC_CONTEXT( Pacs ) +01680 +01681 <span class="comment">// Add this world image in the static set of world image</span> +01682 _StaticWorldImage.insert (worldImage); +01683 } +01684 +01685 <span class="comment">// ***************************************************************************</span> +01686 +01687 <span class="keywordtype">void</span> CMoveContainer::duplicateWorldImage (<a class="code" href="a04558.html#a7">uint8</a> source, <a class="code" href="a04558.html#a7">uint8</a> dest) +01688 { +01689 NL_ALLOC_CONTEXT( Pacs ) +01690 +01691 <span class="comment">// Cell count</span> +01692 <a class="code" href="a04558.html#a15">uint</a> cellCount=_CellCountWidth*_CellCountHeight; +01693 +01694 <span class="comment">// Clear dest modified list</span> +01695 clearModifiedList (dest); +01696 +01697 <span class="comment">// Clear destination cells</span> +01698 <a class="code" href="a04558.html#a15">uint</a> i; +01699 <span class="keywordflow">for</span> (i=0; i<cellCount; i++) +01700 { +01701 <span class="comment">// Get first X</span> +01702 CMoveElement *elm; +01703 <span class="keywordflow">while</span> ((elm=_VectorCell[dest][i].getFirstX ())) +01704 { +01705 <span class="comment">// Get primitive world image</span> +01706 CPrimitiveWorldImage *wI=elm->Primitive->getWorldImage (dest); +01707 +01708 <span class="comment">// Remove the primitive</span> +01709 <span class="keywordtype">int</span> i; +01710 <span class="keywordflow">for</span> (i=0; i<4; i++) +01711 { +01712 <span class="keywordflow">if</span> (wI->getMoveElement(i)) +01713 wI->removeMoveElement (i, *<span class="keyword">this</span>, dest); +01714 } +01715 } +01716 } +01717 +01718 <span class="comment">// Duplicate destination cells</span> +01719 <span class="keywordflow">for</span> (i=0; i<cellCount; i++) +01720 { +01721 <span class="comment">// Get first X</span> +01722 CMoveElement *elm=_VectorCell[source][i].getFirstX (); +01723 <span class="keywordflow">while</span> (elm) +01724 { +01725 <span class="comment">// Get primitive world image</span> +01726 CPrimitiveWorldImage *wISource=elm->Primitive->getWorldImage (source); +01727 CPrimitiveWorldImage *wIDest=elm->Primitive->getWorldImage (dest); +01728 +01729 <span class="comment">// First time the primitive is visited ?</span> +01730 <span class="keywordflow">if</span> (wIDest->getMoveElement (0)==NULL) +01731 { +01732 wIDest->copy (*wISource); +01733 } +01734 +01735 <span class="comment">// Add at the end of the list</span> +01736 wIDest->addMoveElementendOfList (_VectorCell[dest][i], elm->X, elm->Y, elm->Primitive, *<span class="keyword">this</span>); +01737 +01738 <span class="comment">// Added ?</span> +01739 <a class="code" href="a04199.html#a6">nlassert</a> (wIDest->getMoveElement (0)!=NULL); +01740 +01741 <span class="comment">// Next primitive</span> +01742 elm=elm->NextX; +01743 } +01744 } +01745 } +01746 +01747 <span class="comment">// ***************************************************************************</span> +01748 +01749 UMoveContainer *UMoveContainer::createMoveContainer (<span class="keywordtype">double</span> xmin, <span class="keywordtype">double</span> ymin, <span class="keywordtype">double</span> xmax, <span class="keywordtype">double</span> ymax, +01750 <a class="code" href="a04558.html#a15">uint</a> widthCellCount, <a class="code" href="a04558.html#a15">uint</a> heightCellCount, <span class="keywordtype">double</span> primitiveMaxSize, <a class="code" href="a04558.html#a7">uint8</a> numWorldImage, +01751 <a class="code" href="a04558.html#a15">uint</a> maxIteration, <a class="code" href="a04558.html#a15">uint</a> otSize) +01752 { +01753 NL_ALLOC_CONTEXT( Pacs ) +01754 +01755 <span class="comment">// Create a CMoveContainer</span> +01756 <span class="keywordflow">return</span> <span class="keyword">new</span> CMoveContainer (xmin, ymin, xmax, ymax, widthCellCount, heightCellCount, primitiveMaxSize, numWorldImage, maxIteration, otSize); +01757 } +01758 +01759 <span class="comment">// ***************************************************************************</span> +01760 +01761 UMoveContainer *UMoveContainer::createMoveContainer (UGlobalRetriever* retriever, <a class="code" href="a04558.html#a15">uint</a> widthCellCount, +01762 <a class="code" href="a04558.html#a15">uint</a> heightCellCount, <span class="keywordtype">double</span> primitiveMaxSize, <a class="code" href="a04558.html#a7">uint8</a> numWorldImage, <a class="code" href="a04558.html#a15">uint</a> maxIteration, <a class="code" href="a04558.html#a15">uint</a> otSize) +01763 { +01764 NL_ALLOC_CONTEXT( Pacs ) +01765 +01766 <span class="comment">// Cast</span> +01767 <a class="code" href="a04199.html#a6">nlassert</a> (dynamic_cast<CGlobalRetriever*>(retriever)); +01768 CGlobalRetriever* <a class="code" href="a04223.html#a628">r</a>=static_cast<CGlobalRetriever*>(retriever); +01769 +01770 <span class="comment">// Create a CMoveContainer</span> +01771 <span class="keywordflow">return</span> <span class="keyword">new</span> CMoveContainer (r, widthCellCount, heightCellCount, primitiveMaxSize, numWorldImage, maxIteration, otSize); +01772 } +01773 +01774 <span class="comment">// ***************************************************************************</span> +01775 +01776 <span class="keywordtype">void</span> UCollisionDesc::serial (<a class="code" href="a02270.html">NLMISC::IStream</a>& stream) +01777 { +01778 stream.<a class="code" href="a02270.html#NLMISC_1_1IStreama5">serial</a> (ContactPosition); +01779 stream.<a class="code" href="a02270.html#NLMISC_1_1IStreama5">serial</a> (ContactNormal0); +01780 stream.<a class="code" href="a02270.html#NLMISC_1_1IStreama5">serial</a> (ContactNormal1); +01781 stream.<a class="code" href="a02270.html#NLMISC_1_1IStreama5">serial</a> (ContactTime); +01782 }; +01783 +01784 <span class="comment">// ***************************************************************************</span> +01785 +01786 <span class="keywordtype">void</span> UTriggerInfo::serial (<a class="code" href="a02270.html">NLMISC::IStream</a>& stream) +01787 { +01788 stream.<a class="code" href="a02270.html#NLMISC_1_1IStreama5">serial</a> (Object0); +01789 stream.<a class="code" href="a02270.html#NLMISC_1_1IStreama5">serial</a> (Object1); +01790 stream.<a class="code" href="a02270.html#NLMISC_1_1IStreama5">serial</a> (CollisionDesc); +01791 } +01792 +01793 +01794 +01795 <span class="comment">// ***************************************************************************</span> +01796 <span class="keywordtype">void</span> CMoveContainer::addCollisionnablePrimitiveBlock(UPrimitiveBlock *pb,<a class="code" href="a04558.html#a7">uint8</a> firstWorldImage,<a class="code" href="a04558.html#a7">uint8</a> numWorldImage,std::vector<UMovePrimitive*> *primitives,<span class="keywordtype">float</span> orientation,<span class="keyword">const</span> <a class="code" href="a03128.html">NLMISC::CVector</a> &position, <span class="keywordtype">bool</span> dontSnapToGround <span class="comment">/* = false*/</span>, <span class="keyword">const</span> <a class="code" href="a03128.html">NLMISC::CVector</a> &scale <span class="comment">/* = NLMISC::CVector(1.0f, 1.0f, 1.0f)*/</span>) +01797 { +01798 NL_ALLOC_CONTEXT( Pacs ) +01799 +01800 CPrimitiveBlock *block = NLMISC::safe_cast<CPrimitiveBlock *>(pb); +01801 <span class="comment">// Reserve the pointer array</span> +01802 <span class="keywordflow">if</span> (primitives) +01803 primitives->reserve (block->Primitives.size()); +01804 +01805 <span class="comment">// For each primitive</span> +01806 <a class="code" href="a04558.html#a15">uint</a> prim; +01807 <span class="keywordflow">for</span> (prim=0; prim<block->Primitives.size(); prim++) +01808 { +01809 <span class="comment">// Create a collisionable primitive</span> +01810 UMovePrimitive *primitive = addCollisionablePrimitive (firstWorldImage, numWorldImage); +01811 +01812 <span class="comment">// Ref on the block descriptor</span> +01813 CPrimitiveDesc &desc = block->Primitives[prim]; +01814 +01815 <span class="comment">// Set its properties</span> +01816 primitive->setPrimitiveType (desc.Type); +01817 primitive->setReactionType (desc.Reaction); +01818 primitive->setTriggerType (desc.Trigger); +01819 primitive->setCollisionMask (desc.CollisionMask); +01820 primitive->setOcclusionMask (desc.OcclusionMask); +01821 primitive->setObstacle (desc.Obstacle); +01822 primitive->setAbsorbtion (desc.Attenuation); +01823 primitive->setDontSnapToGround(dontSnapToGround); +01824 primitive->UserData = desc.UserData; +01825 <span class="keywordflow">if</span> (desc.Type == UMovePrimitive::_2DOrientedBox) +01826 { +01827 <span class="comment">// ONLY ASSUME UNIFORM SCALE ON X/Y</span> +01828 primitive->setSize (desc.Length[0]*scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro0">x</a>, desc.Length[1]*scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro0">x</a>); +01829 } +01830 <span class="keywordflow">else</span> +01831 { +01832 <span class="comment">// ONLY ASSUME UNIFORM SCALE ON X/Y</span> +01833 <a class="code" href="a04199.html#a6">nlassert</a> (desc.Type == UMovePrimitive::_2DOrientedCylinder); +01834 primitive->setRadius (desc.Length[0]*scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro0">x</a>); +01835 } +01836 primitive->setHeight (desc.Height*scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro2">z</a>); +01837 +01838 <span class="comment">// Insert the primitives</span> +01839 +01840 <span class="comment">// For each world image</span> +01841 <a class="code" href="a04558.html#a15">uint</a> wI; +01842 <span class="keywordflow">for</span> (wI=firstWorldImage; wI<(<a class="code" href="a04558.html#a15">uint</a>)(firstWorldImage+numWorldImage); wI++) +01843 { +01844 <span class="comment">// Insert the primitive</span> +01845 primitive->insertInWorldImage (wI); +01846 +01847 <span class="comment">// Final position&</span> +01848 <span class="keywordtype">float</span> cosa = (<span class="keywordtype">float</span>) cos (orientation); +01849 <span class="keywordtype">float</span> sina = (<span class="keywordtype">float</span>) sin (orientation); +01850 CVector finalPos; +01851 finalPos.x = cosa * desc.Position.x * scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro0">x</a> - sina * desc.Position.y * scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro1">y</a> + position.<a class="code" href="a03128.html#NLMISC_1_1CVectoro0">x</a>; +01852 finalPos.y = sina * desc.Position.x * scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro0">x</a> + cosa * desc.Position.y * scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro1">y</a> + position.<a class="code" href="a03128.html#NLMISC_1_1CVectoro1">y</a>; +01853 finalPos.z = desc.Position.z *scale.<a class="code" href="a03128.html#NLMISC_1_1CVectoro2">z</a> + position.<a class="code" href="a03128.html#NLMISC_1_1CVectoro2">z</a>; +01854 +01855 <span class="comment">// Set the primtive orientation</span> +01856 <span class="keywordflow">if</span> (desc.Type == UMovePrimitive::_2DOrientedBox) +01857 primitive->setOrientation ((<span class="keywordtype">float</span>)fmod (desc.Orientation + orientation, 2*Pi), wI); +01858 +01859 <span class="comment">// Set the primitive global position</span> +01860 primitive->setGlobalPosition (finalPos, wI); +01861 } +01862 +01863 <span class="comment">// Feedback asked ?</span> +01864 <span class="keywordflow">if</span> (primitives) +01865 { +01866 <span class="comment">// Add the pointer</span> +01867 primitives->push_back (primitive); +01868 } +01869 } +01870 } +01871 +01872 +01873 <span class="comment">// ***************************************************************************</span> +01874 +01875 <span class="keywordtype">bool</span> CMoveContainer::loadCollisionablePrimitiveBlock (<span class="keyword">const</span> <span class="keywordtype">char</span> *filename, <a class="code" href="a04558.html#a7">uint8</a> firstWorldImage, <a class="code" href="a04558.html#a7">uint8</a> numWorldImage, std::vector<UMovePrimitive*> *primitives, <span class="keywordtype">float</span> orientation, <span class="keyword">const</span> <a class="code" href="a03128.html">NLMISC::CVector</a> &position, <span class="keywordtype">bool</span> dontSnapToGround <span class="comment">/*= false*/</span>) +01876 { +01877 NL_ALLOC_CONTEXT( Pacs ) +01878 +01879 <span class="comment">// Check world image</span> +01880 <span class="keywordflow">if</span> ( (<a class="code" href="a04558.html#a15">uint</a>)(firstWorldImage+numWorldImage) > _ChangedRoot.size() ) +01881 { +01882 <a class="code" href="a04199.html#a2">nlwarning</a> (<span class="stringliteral">"Invalid world image number."</span>); +01883 <span class="keywordflow">return</span> <span class="keyword">false</span>; +01884 } +01885 +01886 <span class="comment">// Try to load the file</span> +01887 <a class="code" href="a02653.html">CIFile</a> <a class="code" href="a04115.html#a95">file</a>; +01888 <span class="keywordflow">if</span> (<a class="code" href="a04115.html#a95">file</a>.open (filename)) +01889 { +01890 <span class="comment">// Create the XML stream</span> +01891 CIXml input; +01892 +01893 <span class="comment">// Init</span> +01894 <span class="keywordflow">if</span> (input.init (file)) +01895 { +01896 <span class="comment">// The primitive block</span> +01897 CPrimitiveBlock block; +01898 +01899 <span class="comment">// Serial it</span> +01900 <a class="code" href="a04115.html#a95">file</a>.serial (block); +01901 +01902 <span class="comment">// add primitives</span> +01903 addCollisionnablePrimitiveBlock(&block, firstWorldImage, numWorldImage, primitives, orientation, position, dontSnapToGround); +01904 +01905 <span class="keywordflow">return</span> <span class="keyword">true</span>; +01906 } +01907 <span class="keywordflow">else</span> +01908 { +01909 <span class="comment">// Warning</span> +01910 <a class="code" href="a04199.html#a2">nlwarning</a> (<span class="stringliteral">"Can't init XML stream with file %s."</span>, filename); +01911 +01912 <span class="keywordflow">return</span> <span class="keyword">false</span>; +01913 } +01914 } +01915 <span class="keywordflow">else</span> +01916 { +01917 <span class="comment">// Warning</span> +01918 <a class="code" href="a04199.html#a2">nlwarning</a> (<span class="stringliteral">"Can't load primitive block %s."</span>, filename); +01919 +01920 <span class="keywordflow">return</span> <span class="keyword">false</span>; +01921 } +01922 } +01923 +01924 +01925 <span class="comment">// ***************************************************************************</span> +01926 <span class="keywordtype">void</span> CMoveContainer::getPrimitives(std::vector<const UMovePrimitive *> &dest)<span class="keyword"> const</span> +01927 <span class="keyword"></span>{ +01928 NL_ALLOC_CONTEXT( Pacs ) +01929 +01930 dest.resize(_PrimitiveSet.size()); +01931 std::copy(_PrimitiveSet.begin(), _PrimitiveSet.end(), dest.begin()); +01932 } +01933 +01934 +01935 <span class="comment">// ***************************************************************************</span> +01936 <span class="keywordtype">void</span> UMoveContainer::getPACSCoordsFromMatrix(<a class="code" href="a03128.html">NLMISC::CVector</a> &pos,<span class="keywordtype">float</span> &angle,<span class="keyword">const</span> <a class="code" href="a02851.html">NLMISC::CMatrix</a> &mat) +01937 { +01938 pos = mat.<a class="code" href="a02851.html#NLMISC_1_1CMatrixz1963_6">getPos</a>(); +01939 CVector orient = mat.<a class="code" href="a02851.html#NLMISC_1_1CMatrixz1968_1">mulVector</a>(NLMISC::CVector::I); +01940 orient.z = 0.f; +01941 orient.normalize(); +01942 angle = orient.y >= 0.f ? ::acosf(orient.x) +01943 : 2.f * (<span class="keywordtype">float</span>) NLMISC::Pi - ::acosf(orient.x); +01944 +01945 } +01946 +01947 <span class="comment">// ***************************************************************************</span> +01948 <span class="keywordtype">bool</span> CMoveContainer::evalNCPrimitiveCollision (<span class="keywordtype">double</span> deltaTime, UMovePrimitive *primitive, <a class="code" href="a04558.html#a7">uint8</a> worldImage) +01949 { +01950 NL_ALLOC_CONTEXT( Pacs ) +01951 +01952 <span class="comment">// New test time</span> +01953 _TestTime++; +01954 +01955 <span class="comment">// Clear triggers</span> +01956 _Triggers.clear (); +01957 +01958 <span class="comment">// Only non-collisionable primitives</span> +01959 <span class="keywordflow">if</span> (!primitive->isCollisionable()) +01960 { +01961 <span class="comment">// Delta time</span> +01962 _DeltaTime=deltaTime; +01963 +01964 <span class="comment">// Begin of the time slice to compute</span> +01965 <span class="keywordtype">double</span> beginTime = 0; +01966 <span class="keywordtype">double</span> collisionTime = deltaTime; +01967 +01968 <span class="comment">// Get the world image</span> +01969 CPrimitiveWorldImage *wI = ((CMovePrimitive*)primitive)->getWorldImage (0); +01970 +01971 CCollisionOTInfo *firstCollision = NULL; +01972 <span class="keywordflow">do</span> +01973 { +01974 <span class="comment">//nlassert (beginTime < 1.0);</span> +01975 <span class="keywordflow">if</span> (beginTime >= 1.0) +01976 { +01977 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: evalNCPrimitiveCollision() failure, beginTime [%f] >= 1.0"</span>, beginTime); +01978 <span class="keywordflow">return</span> <span class="keyword">false</span>; +01979 } +01980 +01981 <span class="comment">// Update the primitive</span> +01982 wI->update (beginTime, deltaTime, *(CMovePrimitive*)primitive); +01983 +01984 <a class="code" href="a03664.html">CVectorD</a> d0=wI->getDeltaPosition(); +01985 +01986 <span class="comment">// Eval collision again the terrain</span> +01987 <span class="keywordtype">bool</span> testMoveValid = <span class="keyword">false</span>; +01988 CCollisionOTStaticInfo staticColInfo; +01989 CCollisionOTDynamicInfo dynamicColInfoWI0; +01990 CCollisionOTDynamicInfo dynamicColInfoWI; +01991 +01992 firstCollision = NULL; +01993 +01994 <span class="comment">// If collision found, note it is on the landscape</span> +01995 <span class="keywordflow">if</span> (evalOneTerrainCollision (beginTime, (CMovePrimitive*)primitive, worldImage, <span class="keyword">false</span>, testMoveValid, &staticColInfo, NULL)) +01996 { +01997 firstCollision = &staticColInfo; +01998 } +01999 +02000 <span class="comment">// Eval collision again the static primitives</span> +02001 std::set<uint8>::iterator ite=_StaticWorldImage.begin(); +02002 <span class="keywordflow">while</span> (ite!=_StaticWorldImage.end()) +02003 { +02004 <span class="comment">// Eval in this world image</span> +02005 <span class="keywordflow">if</span> (evalOnePrimitiveCollision (beginTime, (CMovePrimitive*)primitive, *ite, worldImage, <span class="keyword">false</span>, <span class="keyword">true</span>, testMoveValid, &dynamicColInfoWI0, NULL)) +02006 { +02007 <span class="comment">// First collision..</span> +02008 <span class="keywordflow">if</span> (!firstCollision || (firstCollision->getCollisionTime () > dynamicColInfoWI0.getCollisionTime ())) +02009 { +02010 firstCollision = &dynamicColInfoWI0; +02011 } +02012 } +02013 +02014 <span class="comment">// Next world image</span> +02015 ite++; +02016 } +02017 +02018 <span class="comment">// Checks</span> +02019 <a class="code" href="a03664.html">CVectorD</a> d1=wI->getDeltaPosition(); +02020 +02021 <span class="comment">// Eval collision again the world image</span> +02022 <span class="keywordflow">if</span> (_StaticWorldImage.find (worldImage)==_StaticWorldImage.end()) +02023 { +02024 <span class="keywordflow">if</span> (evalOnePrimitiveCollision (beginTime, (CMovePrimitive*)primitive, worldImage, worldImage, <span class="keyword">false</span>, <span class="keyword">false</span>, testMoveValid, &dynamicColInfoWI, NULL)) +02025 { +02026 <span class="comment">// First collision..</span> +02027 <span class="keywordflow">if</span> (!firstCollision || (firstCollision->getCollisionTime () > dynamicColInfoWI.getCollisionTime ())) +02028 { +02029 firstCollision = &dynamicColInfoWI; +02030 } +02031 } +02032 } +02033 +02034 <span class="comment">// Checks</span> +02035 <a class="code" href="a03664.html">CVectorD</a> d2=wI->getDeltaPosition(); +02036 <a class="code" href="a04199.html#a6">nlassert</a> ((d0==d1)&&(d0==d2)); +02037 +02038 <span class="comment">// if (found)</span> +02039 <span class="comment">// nlstop;</span> +02040 +02041 <span class="comment">// Reaction</span> +02042 <span class="keywordflow">if</span> (firstCollision) +02043 { +02044 collisionTime = firstCollision->getCollisionTime (); +02045 reaction (*firstCollision); +02046 <span class="comment">//nlassert (collisionTime != 1);</span> +02047 +02048 <span class="keywordflow">if</span> (collisionTime == 1) +02049 { +02050 <a class="code" href="a04199.html#a2">nlwarning</a>(<span class="stringliteral">"PACS: evalNCPrimitiveCollision() failure, collisionTime [%f] == 1"</span>, collisionTime); +02051 <span class="keywordflow">return</span> <span class="keyword">false</span>; +02052 } +02053 } +02054 <span class="keywordflow">else</span> +02055 { +02056 <span class="comment">// Retriever mode ?</span> +02057 <span class="keywordflow">if</span> (_Retriever&&testMoveValid) +02058 { +02059 <span class="comment">// Do move</span> +02060 wI->doMove (*_Retriever, _SurfaceTemp, deltaTime, collisionTime, ((CMovePrimitive*)primitive)->getDontSnapToGround()); +02061 } +02062 <span class="keywordflow">else</span> +02063 { +02064 <span class="comment">// Do move</span> +02065 wI->doMove (_DeltaTime); +02066 } +02067 } +02068 +02069 beginTime = collisionTime; +02070 } +02071 <span class="keywordflow">while</span> (firstCollision); +02072 } +02073 <span class="keywordflow">else</span> +02074 <span class="keywordflow">return</span> <span class="keyword">false</span>; +02075 +02076 <span class="keywordflow">return</span> <span class="keyword">true</span>; +02077 } +02078 +02079 +02080 } <span class="comment">// NLPACS</span> +</pre></div> </td> + </tr> +</table> +<hr size="1"><address style="align: right;"><small>Generated on Tue Mar 16 06:43:06 2004 for NeL by +<a href="http://www.doxygen.org/index.html"> +<img src="doxygen.png" alt="doxygen" align="middle" border=0 > +</a>1.3.6 </small></address> +</body> +</html> |