11using namespace Tempest;
16 wayPoints.resize(dat.points.size());
17 for(
size_t i=0; i<wayPoints.size(); ++i){
18 wayPoints[i] =
WayPoint(*dat.points[i]);
21 edges.resize(dat.edges.size());
22 for(
size_t i=0; i<edges.size(); ++i){
24 e.a = size_t(std::distance(dat.points.begin(), std::find(dat.points.begin(), dat.points.end(), dat.edges[i].first )));
25 e.b = size_t(std::distance(dat.points.begin(), std::find(dat.points.begin(), dat.points.end(), dat.edges[i].second)));
35 adjustWaypoints(wayPoints);
36 adjustWaypoints(freePoints);
37 adjustWaypoints(startPoints);
38 std::sort(indexPoints.begin(),indexPoints.end(),[](
const WayPoint* a,
const WayPoint* b){
39 return a->name<b->name;
42 for(
auto& i:freePoints)
46 return a->pos.x < b->pos.x;
50 if(i.a<wayPoints.size() && i.b<wayPoints.size()) {
51 auto& a = wayPoints[i.a];
52 auto& b = wayPoints[i.b];
59 calculateLadderPoints();
64 float dist=std::numeric_limits<float>::max();
65 for(
auto& w:wayPoints) {
68 auto dp0 = at-w.position();
69 float l0 = dp0.quadLength();
80 auto& index = findFpIndex(name);
86 float dist = distanceThreshold;
89 for(
auto pw:indexPoints){
91 auto dp = w.position()-at;
92 float l = dp.quadLength();
94 if(l<dist && !w.isLocked()) {
103 freePoints.emplace_back(pos,dir,name,
true);
107 startPoints.emplace_back(pos,dir,name,
true);
111 if(startPoints.size()>0)
112 return startPoints[0];
114 for(
auto& i:freePoints)
115 if(i.name==
"START_GOTHIC2")
118 for(
auto& i:freePoints)
127 for(
auto& i:indexPoints)
130 static WayPoint p(Vec3(-1000,-1000,-1000),
"TOT");
135 auto it = std::lower_bound(indexPoints.begin(),indexPoints.end(),name,[](
const WayPoint* a, std::string_view b){
138 if(it!=indexPoints.end() && !(*it)->isFreePoint() && name==(*it)->name)
146 for(
size_t i=0; i<startPoints.size(); ++i) {
147 auto& sp = startPoints[startPoints.size()-1-i];
151 auto it = std::lower_bound(indexPoints.begin(),indexPoints.end(),name,[](
const WayPoint* a, std::string_view b){
154 if(it!=indexPoints.end() && name==(*it)->name)
158 for(
auto i:indexPoints)
159 if(i->checkName(name))
165 static bool ddraw=
false;
168 static bool fp =
true;
169 static bool sp =
false;
170 auto *ppoints = &wayPoints;
172 ppoints = &freePoints;
174 ppoints = &startPoints;
176 auto &points = *ppoints;
178 for(
auto& i:points) {
179 float x = i.pos.x, y = i.pos.y, z = i.pos.z;
180 p.
mvp.project(x,y,z);
184 x = (0.5f*x+0.5f)*
float(p.
w);
185 y = (0.5f*y+0.5f)*
float(p.
h);
187 p.
setBrush(Tempest::Color(1,0,0,1));
188 p.
painter.drawRect(
int(x),int(y),4,4);
190 p.
drawText(
int(x),int(y),(i.name+
" #"+std::to_string(
id)).c_str());
195void WayMatrix::adjustWaypoints(std::vector<WayPoint> &wp) {
202 indexPoints.push_back(&w);
206void WayMatrix::calculateLadderPoints() {
207 static const float dist = 100.f;
208 for(uint32_t i=0;;++i) {
212 if(!inter->isLadder())
214 auto box = inter->
bBox();
216 if(e.a>=wayPoints.size() || e.b>=wayPoints.size() || e.a==e.b)
218 auto& a = wayPoints[e.a], b = wayPoints[e.b];
219 Vec3 posA = a.position(), posB = b.position();
220 Vec3 dTopA = box[1] - posA;
221 Vec3 dBotA = box[0] - posA;
222 Vec3 dBA = posB - posA;
224 std::swap(dTopA.x,dBotA.x);
226 std::swap(dTopA.y,dBotA.y);
228 std::swap(dTopA.z,dBotA.z);
229 float max = std::min({dTopA.x/dBA.x,dTopA.y/dBA.y,dTopA.z/dBA.z});
230 float min = std::max({dBotA.x/dBA.x,dBotA.y/dBA.y,dBotA.z/dBA.z});
231 if(max<min || max<0.f || min>1.f)
233 float dy = 0.5f * std::abs(box[0].y+box[1].y-posA.y-posB.y);
235 wayPoints[e.a].ladder = inter;
236 wayPoints[e.b].ladder = inter;
243const WayMatrix::FpIndex &WayMatrix::findFpIndex(std::string_view name)
const {
244 auto it = std::lower_bound(fpIndex.begin(),fpIndex.end(),name,[](FpIndex& l, std::string_view r){
247 if(it!=fpIndex.end() && it->key==name){
253 for(
auto& w:freePoints){
254 if(!w.checkName(name))
256 id.index.push_back(&w);
259 std::sort(
id.index.begin(),
id.index.end(),[](
const WayPoint* a,
const WayPoint* b){
260 return a->pos.x < b->pos.x;
263 it = fpIndex.insert(it,std::move(
id));
268 const std::function<
bool(
const WayPoint&)>& filter)
const {
269 float R = distanceThreshold;
270 auto b = std::lower_bound(ind.index.begin(),ind.index.end(), x-R ,[](
const WayPoint *a,
float b){
273 auto e = std::upper_bound(ind.index.begin(),ind.index.end(), x+R ,[](
float a,
const WayPoint *b){
278 auto count = std::distance(b,e);(void) count;
280 for(
auto i=b;i!=e;++i){
284 float dx = w.pos.x-x;
285 float dy = w.pos.y-y;
286 float dz = w.pos.z-z;
287 float l = dx*dx+dy*dy+dz*dz;
302 intptr_t endId = std::distance<const WayPoint*>(&wayPoints[0],&end);
303 if(endId<0 ||
size_t(endId)>=wayPoints.size()){
316 for(
auto& i:wayPoints)
320 std::vector<const WayPoint*> *front=&stk[0], *back=&stk[1];
326 front->push_back(&end);
328 while(front->size()>0) {
330 for(
size_t i=0; i<beginSz; ++i)
331 if(begin[i]->pathGen!=pathGen) {
338 for(
auto& wp:*front) {
339 int32_t l0 = wp->pathLen;
341 for(
auto i:wp->connections()){
343 int32_t l1 = l0+i.len;
344 if(w.pathGen!=pathGen || w.pathLen>l1){
351 std::swap(front,back);
356 for(
size_t i=0; i<beginSz; ++i) {
357 int32_t iLen = begin[i]->
pathLen + int((exactBegin - begin[i]->position()).length());
358 int32_t fLen = first ->
pathLen + int((exactBegin - first ->position()).length());
366 while(current!=&end) {
367 int32_t l0 = current->
pathLen, l1=l0;
371 if(i.point->pathGen==pathGen && i.point->pathLen+i.len<=l0 && i.point->pathLen<l1){
void setBrush(const Tempest::Brush &brush)
void drawText(int x, int y, std::string_view txt)
Tempest::Painter & painter
const Tempest::Matrix4x4 mvp
RayLandResult landRay(const Tempest::Vec3 &from, float maxDy=0) const
auto bBox() const -> const Tempest::Vec3 *
const WayPoint * findNextPoint(const Tempest::Vec3 &at) const
const WayPoint & startPoint() const
void addFreePoint(const Tempest::Vec3 &pos, const Tempest::Vec3 &dir, std::string_view name)
const WayPoint * findFreePoint(const Tempest::Vec3 &at, std::string_view name, const std::function< bool(const WayPoint &)> &filter) const
const WayPoint * findPoint(std::string_view name, bool inexact) const
void addStartPoint(const Tempest::Vec3 &pos, const Tempest::Vec3 &dir, std::string_view name)
const WayPoint * findWayPoint(const Tempest::Vec3 &at, const std::function< bool(const WayPoint &)> &filter) const
WayMatrix(World &owner, const zenkit::WayNet &dat)
const WayPoint & deadPoint() const
WayPath wayTo(const WayPoint **begin, size_t beginSz, const Tempest::Vec3 exactBegin, const WayPoint &end) const
void marchPoints(DbgPainter &p) const
void add(const WayPoint &p)
const std::vector< Conn > & connections() const
void connect(WayPoint &w)
DynamicWorld * physic() const
Interactive * mobsiById(uint32_t id)