MCPcopy Create free account
hub / github.com/assaultcube/AC / intersectgeometry

Function intersectgeometry

source/src/weapon.cpp:435–569  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

433}
434
435void intersectgeometry(const vec &from, vec &to) // check line for contact with map geometry, shorten if necessary
436{
437 int x = from.x, y = from.y, hfnb[4] = { 0, 1, ssize, ssize +1 };
438 if(OUTBORD(x, y) || from.z < -127.0f || from.z > 127.0f) return;
439 vec d = to; // d: direction
440 d.sub(from);
441
442 float distmin = 1.0f, vdelta[4];
443 sqr *r[2], *s, *nb[4];
444 loop(xy, 2) // first check x == const planes and then y == const planes
445 {
446 float dxy = xy ? d.y : d.x, fromxy = xy ? from.y : from.x;
447 bool dxynz = fabs(dxy) < NEARZERO;
448 if(dxy == 0.0f) dxy = 1e-20; // hack
449
450 int ixy = fromxy, step = dxy < 0 ? -1 : 1, steps = fabs(dxy) + 1, sqrdir = xy ? -ssize : -1;
451 while(steps-- > 0)
452 {
453 // intersect d with plane
454 float t = dxynz ? distmin : (ixy - fromxy) / dxy;
455 vec p = d;
456 p.mul(t).add(from);
457
458 // check position
459 if(xy) x = p.x, y = ixy;
460 else x = ixy, y = p.y;
461 if(t > distmin || OUTBORD(x, y)) break;
462
463 // always check cubes on both sides of the plane
464 r[0] = S(x, y);
465 r[1] = r[0] + sqrdir;
466 if(t > 0) loopk(2)
467 {
468 s = r[k];
469 if(SOLID(s) || s->floor > p.z || s->ceil < p.z || s->type == CORNER)
470 { // cube s is a probable hit, examine further
471 if(k)
472 { // match x|y back to s
473 if(xy) y--;
474 else x--;
475 }
476
477 if(s->type == CORNER)
478 {
479 sqr *ns, *h = NULL, *n;
480 int bx, by, bs;
481 int q = cornertest(x, y, bx, by, bs, ns, h);
482 vec newto; float newdist;
483 if(intersectcorner(from, d, bx, by, bs, !(q & 1), &newto, &newdist) && newdist < distmin && (!h || newto.z < ns->floor || newto.z > ns->ceil)) to = newto, distmin = newdist;
484 if(d.z)
485 { // intersect with z == const plane where the corner ends
486 bool downwards = d.z < 0.0f;
487 n = h ? h : ns;
488 float endplate = downwards ? n->floor : n->ceil;
489 float tz = (endplate - from.z) / d.z;
490 vec pz = d;
491 pz.mul(tz).add(from);
492 if(pz.x >= bx && pz.x <= bx + bs && pz.y >= by && pz.y <= by + bs && tz < distmin) to = pz, distmin = tz;

Callers 2

readdepthFunction · 0.85
attackMethod · 0.85

Calls 8

cornertestFunction · 0.85
intersectcornerFunction · 0.85
intersecttriangleFunction · 0.85
mulMethod · 0.80
loopFunction · 0.70
loopkFunction · 0.70
loopiFunction · 0.70
addMethod · 0.45

Tested by

no test coverage detected