1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2015 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "nel/misc/types_nl.h"
22 #include "nel/misc/debug.h"
23 #include "nel/misc/path.h"
24 #include "nel/misc/common.h"
25 #include "nel/misc/file.h"
26 #include "nel/misc/time_nl.h"
27 #include "nel/misc/polygon.h"
28 #include "nel/misc/smart_ptr.h"
30 #include "nel/3d/scene_group.h"
31 #include "nel/3d/transform_shape.h"
32 #include "nel/3d/water_model.h"
33 #include "nel/3d/water_shape.h"
34 #include "nel/3d/quad_grid.h"
36 #include "build_rbank.h"
37 #include "build_surf.h"
39 #include "surface_splitter.h"
41 #include "nel/pacs/global_retriever.h"
42 #include "nel/pacs/retriever_bank.h"
43 #include "nel/pacs/surface_quad.h"
44 #include "nel/pacs/local_retriever.h"
45 #include "nel/pacs/retriever_instance.h"
46 #include "nel/pacs/chain.h"
47 #include "nel/pacs/collision_mesh_build.h"
54 using namespace NLMISC
;
62 CIGBox(const string
&name
, const CAABBox
&bbox
) : Name(name
), BBox(bbox
) {}
65 void serial(NLMISC::IStream
&f
) { f
.serial(Name
, BBox
); }
69 string getZoneNameById(uint16 id)
75 sprintf(ych,"%d_%c%c", y+1, 'A'+x/26, 'A'+x%26);
79 string
getZoneNameByCoord(float x
, float y
)
81 const float zoneDim
= 160.0f
;
83 float xcount
= x
/zoneDim
;
84 float ycount
= -y
/zoneDim
+ 1;
87 sprintf(ych
,"%d_%c%c",(sint
)ycount
, 'A'+(sint
)xcount
/26, 'A'+(sint
)xcount
%26);
91 CVector
getZoneCenterById(uint16 id
)
95 const float zdim
= 160.0f
;
100 return CVector(zdim
*((float)x
+0.5f
), -zdim
*((float)y
+0.5f
), 0.0f
);
103 uint32
getIdByCoord(uint x
, uint y
)
108 string
changeExt(string name
, const string
&ext
)
110 string::iterator it
, last
;
113 for (it
=name
.begin(); it
!=name
.end(); ++it
)
117 name
.erase(last
, name
.end());
125 void processAllPasses(string
&zoneName
)
129 NLPACS::CZoneTessellation tessellation
;
130 vector
<NLPACS::COrderedChain3f
> fullChains
;
136 uint16 zid
= getZoneIdByName(zoneName
);
137 CAABBox box
= getZoneBBoxById(zid
);
139 CVector translation
= -box
.getCenter();
140 if (tessellation
.setup(zid
, 4, translation
))
142 tessellation
.build();
144 CAABBox tbox
= tessellation
.computeBBox();
146 tessellation
.compile();
147 tessellation
.generateBorders(1.0);
149 NLPACS::CLocalRetriever retriever
;
151 CAABBox rbbox
= tessellation
.BestFittingBBox
;
152 CVector hs
= rbbox
.getHalfSize();
154 rbbox
.setHalfSize(hs
);
155 retriever
.setBBox(rbbox
);
156 retriever
.setType(NLPACS::CLocalRetriever::Landscape
);
158 for (j
=0; j
<tessellation
.Surfaces
.size(); ++j
)
160 retriever
.addSurface(0,
165 tessellation
.Surfaces
[j
].IsUnderWater
,
166 tessellation
.Surfaces
[j
].WaterHeight
,
167 tessellation
.Surfaces
[j
].ClusterHint
,
168 tessellation
.Surfaces
[j
].Center
,
169 tessellation
.Surfaces
[j
].HeightQuad
,
170 tessellation
.Surfaces
[j
].QuantHeight
);
174 nlinfo("Added surface %d: water=%d", j
, (tessellation
.Surfaces
[j
].IsUnderWater
? 1 : 0));
178 for (j
=0; j
<tessellation
.Borders
.size(); ++j
)
180 if (tessellation
.Borders
[j
].Right
< -1)
182 retriever
.addChain(tessellation
.Borders
[j
].Vertices
,
183 tessellation
.Borders
[j
].Left
,
184 NLPACS::CChain::getDummyBorderChainId());
189 retriever
.addChain(tessellation
.Borders
[j
].Vertices
,
190 tessellation
.Borders
[j
].Left
,
191 tessellation
.Borders
[j
].Right
);
195 retriever
.computeLoopsAndTips();
197 retriever
.findBorderChains();
198 retriever
.updateChainIds();
199 retriever
.computeTopologies();
201 retriever
.computeCollisionChainQuad();
203 retriever
.setType(NLPACS::CLocalRetriever::Landscape
);
207 if (!retriever
.checkSurfacesIntegrity(translation
))
209 nlwarning("retriever '%s' has a surface issue (self covering surface...)", zoneName
.c_str());
212 COFile outputRetriever
;
213 name
= changeExt(zoneName
, string("lr"));
214 filename
= OutputPath
+name
;
216 nlinfo("save file %s", filename
.c_str());
217 outputRetriever
.open(filename
);
218 retriever
.serial(outputRetriever
);
221 catch(const Exception
&e
)
223 printf("%s\n", e
.what ());
236 void tessellateAndMoulineZone(string &zoneName)
240 NLPACS::CZoneTessellation tessellation;
241 vector<NLPACS::COrderedChain3f> fullChains;
247 uint16 zid = getZoneIdByName(zoneName);
248 CAABBox box = getZoneBBoxById(zid);
250 CVector translation = -box.getCenter();
251 if (tessellation.setup(zid, 4, translation))
253 tessellation.build();
255 CAABBox tbox = tessellation.computeBBox();
257 vector<CIGBox> boxes;
260 if (CFile::fileExists (IGBoxes))
262 CIFile binput(IGBoxes);
263 binput.serialCont(boxes);
267 nlinfo("WARNING: IG list no found");
270 catch (const Exception &) { nlinfo("WARNING: IG list no found"); }
272 for (i=0; i<boxes.size(); ++i)
274 if (tbox.intersect(boxes[i].BBox))
278 // load ig associated to the zone
279 string igname = boxes[i].Name;
280 CIFile monStream(CPath::lookup(igname));
282 monStream.serial(ig);
284 // search in group for water instance
285 for (j=0; j<ig._InstancesInfos.size(); ++j)
287 string shapeName = ig._InstancesInfos[j].Name;
288 if (CFile::getExtension (shapeName) == "")
289 shapeName += ".shape";
291 string shapeNameLookup = CPath::lookup (shapeName, false, false);
292 if (!shapeNameLookup.empty())
295 if (f.open (shapeNameLookup))
300 CWaterShape *wshape = dynamic_cast<CWaterShape *>(shape.getShapePointer());
305 ig.getInstanceMatrix(j, matrix);
308 wshape->getShapeInWorldSpace(wpoly);
311 for (k=0; k<wpoly.Vertices.size(); ++k)
313 //wpoly.Vertices[k].z = 0.0f;
314 wpoly.Vertices[k] = matrix * wpoly.Vertices[k];
317 tessellation.addWaterShape(wpoly);
321 nlwarning ("Can't load shape %s", shapeNameLookup.c_str());
326 catch (const Exception &e)
328 nlwarning("%s", e.what());
333 tessellation.compile();
334 tessellation.generateBorders(1.0);
336 NLPACS::CLocalRetriever retriever;
338 CAABBox rbbox = tessellation.BestFittingBBox;
339 CVector hs = rbbox.getHalfSize();
341 rbbox.setHalfSize(hs);
342 retriever.setBBox(rbbox);
343 retriever.setType(NLPACS::CLocalRetriever::Landscape);
345 for (j=0; j<(sint)tessellation.Surfaces.size(); ++j)
347 retriever.addSurface(0,
352 tessellation.Surfaces[j].IsUnderWater,
353 tessellation.Surfaces[j].WaterHeight,
354 tessellation.Surfaces[j].ClusterHint,
355 tessellation.Surfaces[j].Center,
356 tessellation.Surfaces[j].HeightQuad,
357 tessellation.Surfaces[j].QuantHeight);
360 for (j=0; j<(sint)tessellation.Borders.size(); ++j)
362 if (tessellation.Borders[j].Right < -1)
364 retriever.addChain(tessellation.Borders[j].Vertices,
365 tessellation.Borders[j].Left,
366 NLPACS::CChain::getDummyBorderChainId());
371 retriever.addChain(tessellation.Borders[j].Vertices,
372 tessellation.Borders[j].Left,
373 tessellation.Borders[j].Right);
377 fullChains = retriever.getFullOrderedChains();
379 // save raw retriever
380 COFile outputRetriever;
381 name = changeExt(zoneName, string("lr"));
382 filename = OutputPath+PreprocessDirectory+name;
384 nlinfo("save file %s", filename.c_str());
385 outputRetriever.open(filename);
386 retriever.serial(outputRetriever);
390 name = changeExt(zoneName, string("ochain"));
391 filename = OutputPath+name;
393 nlinfo("save file %s", filename.c_str());
394 outputChains.open(filename);
395 outputChains.serialCont(fullChains);
398 catch(const Exception &e)
407 void processRetriever(string &zoneName)
414 uint16 zid = getZoneIdByName(zoneName);
415 CAABBox box = getZoneBBoxById(zid);
417 NLPACS::CLocalRetriever retriever;
419 // load raw retriever
420 CIFile inputRetriever;
421 name = changeExt(zoneName, string("lr"));
422 filename = OutputPath+PreprocessDirectory+name;
424 nlinfo("load file %s", filename.c_str());
426 if (CFile::fileExists(filename))
428 inputRetriever.open(filename);
429 retriever.serial(inputRetriever);
431 // compute the retriever
433 retriever.computeLoopsAndTips();
435 retriever.findBorderChains();
436 retriever.updateChainIds();
437 retriever.computeTopologies();
439 retriever.computeCollisionChainQuad();
441 retriever.setType(NLPACS::CLocalRetriever::Landscape);
444 CSurfaceSplitter splitter;
445 //splitter.build(retriever);
449 COFile outputRetriever;
450 name = changeExt(zoneName, string("lr"));
451 filename = OutputPath+name;
453 nlinfo("save file %s", filename.c_str());
454 outputRetriever.open(filename);
455 retriever.serial(outputRetriever);
458 catch(const Exception &e)
474 sint PreviousChain
, NextChain
;
480 CReconstructed() : FrontInstance(-1), FrontChain(-1) {}
483 sint FrontInstance
, FrontChain
;
486 class CFaultyInstance
490 vector
<CFaultyChain
> Chains
;
491 vector
<CReconstructed
> Reconstructed
;
497 uint Chain
, Previous
;
507 vector
<CVector
> Vertices
;
508 vector
<CChainRef
> Chains
;
512 void fixFaultyLinks(map
<uint
, CFaultyInstance
> &faultyInstances
,
513 const vector
<NLPACS::CRetrieverInstance
> &instances
,
514 const vector
<NLPACS::CLocalRetriever
> &retrievers
)
516 map
<uint
, CFaultyInstance
>::iterator ifi
;
520 // rebuild full chains
521 // -- join all chains that are missing a link
522 for (ifi
=faultyInstances
.begin(); ifi
!=faultyInstances
.end(); ++ifi
)
524 CFaultyInstance
&inst
= (*ifi
).second
;
526 // for each chain, find best matching ending chain
527 for (k
=0; k
<inst
.Chains
.size(); ++k
)
530 double bestDist
= 1.0e10
;
531 for (l
=0; l
<inst
.Chains
.size(); ++l
)
533 if (l
== k
|| (best
!= -1 && inst
.Chains
[best
].PreviousChain
!= -1))
536 CVectorD diff
= inst
.Chains
[k
].End
- inst
.Chains
[l
].Start
;
537 double dist
= diff
.norm();
539 if (dist
< 0.1 && dist
< bestDist
)
548 inst
.Chains
[best
].PreviousChain
= k
;
549 inst
.Chains
[k
].NextChain
= best
;
554 for (k
=0; k
<inst
.Chains
.size(); ++k
)
556 if (inst
.Chains
[k
].PreviousChain
== -1)
559 inst
.Reconstructed
.push_back(CReconstructed());
562 inst
.Reconstructed
.back().Chains
.push_back(l
);
564 while ((sint
)(l
=inst
.Chains
[l
].NextChain
) != -1);
565 inst
.Reconstructed
.back().Start
= inst
.Chains
[inst
.Reconstructed
.back().Chains
.front()].Start
;
566 inst
.Reconstructed
.back().End
= inst
.Chains
[inst
.Reconstructed
.back().Chains
.back()].End
;
572 // match reconstructed chains
573 // -- for each reconstructed chain in an instance, find best matching reconstructed chain in neighbour instances
574 for (ifi
=faultyInstances
.begin(); ifi
!=faultyInstances
.end(); ++ifi
)
576 CFaultyInstance
&inst
= (*ifi
).second
;
578 const NLPACS::CRetrieverInstance
&instance
= instances
[inst
.Instance
];
579 const NLPACS::CLocalRetriever
&retriever
= retrievers
[instance
.getRetrieverId()];
580 vector
<sint32
> neighbs
= instance
.getNeighbors();
582 for (i
=0; i
<neighbs
.size(); ++i
)
584 map
<uint
, CFaultyInstance
>::iterator ifn
= faultyInstances
.find(neighbs
[i
]);
585 if (ifn
== faultyInstances
.end())
588 CFaultyInstance
&neighb
= (*ifn
).second
;
590 for (j
=0; j
<inst
.Reconstructed
.size(); ++j
)
592 if (inst
.Reconstructed
[j
].FrontInstance
!= -1)
595 CVectorD
&astart
= inst
.Reconstructed
[j
].Start
,
596 &aend
= inst
.Reconstructed
[j
].End
;
598 const NLPACS::CRetrieverInstance
&ninstance
= instances
[neighb
.Instance
];
599 const NLPACS::CLocalRetriever
&nretriever
= retrievers
[ninstance
.getRetrieverId()];
601 for (k
=0; k
<neighb
.Reconstructed
.size(); ++k
)
603 if (neighb
.Reconstructed
[k
].FrontInstance
!= -1)
606 CVectorD
&bstart
= neighb
.Reconstructed
[j
].Start
,
607 &bend
= neighb
.Reconstructed
[j
].End
;
609 if ((astart
-bend
).norm() < 0.1 && (aend
-bstart
).norm() < 0.1)
611 // ok, found missing match !
612 inst
.Reconstructed
[j
].FrontInstance
= neighb
.Instance
;
613 inst
.Reconstructed
[j
].FrontChain
= k
;
614 neighb
.Reconstructed
[k
].FrontInstance
= inst
.Instance
;
615 neighb
.Reconstructed
[k
].FrontChain
= j
;
620 CVector ori
= instance
.getOrigin(),
621 orn
= ninstance
.getOrigin();
623 fci
.Instance
= inst
.Instance
;
624 fcn
.Instance
= neighb
.Instance
;
627 for (l
=0; l
<inst
.Reconstructed
[j
].Chains
.size(); ++l
)
629 uint chain
= inst
.Chains
[inst
.Reconstructed
[j
].Chains
[l
]].Chain
;
630 NLPACS::CLocalRetriever::CIterator
it(&retriever
, chain
);
635 cr
.From
= (uint
)fci
.Vertices
.size();
636 cr
.BorderId
= NLPACS::CChain::convertBorderChainId(retriever
.getChain(chain
).getRight());
640 fci
.Vertices
.push_back(it
.get3d()+ori
);
644 cr
.To
= (uint
)fci
.Vertices
.size()-1;
646 if (l
< inst
.Reconstructed
[j
].Chains
.size()-1)
647 fci
.Vertices
.pop_back();
649 fci
.Chains
.push_back(cr
);
652 for (l
=0; l
<neighb
.Reconstructed
[k
].Chains
.size(); ++l
)
654 uint chain
= neighb
.Chains
[neighb
.Reconstructed
[k
].Chains
[l
]].Chain
;
655 NLPACS::CLocalRetriever::CIterator
it(&nretriever
, chain
);
660 cr
.From
= (uint
)fcn
.Vertices
.size();
661 cr
.BorderId
= NLPACS::CChain::convertBorderChainId(nretriever
.getChain(chain
).getRight());
665 fcn
.Vertices
.push_back(it
.get3d()+orn
);
669 cr
.To
= (uint
)fcn
.Vertices
.size()-1;
671 if (l
< neighb
.Reconstructed
[k
].Chains
.size()-1)
672 fcn
.Vertices
.pop_back();
674 fcn
.Chains
.push_back(cr
);
677 if (fcn
.Vertices
.size() != fci
.Vertices
.size())
679 nlwarning("Couldn't reconstruct link between %d and %d, mismatching number of vertices", inst
.Instance
, neighb
.Instance
);
683 for (l
=0; l
<fci
.Vertices
.size(); ++l
)
685 if ((fci
.Vertices
[l
] - fcn
.Vertices
[fci
.Vertices
.size()-1-l
]).norm() > 0.2f
)
687 nlwarning("Couldn't reconstruct link between %d and %d, some vertices don't match", inst
.Instance
, neighb
.Instance
);
691 fci
.Vertices
[l
] -= ori
;
692 fcn
.Vertices
[fci
.Vertices
.size()-1-l
] -= orn
;
695 if (l
<fci
.Vertices
.size())
698 uint newChaini
= (uint
)retriever
.getChains().size(),
699 newChainn
= (uint
)nretriever
.getChains().size();
701 // save free border ids in order to renumerate them after splits
702 vector
<uint
> ifreeBorderIds
, nfreeBorderIds
;
703 uint inextBorderId
, nnextBorderId
;
705 for (l
=0; l
<fci
.Chains
.size(); ++l
)
706 ifreeBorderIds
.push_back(fci
.Chains
[l
].BorderId
);
707 inextBorderId
= (uint
)retriever
.getBorderChains().size();
709 for (l
=0; l
<fcn
.Chains
.size(); ++l
)
710 nfreeBorderIds
.push_back(fcn
.Chains
[l
].BorderId
);
711 nnextBorderId
= (uint
)nretriever
.getBorderChains().size();
713 // generate splits from first chain on second chain
714 for (l
=0; l
<fci
.Chains
.size()-1; ++l
)
716 uint splitAt
= (uint
)fci
.Vertices
.size()-1 - fci
.Chains
[l
].To
;
718 for (m
=(uint
)fcn
.Chains
.size()-1; (sint
)m
>=0 && fcn
.Chains
[m
].From
>splitAt
; --m
)
722 if ((sint
)m
< 0 || fcn
.Chains
[m
].From
== splitAt
)
725 // insert split in second chain
726 fcn
.Chains
.insert(fcn
.Chains
.begin()+m
+1, fcn
.Chains
[m
]);
727 fcn
.Chains
[m
].To
= splitAt
;
728 fcn
.Chains
[m
+1].From
= splitAt
;
729 fcn
.Chains
[m
+1].Chain
= newChainn
++;
732 // generate splits from second chain on first chain
733 for (l
=0; l
<fcn
.Chains
.size()-1; ++l
)
735 uint splitAt
= (uint
)fcn
.Vertices
.size()-1 - fcn
.Chains
[l
].To
;
737 for (m
=(uint
)fci
.Chains
.size()-1; (sint
)m
>=0 && fci
.Chains
[m
].From
>splitAt
; --m
)
741 if ((sint
)m
< 0 || fci
.Chains
[m
].From
== splitAt
)
744 // insert split in first chain
745 fci
.Chains
.insert(fci
.Chains
.begin()+m
+1, fci
.Chains
[m
]);
746 fci
.Chains
[m
].To
= splitAt
;
747 fci
.Chains
[m
+1].From
= splitAt
;
748 fci
.Chains
[m
+1].Chain
= newChaini
++;
751 if (fci
.Chains
.size() != fcn
.Chains
.size())
753 nlwarning("Couldn't reconstruct link between %d and %d, chain splitting failed", inst
.Instance
, neighb
.Instance
);
757 // renumerate border ids after splits
758 for (l
=0; l
<fci
.Chains
.size(); ++l
)
760 if (!ifreeBorderIds
.empty())
762 fci
.Chains
[l
].BorderId
= ifreeBorderIds
.back();
763 ifreeBorderIds
.pop_back();
767 fci
.Chains
[l
].BorderId
= inextBorderId
++;
770 (const_cast<NLPACS::CLocalRetriever
&>(retriever
)).forceBorderChainId(fci
.Chains
[l
].Chain
, fci
.Chains
[l
].BorderId
);
773 for (l
=0; l
<fcn
.Chains
.size(); ++l
)
775 if (!nfreeBorderIds
.empty())
777 fcn
.Chains
[l
].BorderId
= nfreeBorderIds
.back();
778 nfreeBorderIds
.pop_back();
782 fcn
.Chains
[l
].BorderId
= nnextBorderId
++;
785 (const_cast<NLPACS::CLocalRetriever
&>(nretriever
)).forceBorderChainId(fcn
.Chains
[l
].Chain
, fcn
.Chains
[l
].BorderId
);
788 // insert/replace new chains in instances
790 vector
<NLPACS::CLocalRetriever::CChainReplacement
> replacement
;
794 while (l
<fci
.Chains
.size())
801 for (; l
<fci
.Chains
.size(); ++l
)
803 if (previous
!= -1 && previous
!= (sint
)fci
.Chains
[l
].Previous
)
806 previous
= fci
.Chains
[l
].Previous
;
808 NLPACS::CLocalRetriever::CChainReplacement cr
;
810 cr
.Chain
= fci
.Chains
[l
].Chain
;
811 cr
.Left
= retriever
.getChain(previous
).getLeft();
812 cr
.Right
= NLPACS::CChain::convertBorderChainId(fci
.Chains
[l
].BorderId
);
814 cr
.Vertices
.insert(cr
.Vertices
.begin(),
815 fci
.Vertices
.begin()+fci
.Chains
[l
].From
,
816 fci
.Vertices
.begin()+fci
.Chains
[l
].To
+1);
818 replacement
.push_back(cr
);
819 newIds
.push_back(fci
.Chains
[l
].BorderId
);
822 if (replacement
.size() >= 2)
824 (const_cast<NLPACS::CLocalRetriever
&>(retriever
)).replaceChain(previous
, replacement
);
825 (const_cast<NLPACS::CRetrieverInstance
&>(instance
)).resetBorderChainLinks(newIds
);
830 while (l
<fcn
.Chains
.size())
837 for (; l
<fcn
.Chains
.size(); ++l
)
839 if (previous
!= -1 && previous
!= (sint
)fcn
.Chains
[l
].Previous
)
842 previous
= fcn
.Chains
[l
].Previous
;
844 NLPACS::CLocalRetriever::CChainReplacement cr
;
846 cr
.Chain
= fcn
.Chains
[l
].Chain
;
847 cr
.Left
= nretriever
.getChain(previous
).getLeft();
848 cr
.Right
= NLPACS::CChain::convertBorderChainId(fcn
.Chains
[l
].BorderId
);
850 cr
.Vertices
.insert(cr
.Vertices
.begin(),
851 fcn
.Vertices
.begin()+fcn
.Chains
[l
].From
,
852 fcn
.Vertices
.begin()+fcn
.Chains
[l
].To
+1);
854 replacement
.push_back(cr
);
855 newIds
.push_back(fcn
.Chains
[l
].BorderId
);
858 if (replacement
.size() >= 2)
860 (const_cast<NLPACS::CLocalRetriever
&>(nretriever
)).replaceChain(previous
, replacement
);
861 (const_cast<NLPACS::CRetrieverInstance
&>(ninstance
)).resetBorderChainLinks(newIds
);
865 // force links between instances (border chain links)
866 for (l
=0; l
<fci
.Chains
.size(); ++l
)
868 m
= (uint
)fci
.Chains
.size()-1-l
;
869 (const_cast<NLPACS::CRetrieverInstance
&>(instance
)).forceBorderChainLink(fci
.Chains
[l
].BorderId
,
871 fcn
.Chains
[m
].BorderId
,
873 nretriever
.getChain(fcn
.Chains
[m
].Chain
).getLeft());
874 (const_cast<NLPACS::CRetrieverInstance
&>(ninstance
)).forceBorderChainLink(fcn
.Chains
[m
].BorderId
,
876 fci
.Chains
[l
].BorderId
,
878 retriever
.getChain(fci
.Chains
[l
].Chain
).getLeft());
881 nlinfo("Fixed: link between %d/%d and %d/%d => %d/%d - %d/%d", fci
.Instance
, fci
.Chains
[l
].Previous
, fcn
.Instance
, fcn
.Chains
[m
].Previous
, fci
.Instance
, fci
.Chains
[l
].Chain
, fcn
.Instance
, fcn
.Chains
[m
].Chain
);
890 (const_cast<NLPACS::CLocalRetriever
&>(retriever
)).computeCollisionChainQuad();
895 void processGlobalRetriever()
897 NLPACS::CRetrieverBank retrieverBank
;
898 NLPACS::CGlobalRetriever globalRetriever
;
900 uint ULid
= getZoneIdByName(GlobalUL
),
901 DRid
= getZoneIdByName(GlobalDR
);
903 CAABBox ULbbox
= getZoneBBoxById(ULid
);
904 CAABBox DRbbox
= getZoneBBoxById(DRid
);
909 vmin
.minof(ULbbox
.getMin(), DRbbox
.getMin());
910 vmax
.maxof(ULbbox
.getMax(), DRbbox
.getMax());
911 bbox
.setMinMax(vmin
, vmax
);
918 globalRetriever
.setRetrieverBank(&retrieverBank
);
919 globalRetriever
.init();
924 nlinfo("make all instances");
926 for (y
=y0
; y
<=y1
; ++y
)
928 for (x
=x0
; x
<=x1
; ++x
)
932 string filename
= OutputPath
+getZoneNameById(x
+y
*256)+".lr";
933 if (CFile::fileExists (filename
))
935 uint retrieverId
= retrieverBank
.addRetriever(filename
);
936 globalRetriever
.makeInstance(retrieverId
, 0, getZoneCenterById((uint16
)getIdByCoord(x
, y
)));
939 catch (const Exception
&e
)
941 printf("%s\n", e
.what ());
947 nlinfo("make all links");
948 globalRetriever
.makeAllLinks();
951 // nlinfo("clean retriever bank up");
952 // retrieverBank.clean();
954 map
<uint
, CFaultyInstance
> faultyInstances
;
956 const vector
<NLPACS::CRetrieverInstance
> &instances
= globalRetriever
.getInstances();
957 const vector
<NLPACS::CLocalRetriever
> &retrievers
= retrieverBank
.getRetrievers();
959 uint totalUnlinked
= 0, totalLink
= 0;
960 for (i
=0; i
<instances
.size(); ++i
)
962 const vector
<NLPACS::CRetrieverInstance::CLink
> &links
= instances
[i
].getBorderChainLinks();
963 CVector pos
= instances
[i
].getBBox().getCenter();
964 string unlinkstr
= "instance "+toString(i
)+":"+getZoneNameById(getZoneIdByPos(pos
))+":";
965 bool unlinkerr
= false;
967 const NLPACS::CLocalRetriever
&retriever
= retrievers
[instances
[i
].getRetrieverId()];
972 for (j
=0; j
<links
.size(); ++j
)
975 if (links
[j
].Instance
== 0xffff)
977 unlinkstr
+= (string(" ")+toString(j
));
983 fc
.Chain
= retriever
.getBorderChain(j
);
984 fc
.Start
= retriever
.getStartVector(fc
.Chain
) + instances
[i
].getOrigin();
985 fc
.End
= retriever
.getStopVector(fc
.Chain
) + instances
[i
].getOrigin();
986 fc
.PreviousChain
= -1;
989 fi
.Chains
.push_back(fc
);
995 nlinfo("unlink: %s", unlinkstr
.c_str());
996 faultyInstances
.insert(std::pair
<uint
, CFaultyInstance
>(i
, fi
));
1001 nlinfo("%d are still unlinked (%d links total)", totalUnlinked
, totalLink
);
1003 // rebuild full chains
1004 if (totalUnlinked
> 0)
1007 nlinfo("Fixing faulty links...");
1008 fixFaultyLinks(faultyInstances
, instances
, retrievers
);
1012 const vector
<NLPACS::CRetrieverInstance
> &instances
= globalRetriever
.getInstances();
1013 const vector
<NLPACS::CLocalRetriever
> &retrievers
= retrieverBank
.getRetrievers();
1015 uint totalUnlinked
= 0, totalLink
= 0;
1016 for (i
=0; i
<instances
.size(); ++i
)
1018 const vector
<NLPACS::CRetrieverInstance::CLink
> &links
= instances
[i
].getBorderChainLinks();
1019 CVector pos
= instances
[i
].getBBox().getCenter();
1020 string unlinkstr
= "instance "+toString(i
)+":"+getZoneNameById(getZoneIdByPos(pos
))+":";
1021 bool unlinkerr
= false;
1023 const NLPACS::CLocalRetriever
&retriever
= retrievers
[instances
[i
].getRetrieverId()];
1028 for (j
=0; j
<links
.size(); ++j
)
1031 if (links
[j
].Instance
== 0xffff)
1033 unlinkstr
+= (string(" ")+toString(j
));
1039 fc
.Chain
= retriever
.getBorderChain(j
);
1040 fc
.Start
= retriever
.getStartVector(fc
.Chain
) + instances
[i
].getOrigin();
1041 fc
.End
= retriever
.getStopVector(fc
.Chain
) + instances
[i
].getOrigin();
1042 fc
.PreviousChain
= -1;
1045 fi
.Chains
.push_back(fc
);
1051 nlinfo("after fix: unlink: %s", unlinkstr
.c_str());
1052 faultyInstances
.insert(std::pair
<uint
, CFaultyInstance
>(i
, fi
));
1058 nlinfo("init the quad grid");
1059 globalRetriever
.initQuadGrid();
1063 COFile outputRetriever
;
1064 filename
= OutputPath
+GlobalRetriever
;
1066 nlinfo("save file %s", filename
.c_str());
1067 outputRetriever
.open(filename
);
1068 globalRetriever
.serial(outputRetriever
);
1071 filename
= OutputPath
+RetrieverBank
;
1073 nlinfo("save file %s", filename
.c_str());
1074 outputBank
.open(filename
);
1075 retrieverBank
.serial(outputBank
);
1077 retrieverBank
.saveRetrievers(OutputPath
, CFile::getFilenameWithoutExtension(RetrieverBank
));
1082 void updateRetrieverBank()
1084 NLPACS::CRetrieverBank retrieverBank
;
1087 filename
= OutputPath
+RetrieverBank
;
1091 nlinfo("load file %s", filename
.c_str());
1092 inputBank
.open(filename
);
1093 retrieverBank
.serial(inputBank
);
1098 nlinfo("save file %s", filename
.c_str());
1099 outputBank
.open(filename
);
1100 retrieverBank
.serial(outputBank
);