Beispiel #1
0
void Build_CAM4DV1_Matrix_UVN(CAM4DV1_PTR cam, int mode)
{
	MATRIX4X4 mt_inv;
	MATRIX4X4 mt_uvn;
	MATRIX4X4 mtmp;

	//Ïà»úƽÒƾØÕóµÄÄæ¾ØÕó
	Mat_Init_4X4(&mt_inv, 1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 0, 1,
		-cam->pos.x, -cam->pos.y, -cam->pos.z, 1);

	if (UVN_MODE_SPHERICAL == mode)
	{
		float phi = cam->dir.x;
		float theta = cam->dir.y;

		float sin_phi = Fast_Sin(phi);
		float cos_phi = Fast_Cos(theta);

		float sin_theta = Fast_Sin(theta);
		float cos_theta = Fast_Cos(theta);

		cam->target.x = -1 * sin_phi * sin_theta;
		cam->target.y = 1 * cos_phi;
		cam->target.z = 1 * sin_phi * cos_theta;
	}

	VECTOR4D_Build(&cam->pos, &cam->target, &cam->n);
	
	VECTOR4D_INITXYZ(&cam->v, 0, 1, 0);

	VECTOR4D_Cross(&cam->v, &cam->n, &cam->u);
	
	VECTOR4D_Cross(&cam->n, &cam->u, &cam->v);
	
	VECTOR4D_Normalize(&cam->u);
	VECTOR4D_Normalize(&cam->v);
	VECTOR4D_Normalize(&cam->n);

	Mat_Init_4X4(&mt_uvn, cam->u.x, cam->v.x, cam->n.x, 0,
		cam->u.y, cam->v.y, cam->n.y, 0,
		cam->u.z, cam->v.z, cam->n.z, 0,
		0, 0, 0, 1);

	Mat_Mul_4X4(&mt_inv, &mt_uvn, &cam->mcam);
}
Beispiel #2
0
int Prepare_OBJECT4DV2_For_MD2(OBJECT4DV2_PTR obj, /* pointer to destination object */ MD2_CONTAINER_PTR obj_md2)	/* md2
																													 * object
																													 * to
																													 * extract
																													 * frame
																													 * from
																													 * */
{

	/*
	 * this function prepares the OBJECT4DV2 to be used as a vessel to hold ;
	 * frames from the md2 container, it allocated the memory needed, set fields ;
	 * and pre-computes as much as possible since each new frame will change only ;
	 * the vertex list
	 */
	Write_Error("\nPreparing MD2_CONTAINER_PTR %x for OBJECT4DV2_PTR %x", obj_md2, obj);

	/* clear out the object and initialize it a bit */
	memset(obj, 0, sizeof(OBJECT4DV2));

	/* set state of object to active and visible */
	obj->state = OBJECT4DV2_STATE_ACTIVE | OBJECT4DV2_STATE_VISIBLE;

	/* set some information in object */
	obj->num_frames = 1;	/* always set to 1 */
	obj->curr_frame = 0;
	obj->attr = OBJECT4DV2_ATTR_SINGLE_FRAME | OBJECT4DV2_ATTR_TEXTURES;

	obj->num_vertices = obj_md2->num_verts;
	obj->num_polys = obj_md2->num_polys;
	obj->texture = obj_md2->skin;

	/* set position of object */
	obj->world_pos = obj_md2->world_pos;

	/*
	 * allocate the memory for the vertices and number of polys ;
	 * the call parameters are redundant in this case, but who cares
	 */
	if(!Init_OBJECT4DV2(obj, obj->num_vertices, obj->num_polys, obj->num_frames))
	{
		Write_Error("\n(can't allocate memory).");
	}	/* end if */

	/*
	 * compute average and max radius using the vertices from frame 0, this isn't ;
	 * totally accurate, but the volume of the object hopefully does vary wildly ;
	 * during animation ;
	 * reset incase there's any residu
	 */
	obj->avg_radius[0] = 0;
	obj->max_radius[0] = 0;

	/* loop thru and compute radius */
	for(int vindex = 0; vindex < obj_md2->num_verts; vindex++)
	{

		/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
		/* update the average and maximum radius (use frame 0) */
		float	dist_to_vertex = sqrt
			(
				obj_md2->vlist[vindex].x *
					obj_md2->vlist[vindex].x +
					obj_md2->vlist[vindex].y *
					obj_md2->vlist[vindex].y +
					obj_md2->vlist[vindex].z *
					obj_md2->vlist[vindex].z
			);
		/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

		/* accumulate total radius */
		obj->avg_radius[0] += dist_to_vertex;

		/* update maximum radius */
		if(dist_to_vertex > obj->max_radius[0]) obj->max_radius[0] = dist_to_vertex;
	}	/* end for vertex */

	/* finallize average radius computation */
	obj->avg_radius[0] /= obj->num_vertices;

	Write_Error("\nMax radius=%f, Avg. Radius=%f", obj->max_radius[0], obj->avg_radius[0]);
	Write_Error("\nWriting texture coordinates...");

	/* copy texture coordinate list always the same */
	for(int tindex = 0; tindex < obj_md2->num_textcoords; tindex++)
	{

		/* now texture coordinates */
		obj->tlist[tindex].x = obj_md2->tlist[tindex].x;
		obj->tlist[tindex].y = obj_md2->tlist[tindex].y;
	}	/* end for tindex */

	Write_Error("\nWriting polygons...");

	/* generate the polygon index list, always the same */
	for(int pindex = 0; pindex < obj_md2->num_polys; pindex++)
	{

		/* set polygon indices */
		obj->plist[pindex].vert[0] = obj_md2->polys[pindex].vindex[0];
		obj->plist[pindex].vert[1] = obj_md2->polys[pindex].vindex[1];
		obj->plist[pindex].vert[2] = obj_md2->polys[pindex].vindex[2];

		/*
		 * point polygon vertex list to object's vertex list ;
		 * note that this is redundant since the polylist is contained ;
		 * within the object in this case and its up to the user to select ;
		 * whether the local or transformed vertex list is used when building up ;
		 * polygon geometry, might be a better idea to set to NULL in the context ;
		 * of polygons that are part of an object
		 */
		obj->plist[pindex].vlist = obj->vlist_local;

		/* set attributes of polygon with sent attributes */
		obj->plist[pindex].attr = obj_md2->attr;

		/* set color of polygon */
		obj->plist[pindex].color = obj_md2->color;

		/* apply texture to this polygon */
		obj->plist[pindex].texture = obj_md2->skin;

		/* assign the texture coordinates */
		obj->plist[pindex].text[0] = obj_md2->polys[pindex].tindex[0];
		obj->plist[pindex].text[1] = obj_md2->polys[pindex].tindex[1];
		obj->plist[pindex].text[2] = obj_md2->polys[pindex].tindex[2];

		/* set texture coordinate attributes */
		SET_BIT(obj->vlist_local[obj->plist[pindex].vert[0]].attr, VERTEX4DTV1_ATTR_TEXTURE);
		SET_BIT(obj->vlist_local[obj->plist[pindex].vert[1]].attr, VERTEX4DTV1_ATTR_TEXTURE);
		SET_BIT(obj->vlist_local[obj->plist[pindex].vert[2]].attr, VERTEX4DTV1_ATTR_TEXTURE);

		/* set the material mode to ver. 1.0 emulation */
		SET_BIT(obj->plist[pindex].attr, POLY4DV2_ATTR_DISABLE_MATERIAL);

		/* finally set the polygon to active */
		obj->plist[pindex].state = POLY4DV2_STATE_ACTIVE;

		/*
		 * point polygon vertex list to object's vertex list ;
		 * note that this is redundant since the polylist is contained ;
		 * within the object in this case and its up to the user to select ;
		 * whether the local or transformed vertex list is used when building up ;
		 * polygon geometry, might be a better idea to set to NULL in the context ;
		 * of polygons that are part of an object
		 */
		obj->plist[pindex].vlist = obj->vlist_local;

		/* set texture coordinate list, this is needed */
		obj->plist[pindex].tlist = obj->tlist;

		/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
		/* extract vertex indices */
		int			vindex_0 = obj_md2->polys[pindex].vindex[0];
		int			vindex_1 = obj_md2->polys[pindex].vindex[1];
		int			vindex_2 = obj_md2->polys[pindex].vindex[2];
		/*
		 * we need to compute the normal of this polygon face, and recall ;
		 * that the vertices are in cw order, u=p0->p1, v=p0->p2, n=uxv
		 */
		VECTOR4D	u, v, n;
		/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

		/*
		 * build u, v ;
		 * VECTOR4D_Build(&obj->vlist_local[ vindex_0 ].v, &obj->vlist_local[ vindex_1
		 * ].v, &u);
		 * VECTOR4D_Build(&obj->vlist_local[ vindex_0 ].v, &obj->vlist_local[ vindex_2
		 * ].v, &v);
		 */
		u.x = obj_md2->vlist[vindex_1].x - obj_md2->vlist[vindex_0].x;
		u.y = obj_md2->vlist[vindex_1].y - obj_md2->vlist[vindex_0].y;
		u.z = obj_md2->vlist[vindex_1].z - obj_md2->vlist[vindex_0].z;
		u.w = 1;

		v.x = obj_md2->vlist[vindex_2].x - obj_md2->vlist[vindex_0].x;
		v.y = obj_md2->vlist[vindex_2].y - obj_md2->vlist[vindex_0].y;
		v.z = obj_md2->vlist[vindex_2].z - obj_md2->vlist[vindex_0].z;
		v.w = 1;

		/* compute cross product */
		VECTOR4D_Cross(&u, &v, &n);

		/*
		 * compute length of normal accurately and store in poly nlength ;
		 * +- epsilon later to fix over/underflows
		 */
		obj->plist[pindex].nlength = VECTOR4D_Length(&n);
	}	/* end for poly */

	/* return success */
	return(1);
}		/* end Prepare_OBJECT4DV2_For_MD2 */