예제 #1
0
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;
}