Fix game:addSpawnShapesByZone
[ryzomcore.git] / nel / tools / pacs / build_rbank / build_rbank.cpp
blobcdcaa0e484fc54d145490daadd9885b083f9ac48
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2015 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
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"
49 #include <string>
50 #include <deque>
51 #include <map>
53 using namespace std;
54 using namespace NLMISC;
55 using namespace NL3D;
58 class CIGBox
60 public:
61 CIGBox() {}
62 CIGBox(const string &name, const CAABBox &bbox) : Name(name), BBox(bbox) {}
63 string Name;
64 CAABBox BBox;
65 void serial(NLMISC::IStream &f) { f.serial(Name, BBox); }
69 string getZoneNameById(uint16 id)
71 uint x = id%256;
72 uint y = id/256;
74 char ych[32];
75 sprintf(ych,"%d_%c%c", y+1, 'A'+x/26, 'A'+x%26);
76 return string(ych);
79 string getZoneNameByCoord(float x, float y)
81 const float zoneDim = 160.0f;
83 float xcount = x/zoneDim;
84 float ycount = -y/zoneDim + 1;
86 char ych[32];
87 sprintf(ych,"%d_%c%c",(sint)ycount, 'A'+(sint)xcount/26, 'A'+(sint)xcount%26);
88 return string(ych);
91 CVector getZoneCenterById(uint16 id)
93 CAABBox bbox;
94 uint x, y;
95 const float zdim = 160.0f;
97 x = id%256;
98 y = id/256;
100 return CVector(zdim*((float)x+0.5f), -zdim*((float)y+0.5f), 0.0f);
103 uint32 getIdByCoord(uint x, uint y)
105 return y*256+x;
108 string changeExt(string name, const string &ext)
110 string::iterator it, last;
111 last = name.end();
113 for (it=name.begin(); it!=name.end(); ++it)
114 if (*it == '.')
115 last = it;
117 name.erase(last, name.end());
118 name.append(".");
119 name.append(ext);
120 return name;
125 void processAllPasses(string &zoneName)
127 uint /*i,*/ j;
129 NLPACS::CZoneTessellation tessellation;
130 vector<NLPACS::COrderedChain3f> fullChains;
131 string name;
132 string filename;
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();
153 hs.z = 10000.0f;
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);
172 if (Verbose)
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());
187 else
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);
205 // and save it...
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;
215 if (Verbose)
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)
238 uint i, j;
240 NLPACS::CZoneTessellation tessellation;
241 vector<NLPACS::COrderedChain3f> fullChains;
242 string name;
243 string filename;
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);
265 else
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));
281 CInstanceGroup ig;
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())
294 CIFile f;
295 if (f.open (shapeNameLookup))
297 CShapeStream shape;
298 shape.serial(f);
300 CWaterShape *wshape = dynamic_cast<CWaterShape *>(shape.getShapePointer());
301 if (wshape == NULL)
302 continue;
304 CMatrix matrix;
305 ig.getInstanceMatrix(j, matrix);
307 CPolygon wpoly;
308 wshape->getShapeInWorldSpace(wpoly);
310 uint k;
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);
319 else
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();
340 hs.z = 10000.0f;
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());
369 else
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;
383 if (Verbose)
384 nlinfo("save file %s", filename.c_str());
385 outputRetriever.open(filename);
386 retriever.serial(outputRetriever);
388 // save raw chains
389 COFile outputChains;
390 name = changeExt(zoneName, string("ochain"));
391 filename = OutputPath+name;
392 if (Verbose)
393 nlinfo("save file %s", filename.c_str());
394 outputChains.open(filename);
395 outputChains.serialCont(fullChains);
398 catch(const Exception &e)
400 printf(e.what ());
407 void processRetriever(string &zoneName)
409 string name;
410 string filename;
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;
423 if (Verbose)
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);
447 // and save it...
449 COFile outputRetriever;
450 name = changeExt(zoneName, string("lr"));
451 filename = OutputPath+name;
452 if (Verbose)
453 nlinfo("save file %s", filename.c_str());
454 outputRetriever.open(filename);
455 retriever.serial(outputRetriever);
458 catch(const Exception &e)
460 printf(e.what ());
469 class CFaultyChain
471 public:
472 uint Chain;
473 CVectorD Start, End;
474 sint PreviousChain, NextChain;
477 class CReconstructed
479 public:
480 CReconstructed() : FrontInstance(-1), FrontChain(-1) {}
481 vector<uint> Chains;
482 CVectorD Start, End;
483 sint FrontInstance, FrontChain;
486 class CFaultyInstance
488 public:
489 uint Instance;
490 vector<CFaultyChain> Chains;
491 vector<CReconstructed> Reconstructed;
494 class CChainRef
496 public:
497 uint Chain, Previous;
498 uint FrontChain;
499 uint BorderId;
500 uint From, To;
503 class CFullChain
505 public:
506 uint Instance;
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;
517 uint i, j, k, l;
519 // first
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)
529 sint best = -1;
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))
534 continue;
536 CVectorD diff = inst.Chains[k].End - inst.Chains[l].Start;
537 double dist = diff.norm();
539 if (dist < 0.1 && dist < bestDist)
541 best = l;
542 bestDist = dist;
546 if (best != -1)
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)
558 l = k;
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;
571 // second
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())
586 continue;
588 CFaultyInstance &neighb = (*ifn).second;
590 for (j=0; j<inst.Reconstructed.size(); ++j)
592 if (inst.Reconstructed[j].FrontInstance != -1)
593 continue;
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)
604 continue;
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;
617 CFullChain fci, fcn;
618 uint m;
620 CVector ori = instance.getOrigin(),
621 orn = ninstance.getOrigin();
623 fci.Instance = inst.Instance;
624 fcn.Instance = neighb.Instance;
626 // build full chains
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);
632 CChainRef cr;
633 cr.Chain = chain;
634 cr.Previous = chain;
635 cr.From = (uint)fci.Vertices.size();
636 cr.BorderId = NLPACS::CChain::convertBorderChainId(retriever.getChain(chain).getRight());
638 while (!it.end())
640 fci.Vertices.push_back(it.get3d()+ori);
641 ++it;
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);
657 CChainRef cr;
658 cr.Chain = chain;
659 cr.Previous = chain;
660 cr.From = (uint)fcn.Vertices.size();
661 cr.BorderId = NLPACS::CChain::convertBorderChainId(nretriever.getChain(chain).getRight());
663 while (!it.end())
665 fcn.Vertices.push_back(it.get3d()+orn);
666 ++it;
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);
680 break;
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);
688 break;
691 fci.Vertices[l] -= ori;
692 fcn.Vertices[fci.Vertices.size()-1-l] -= orn;
695 if (l<fci.Vertices.size())
696 break;
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)
721 // no split ?
722 if ((sint)m < 0 || fcn.Chains[m].From == splitAt)
723 continue;
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)
740 // no split ?
741 if ((sint)m < 0 || fci.Chains[m].From == splitAt)
742 continue;
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);
754 break;
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();
765 else
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();
780 else
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;
791 vector<uint> newIds;
793 l=0;
794 while (l<fci.Chains.size())
796 sint previous=-1;
798 newIds.clear();
799 replacement.clear();
801 for (; l<fci.Chains.size(); ++l)
803 if (previous != -1 && previous != (sint)fci.Chains[l].Previous)
804 break;
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);
813 cr.Vertices.clear();
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);
829 l=0;
830 while (l<fcn.Chains.size())
832 sint previous=-1;
834 newIds.clear();
835 replacement.clear();
837 for (; l<fcn.Chains.size(); ++l)
839 if (previous != -1 && previous != (sint)fcn.Chains[l].Previous)
840 break;
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);
849 cr.Vertices.clear();
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,
870 neighb.Instance,
871 fcn.Chains[m].BorderId,
872 fcn.Chains[m].Chain,
873 nretriever.getChain(fcn.Chains[m].Chain).getLeft());
874 (const_cast<NLPACS::CRetrieverInstance&>(ninstance)).forceBorderChainLink(fcn.Chains[m].BorderId,
875 inst.Instance,
876 fci.Chains[l].BorderId,
877 fci.Chains[l].Chain,
878 retriever.getChain(fci.Chains[l].Chain).getLeft());
880 if (Verbose)
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);
884 break;
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);
905 CAABBox bbox;
907 CVector vmin, vmax;
909 vmin.minof(ULbbox.getMin(), DRbbox.getMin());
910 vmax.maxof(ULbbox.getMax(), DRbbox.getMax());
911 bbox.setMinMax(vmin, vmax);
913 uint x0 = ULid%256,
914 y0 = ULid/256,
915 x1 = DRid%256,
916 y1 = DRid/256;
918 globalRetriever.setRetrieverBank(&retrieverBank);
919 globalRetriever.init();
921 uint x, y;
923 if (Verbose)
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 ());
946 if (Verbose)
947 nlinfo("make all links");
948 globalRetriever.makeAllLinks();
950 // if (Verbose)
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();
958 uint i, j;
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()];
969 CFaultyInstance fi;
970 fi.Instance = i;
972 for (j=0; j<links.size(); ++j)
974 ++totalLink;
975 if (links[j].Instance == 0xffff)
977 unlinkstr += (string(" ")+toString(j));
978 ++totalUnlinked;
979 unlinkerr = true;
981 CFaultyChain fc;
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;
987 fc.NextChain = -1;
989 fi.Chains.push_back(fc);
992 if (unlinkerr)
994 if (Verbose)
995 nlinfo("unlink: %s", unlinkstr.c_str());
996 faultyInstances.insert(std::pair<uint, CFaultyInstance>(i, fi));
1000 if (Verbose)
1001 nlinfo("%d are still unlinked (%d links total)", totalUnlinked, totalLink);
1003 // rebuild full chains
1004 if (totalUnlinked > 0)
1006 if (Verbose)
1007 nlinfo("Fixing faulty links...");
1008 fixFaultyLinks(faultyInstances, instances, retrievers);
1010 // recheck
1012 const vector<NLPACS::CRetrieverInstance> &instances = globalRetriever.getInstances();
1013 const vector<NLPACS::CLocalRetriever> &retrievers = retrieverBank.getRetrievers();
1014 uint i, j;
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()];
1025 CFaultyInstance fi;
1026 fi.Instance = i;
1028 for (j=0; j<links.size(); ++j)
1030 ++totalLink;
1031 if (links[j].Instance == 0xffff)
1033 unlinkstr += (string(" ")+toString(j));
1034 ++totalUnlinked;
1035 unlinkerr = true;
1037 CFaultyChain fc;
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;
1043 fc.NextChain = -1;
1045 fi.Chains.push_back(fc);
1048 if (unlinkerr)
1050 if (Verbose)
1051 nlinfo("after fix: unlink: %s", unlinkstr.c_str());
1052 faultyInstances.insert(std::pair<uint, CFaultyInstance>(i, fi));
1057 if (Verbose)
1058 nlinfo("init the quad grid");
1059 globalRetriever.initQuadGrid();
1061 string filename;
1063 COFile outputRetriever;
1064 filename = OutputPath+GlobalRetriever;
1065 if (Verbose)
1066 nlinfo("save file %s", filename.c_str());
1067 outputRetriever.open(filename);
1068 globalRetriever.serial(outputRetriever);
1070 COFile outputBank;
1071 filename = OutputPath+RetrieverBank;
1072 if (Verbose)
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;
1086 string filename;
1087 filename = OutputPath+RetrieverBank;
1089 CIFile inputBank;
1090 if (Verbose)
1091 nlinfo("load file %s", filename.c_str());
1092 inputBank.open(filename);
1093 retrieverBank.serial(inputBank);
1094 inputBank.close();
1096 COFile outputBank;
1097 if (Verbose)
1098 nlinfo("save file %s", filename.c_str());
1099 outputBank.open(filename);
1100 retrieverBank.serial(outputBank);
1101 outputBank.close();