static bool AddAnchor_Original_Method(EERIE_BACKGROUND * eb, EERIE_BKG_INFO * eg, Vec3f * pos) { long found = 0; long best = 0; long stop_radius = 0; float best_dist = 99999999999.f; Cylinder testcyl; Cylinder currcyl; Cylinder bestcyl; bestcyl.height = 0; bestcyl.radius = 0; for (long rad = 0; rad < 20; rad += 10) for (long ang = 0; ang < 360; ang += 45) // 45 { float t = glm::radians((float)ang); // We set our current position depending on given position, radius & angle. currcyl.radius = 40; currcyl.height = -165; currcyl.origin.x = pos->x - std::sin(t) * (float)rad; currcyl.origin.y = pos->y; currcyl.origin.z = pos->z + std::cos(t) * (float)rad; stop_radius = 0; found = 0; long climb = 0; while ((stop_radius != 1)) { testcyl = currcyl; testcyl.radius += INC_RADIUS; if (ANCHOR_AttemptValidCylinderPos(testcyl, NULL, CFLAG_NO_INTERCOL | CFLAG_EXTRA_PRECISION | CFLAG_ANCHOR_GENERATION)) { currcyl = testcyl; found = 1; } else { if ((testcyl.origin.y != currcyl.origin.y) && (glm::abs(testcyl.origin.y - pos->y) < 50)) { testcyl.radius -= INC_RADIUS; currcyl = testcyl; climb++; } else stop_radius = 1; } if (climb > 4) stop_radius = 1; if (currcyl.radius >= 50.f) stop_radius = 1; } if (found) { float d = glm::distance(*pos, currcyl.origin); if (currcyl.radius >= bestcyl.radius) { if (((best_dist > d) && (currcyl.radius == bestcyl.radius)) || (currcyl.radius > bestcyl.radius)) { bestcyl = currcyl; best_dist = d; best = 1; } } } } if (!best) return false; if(CylinderAboveInvalidZone(bestcyl)) return false; // avoid to recreate same anchor twice... if (0) for (long k = 0; k < eb->nbanchors; k++) { ANCHOR_DATA * ad = &eb->anchors[k]; if ((ad->pos.x == bestcyl.origin.x) && (ad->pos.y == bestcyl.origin.y) && (ad->pos.z == bestcyl.origin.z)) { if (ad->radius >= bestcyl.radius) return false; if (ad->radius <= bestcyl.radius) { ad->height = bestcyl.height; ad->radius = bestcyl.radius; return false; } } } eg->ianchors = (long *)realloc(eg->ianchors, sizeof(long) * (eg->nbianchors + 1)); eg->ianchors[eg->nbianchors] = eb->nbanchors; eg->nbianchors++; eb->anchors = (ANCHOR_DATA *)realloc(eb->anchors, sizeof(ANCHOR_DATA) * (eb->nbanchors + 1)); ANCHOR_DATA * ad = &eb->anchors[eb->nbanchors]; ad->pos = bestcyl.origin; ad->height = bestcyl.height; ad->radius = bestcyl.radius; ad->linked = NULL; ad->nblinked = 0; ad->flags = 0; eb->nbanchors++; return true; }
static bool DirectAddAnchor_Original_Method(EERIE_BACKGROUND * eb, EERIE_BKG_INFO * eg, Vec3f * pos) { long found = 0; long stop_radius = 0; Cylinder testcyl; Cylinder currcyl; Cylinder bestcyl; bestcyl.height = 0; bestcyl.radius = 0; currcyl.radius = 40; currcyl.height = -165.f; currcyl.origin = *pos; stop_radius = 0; found = 0; long climb = 0; while (stop_radius != 1) { testcyl = currcyl; testcyl.radius += INC_RADIUS; if (ANCHOR_AttemptValidCylinderPos(testcyl, NULL, CFLAG_NO_INTERCOL | CFLAG_EXTRA_PRECISION | CFLAG_ANCHOR_GENERATION)) { currcyl = testcyl; found = 1; } else { if ((testcyl.origin.y != currcyl.origin.y) && (glm::abs(testcyl.origin.y - pos->y) < 50)) { testcyl.radius -= INC_RADIUS; currcyl = testcyl; climb++; } else stop_radius = 1; } if (climb > 4) stop_radius = 1; if (currcyl.radius >= 50.f) stop_radius = 1; } if(found && currcyl.radius >= bestcyl.radius) { bestcyl = currcyl; } else { return false; } if(CylinderAboveInvalidZone(bestcyl)) return false; for (long k = 0; k < eb->nbanchors; k++) { ANCHOR_DATA * ad = &eb->anchors[k]; if(closerThan(ad->pos, bestcyl.origin, 50.f)) { return false; } if(closerThan(Vec2f(ad->pos.x, ad->pos.z), Vec2f(bestcyl.origin.x, bestcyl.origin.z), 45.f)) { if (glm::abs(ad->pos.y - bestcyl.origin.y) < 90.f) return false; EERIEPOLY * ep = ANCHOR_CheckInPolyPrecis(ad->pos); EERIEPOLY * ep2 = ANCHOR_CheckInPolyPrecis(Vec3f(ad->pos.x, bestcyl.origin.y, ad->pos.z)); if (ep2 == ep) return false; } } eg->ianchors = (long *)realloc(eg->ianchors, sizeof(long) * (eg->nbianchors + 1)); eg->ianchors[eg->nbianchors] = eb->nbanchors; eg->nbianchors++; eb->anchors = (ANCHOR_DATA *)realloc(eb->anchors, sizeof(ANCHOR_DATA) * (eb->nbanchors + 1)); ANCHOR_DATA * ad = &eb->anchors[eb->nbanchors]; ad->pos = bestcyl.origin; ad->height = bestcyl.height; ad->radius = bestcyl.radius; ad->linked = NULL; ad->nblinked = 0; ad->flags = 0; eb->nbanchors++; return true; }
static bool ANCHOR_ARX_COLLISION_Move_Cylinder(IO_PHYSICS * ip, Entity * io, float MOVE_CYLINDER_STEP, CollisionFlags flags) { MOVING_CYLINDER = 1; DIRECT_PATH = true; IO_PHYSICS test; if(ip == NULL) { MOVING_CYLINDER = 0; return false; } float distance = glm::distance(ip->startpos, ip->targetpos); if(distance <= 0.f) { MOVING_CYLINDER = 0; return true; } Vec3f mvector = (ip->targetpos - ip->startpos) / distance; while(distance > 0.f) { // First We compute current increment float curmovedist = std::min(distance, MOVE_CYLINDER_STEP); distance -= curmovedist; //CUR_FRAME_SLICE=curmovedist*onedist; // Store our cylinder desc into a test struct test = *ip; // uses test struct to simulate movement. test.cyl.origin += mvector * curmovedist; vector2D.x = mvector.x * curmovedist; vector2D.y = 0.f; vector2D.z = mvector.z * curmovedist; if ((flags & CFLAG_CHECK_VALID_POS) && (CylinderAboveInvalidZone(test.cyl))) return false; if(ANCHOR_AttemptValidCylinderPos(test.cyl, io, flags)) { *ip = test; } else { if(flags & CFLAG_CLIMBING) { test.cyl = ip->cyl; test.cyl.origin.y += mvector.y * curmovedist; if(ANCHOR_AttemptValidCylinderPos(test.cyl, io, flags)) { *ip = test; goto oki; } } DIRECT_PATH = false; // Must Attempt To Slide along collisions Vec3f vecatt; Vec3f rpos = Vec3f_ZERO; Vec3f lpos = Vec3f_ZERO; long RFOUND = 0; long LFOUND = 0; long maxRANGLE = 90; float ANGLESTEPP; // player sliding in fact... if(flags & CFLAG_EASY_SLIDING) { ANGLESTEPP = 10.f; maxRANGLE = 70; } else { ANGLESTEPP = 30.f; } float rangle = ANGLESTEPP; float langle = 360.f - ANGLESTEPP; //tries on the Right and Left sides while(rangle <= maxRANGLE) { test.cyl = ip->cyl; float t = MAKEANGLE(rangle); vecatt = VRotateY(mvector, t); test.cyl.origin += vecatt * curmovedist; if(ANCHOR_AttemptValidCylinderPos(test.cyl, io, flags)) { rpos = test.cyl.origin; RFOUND = 1; } rangle += ANGLESTEPP; test.cyl = ip->cyl; t = MAKEANGLE(langle); vecatt = VRotateY(mvector, t); test.cyl.origin += vecatt * curmovedist; if(ANCHOR_AttemptValidCylinderPos(test.cyl, io, flags)) { lpos = test.cyl.origin; LFOUND = 1; } langle -= ANGLESTEPP; if(RFOUND || LFOUND) break; } if(LFOUND && RFOUND) { langle = 360.f - langle; if(langle < rangle) { ip->cyl.origin = lpos; distance -= curmovedist; } else { ip->cyl.origin = rpos; distance -= curmovedist; } } else if(LFOUND) { ip->cyl.origin = lpos; distance -= curmovedist; } else if(RFOUND) { ip->cyl.origin = rpos; distance -= curmovedist; } else { //stopped ip->velocity = Vec3f_ZERO; MOVING_CYLINDER = 0; return false; } } oki: ; } MOVING_CYLINDER = 0; return true; }
bool AddAnchor_Original_Method(EERIE_BACKGROUND * eb, EERIE_BKG_INFO * eg, EERIE_3D * pos, long flags) { long found = 0; long best = 0; long stop_radius = 0; float best_dist = 99999999999.f; float v_dist = 99999999999.f; EERIE_CYLINDER testcyl; EERIE_CYLINDER currcyl; EERIE_CYLINDER bestcyl; bestcyl.height = 0; bestcyl.radius = 0; for (long rad = 0; rad < 20; rad += 10) for (long ang = 0; ang < 360; ang += 45) // 45 { float t = DEG2RAD((float)ang); // We set our current position depending on given position, radius & angle. currcyl.radius = 40; currcyl.height = -165; currcyl.origin.x = pos->x - EEsin(t) * (float)rad; currcyl.origin.y = pos->y; currcyl.origin.z = pos->z + EEcos(t) * (float)rad; stop_radius = 0; found = 0; long climb = 0; while ((stop_radius != 1)) { memcpy(&testcyl, &currcyl, sizeof(EERIE_CYLINDER)); testcyl.radius += INC_RADIUS; if (ANCHOR_AttemptValidCylinderPos(&testcyl, NULL, CFLAG_NO_INTERCOL | CFLAG_EXTRA_PRECISION | CFLAG_ANCHOR_GENERATION)) { memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); found = 1; } else { if ((testcyl.origin.y != currcyl.origin.y) && (EEfabs(testcyl.origin.y - pos->y) < 50)) { testcyl.radius -= INC_RADIUS; memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); climb++; } else stop_radius = 1; } if (climb > 4) stop_radius = 1; if (currcyl.radius >= 50.f) stop_radius = 1; } if (found) { float dist = TRUEEEDistance3D(pos, &currcyl.origin); float vd = EEfabs(pos->y - currcyl.origin.y); if (currcyl.radius >= bestcyl.radius) { if (((best_dist > dist) && (currcyl.radius == bestcyl.radius)) || (currcyl.radius > bestcyl.radius)) { memcpy(&bestcyl, &currcyl, sizeof(EERIE_CYLINDER)); best_dist = dist; v_dist = vd; best = 1; } } } } if (!best) return FALSE; if (CylinderAboveInvalidZone(&bestcyl)) return FALSE; if (flags == MUST_BE_BIG) { if (bestcyl.radius < 60) return FALSE; } // avoid to recreate same anchor twice... if (0) for (long k = 0; k < eb->nbanchors; k++) { _ANCHOR_DATA * ad = &eb->anchors[k]; if ((ad->pos.x == bestcyl.origin.x) && (ad->pos.y == bestcyl.origin.y) && (ad->pos.z == bestcyl.origin.z)) { if (ad->radius >= bestcyl.radius) return FALSE; if (ad->radius <= bestcyl.radius) { ad->height = bestcyl.height; ad->radius = bestcyl.radius; return FALSE; } } } eg->ianchors = (long *)realloc(eg->ianchors, sizeof(long) * (eg->nbianchors + 1)); if (!eg->ianchors) HERMES_Memory_Emergency_Out(); eg->ianchors[eg->nbianchors] = eb->nbanchors; eg->nbianchors++; eb->anchors = (_ANCHOR_DATA *)realloc(eb->anchors, sizeof(_ANCHOR_DATA) * (eb->nbanchors + 1)); if (!eb->anchors) HERMES_Memory_Emergency_Out(); _ANCHOR_DATA * ad = &eb->anchors[eb->nbanchors]; ad->pos.x = bestcyl.origin.x; ad->pos.y = bestcyl.origin.y; ad->pos.z = bestcyl.origin.z; ad->height = bestcyl.height; ad->radius = bestcyl.radius; ad->linked = NULL; ad->nblinked = 0; ad->flags = 0; eb->nbanchors++; return TRUE; }
bool DirectAddAnchor_Original_Method(EERIE_BACKGROUND * eb, EERIE_BKG_INFO * eg, EERIE_3D * pos, long flags) { long found = 0; long best = 0; long stop_radius = 0; float best_dist = 99999999999.f; float v_dist = 99999999999.f; EERIE_CYLINDER testcyl; EERIE_CYLINDER currcyl; EERIE_CYLINDER bestcyl; bestcyl.height = 0; bestcyl.radius = 0; currcyl.radius = 40; currcyl.height = -165.f; currcyl.origin.x = pos->x; currcyl.origin.y = pos->y; currcyl.origin.z = pos->z; stop_radius = 0; found = 0; long climb = 0; while (stop_radius != 1) { memcpy(&testcyl, &currcyl, sizeof(EERIE_CYLINDER)); testcyl.radius += INC_RADIUS; if (ANCHOR_AttemptValidCylinderPos(&testcyl, NULL, CFLAG_NO_INTERCOL | CFLAG_EXTRA_PRECISION | CFLAG_ANCHOR_GENERATION)) { memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); found = 1; } else { if ((testcyl.origin.y != currcyl.origin.y) && (EEfabs(testcyl.origin.y - pos->y) < 50)) { testcyl.radius -= INC_RADIUS; memcpy(&currcyl, &testcyl, sizeof(EERIE_CYLINDER)); climb++; } else stop_radius = 1; } if (climb > 4) stop_radius = 1; if (currcyl.radius >= 50.f) stop_radius = 1; } if (found) { float dist = TRUEEEDistance3D(pos, &currcyl.origin); float vd = EEfabs(pos->y - currcyl.origin.y); if ((currcyl.radius >= bestcyl.radius)) { if (((best_dist > dist) && (currcyl.radius == bestcyl.radius)) || (currcyl.radius > bestcyl.radius)) { memcpy(&bestcyl, &currcyl, sizeof(EERIE_CYLINDER)); best_dist = dist; v_dist = vd; best = 1; } } } if (!best) return FALSE; if (CylinderAboveInvalidZone(&bestcyl)) return FALSE; for (long k = 0; k < eb->nbanchors; k++) { _ANCHOR_DATA * ad = &eb->anchors[k]; if (TRUEEEDistance3D(&ad->pos, &bestcyl.origin) < 50.f) return FALSE; if (TRUEDistance2D(ad->pos.x, ad->pos.z, bestcyl.origin.x, bestcyl.origin.z) < 45.f) { if (EEfabs(ad->pos.y - bestcyl.origin.y) < 90.f) return FALSE; EERIEPOLY * ep = ANCHOR_CheckInPolyPrecis(ad->pos.x, ad->pos.y, ad->pos.z); EERIEPOLY * ep2 = ANCHOR_CheckInPolyPrecis(ad->pos.x, bestcyl.origin.y, ad->pos.z); if (ep2 == ep) return FALSE; } } eg->ianchors = (long *)realloc(eg->ianchors, sizeof(long) * (eg->nbianchors + 1)); if (!eg->ianchors) HERMES_Memory_Emergency_Out(); eg->ianchors[eg->nbianchors] = eb->nbanchors; eg->nbianchors++; eb->anchors = (_ANCHOR_DATA *)realloc(eb->anchors, sizeof(_ANCHOR_DATA) * (eb->nbanchors + 1)); if (!eb->anchors) HERMES_Memory_Emergency_Out(); _ANCHOR_DATA * ad = &eb->anchors[eb->nbanchors]; ad->pos.x = bestcyl.origin.x; ad->pos.y = bestcyl.origin.y; ad->pos.z = bestcyl.origin.z; ad->height = bestcyl.height; ad->radius = bestcyl.radius; ad->linked = NULL; ad->nblinked = 0; ad->flags = 0; eb->nbanchors++; return TRUE; }
BOOL ANCHOR_ARX_COLLISION_Move_Cylinder(IO_PHYSICS * ip, INTERACTIVE_OBJ * io, float MOVE_CYLINDER_STEP, long flags) { MOVING_CYLINDER = 1; DIRECT_PATH = TRUE; IO_PHYSICS test; if (ip == NULL) { MOVING_CYLINDER = 0; return FALSE; } float distance = TRUEEEDistance3D(&ip->startpos, &ip->targetpos); if (distance <= 0.f) { MOVING_CYLINDER = 0; return TRUE; } float onedist = 1.f / distance; EERIE_3D mvector; mvector.x = (ip->targetpos.x - ip->startpos.x) * onedist; mvector.y = (ip->targetpos.y - ip->startpos.y) * onedist; mvector.z = (ip->targetpos.z - ip->startpos.z) * onedist; while (distance > 0.f) { // First We compute current increment float curmovedist = __min(distance, MOVE_CYLINDER_STEP); distance -= curmovedist; //CUR_FRAME_SLICE=curmovedist*onedist; // Store our cylinder desc into a test struct memcpy(&test, ip, sizeof(IO_PHYSICS)); // uses test struct to simulate movement. test.cyl.origin.x += mvector.x * curmovedist; test.cyl.origin.y += mvector.y * curmovedist; test.cyl.origin.z += mvector.z * curmovedist; vector2D.x = mvector.x * curmovedist; vector2D.y = 0.f; vector2D.z = mvector.z * curmovedist; if ((flags & CFLAG_CHECK_VALID_POS) && (CylinderAboveInvalidZone(&test.cyl))) return FALSE; if (ANCHOR_AttemptValidCylinderPos(&test.cyl, io, flags)) { memcpy(ip, &test, sizeof(IO_PHYSICS)); } else { if (flags & CFLAG_CLIMBING) { memcpy(&test.cyl, &ip->cyl, sizeof(EERIE_CYLINDER)); test.cyl.origin.y += mvector.y * curmovedist; if (ANCHOR_AttemptValidCylinderPos(&test.cyl, io, flags)) { memcpy(ip, &test, sizeof(IO_PHYSICS)); goto oki; } } DIRECT_PATH = FALSE; // Must Attempt To Slide along collisions register EERIE_3D vecatt; EERIE_3D rpos = { 0, 0, 0 }; EERIE_3D lpos = { 0, 0, 0 }; long RFOUND = 0; long LFOUND = 0; long maxRANGLE = 90; long maxLANGLE = 270; float ANGLESTEPP; if (flags & CFLAG_EASY_SLIDING) // player sliding in fact... { ANGLESTEPP = 10.f; maxRANGLE = 70; maxLANGLE = 290; } else ANGLESTEPP = 30.f; register float rangle = ANGLESTEPP; register float langle = 360.f - ANGLESTEPP; while (rangle <= maxRANGLE) //tries on the Right and Left sides { memcpy(&test.cyl, &ip->cyl, sizeof(EERIE_CYLINDER)); float t = DEG2RAD(MAKEANGLE(rangle)); _YRotatePoint(&mvector, &vecatt, EEcos(t), EEsin(t)); test.cyl.origin.x += vecatt.x * curmovedist; test.cyl.origin.y += vecatt.y * curmovedist; test.cyl.origin.z += vecatt.z * curmovedist; if (ANCHOR_AttemptValidCylinderPos(&test.cyl, io, flags)) { memcpy(&rpos, &test.cyl.origin, sizeof(EERIE_3D)); RFOUND = 1; } rangle += ANGLESTEPP; memcpy(&test.cyl, &ip->cyl, sizeof(EERIE_CYLINDER)); t = DEG2RAD(MAKEANGLE(langle)); _YRotatePoint(&mvector, &vecatt, EEcos(t), EEsin(t)); test.cyl.origin.x += vecatt.x * curmovedist; test.cyl.origin.y += vecatt.y * curmovedist; test.cyl.origin.z += vecatt.z * curmovedist; if (ANCHOR_AttemptValidCylinderPos(&test.cyl, io, flags)) { memcpy(&lpos, &test.cyl.origin, sizeof(EERIE_3D)); LFOUND = 1; } langle -= ANGLESTEPP; if ((RFOUND) || (LFOUND)) break; } if ((LFOUND) && (RFOUND)) { langle = 360.f - langle; if (langle < rangle) { memcpy(&ip->cyl.origin, &lpos, sizeof(EERIE_3D)); distance -= curmovedist; } else { memcpy(&ip->cyl.origin, &rpos, sizeof(EERIE_3D)); distance -= curmovedist; } } else if (LFOUND) { memcpy(&ip->cyl.origin, &lpos, sizeof(EERIE_3D)); distance -= curmovedist; } else if (RFOUND) { memcpy(&ip->cyl.origin, &rpos, sizeof(EERIE_3D)); distance -= curmovedist; } else //stopped { ip->velocity.x = ip->velocity.y = ip->velocity.z = 0.f; MOVING_CYLINDER = 0; return FALSE; } } oki: ; } MOVING_CYLINDER = 0; return TRUE; }