//************************************************************************************* // Apply spring force on two physical vertexes //************************************************************************************* void ApplySpring(EERIE_3DOBJ * obj, long k, long l, float PHYSICS_constant, float PHYSICS_Damp) { EERIE_3D deltaP, deltaV, springforce; PHYSVERT * pv_k = &obj->pbox->vert[k]; PHYSVERT * pv_l = &obj->pbox->vert[l]; float Dterm, Hterm; float restlength = TRUEEEDistance3D(&obj->pbox->vert[k].initpos, &obj->pbox->vert[l].initpos); //Computes Spring Magnitude deltaP.x = pv_k->pos.x - pv_l->pos.x; // Vector distance deltaP.y = pv_k->pos.y - pv_l->pos.y; // Vector distance deltaP.z = pv_k->pos.z - pv_l->pos.z; // Vector distance float dist = (float)TRUEsqrt(deltaP.x * deltaP.x + deltaP.y * deltaP.y + deltaP.z * deltaP.z); // Magnitude of delta float divdist = 1.f / dist; Hterm = (dist - restlength) * PHYSICS_constant; deltaV.x = pv_k->velocity.x - pv_l->velocity.x; deltaV.y = pv_k->velocity.y - pv_l->velocity.y; deltaV.z = pv_k->velocity.z - pv_l->velocity.z; // Delta Velocity Vector Dterm = (Vector_DotProduct(&deltaV, &deltaP) * PHYSICS_Damp) * divdist; // Damping Term Dterm = (-(Hterm + Dterm)); divdist *= Dterm; springforce.x = deltaP.x * divdist; // Normalize Distance Vector springforce.y = deltaP.y * divdist; // & Calc Force springforce.z = deltaP.z * divdist; pv_k->force.x += springforce.x; // + force on particle 1 pv_k->force.y += springforce.y; pv_k->force.z += springforce.z; pv_l->force.x -= springforce.x; // - force on particle 2 pv_l->force.y -= springforce.y; pv_l->force.z -= springforce.z; }
void AnchorData_Create_Links_Original_Method(EERIE_BACKGROUND * eb) { EERIE_BKG_INFO * eg; EERIE_BKG_INFO * eg2; long ii, ia, ji, ja; EERIE_3D p1, p2; char text[256]; long count = 0; long per; long lastper = -1; long total = eb->Zsize * eb->Xsize; for (long j = 0; j < eb->Zsize; j++) for (long i = 0; i < eb->Xsize; i++) { F2L((float)count / (float)total * 100.f, &per); if (per != lastper) { sprintf(text, "Anchor Links Generation: %d%%", per); lastper = per; _ShowText(text); } danaeApp.WinManageMess(); count++; eg = &eb->Backg[i+j*eb->Xsize]; long precise = 0; for (long kkk = 0; kkk < eg->nbpolyin; kkk++) { EERIEPOLY * ep = eg->polyin[kkk]; if (ep->type & POLY_PRECISE_PATH) { precise = 1; break; } } for (long k = 0; k < eg->nbianchors; k++) { ii = i - 2; ia = i + 2; ji = j - 2; ja = j + 2; FORCERANGE(ii, 0, eb->Xsize - 1); FORCERANGE(ia, 0, eb->Xsize - 1); FORCERANGE(ji, 0, eb->Zsize - 1); FORCERANGE(ja, 0, eb->Zsize - 1); for (long j2 = ji; j2 <= ja; j2++) for (long i2 = ii; i2 <= ia; i2++) { eg2 = &eb->Backg[i2+j2*eb->Xsize]; long precise2 = 0; for (long kkk = 0; kkk < eg2->nbpolyin; kkk++) { EERIEPOLY * ep2 = eg2->polyin[kkk]; if (ep2->type & POLY_PRECISE_PATH) { precise2 = 1; break; } } for (long k2 = 0; k2 < eg2->nbianchors; k2++) { // don't treat currently treated anchor if (eg->ianchors[k] == eg2->ianchors[k2]) continue; memcpy(&p1, &eb->anchors[eg->ianchors[k]].pos, sizeof(EERIE_3D)); memcpy(&p2, &eb->anchors[eg2->ianchors[k2]].pos, sizeof(EERIE_3D)); p1.y += 10.f; p2.y += 10.f; long _onetwo = 0; BOOL treat = TRUE; float dist = TRUEEEDistance3D(&p1, &p2); float dd = TRUEDistance2D(p1.x, p1.z, p2.x, p2.z); if (dd < 5.f) continue; if (dd > 200.f) continue; if (precise || precise2) { if (dist > 120.f) continue; } else if (dist > 200.f) continue; if (EEfabs(p1.y - p2.y) > dd * 0.9f) continue; IO_PHYSICS ip; ip.startpos.x = ip.cyl.origin.x = p1.x; ip.startpos.y = ip.cyl.origin.y = p1.y; ip.startpos.z = ip.cyl.origin.z = p1.z; ip.targetpos.x = p2.x; ip.targetpos.y = p2.y; ip.targetpos.z = p2.z; ip.cyl.height = eb->anchors[eg->ianchors[k]].height; ip.cyl.radius = eb->anchors[eg->ianchors[k]].radius; EERIE_3D vect; vect.x = p2.x - p1.x; vect.y = p2.y - p1.y; vect.z = p2.z - p1.z; long t = 2; if (ANCHOR_ARX_COLLISION_Move_Cylinder(&ip, NULL, 20, CFLAG_CHECK_VALID_POS | CFLAG_NO_INTERCOL | CFLAG_EASY_SLIDING | CFLAG_NPC | CFLAG_JUST_TEST | CFLAG_EXTRA_PRECISION)) //CFLAG_SPECIAL { if (TRUEDistance2D(ip.cyl.origin.x, ip.cyl.origin.z, ip.targetpos.x, ip.targetpos.z) > 25) t--; else _onetwo = 1; } else t--; if (t == 1) { ip.startpos.x = ip.cyl.origin.x = p2.x; ip.startpos.y = ip.cyl.origin.y = p2.y; ip.startpos.z = ip.cyl.origin.z = p2.z; ip.targetpos.x = p1.x; ip.targetpos.y = p1.y; ip.targetpos.z = p1.z; ip.cyl.height = eb->anchors[eg2->ianchors[k2]].height; ip.cyl.radius = eb->anchors[eg2->ianchors[k2]].radius; if (ANCHOR_ARX_COLLISION_Move_Cylinder(&ip, NULL, 20, CFLAG_CHECK_VALID_POS | CFLAG_NO_INTERCOL | CFLAG_EASY_SLIDING | CFLAG_NPC | CFLAG_JUST_TEST | CFLAG_EXTRA_PRECISION | CFLAG_RETURN_HEIGHT)) //CFLAG_SPECIAL { if (TRUEDistance2D(ip.cyl.origin.x, ip.cyl.origin.z, ip.targetpos.x, ip.targetpos.z) > 25) t--; else _onetwo |= 2; } else t--; } else t--; if (t <= 0) treat = FALSE; else treat = TRUE; if (treat) { if (_onetwo) { AddAnchorLink(eb, eg->ianchors[k], eg2->ianchors[k2]); AddAnchorLink(eb, eg2->ianchors[k2], eg->ianchors[k]); } } } } } } EERIE_PATHFINDER_Create(eb); }
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; }
// Creation of the physics box... quite cabalistic and extensive func... // Need to put a (really) smarter algorithm in there... void EERIE_PHYSICS_BOX_Create(EERIE_3DOBJ * obj) { if (!obj) return; EERIE_PHYSICS_BOX_Release(obj); if (obj->nbvertex == 0) return; obj->pbox = (PHYSICS_BOX_DATA *) malloc(sizeof(PHYSICS_BOX_DATA)); memset(obj->pbox, 0, sizeof(PHYSICS_BOX_DATA)); obj->pbox->nb_physvert = 15; obj->pbox->stopcount = 0; obj->pbox->vert = (PHYSVERT *) malloc(sizeof(PHYSVERT) * obj->pbox->nb_physvert); memset(obj->pbox->vert, 0, sizeof(PHYSVERT)*obj->pbox->nb_physvert); EERIE_3D cubmin, cubmax; cubmin.x = FLT_MAX; cubmin.y = FLT_MAX; cubmin.z = FLT_MAX; cubmax.x = -FLT_MAX; cubmax.y = -FLT_MAX; cubmax.z = -FLT_MAX; for (long k = 0; k < obj->nbvertex; k++) { if (k == obj->origin) continue; cubmin.x = __min(cubmin.x, obj->vertexlist[k].v.x); cubmin.y = __min(cubmin.y, obj->vertexlist[k].v.y); cubmin.z = __min(cubmin.z, obj->vertexlist[k].v.z); cubmax.x = __max(cubmax.x, obj->vertexlist[k].v.x); cubmax.y = __max(cubmax.y, obj->vertexlist[k].v.y); cubmax.z = __max(cubmax.z, obj->vertexlist[k].v.z); } obj->pbox->vert[0].pos.x = cubmin.x + (cubmax.x - cubmin.x) * DIV2; obj->pbox->vert[0].pos.y = cubmin.y + (cubmax.y - cubmin.y) * DIV2; obj->pbox->vert[0].pos.z = cubmin.z + (cubmax.z - cubmin.z) * DIV2; obj->pbox->vert[13].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[13].pos.y = cubmin.y; obj->pbox->vert[13].pos.z = obj->pbox->vert[0].pos.z; obj->pbox->vert[14].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[14].pos.y = cubmax.y; obj->pbox->vert[14].pos.z = obj->pbox->vert[0].pos.z; for (int k = 1; k < obj->pbox->nb_physvert - 2; k++) { obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z; if (k < 5) obj->pbox->vert[k].pos.y = cubmin.y; else if (k < 9) obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y; else obj->pbox->vert[k].pos.y = cubmax.y; } float diff = cubmax.y - cubmin.y; if (diff < 12.f) { cubmax.y += 8.f; cubmin.y -= 8.f; for (int k = 1; k < obj->pbox->nb_physvert - 2; k++) { obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x; obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z; if (k < 5) obj->pbox->vert[k].pos.y = cubmin.y; else if (k < 9) obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y; else obj->pbox->vert[k].pos.y = cubmax.y; } obj->pbox->vert[14].pos.y = cubmax.y; obj->pbox->vert[13].pos.y = cubmin.y; float RATI = diff * DIV8; for (int k = 0; k < obj->nbvertex; k++) { if (k == obj->origin) continue; EERIE_3D curr; memcpy(&curr, &obj->vertexlist[k].v, sizeof(EERIE_3D)); long SEC = 1; obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z); SEC = 5; obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x - RATI); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z - RATI); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x - RATI); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z + RATI); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x + RATI); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z + RATI); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x + RATI); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z - RATI); SEC = 9; obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z); } } else { float cut = (cubmax.y - cubmin.y) * DIV3; float ysec2 = cubmin.y + cut * 2.f; float ysec1 = cubmin.y + cut; for (int k = 0; k < obj->nbvertex; k++) { if (k == obj->origin) continue; EERIE_3D curr; memcpy(&curr, &obj->vertexlist[k].v, sizeof(EERIE_3D)); long SEC; if (curr.y < ysec1) { SEC = 1; } else if (curr.y < ysec2) { SEC = 5; } else { SEC = 9; } obj->pbox->vert[SEC].pos.x = __min(obj->pbox->vert[SEC].pos.x, curr.x); obj->pbox->vert[SEC].pos.z = __min(obj->pbox->vert[SEC].pos.z, curr.z); obj->pbox->vert[SEC+1].pos.x = __min(obj->pbox->vert[SEC+1].pos.x, curr.x); obj->pbox->vert[SEC+1].pos.z = __max(obj->pbox->vert[SEC+1].pos.z, curr.z); obj->pbox->vert[SEC+2].pos.x = __max(obj->pbox->vert[SEC+2].pos.x, curr.x); obj->pbox->vert[SEC+2].pos.z = __max(obj->pbox->vert[SEC+2].pos.z, curr.z); obj->pbox->vert[SEC+3].pos.x = __max(obj->pbox->vert[SEC+3].pos.x, curr.x); obj->pbox->vert[SEC+3].pos.z = __min(obj->pbox->vert[SEC+3].pos.z, curr.z); } } for (int k = 0; k < 4; k++) { if (EEfabs(obj->pbox->vert[5+k].pos.x - obj->pbox->vert[0].pos.x) < 2.f) obj->pbox->vert[5+k].pos.x = (obj->pbox->vert[1+k].pos.x + obj->pbox->vert[9+k].pos.x) * DIV2; if (EEfabs(obj->pbox->vert[5+k].pos.z - obj->pbox->vert[0].pos.z) < 2.f) obj->pbox->vert[5+k].pos.z = (obj->pbox->vert[1+k].pos.z + obj->pbox->vert[9+k].pos.z) * DIV2; } obj->pbox->radius = 0.f; for (int k = 0; k < obj->pbox->nb_physvert; k++) { float distt = TRUEEEDistance3D(&obj->pbox->vert[k].pos, &obj->pbox->vert[0].pos); if (distt > 20.f) { obj->pbox->vert[k].pos.x = (obj->pbox->vert[k].pos.x - obj->pbox->vert[0].pos.x) * 0.5f + obj->pbox->vert[0].pos.x; obj->pbox->vert[k].pos.z = (obj->pbox->vert[k].pos.z - obj->pbox->vert[0].pos.z) * 0.5f + obj->pbox->vert[0].pos.z; } memcpy(&obj->pbox->vert[k].initpos, &obj->pbox->vert[k].pos, sizeof(EERIE_3D)); if (k != 0) { float dist = TRUEEEDistance3D(&obj->pbox->vert[0].pos, &obj->pbox->vert[k].pos); obj->pbox->radius = __max(obj->pbox->radius, dist); } } }