1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/pacs/retriever_instance.h"
20 #include "nel/pacs/global_retriever.h"
23 using namespace NLMISC
;
27 NLPACS::CRetrieverInstance::CRetrieverInstance()
33 void NLPACS::CRetrieverInstance::resetLinks()
37 // this is a HARD reset !
38 // only the instance i reset, no care about neighbors !!
39 for (i
=0; i
<_Neighbors
.size(); ++i
)
41 _BorderChainLinks
.clear();
43 _ExteriorEdgeQuad
.removeLinks();
46 void NLPACS::CRetrieverInstance::resetLinks(uint32 id
)
48 vector
<sint32
>::iterator rit
;
49 for (rit
=_Neighbors
.begin(); rit
!=_Neighbors
.end(); )
50 if (*rit
== (sint32
)id
)
51 rit
= _Neighbors
.erase(rit
);
56 for (i
=0; i
<_BorderChainLinks
.size(); ++i
)
57 if (_BorderChainLinks
[i
].Instance
== (uint16
)id
)
58 _BorderChainLinks
[i
].reset();
60 _ExteriorEdgeQuad
.removeLinks(id
);
63 void NLPACS::CRetrieverInstance::reset()
66 // this is a HARD reset !
67 // only the instance i reset, no care about neighbors !!
68 _NodesInformation
.clear();
72 _Origin
= CVector::Null
;
73 _Type
= CLocalRetriever::Landscape
;
74 _BorderChainLinks
.clear();
75 _ExteriorEdgeQuad
.clear();
80 void NLPACS::CRetrieverInstance::init(const CLocalRetriever
&retriever
)
82 if (!retriever
.isLoaded())
85 _NodesInformation.resize(retriever.getSurfaces().size());
88 // Resets _NodesInformation for later pathfinding graph annotation.
89 for (i=0; i<_NodesInformation.size(); ++i)
91 CVector pos = getGlobalPosition(retriever.getSurfaces()[i].getCenter());
92 _NodesInformation[i].Position = CVector2f(pos.x, pos.y);
96 _Type
= retriever
.getType();
97 _BorderChainLinks
.resize(retriever
.getBorderChains().size());
100 void NLPACS::CRetrieverInstance::make(sint32 instanceId
, sint32 retrieverId
, const CLocalRetriever
&retriever
,
101 uint8 orientation
, const CVector
&origin
)
103 if (_InstanceId
!= -1 || _RetrieverId
!= -1)
105 nlwarning("in call to NLPACS::CRetrieverInstance::make");
106 nlwarning("_InstanceId=%d _RetrieverId=%d _Orientation=%d", _InstanceId
, _RetrieverId
, _Orientation
);
107 nlwarning("instanceId=%d retrieverId=%d orientation=%d", instanceId
, retrieverId
, orientation
);
108 nlerror("Retriever instance %d has already been set", _InstanceId
);
111 _InstanceId
= instanceId
;
112 _RetrieverId
= retrieverId
;
113 _Orientation
= (orientation
%4);
116 _BBox
= retriever
.getBBox();
117 _BBox
.setCenter(_BBox
.getCenter()+_Origin
);
119 if (_Orientation
== 1 || _Orientation
== 3)
121 CVector hs
= _BBox
.getHalfSize();
122 std::swap(hs
.x
, hs
.y
);
123 _BBox
.setHalfSize(hs
);
130 void NLPACS::CRetrieverInstance::initEdgeQuad(NLPACS::CGlobalRetriever
&gr
)
132 const CLocalRetriever
&lr
= gr
.getRetriever(_RetrieverId
);
134 if (lr
.getType() != CLocalRetriever::Interior
)
136 nlerror("Attempt to init the edgequad of instance %d whereas local retriever %d is not interior", _InstanceId
, _RetrieverId
);
139 // build the edge quad
140 _ExteriorEdgeQuad
.build(lr
.getExteriorMesh(), gr
, gr
.getInternalCST(),_InstanceId
);
143 void NLPACS::CRetrieverInstance::linkEdgeQuad(NLPACS::CGlobalRetriever
&gr
)
145 const CLocalRetriever
&lr
= gr
.getRetriever(_RetrieverId
);
146 const CExteriorMesh
&em
= lr
.getExteriorMesh();
148 const vector
<CExteriorEdgeEntry
> &ee
= _ExteriorEdgeQuad
.getEdgeEntries();
150 // here we fill (partially) the _BorderChainLinks table
152 for (i
=0; i
<ee
.size(); ++i
)
154 const CExteriorMesh::CEdge
&edge
= em
.getEdge(ee
[i
].EdgeId
);
157 const CExteriorMesh::CLink
&link
= em
.getLink(edge
.Link
);
159 if (link
.SurfaceId
!= 0xFFFF && link
.ChainId
!= 0xFFFF && link
.BorderChainId
!= 0xFFFF)
161 CRetrieverInstance::CLink
&borderLink
= _BorderChainLinks
[link
.BorderChainId
];
162 borderLink
.ChainId
= 0xFFFF; // no opposite chain
163 borderLink
.BorderChainId
= 0xFFFF; // idem
164 if ((borderLink
.Instance
== 0xFFFF && borderLink
.SurfaceId
== 0xFFFF) ||
165 (borderLink
.Instance
== (uint16
)(ee
[i
].Exterior
.RetrieverInstanceId
) &&
166 borderLink
.SurfaceId
== (uint16
)(ee
[i
].Exterior
.SurfaceId
) ))
168 borderLink
.Instance
= (uint16
)(ee
[i
].Exterior
.RetrieverInstanceId
);
169 borderLink
.SurfaceId
= (uint16
)(ee
[i
].Exterior
.SurfaceId
);
173 nlwarning("Instance %d, borderLink %d: link already set to inst=%d, surf=%d, try to set to inst=%d, surf=%d",
174 _InstanceId
, link
.BorderChainId
, borderLink
.Instance
, borderLink
.SurfaceId
,
175 (uint16
)(ee
[i
].Exterior
.RetrieverInstanceId
), (uint16
)(ee
[i
].Exterior
.SurfaceId
));
182 /* Links the current retriever instance to another instance
185 void NLPACS::CRetrieverInstance::link(CRetrieverInstance
&neighbor
,
186 const vector
<CLocalRetriever
> &retrievers
)
189 for (i
=0; i
<_Neighbors
.size(); ++i
)
190 if (_Neighbors
[i
] == neighbor
._InstanceId
)
193 const CLocalRetriever
&retriever
= retrievers
[_RetrieverId
];
194 const CLocalRetriever
&nRetriever
= retrievers
[neighbor
._RetrieverId
];
196 const vector
<CChain
> &chains
= retriever
.getChains(),
197 &nChains
= nRetriever
.getChains();
198 const vector
<uint16
> &borderChains
= retriever
.getBorderChains(),
199 &nBorderChains
= nRetriever
.getBorderChains();
201 vector
< pair
<CVector
,CVector
> > chainTips
,
204 _BorderChainLinks
.resize(borderChains
.size());
205 neighbor
._BorderChainLinks
.resize(nBorderChains
.size());
208 for (i=0; i<borderChains.size(); ++i)
209 chainTips.push_back(make_pair(retriever.getTip(chains[borderChains[i]].getStartTip()).Point,
210 retriever.getTip(chains[borderChains[i]].getStopTip()).Point));
212 for (i
=0; i
<borderChains
.size(); ++i
)
213 chainTips
.push_back(make_pair(retriever
.getStartVector(borderChains
[i
]),
214 retriever
.getStopVector(borderChains
[i
])));
216 CVector translation
= neighbor
._Origin
- _Origin
;
218 for (i=0; i<nBorderChains.size(); ++i)
219 nChainTips.push_back(make_pair(nRetriever.getTip(nChains[nBorderChains[i]].getStartTip()).Point+translation,
220 nRetriever.getTip(nChains[nBorderChains[i]].getStopTip()).Point+translation));
222 for (i
=0; i
<nBorderChains
.size(); ++i
)
223 nChainTips
.push_back(make_pair(nRetriever
.getStartVector(nBorderChains
[i
])+translation
,
224 nRetriever
.getStopVector(nBorderChains
[i
])+translation
));
226 for (i
=0; i
<borderChains
.size(); ++i
)
228 // if the chain is already linked, just step
229 if (_BorderChainLinks
[i
].Instance
!= 0xFFFF || _BorderChainLinks
[i
].BorderChainId
!= 0xFFFF ||
230 _BorderChainLinks
[i
].ChainId
!= 0xFFFF || _BorderChainLinks
[i
].SurfaceId
!= 0xFFFF)
233 float bestDist
= 1.0f
;
236 for (j
=0; j
<nBorderChains
.size(); ++j
)
238 if (neighbor
._BorderChainLinks
[j
].Instance
!= 0xFFFF || neighbor
._BorderChainLinks
[j
].BorderChainId
!= 0xFFFF ||
239 neighbor
._BorderChainLinks
[j
].ChainId
!= 0xFFFF || neighbor
._BorderChainLinks
[j
].SurfaceId
!= 0xFFFF)
242 float d
= (chainTips
[i
].first
-nChainTips
[j
].second
).norm()+(chainTips
[i
].second
-nChainTips
[j
].first
).norm();
250 // if no best match, just don't link
251 if (bestDist
> 1.0e-1f
|| best
== -1)
254 _BorderChainLinks
[i
].Instance
= (uint16
)neighbor
._InstanceId
;
255 _BorderChainLinks
[i
].BorderChainId
= (uint16
)best
;
256 _BorderChainLinks
[i
].ChainId
= nBorderChains
[_BorderChainLinks
[i
].BorderChainId
];
257 _BorderChainLinks
[i
].SurfaceId
= (uint16
)nChains
[_BorderChainLinks
[i
].ChainId
].getLeft();
259 neighbor
._BorderChainLinks
[best
].Instance
= (uint16
)_InstanceId
;
260 neighbor
._BorderChainLinks
[best
].BorderChainId
= (uint16
)i
;
261 neighbor
._BorderChainLinks
[best
].ChainId
= borderChains
[neighbor
._BorderChainLinks
[best
].BorderChainId
];
262 neighbor
._BorderChainLinks
[best
].SurfaceId
= (uint16
)chains
[neighbor
._BorderChainLinks
[best
].ChainId
].getLeft();
265 _Neighbors
.push_back(neighbor
._InstanceId
);
266 neighbor
._Neighbors
.push_back(_InstanceId
);
270 void NLPACS::CRetrieverInstance::unlink(vector
<CRetrieverInstance
> &instances
)
274 for (i
=0; i
<_Neighbors
.size(); ++i
)
275 instances
[_Neighbors
[i
]].resetLinks(_InstanceId
);
283 void NLPACS::CRetrieverInstance::retrievePosition(const NLMISC::CVector
&estimated
, const CLocalRetriever
&retriever
, CCollisionSurfaceTemp
&cst
, bool sortByDistance
) const
284 //NLPACS::CLocalRetriever::CLocalPosition NLPACS::CRetrieverInstance::retrievePosition(const NLMISC::CVector &estimated, const CLocalRetriever &retriever, CCollisionSurfaceTemp &cst) const
287 CVector localEstimated;
288 CLocalRetriever::CLocalPosition retrieved;
290 // get local coordinates
291 localEstimated = getLocalPosition(estimated);
292 // Yoyo: must snap vector.
293 CRetrieverInstance::snapVector(localEstimated);
295 // fills _RetrieveTable by retrievingPosition.
296 retriever.retrievePosition(localEstimated, cst);
301 float bestDistance = 1.0e10f;
305 // for each surface in the retriever
306 for (i=0; i<cst.PossibleSurfaces.size(); ++i)
308 surf = cst.PossibleSurfaces[i];
309 cst.SurfaceLUT[surf].first = false;
310 // if the surface contains the estimated position.
311 if (cst.SurfaceLUT[surf].second != 0)
313 // at least remembers the last seen surface...
314 cst.SurfaceLUT[surf].second = 0;
316 const CQuadLeaf *leaf;
322 case CLocalRetriever::Landscape:
324 // search in the surface's quad tree for the actual height
325 leaf = retriever.getSurfaces()[surf].getQuadTree().getLeaf(localEstimated);
326 // if there is no acceptable leaf, just give up
329 meanHeight = leaf->getMaxHeight();
332 case CLocalRetriever::Interior:
334 // get the exact position
336 lp.Estimation = localEstimated;
337 meanHeight = localEstimated.z;
338 retriever.snapToInteriorGround(lp, lfound);
340 meanHeight = lp.Estimation.z;
347 // if it is closer to the estimation than the previous remembered...
348 float distance = (float)fabs(localEstimated.z-meanHeight);
349 if (distance < bestDistance && lfound)
351 bestDistance = distance;
352 bestHeight = meanHeight;
360 // if there is a best surface, returns it
361 retrieved.Surface = bestSurf;
362 retrieved.Estimation = CVector(localEstimated.x, localEstimated.y, bestHeight);
366 // else return the last remembered...
367 retrieved.Surface = lastSurf;
368 retrieved.Estimation = localEstimated;
373 retrievePosition(CVectorD(estimated
), retriever
, cst
, sortByDistance
);
376 void NLPACS::CRetrieverInstance::retrievePosition(const NLMISC::CVectorD
&estimated
, const CLocalRetriever
&retriever
, CCollisionSurfaceTemp
&cst
, bool sortByDistance
) const
378 CVector localEstimated
;
380 // nldebug("PACS: retrievePosition in instance %d (retriever %d)", _InstanceId, _RetrieverId);
382 // get local coordinates
383 localEstimated
= getLocalPosition(estimated
);
384 // Yoyo: must snap vector.
385 CRetrieverInstance::snapVector(localEstimated
);
387 // fills _RetrieveTable by retrievingPosition.
388 retriever
.retrievePosition(localEstimated
, cst
);
391 /* sint bestSurf = -1;
393 float bestDistance = 1.0e10f;
399 case CLocalRetriever::Landscape
:
401 for (i
=0; i
<cst
.PossibleSurfaces
.size(); ++i
)
403 surf
= cst
.PossibleSurfaces
[i
];
405 // nldebug("PACS: surface %d: count %d", surf, cst.SurfaceLUT[surf].Counter);
407 // if the surface contains the estimated position.
408 if (cst
.SurfaceLUT
[surf
].Counter
== 2)
412 const CQuadLeaf *leaf;
414 // search in the surface's quad tree for the actual height
415 leaf = retriever.getSurfaces()[surf].getQuadTree().getLeaf(localEstimated);
416 // if there is no acceptable leaf, just give up
419 meanHeight = leaf->getMaxHeight();
420 //meanHeight = retriever.getSurfaces()[surf].getQuadTree().getInterpZ(localEstimated);
422 // if it is closer to the estimation than the previous remembered...
424 float distance = (float)fabs(localEstimated.z-meanHeight);
425 cst.SortedSurfaces.push_back(CCollisionSurfaceTemp::CDistanceSurface(distance, (uint16)surf, (uint16)_InstanceId, cst.SurfaceLUT[surf].FoundCloseEdge));
429 meanHeight
= retriever
.getSurface(surf
).getQuantHeight()*2.0f
+ 1.0f
;
431 // if it is closer to the estimation than the previous remembered...
433 float distance
= sortByDistance
? (float)fabs(localEstimated
.z
-meanHeight
) : meanHeight
;
434 cst
.SortedSurfaces
.push_back(CCollisionSurfaceTemp::CDistanceSurface(distance
, (uint16
)surf
, (uint16
)_InstanceId
, cst
.SurfaceLUT
[surf
].FoundCloseEdge
));
437 else if (cst
.SurfaceLUT
[surf
].Counter
!= 0)
439 nlwarning("PACS: unexpected surface (%d) count (%d) at instance %d (pos=(%f,%f,%f))", surf
, cst
.SurfaceLUT
[surf
].Counter
, _InstanceId
, estimated
.x
, estimated
.y
, estimated
.z
);
442 cst
.SurfaceLUT
[surf
].reset();
447 case CLocalRetriever::Interior
:
449 for (i
=0; i
<cst
.PossibleSurfaces
.size(); ++i
)
451 surf
= cst
.PossibleSurfaces
[i
];
452 // if the surface contains the estimated position.
453 if (cst
.SurfaceLUT
[surf
].Counter
== 2)
458 // get the exact position
460 lp
.Estimation
= localEstimated
;
461 retriever
.snapToInteriorGround(lp
, lfound
);
464 // if it is closer to the estimation than the previous remembered...
466 float distance
= sortByDistance
? (float)fabs(localEstimated
.z
-lp
.Estimation
.z
) : lp
.Estimation
.z
;
467 cst
.SortedSurfaces
.push_back(CCollisionSurfaceTemp::CDistanceSurface(distance
, (uint16
)surf
, (uint16
)_InstanceId
, cst
.SurfaceLUT
[surf
].FoundCloseEdge
));
470 else if (cst
.SurfaceLUT
[surf
].Counter
!= 0)
472 nlwarning("PACS: unexpected surface (%d) count (%d) at instance %d (pos=(%f,%f,%f))", surf
, cst
.SurfaceLUT
[surf
].Counter
, _InstanceId
, estimated
.x
, estimated
.y
, estimated
.z
);
475 cst
.SurfaceLUT
[surf
].reset();
480 nlerror("Unknown instance type %d !!", _Type
);
489 void NLPACS::CRetrieverInstance::snapToInteriorGround(NLPACS::ULocalPosition
&position
,
490 const NLPACS::CLocalRetriever
&retriever
) const
493 retriever
.snapToInteriorGround(position
, lfound
);
496 void NLPACS::CRetrieverInstance::snap(NLPACS::ULocalPosition
&position
, const NLPACS::CLocalRetriever
&retriever
) const
498 if (_Type
== CLocalRetriever::Landscape
)
500 // search in the surface's quad tree for the actual height
501 // position.Estimation.z = retriever.getSurfaces()[position.Surface].getQuadTree().getInterpZ(position.Estimation);
503 position
.Estimation
.z
= retriever
.getHeight(position
);
506 const CQuadLeaf *leaf = retriever.getSurfaces()[position.Surface].getQuadTree().getLeaf(position.Estimation);
507 // if there is no acceptable leaf, just give up
510 position.Estimation.z = leaf->getMaxHeight();
514 nlwarning("PACS: couldn't snap position (%f,%f,%f) on surface %d instance %d", position.Estimation.x, position.Estimation.y, position.Estimation.z, position.Surface, _InstanceId);
518 else if (_Type
== CLocalRetriever::Interior
)
521 retriever
.snapToInteriorGround(position
, lfound
);
525 nlwarning("PACS: unknown instance (%d) type %d", _InstanceId
, _Type
);
533 CVector
NLPACS::CRetrieverInstance::getLocalPosition(const CVector
&globalPosition
) const
535 switch (_Orientation
)
538 nlwarning("in NLPACS::CRetrieverInstance::getLocalPosition()");
539 nlerror("unexpected orientation value (%d)", _Orientation
);
541 return CVector(+globalPosition
.x
-_Origin
.x
, +globalPosition
.y
-_Origin
.y
, globalPosition
.z
-_Origin
.z
);
544 return CVector(+globalPosition
.y
-_Origin
.y
, -globalPosition
.x
+_Origin
.x
, globalPosition
.z
-_Origin
.z
);
547 return CVector(-globalPosition
.x
+_Origin
.x
, -globalPosition
.y
+_Origin
.y
, globalPosition
.z
-_Origin
.z
);
550 return CVector(-globalPosition
.y
+_Origin
.y
, +globalPosition
.x
-_Origin
.x
, globalPosition
.z
-_Origin
.z
);
555 CVector
NLPACS::CRetrieverInstance::getLocalPosition(const CVectorD
&globalPosition
) const
557 switch (_Orientation
)
560 nlwarning("in NLPACS::CRetrieverInstance::getLocalPosition()");
561 nlerror("unexpected orientation value (%d)", _Orientation
);
563 return CVector((float)(+globalPosition
.x
-_Origin
.x
), (float)(+globalPosition
.y
-_Origin
.y
), (float)(globalPosition
.z
-_Origin
.z
));
566 return CVector((float)(+globalPosition
.y
-_Origin
.y
), (float)(-globalPosition
.x
+_Origin
.x
), (float)(globalPosition
.z
-_Origin
.z
));
569 return CVector((float)(-globalPosition
.x
+_Origin
.x
), (float)(-globalPosition
.y
+_Origin
.y
), (float)(globalPosition
.z
-_Origin
.z
));
572 return CVector((float)(-globalPosition
.y
+_Origin
.y
), (float)(+globalPosition
.x
-_Origin
.x
), (float)(globalPosition
.z
-_Origin
.z
));
577 CVector
NLPACS::CRetrieverInstance::getGlobalPosition(const CVector
&localPosition
) const
579 switch (_Orientation
)
582 nlwarning("in NLPACS::CRetrieverInstance::getLocalPosition()");
583 nlerror("unexpected orientation value (%d)", _Orientation
);
585 return CVector(+localPosition
.x
+_Origin
.x
, +localPosition
.y
+_Origin
.y
, localPosition
.z
+_Origin
.z
);
588 return CVector(-localPosition
.y
+_Origin
.x
, +localPosition
.x
+_Origin
.y
, localPosition
.z
+_Origin
.z
);
591 return CVector(-localPosition
.x
+_Origin
.x
, -localPosition
.y
+_Origin
.y
, localPosition
.z
+_Origin
.z
);
594 return CVector(+localPosition
.y
+_Origin
.x
, -localPosition
.x
+_Origin
.y
, localPosition
.z
+_Origin
.z
);
599 CVectorD
NLPACS::CRetrieverInstance::getDoubleGlobalPosition(const CVector
&localPosition
) const
601 switch (_Orientation
)
604 nlwarning("in NLPACS::CRetrieverInstance::getLocalPosition()");
605 nlerror("unexpected orientation value (%d)", _Orientation
);
607 return CVectorD(+(double)localPosition
.x
+(double)_Origin
.x
, +(double)localPosition
.y
+(double)_Origin
.y
, (double)localPosition
.z
+(double)_Origin
.z
);
610 return CVectorD(-(double)localPosition
.y
+(double)_Origin
.x
, +(double)localPosition
.x
+(double)_Origin
.y
, (double)localPosition
.z
+(double)_Origin
.z
);
613 return CVectorD(-(double)localPosition
.x
+(double)_Origin
.x
, -(double)localPosition
.y
+(double)_Origin
.y
, (double)localPosition
.z
+(double)_Origin
.z
);
616 return CVectorD(+(double)localPosition
.y
+(double)_Origin
.x
, -(double)localPosition
.x
+(double)_Origin
.y
, (double)localPosition
.z
+(double)_Origin
.z
);
623 // ***************************************************************************
624 void NLPACS::CRetrieverInstance::testExteriorCollision(NLPACS::CCollisionSurfaceTemp
&cst
, const CAABBox
&bboxMove
, const CVector2f
&transBase
, const NLPACS::CLocalRetriever
&retriever
) const
628 // 0. select ordered chains in the chainquad.
629 //=====================================
630 sint nEei
= _ExteriorEdgeQuad
.selectEdges(bboxMove
, cst
);
631 // NB: cst.OChainLUT is assured to be full of 0xFFFF after this call (if was right before).
634 // 1. regroup them in chains. build cst.CollisionChains
635 //=====================================
636 // NB: use cst.OChainLUT to look if a Chain has been inserted before.
637 uint16
*edgeLUT
= cst
.OChainLUT
;
639 // bkup where we begin to add chains.
640 uint firstChainAdded
= (uint
)cst
.CollisionChains
.size();
642 // For all exterioredge entry.
645 // get the edge entry and the edge
646 uint16 eei
= cst
.ExteriorEdgeIndexes
[i
];
647 const CExteriorEdgeEntry
&eee
= _ExteriorEdgeQuad
.getEdgeEntry(eei
);
649 // WELL ACTUALLY DO BOTHER ABOUT DOORS !!
651 // don't bother about doors
652 if (eee.Interior.RetrieverInstanceId != -1)
656 // add/retrieve the id in cst.CollisionChains.
657 //=================================
660 if(edgeLUT
[eei
]==0xFFFF)
662 // add a new CCollisionChain.
663 ccId
= (uint
)cst
.CollisionChains
.size();
664 cst
.CollisionChains
.push_back(CCollisionChain());
665 // Fill it with default.
666 cst
.CollisionChains
[ccId
].Tested
= false;
667 cst
.CollisionChains
[ccId
].ExteriorEdge
= true;
668 cst
.CollisionChains
[ccId
].FirstEdgeCollide
= 0xFFFFFFFF;
669 cst
.CollisionChains
[ccId
].ChainId
= eei
;
670 // Fill Left right info.
671 cst
.CollisionChains
[ccId
].LeftSurface
= eee
.Interior
;
672 cst
.CollisionChains
[ccId
].RightSurface
= eee
.Exterior
;
674 // store this Id in the LUT of chains.
675 edgeLUT
[eei
]= uint16(ccId
);
679 // get the id of this collision chain.
682 // ACTUALLY, THIS SHOULD NEVER HAPPEN
683 // since ext edge are only 1 segment
686 // add edge collide to the list.
687 //=================================
688 CCollisionChain
&colChain
= cst
.CollisionChains
[ccId
];
690 CVector2f p0
= CVector2f(retriever
._ExteriorMesh
.getEdge(eee
.EdgeId
).Start
);
691 CVector2f p1
= CVector2f(retriever
._ExteriorMesh
.getEdge(eee
.EdgeId
+1).Start
);
693 // alloc a new edgeCollide.
694 uint32 ecnId
= cst
.allocEdgeCollideNode();
695 CEdgeCollideNode
&ecn
= cst
.getEdgeCollideNode(ecnId
);
697 // append to the front of the list.
698 ecn
.Next
= colChain
.FirstEdgeCollide
;
699 colChain
.FirstEdgeCollide
= ecnId
;
709 // 2. Reset LUT to 0xFFFF.
710 //=====================================
712 // for all collisions chains inserted (starting from firstChainAdded), reset LUT.
713 for(i
=firstChainAdded
; i
<(sint
)cst
.CollisionChains
.size(); i
++)
715 uint ccId
= cst
.CollisionChains
[i
].ChainId
;
716 edgeLUT
[ccId
]= 0xFFFF;
717 cst
.CollisionChains
[i
].ChainId
= _ExteriorEdgeQuad
.getEdgeEntry(ccId
).EdgeId
;
725 void NLPACS::CRetrieverInstance::serial(NLMISC::IStream
&f
)
731 - added type and _EdgeQuad
733 sint ver
= f
.serialVersion(1);
735 f
.serial(_InstanceId
, _RetrieverId
, _Orientation
, _Origin
);
736 f
.serialCont(_Neighbors
);
737 f
.serialCont(_BorderChainLinks
);
740 // serialises the number of nodes
741 uint16 totalNodes
= uint16(_NodesInformation
.size());
742 f
.serial(totalNodes
);
745 // if the stream is reading, reinits the temps table...
746 _NodesInformation
.resize(totalNodes
);
752 f
.serial(_ExteriorEdgeQuad
);
754 // a fix for old versions (with wrong _Type value)
755 if (_Type
!= CLocalRetriever::Interior
) _Type
= CLocalRetriever::Landscape
;
761 void NLPACS::CRetrieverInstance::resetBorderChainLinks(const vector
<uint
> &links
)
764 for (i
=0; i
<links
.size(); ++i
)
766 if (links
[i
] >= _BorderChainLinks
.size())
767 _BorderChainLinks
.resize(links
[i
]+1);
769 _BorderChainLinks
[links
[i
]].reset();