1 /*
2  * Copyright 2011-2012 Arx Libertatis Team (see the AUTHORS file)
3  *
4  * This file is part of Arx Libertatis.
5  *
6  * Arx Libertatis is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Arx Libertatis is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Arx Libertatis.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 /* Based on:
20 ===========================================================================
21 ARX FATALIS GPL Source Code
22 Copyright (C) 1999-2010 Arkane Studios SA, a ZeniMax Media company.
23 
24 This file is part of the Arx Fatalis GPL Source Code ('Arx Fatalis Source Code').
25 
26 Arx Fatalis Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
27 License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
28 
29 Arx Fatalis Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
30 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
31 
32 You should have received a copy of the GNU General Public License along with Arx Fatalis Source Code.  If not, see
33 <http://www.gnu.org/licenses/>.
34 
35 In addition, the Arx Fatalis Source Code is also subject to certain additional terms. You should have received a copy of these
36 additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Arx
37 Fatalis Source Code. If not, please request a copy in writing from Arkane Studios at the address below.
38 
39 If you have questions concerning this license or the applicable additional terms, you may contact in writing Arkane Studios, c/o
40 ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
41 ===========================================================================
42 */
43 // Code: Cyril Meynier
44 //
45 // Copyright (c) 1999 ARKANE Studios SA. All rights reserved
46 
47 #include "physics/Box.h"
48 
49 #include "graphics/Math.h"
50 
51 using std::min;
52 using std::max;
53 
54 #define FULLTESTS 0
55 
56 long CUR_COLLISION_MATERIAL = 0;
57 
58 // Used to launch an object into the physical world...
EERIE_PHYSICS_BOX_Launch(EERIE_3DOBJ * obj,Vec3f * pos,Vec3f * vect,long flag,Anglef * angle)59 void EERIE_PHYSICS_BOX_Launch(EERIE_3DOBJ * obj, Vec3f * pos, Vec3f * vect, long flag, Anglef * angle)
60 {
61 	if ((!obj) || !(obj->pbox)) return;
62 
63 	obj->pbox->storedtiming = 0;
64 
65 	for(size_t i = 0; i < obj->vertexlist.size(); i++) {
66 		obj->vertexlist[i].vert.p = obj->vertexlist[i].v;
67 	}
68 
69 	float surface = 0.f;
70 
71 	for(size_t i = 0; i < obj->facelist.size(); i++) {
72 		const Vec3f & p0 = obj->vertexlist[obj->facelist[i].vid[0]].v;
73 		const Vec3f & p1 = obj->vertexlist[obj->facelist[i].vid[1]].v;
74 		const Vec3f & p2 = obj->vertexlist[obj->facelist[i].vid[2]].v;
75 		surface += dist((p0 + p1) * .5f, p2) * dist(p0, p1) * .5f;
76 	}
77 
78 	float ratio = surface * ( 1.0f / 10000 );
79 
80 	if (ratio > 0.8f) ratio = 0.8f;
81 	else if (ratio < 0.f) ratio = 0.f;
82 
83 	ratio = 1.f - (ratio * ( 1.0f / 4 ));
84 
85 	for(int i = 0; i < obj->pbox->nb_physvert; i++) {
86 		PHYSVERT * pv = &obj->pbox->vert[i];
87 		pv->pos = pv->initpos + *pos;
88 		pv->inertia = Vec3f::ZERO;
89 		pv->force = Vec3f::ZERO;
90 		pv->velocity = *vect * (250.f * ratio);
91 		pv->mass = 0.4f + ratio * 0.1f;
92 		if(flag) {
93 			Vector_RotateY(&pv->pos, &pv->initpos, angle->b);
94 			pv->pos += *pos;
95 		}
96 	}
97 
98 	obj->pbox->active = 1;
99 	obj->pbox->stopcount = 0;
100 }
101 
IsValidPos3(Vec3f * pos)102 bool IsValidPos3(Vec3f * pos)
103 {
104 	long px, pz;
105 	px = pos->x * ACTIVEBKG->Xmul;
106 
107 	if (px >= ACTIVEBKG->Xsize)
108 	{
109 		return false;
110 	}
111 
112 	if (px < 0)
113 	{
114 		return false;
115 	}
116 
117 	pz = pos->z * ACTIVEBKG->Zmul;
118 
119 	if (pz >= ACTIVEBKG->Zsize)
120 	{
121 		return false;
122 	}
123 
124 	if (pz < 0)
125 	{
126 		return false;
127 	}
128 
129 	EERIE_BKG_INFO * eg;
130 
131 	eg = &ACTIVEBKG->Backg[px+pz*ACTIVEBKG->Xsize];
132 
133 	if (eg->nbpolyin <= 0)
134 		return false;
135 
136 	if (pos->y > eg->tile_maxy)
137 		return false;
138 
139 	return true;
140 }
141 
142 // Checks is a triangle of a physical object is colliding a triangle
IsObjectVertexCollidingTriangle(EERIE_3DOBJ * obj,Vec3f * verts,long k,long * validd)143 bool IsObjectVertexCollidingTriangle(EERIE_3DOBJ * obj, Vec3f * verts, long k, long * validd)
144 {
145 	EERIE_TRI t1, t2;
146 	bool ret = false;
147 	std::copy(verts, verts + 2, t2.v);
148 
149 	PHYSVERT * vert = obj->pbox->vert;
150 
151 	Vec3f center = (verts[0] + verts[1] + verts[2]) * ( 1.0f / 3 );
152 	float rad = fdist(center, verts[0]);
153 
154 	if (k == -1)
155 	{
156 		long nn = 0;
157 
158 		for (; nn < obj->pbox->nb_physvert; nn++)
159 		{
160 			if (distSqr(center, vert[nn].pos) <= max(square(60.0f), square(rad + 25)))
161 			{
162 				nn = 1000;
163 			}
164 		}
165 
166 		if (nn < 1000)
167 			return false;
168 	}
169 	else
170 	{
171 		if (distSqr(center, vert[k].pos) > square(rad + 25))
172 			return false;
173 	}
174 
175 	//TOP
176 	if ((k == -1) || (k == 1) || (k == 2) || (k == 3))
177 	{
178 		t1.v[0] = vert[1].pos;
179 		t1.v[1] = vert[2].pos;
180 		t1.v[2] = vert[3].pos;
181 
182 		if (Triangles_Intersect(&t1, &t2))
183 		{
184 			if (validd)
185 			{
186 				validd[1] = 0;
187 				validd[2] = 0;
188 				validd[3] = 0;
189 				ret = true;
190 			}
191 			else return true;
192 		}
193 	}
194 
195 #if FULLTESTS
196 
197 	if ((k == -1) || (k == 1) || (k == 4) || (k == 3))
198 	{
199 		t1.v[0] = vert[3].pos;
200 		t1.v[1] = vert[4].pos;
201 		t1.v[2] = vert[1].pos;
202 
203 		if (Triangles_Intersect(&t1, &t2))
204 		{
205 			if (validd)
206 			{
207 				validd[1] = 0;
208 				validd[3] = 0;
209 				validd[4] = 0;
210 				ret = true;
211 			}
212 			else return true;
213 		}
214 	}
215 
216 #endif
217 
218 	//BOTTOM
219 	if ((k == -1) || (k == 9) || (k == 10) || (k == 12))
220 	{
221 		t1.v[0] = vert[10].pos;
222 		t1.v[1] = vert[9].pos;
223 		t1.v[2] = vert[11].pos;
224 
225 		if (Triangles_Intersect(&t1, &t2))
226 		{
227 			if (validd)
228 			{
229 				validd[0] = 0;
230 				validd[10] = 0;
231 				validd[12] = 0;
232 				ret = true;
233 			}
234 			else return true;
235 		}
236 	}
237 
238 #if FULLTESTS
239 
240 	if ((k == -1) || (k == 10) || (k == 11) || (k == 12))
241 	{
242 		t1.v[0] = vert[9].pos;
243 		t1.v[1] = vert[12].pos;
244 		t1.v[2] = vert[11].pos;
245 
246 		if (Triangles_Intersect(&t1, &t2))
247 		{
248 			if (validd)
249 			{
250 				validd[10] = 0;
251 				validd[11] = 0;
252 				validd[12] = 0;
253 				ret = true;
254 			}
255 			else return true;
256 		}
257 	}
258 
259 #endif
260 
261 	//UP/FRONT
262 	if ((k == -1) || (k == 1) || (k == 4) || (k == 5))
263 	{
264 		t1.v[0] = vert[1].pos;
265 		t1.v[1] = vert[4].pos;
266 		t1.v[2] = vert[5].pos;
267 
268 		if (Triangles_Intersect(&t1, &t2))
269 		{
270 			if (validd)
271 			{
272 				validd[1] = 0;
273 				validd[4] = 0;
274 				validd[5] = 0;
275 				ret = true;
276 			}
277 			else return true;
278 		}
279 	}
280 
281 #if FULLTESTS
282 
283 	if ((k == -1) || (k == 4) || (k == 5) || (k == 8))
284 	{
285 		t1.v[0] = vert[4].pos;
286 		t1.v[1] = vert[8].pos;
287 		t1.v[2] = vert[5].pos;
288 
289 		if (Triangles_Intersect(&t1, &t2))
290 		{
291 			if (validd)
292 			{
293 				validd[4] = 0;
294 				validd[5] = 0;
295 				validd[8] = 0;
296 				ret = true;
297 			}
298 			else return true;
299 		}
300 	}
301 
302 #endif
303 
304 	//DOWN/FRONT
305 	if ((k == -1) || (k == 5) || (k == 8) || (k == 9))
306 	{
307 		t1.v[0] = vert[5].pos;
308 		t1.v[1] = vert[8].pos;
309 		t1.v[2] = vert[9].pos;
310 
311 		if (Triangles_Intersect(&t1, &t2))
312 		{
313 			if (validd)
314 			{
315 				validd[5] = 0;
316 				validd[8] = 0;
317 				validd[9] = 0;
318 				ret = true;
319 			}
320 			else return true;
321 		}
322 	}
323 
324 #if FULLTESTS
325 
326 	if ((k == -1) || (k == 8) || (k == 12) || (k == 9))
327 	{
328 		t1.v[0] = vert[8].pos;
329 		t1.v[1] = vert[12].pos;
330 		t1.v[2] = vert[9].pos;
331 
332 		if (Triangles_Intersect(&t1, &t2))
333 		{
334 			if (validd)
335 			{
336 				validd[8] = 0;
337 				validd[12] = 0;
338 				validd[9] = 0;
339 				ret = true;
340 			}
341 			else return true;
342 		}
343 	}
344 
345 #endif
346 
347 	//UP/BACK
348 	if ((k == -1) || (k == 3) || (k == 2) || (k == 7))
349 	{
350 		t1.v[0] = vert[3].pos;
351 		t1.v[1] = vert[2].pos;
352 		t1.v[2] = vert[7].pos;
353 
354 		if (Triangles_Intersect(&t1, &t2))
355 		{
356 			if (validd)
357 			{
358 				validd[3] = 0;
359 				validd[2] = 0;
360 				validd[7] = 0;
361 				ret = true;
362 			}
363 			else return true;
364 		}
365 	}
366 
367 #if FULLTESTS
368 
369 	if ((k == -1) || (k == 2) || (k == 6) || (k == 7))
370 	{
371 		t1.v[0] = vert[2].pos;
372 		t1.v[1] = vert[6].pos;
373 		t1.v[2] = vert[7].pos;
374 
375 		if (Triangles_Intersect(&t1, &t2))
376 		{
377 			if (validd)
378 			{
379 				validd[2] = 0;
380 				validd[6] = 0;
381 				validd[7] = 0;
382 				ret = true;
383 			}
384 			else return true;
385 		}
386 	}
387 
388 #endif
389 
390 	//DOWN/BACK
391 	if ((k == -1) || (k == 7) || (k == 6) || (k == 11))
392 	{
393 		t1.v[0] = vert[7].pos;
394 		t1.v[1] = vert[6].pos;
395 		t1.v[2] = vert[11].pos;
396 
397 		if (Triangles_Intersect(&t1, &t2))
398 		{
399 			if (validd)
400 			{
401 				validd[6] = 0;
402 				validd[7] = 0;
403 				validd[11] = 0;
404 				ret = true;
405 			}
406 			else return true;
407 		}
408 	}
409 
410 #if FULLTESTS
411 
412 	if ((k == -1) || (k == 6) || (k == 10) || (k == 11))
413 	{
414 		t1.v[0] = vert[6].pos;
415 		t1.v[1] = vert[10].pos;
416 		t1.v[2] = vert[11].pos;
417 
418 		if (Triangles_Intersect(&t1, &t2))
419 		{
420 			if (validd)
421 			{
422 				validd[6] = 0;
423 				validd[10] = 0;
424 				validd[11] = 0;
425 				ret = true;
426 			}
427 			else return true;
428 		}
429 	}
430 
431 #endif
432 
433 	//UP/LEFT
434 	if ((k == -1) || (k == 1) || (k == 2) || (k == 6))
435 	{
436 		t1.v[0] = vert[6].pos;
437 		t1.v[1] = vert[2].pos;
438 		t1.v[2] = vert[1].pos;
439 
440 		if (Triangles_Intersect(&t1, &t2))
441 		{
442 			if (validd)
443 			{
444 				validd[1] = 0;
445 				validd[2] = 0;
446 				validd[6] = 0;
447 				ret = true;
448 			}
449 			else return true;
450 		}
451 	}
452 
453 #if FULLTESTS
454 
455 	if ((k == -1) || (k == 1) || (k == 5) || (k == 6))
456 	{
457 		t1.v[0] = vert[1].pos;
458 		t1.v[1] = vert[5].pos;
459 		t1.v[2] = vert[6].pos;
460 
461 		if (Triangles_Intersect(&t1, &t2))
462 		{
463 			if (validd)
464 			{
465 				validd[1] = 0;
466 				validd[5] = 0;
467 				validd[6] = 0;
468 				ret = true;
469 			}
470 			else return true;
471 		}
472 	}
473 
474 #endif
475 
476 	//DOWN/LEFT
477 	if ((k == -1) || (k == 10) || (k == 6) || (k == 5))
478 	{
479 		t1.v[0] = vert[10].pos;
480 		t1.v[1] = vert[6].pos;
481 		t1.v[2] = vert[5].pos;
482 
483 		if (Triangles_Intersect(&t1, &t2))
484 		{
485 			if (validd)
486 			{
487 				validd[10] = 0;
488 				validd[6] = 0;
489 				validd[5] = 0;
490 				ret = true;
491 			}
492 			else return true;
493 		}
494 	}
495 
496 #if FULLTESTS
497 
498 	if ((k == -1) || (k == 5) || (k == 9) || (k == 10))
499 	{
500 		t1.v[0] = vert[5].pos;
501 		t1.v[1] = vert[9].pos;
502 		t1.v[2] = vert[10].pos;
503 
504 		if (Triangles_Intersect(&t1, &t2))
505 		{
506 			if (validd)
507 			{
508 				validd[5] = 0;
509 				validd[9] = 0;
510 				validd[10] = 0;
511 				ret = true;
512 			}
513 			else return true;
514 		}
515 	}
516 
517 #endif
518 
519 	//UP/RIGHT
520 	if ((k == -1) || (k == 4) || (k == 3) || (k == 7))
521 	{
522 		t1.v[0] = vert[4].pos;
523 		t1.v[1] = vert[3].pos;
524 		t1.v[2] = vert[7].pos;
525 
526 		if (Triangles_Intersect(&t1, &t2))
527 		{
528 			if (validd)
529 			{
530 				validd[3] = 0;
531 				validd[4] = 0;
532 				validd[7] = 0;
533 				ret = true;
534 			}
535 			else return true;
536 		}
537 	}
538 
539 #if FULLTESTS
540 
541 	if ((k == -1) || (k == 7) || (k == 8) || (k == 4))
542 	{
543 		t1.v[0] = vert[7].pos;
544 		t1.v[1] = vert[8].pos;
545 		t1.v[2] = vert[4].pos;
546 
547 		if (Triangles_Intersect(&t1, &t2))
548 		{
549 			if (validd)
550 			{
551 				validd[4] = 0;
552 				validd[7] = 0;
553 				validd[8] = 0;
554 				ret = true;
555 			}
556 			else return true;
557 		}
558 	}
559 
560 #endif
561 
562 	//DOWN/RIGHT
563 	if ((k == -1) || (k == 8) || (k == 7) || (k == 11))
564 	{
565 		t1.v[0] = vert[8].pos;
566 		t1.v[1] = vert[7].pos;
567 		t1.v[2] = vert[11].pos;
568 
569 		if (Triangles_Intersect(&t1, &t2))
570 		{
571 			if (validd)
572 			{
573 				validd[7] = 0;
574 				validd[8] = 0;
575 				validd[11] = 0;
576 				ret = true;
577 			}
578 			else return true;
579 		}
580 	}
581 
582 #if FULLTESTS
583 
584 	if ((k == -1) || (k == 11) || (k == 12) || (k == 8))
585 	{
586 		t1.v[0] = vert[11].pos;
587 		t1.v[1] = vert[12].pos;
588 		t1.v[2] = vert[8].pos;
589 
590 		if (Triangles_Intersect(&t1, &t2))
591 		{
592 			if (validd)
593 			{
594 				validd[8] = 0;
595 				validd[11] = 0;
596 				validd[12] = 0;
597 				ret = true;
598 			}
599 			else return true;
600 		}
601 	}
602 
603 #endif
604 	return ret;
605 }
606 
607 // Debug function used to show the physical box of an object
EERIE_PHYSICS_BOX_Show(EERIE_3DOBJ * obj)608 void EERIE_PHYSICS_BOX_Show(EERIE_3DOBJ * obj) {
609 
610 	for (long k = 0; k < obj->pbox->nb_physvert; k++) {
611 		if(obj->pbox->active == 2) {
612 			DebugSphere(obj->pbox->vert[k].pos.x, obj->pbox->vert[k].pos.y,  obj->pbox->vert[k].pos.z,
613 			            0.6f, 40, Color::green);
614 		} else if(k == 0 || k == 14 || k == 13) {
615 			DebugSphere(obj->pbox->vert[k].pos.x, obj->pbox->vert[k].pos.y, obj->pbox->vert[k].pos.z,
616 			            0.6f, 40, Color::yellow);
617 		} else if ((k > 0) && (k < 5)) {
618 			DebugSphere(obj->pbox->vert[k].pos.x, obj->pbox->vert[k].pos.y, obj->pbox->vert[k].pos.z,
619 			            0.6f, 40, Color::green);
620 		} else if ((k > 4) && (k < 9)) {
621 			DebugSphere(obj->pbox->vert[k].pos.x, obj->pbox->vert[k].pos.y, obj->pbox->vert[k].pos.z,
622 			            0.6f, 40, Color::blue);
623 		} else {
624 			DebugSphere(obj->pbox->vert[k].pos.x, obj->pbox->vert[k].pos.y, obj->pbox->vert[k].pos.z,
625 			            0.6f, 40, Color::red);
626 		}
627 	}
628 }
629 
630 // Releases physic box data from an object
EERIE_PHYSICS_BOX_Release(EERIE_3DOBJ * obj)631 void EERIE_PHYSICS_BOX_Release(EERIE_3DOBJ * obj) {
632 
633 	if(!obj || !obj->pbox) {
634 		return;
635 	}
636 
637 	free(obj->pbox->vert), obj->pbox->vert = NULL;
638 	free(obj->pbox), obj->pbox = NULL;
639 }
640 
641 // Creation of the physics box... quite cabalistic and extensive func...
642 // Need to put a (really) smarter algorithm in there...
EERIE_PHYSICS_BOX_Create(EERIE_3DOBJ * obj)643 void EERIE_PHYSICS_BOX_Create(EERIE_3DOBJ * obj)
644 {
645 	if (!obj) return;
646 
647 	EERIE_PHYSICS_BOX_Release(obj);
648 
649 	if (obj->vertexlist.empty()) return;
650 
651 	obj->pbox =	(PHYSICS_BOX_DATA *)
652 	            malloc(sizeof(PHYSICS_BOX_DATA));
653 	memset(obj->pbox, 0, sizeof(PHYSICS_BOX_DATA));
654 	obj->pbox->nb_physvert = 15;
655 	obj->pbox->stopcount = 0;
656 	obj->pbox->vert =	(PHYSVERT *)
657 	                    malloc(sizeof(PHYSVERT) * obj->pbox->nb_physvert);
658 	memset(obj->pbox->vert, 0, sizeof(PHYSVERT)*obj->pbox->nb_physvert);
659 
660 	Vec3f cubmin = Vec3f::repeat(std::numeric_limits<float>::max());
661 	Vec3f cubmax = Vec3f::repeat(-std::numeric_limits<float>::max());
662 
663 	for(size_t k = 0; k < obj->vertexlist.size(); k++) {
664 		if(long(k) != obj->origin) {
665 			cubmin = componentwise_min(cubmin, obj->vertexlist[k].v);
666 			cubmax = componentwise_max(cubmax, obj->vertexlist[k].v);
667 		}
668 	}
669 
670 	obj->pbox->vert[0].pos = cubmin + (cubmax - cubmin) * .5f;
671 	obj->pbox->vert[13].pos = obj->pbox->vert[0].pos;
672 	obj->pbox->vert[13].pos.y = cubmin.y;
673 	obj->pbox->vert[14].pos = obj->pbox->vert[0].pos;
674 	obj->pbox->vert[14].pos.y = cubmax.y;
675 
676 	for (int k = 1; k < obj->pbox->nb_physvert - 2; k++)
677 	{
678 		obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x;
679 		obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z;
680 
681 		if (k < 5)		obj->pbox->vert[k].pos.y = cubmin.y;
682 		else if (k < 9)	obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y;
683 		else			obj->pbox->vert[k].pos.y = cubmax.y;
684 	}
685 
686 	float diff = cubmax.y - cubmin.y;
687 
688 	if (diff < 12.f)
689 	{
690 		cubmax.y += 8.f;
691 		cubmin.y -= 8.f;
692 
693 		for (int k = 1; k < obj->pbox->nb_physvert - 2; k++)
694 		{
695 			obj->pbox->vert[k].pos.x = obj->pbox->vert[0].pos.x;
696 			obj->pbox->vert[k].pos.z = obj->pbox->vert[0].pos.z;
697 
698 			if (k < 5)		obj->pbox->vert[k].pos.y = cubmin.y;
699 			else if (k < 9)	obj->pbox->vert[k].pos.y = obj->pbox->vert[0].pos.y;
700 			else			obj->pbox->vert[k].pos.y = cubmax.y;
701 		}
702 
703 		obj->pbox->vert[14].pos.y = cubmax.y;
704 		obj->pbox->vert[13].pos.y = cubmin.y;
705 		float RATI = diff * ( 1.0f / 8 );
706 
707 		for (size_t k = 0; k < obj->vertexlist.size(); k++)
708 		{
709 			if (k == (size_t)obj->origin) continue;
710 
711 			Vec3f curr = obj->vertexlist[k].v;
712 			long SEC = 1;
713 			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x);
714 			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z);
715 
716 			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x);
717 			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z);
718 
719 			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x);
720 			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z);
721 
722 			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x);
723 			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z);
724 
725 			SEC = 5;
726 			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x - RATI);
727 			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z - RATI);
728 
729 			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x - RATI);
730 			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z + RATI);
731 
732 			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x + RATI);
733 			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z + RATI);
734 
735 			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x + RATI);
736 			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z - RATI);
737 
738 
739 			SEC = 9;
740 			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x);
741 			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z);
742 
743 			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x);
744 			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z);
745 
746 			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x);
747 			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z);
748 
749 			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x);
750 			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z);
751 		}
752 	}
753 	else
754 	{
755 		float cut = (cubmax.y - cubmin.y) * ( 1.0f / 3 );
756 		float ysec2 = cubmin.y + cut * 2.f;
757 		float ysec1 = cubmin.y + cut;
758 
759 		for (size_t k = 0; k < obj->vertexlist.size(); k++)
760 		{
761 			if (k == (size_t)obj->origin) continue;
762 
763 			Vec3f curr = obj->vertexlist[k].v;
764 			long SEC;
765 
766 			if (curr.y < ysec1)
767 			{
768 				SEC = 1;
769 			}
770 			else if (curr.y < ysec2)
771 			{
772 				SEC = 5;
773 			}
774 			else
775 			{
776 				SEC = 9;
777 			}
778 
779 			obj->pbox->vert[SEC].pos.x = min(obj->pbox->vert[SEC].pos.x, curr.x);
780 			obj->pbox->vert[SEC].pos.z = min(obj->pbox->vert[SEC].pos.z, curr.z);
781 
782 			obj->pbox->vert[SEC+1].pos.x = min(obj->pbox->vert[SEC+1].pos.x, curr.x);
783 			obj->pbox->vert[SEC+1].pos.z = max(obj->pbox->vert[SEC+1].pos.z, curr.z);
784 
785 			obj->pbox->vert[SEC+2].pos.x = max(obj->pbox->vert[SEC+2].pos.x, curr.x);
786 			obj->pbox->vert[SEC+2].pos.z = max(obj->pbox->vert[SEC+2].pos.z, curr.z);
787 
788 			obj->pbox->vert[SEC+3].pos.x = max(obj->pbox->vert[SEC+3].pos.x, curr.x);
789 			obj->pbox->vert[SEC+3].pos.z = min(obj->pbox->vert[SEC+3].pos.z, curr.z);
790 		}
791 	}
792 
793 	for (int k = 0; k < 4; k++)
794 	{
795 		if (EEfabs(obj->pbox->vert[5+k].pos.x - obj->pbox->vert[0].pos.x) < 2.f)
796 			obj->pbox->vert[5+k].pos.x = (obj->pbox->vert[1+k].pos.x + obj->pbox->vert[9+k].pos.x) * .5f;
797 
798 		if (EEfabs(obj->pbox->vert[5+k].pos.z - obj->pbox->vert[0].pos.z) < 2.f)
799 			obj->pbox->vert[5+k].pos.z = (obj->pbox->vert[1+k].pos.z + obj->pbox->vert[9+k].pos.z) * .5f;
800 	}
801 
802 	obj->pbox->radius = 0.f;
803 
804 	for(int k = 0; k < obj->pbox->nb_physvert; k++) {
805 		float distt = dist(obj->pbox->vert[k].pos, obj->pbox->vert[0].pos);
806 
807 		if (distt > 20.f)
808 		{
809 			obj->pbox->vert[k].pos.x = (obj->pbox->vert[k].pos.x
810 			                            - obj->pbox->vert[0].pos.x) * 0.5f +
811 			                           obj->pbox->vert[0].pos.x;
812 			obj->pbox->vert[k].pos.z = (obj->pbox->vert[k].pos.z
813 			                            - obj->pbox->vert[0].pos.z) * 0.5f +
814 			                           obj->pbox->vert[0].pos.z;
815 		}
816 
817 		obj->pbox->vert[k].initpos = obj->pbox->vert[k].pos;
818 
819 		if(k != 0) {
820 			float d = dist(obj->pbox->vert[0].pos, obj->pbox->vert[k].pos);
821 			obj->pbox->radius = max(obj->pbox->radius, d);
822 		}
823 	}
824 }
825