static bool IsFULLObjectVertexInValidPosition(PHYSICS_BOX_DATA * pbox, EERIEPOLY *& collisionPoly) { float rad = pbox->radius; // TODO copy-paste background tiles int tilex = int(pbox->vert[0].pos.x * ACTIVEBKG->Xmul); int tilez = int(pbox->vert[0].pos.z * ACTIVEBKG->Zmul); int radius = std::min(1, short(rad * (1.0f/100)) + 1); int minx = std::max(tilex - radius, 0); int maxx = std::min(tilex + radius, ACTIVEBKG->Xsize - 1); int minz = std::max(tilez - radius, 0); int maxz = std::min(tilez + radius, ACTIVEBKG->Zsize - 1); for(int z = minz; z <= maxz; z++) for(int x = minx; x <= maxx; x++) { EERIE_BKG_INFO & eg = ACTIVEBKG->fastdata[x][z]; for(long k = 0; k < eg.nbpoly; k++) { EERIEPOLY & ep = eg.polydata[k]; if(ep.area > 190.f && !(ep.type & POLY_WATER) && !(ep.type & POLY_TRANS) && !(ep.type & POLY_NOCOL) ) { if(fartherThan(ep.center, pbox->vert[0].pos, rad + 75.f)) continue; for(long kk = 0; kk < pbox->nb_physvert; kk++) { float radd = 4.f; if(!fartherThan(pbox->vert[kk].pos, ep.center, radd) || !fartherThan(pbox->vert[kk].pos, ep.v[0].p, radd) || !fartherThan(pbox->vert[kk].pos, ep.v[1].p, radd) || !fartherThan(pbox->vert[kk].pos, ep.v[2].p, radd) || !fartherThan(pbox->vert[kk].pos, (ep.v[0].p + ep.v[1].p) * .5f, radd) || !fartherThan(pbox->vert[kk].pos, (ep.v[2].p + ep.v[1].p) * .5f, radd) || !fartherThan(pbox->vert[kk].pos, (ep.v[0].p + ep.v[2].p) * .5f, radd) ) { collisionPoly = &ep; return false; } // Last addon for(long kl = 1; kl < pbox->nb_physvert; kl++) { if(kl != kk) { Vec3f pos = (pbox->vert[kk].pos + pbox->vert[kl].pos) * .5f; if(!fartherThan(pos, ep.center, radd) || !fartherThan(pos, ep.v[0].p, radd) || !fartherThan(pos, ep.v[1].p, radd) || !fartherThan(pos, ep.v[2].p, radd) || !fartherThan(pos, (ep.v[0].p + ep.v[1].p) * .5f, radd) || !fartherThan(pos, (ep.v[2].p + ep.v[1].p) * .5f, radd) || !fartherThan(pos, (ep.v[0].p + ep.v[2].p) * .5f, radd) ) { collisionPoly = &ep; return false; } } } } if(IsObjectVertexCollidingPoly(pbox, ep)) { collisionPoly = &ep; return false; } } } } return true; }
BOOL IsFULLObjectVertexInValidPosition(EERIE_3DOBJ * obj, long flags, long source, long * validd) { BOOL ret = TRUE; long px, pz; float x = obj->pbox->vert[0].pos.x; F2L(x * ACTIVEBKG->Xmul, &px); float z = obj->pbox->vert[0].pos.z; F2L(z * ACTIVEBKG->Zmul, &pz); long ix, iz, ax, az; long n; F2L(obj->pbox->radius * DIV100, &n); n = __min(2, n + 1); ix = __max(px - n, 0); ax = __min(px + n, ACTIVEBKG->Xsize - 1); iz = __max(pz - n, 0); az = __min(pz + n, ACTIVEBKG->Zsize - 1); LAST_COLLISION_POLY = NULL; EERIEPOLY * ep; EERIE_BKG_INFO * eg; for (pz = iz; pz <= az; pz++) for (px = ix; px <= ax; px++) { eg = &ACTIVEBKG->Backg[px+pz*ACTIVEBKG->Xsize]; for (long k = 0; k < eg->nbpoly; k++) { ep = &eg->polydata[k]; if ( (ep->area > 190.f) && (!(ep->type & (POLY_WATER))) && (!(ep->type & (POLY_TRANS))) && (!(ep->type & (POLY_NOCOL))) ) { if ((EEDistance3D(&ep->center, &obj->pbox->vert[0].pos) > obj->pbox->radius + 75.f) && (EEDistance3D((EERIE_3D *)&ep->v[0], &obj->pbox->vert[0].pos) > obj->pbox->radius + 55.f) && (EEDistance3D((EERIE_3D *)&ep->v[1], &obj->pbox->vert[0].pos) > obj->pbox->radius + 55.f) && (EEDistance3D((EERIE_3D *)&ep->v[2], &obj->pbox->vert[0].pos) > obj->pbox->radius + 55.f)) continue; if (IsObjectVertexCollidingPoly(obj, ep, -1, NULL)) { LAST_COLLISION_POLY = ep; if (ep->type & POLY_METAL) CUR_COLLISION_MATERIAL = MATERIAL_METAL; else if (ep->type & POLY_WOOD) CUR_COLLISION_MATERIAL = MATERIAL_WOOD; else if (ep->type & POLY_STONE) CUR_COLLISION_MATERIAL = MATERIAL_STONE; else if (ep->type & POLY_GRAVEL) CUR_COLLISION_MATERIAL = MATERIAL_GRAVEL; else if (ep->type & POLY_WATER) CUR_COLLISION_MATERIAL = MATERIAL_WATER; else if (ep->type & POLY_EARTH) CUR_COLLISION_MATERIAL = MATERIAL_EARTH; else CUR_COLLISION_MATERIAL = MATERIAL_STONE; ret = FALSE; return FALSE; } } } } return ret; }