void Footholdtree::limitmoves(PhysicsObject& phobj) const { if (phobj.hmobile()) { double crntx = phobj.crntx(); double nextx = phobj.nextx(); bool left = phobj.hspeed < 0.0f; double wall = getwall(phobj.fhid, left, phobj.nexty()); bool collision = left ? crntx >= wall && nextx <= wall : crntx <= wall && nextx >= wall; if (!collision && phobj.flagset(PhysicsObject::TURNATEDGES)) { wall = getedge(phobj.fhid, left); collision = left ? crntx >= wall && nextx <= wall : crntx <= wall && nextx >= wall; } if (collision) { phobj.limitx(wall); phobj.clearflag(PhysicsObject::TURNATEDGES); } } if (phobj.vmobile()) { double crnty = phobj.crnty(); double nexty = phobj.nexty(); auto ground = Range<double>( getfh(phobj.fhid).resolvex(phobj.crntx()), getfh(phobj.fhid).resolvex(phobj.nextx()) ); bool collision = crnty <= ground.first() && nexty >= ground.second(); if (collision) { phobj.limity(ground.second()); limitmoves(phobj); } else { if (nexty < borders.first()) { phobj.limity(borders.first()); } else if (nexty > borders.second()) { phobj.limity(borders.second()); } } } }
void Footholdtree::updatefh(PhysicsObject& phobj) const { const Foothold& curfh = getfh(phobj.fhid); bool checkslope = false; double x = phobj.crntx(); double y = phobj.crnty(); if (phobj.onground) { if (std::floor(x) > curfh.getr()) { phobj.fhid = curfh.getnext(); } else if (std::ceil(x) < curfh.getl()) { phobj.fhid = curfh.getprev(); } if (phobj.fhid == 0) { phobj.fhid = getbelow(x, y); } else { checkslope = true; } } else { phobj.fhid = getbelow(x, y); } const Foothold& nextfh = getfh(phobj.fhid); phobj.fhslope = nextfh.getslope(); double ground = nextfh.resolvex(x); if (phobj.vspeed == 0.0 && checkslope) { double vdelta = abs(phobj.fhslope); if (phobj.fhslope < 0.0) { vdelta *= (ground - y); } else if (phobj.fhslope > 0.0) { vdelta *= (y - ground); } if (curfh.getslope() != 0.0 || nextfh.getslope() != 0.0) { if (phobj.hspeed > 0.0 && vdelta <= phobj.hspeed) { phobj.y = ground; } else if (phobj.hspeed < 0.0 && vdelta >= phobj.hspeed) { phobj.y = ground; } } } phobj.onground = phobj.y == ground; uint16_t belowid = getbelow(x, nextfh.resolvex(x) + 1.0); if (belowid > 0) { double nextground = getfh(belowid).resolvex(x); phobj.enablejd = (nextground - ground) < 600.0; phobj.groundbelow = ground + 1.0; } else { phobj.enablejd = false; } if (phobj.fhlayer == 0 || phobj.onground) { phobj.fhlayer = nextfh.getlayer(); } }