Beispiel #1
0
// TODO move to destructor?
EERIE_3DOBJ::~EERIE_3DOBJ() {
	
	free(originaltextures);
	originaltextures = NULL;
	
	if(ndata) {
		KillNeighbours(this);
	}
	
	if(pdata) {
		KillProgressiveData(this);
	}
	
	if(cdata) {
		KillClothesData(this);
	}
	
	EERIE_RemoveCedricData(this);
	EERIE_PHYSICS_BOX_Release(this);
	EERIE_COLLISION_SPHERES_Release(this);
	
	grouplist.clear();
	linked.clear();
}
// 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);
		}
	}
}