Beispiel #1
0
void CopyFace( face_t* in, face_t* out)
{
	int		i;

	out->face_winding = NewWinding(in->face_winding->numpoints);
	out->face_winding->numpoints = in->face_winding->numpoints;
	for (i = 0; i<in->face_winding->numpoints; i++)
	{
		VectorCopy(in->face_winding->points[i],out->face_winding->points[i]);
	}
	for (i = 0; i<3; i++)
	{
		VectorCopy(in->planepts[i],out->planepts[i]);
	}
}
Beispiel #2
0
/*
============
LoadPortals
============
*/
void LoadPortals (char *name)
{
	int			i, j;
	portal_t	*p;
	leaf_t		*l;
	char		magic[80];
	FILE		*f;
	int			numpoints;
	winding_t	*w;
	int			leafnums[2];
	plane_t		plane;
	
	if (!strcmp(name,"-"))
		f = stdin;
	else
	{
		f = fopen(name, "r");
		if (!f)
		{
			printf ("LoadPortals: couldn't read %s\n",name);
			printf ("No vising performed.\n");
			exit (1);
		}
	}

	if (fscanf (f,"%79s\n%i\n%i\n",magic, &portalleafs, &numportals) != 3)
		Error ("LoadPortals: failed to read header");
	if (strcmp(magic,PORTALFILE))
		Error ("LoadPortals: not a portal file");

	printf ("%4i portalleafs\n", portalleafs);
	printf ("%4i numportals\n", numportals);

	bitbytes = ((portalleafs+63)&~63)>>3;
	bitlongs = bitbytes/sizeof(long);
	
// each file portal is split into two memory portals
	portals = malloc(2*numportals*sizeof(portal_t));
	memset (portals, 0, 2*numportals*sizeof(portal_t));
	
	leafs = malloc(portalleafs*sizeof(leaf_t));
	memset (leafs, 0, portalleafs*sizeof(leaf_t));

	originalvismapsize = portalleafs*((portalleafs+7)/8);

	vismap = vismap_p = dvisdata;
	vismap_end = vismap + MAX_MAP_VISIBILITY;
		
	for (i=0, p=portals ; i<numportals ; i++)
	{
		if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1])
			!= 3)
			Error ("LoadPortals: reading portal %i", i);
		if (numpoints > MAX_POINTS_ON_WINDING)
			Error ("LoadPortals: portal %i has too many points", i);
		if ( (unsigned)leafnums[0] > portalleafs
		|| (unsigned)leafnums[1] > portalleafs)
			Error ("LoadPortals: reading portal %i", i);
		
		w = p->winding = NewWinding (numpoints);
		w->original = true;
		w->numpoints = numpoints;
		
		for (j=0 ; j<numpoints ; j++)
		{
			double	v[3];
			int		k;

			// scanf into double, then assign to vec_t
			if (fscanf (f, "(%lf %lf %lf ) "
			, &v[0], &v[1], &v[2]) != 3)
				Error ("LoadPortals: reading portal %i", i);
			for (k=0 ; k<3 ; k++)
				w->points[j][k] = v[k];
		}
		fscanf (f, "\n");
		
	// calc plane
		PlaneFromWinding (w, &plane);

	// create forward portal
		l = &leafs[leafnums[0]];
		if (l->numportals == MAX_PORTALS_ON_LEAF)
			Error ("Leaf with too many portals");
		l->portals[l->numportals] = p;
		l->numportals++;
		
		p->winding = w;
		VectorSubtract (vec3_origin, plane.normal, p->plane.normal);
		p->plane.dist = -plane.dist;
		p->leaf = leafnums[1];
		p++;
		
	// create backwards portal
		l = &leafs[leafnums[1]];
		if (l->numportals == MAX_PORTALS_ON_LEAF)
			Error ("Leaf with too many portals");
		l->portals[l->numportals] = p;
		l->numportals++;
		
		p->winding = NewWinding(w->numpoints);
		p->winding->numpoints = w->numpoints;
		for (j=0 ; j<w->numpoints ; j++)
		{
			VectorCopy (w->points[w->numpoints-1-j], p->winding->points[j]);
		}

		p->plane = plane;
		p->leaf = leafnums[0];
		p++;

	}
	
	fclose (f);
}
Beispiel #3
0
/*	Clips the winding to the plane, returning the new winding on the positive side
	Frees the input winding.
	If keepon is TRUE, an exactly on-plane winding will be saved, otherwise
	it will be clipped away.
*/
winding_t *ClipWinding (winding_t *in, plane_t *split, bool keepon)
{
	vec_t		dists[MAX_POINTS_ON_WINDING];
	int			sides[MAX_POINTS_ON_WINDING];
	int			counts[3];
	vec_t		dot;
	int			i, j;
	vec_t		*p1, *p2;
	vec3_t		mid;
	winding_t	*neww;
	int			maxpts;

	counts[0] = counts[1] = counts[2] = 0;

// determine sides for each point
	for (i=0 ; i<in->numpoints ; i++)
	{
		dot = Math_DotProduct(in->points[i],split->normal);
		dot -= split->dist;
		dists[i] = dot;
		if (dot > ON_EPSILON)
			sides[i] = SIDE_FRONT;
		else if (dot < -ON_EPSILON)
			sides[i] = SIDE_BACK;
		else
			sides[i] = SIDE_ON;

		counts[sides[i]]++;
	}
	sides[i] = sides[0];
	dists[i] = dists[0];

	if (keepon && !counts[0] && !counts[1])
		return in;

	if (!counts[0])
	{
		FreeWinding (in);
		return NULL;
	}
	if (!counts[1])
		return in;

	maxpts = in->numpoints+4;	// can't use counts[0]+2 because
								// of fp grouping errors
	neww = NewWinding (maxpts);

	for (i=0 ; i<in->numpoints ; i++)
	{
		p1 = in->points[i];

		if (sides[i] == SIDE_ON)
		{
			Math_VectorCopy(p1,neww->points[neww->numpoints]);
			neww->numpoints++;
			continue;
		}

		if (sides[i] == SIDE_FRONT)
		{
			Math_VectorCopy(p1,neww->points[neww->numpoints]);
			neww->numpoints++;
		}

		if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
			continue;

	// generate a split point
		p2 = in->points[(i+1)%in->numpoints];

		dot = dists[i] / (dists[i]-dists[i+1]);
		for (j=0 ; j<3 ; j++)
		{	// avoid round off error when possible
			if (split->normal[j] == 1)
				mid[j] = split->dist;
			else if (split->normal[j] == -1)
				mid[j] = -split->dist;
			else
				mid[j] = p1[j] + dot*(p2[j]-p1[j]);
		}

		Math_VectorCopy(mid,neww->points[neww->numpoints]);
		neww->numpoints++;
	}

	if (neww->numpoints > maxpts)
		Error ("ClipWinding: points exceeded estimate");

// free the original winding
	FreeWinding (in);

	return neww;
}
Beispiel #4
0
winding_t *BasePolyForPlane (plane_t *p)
{
	int			i, x;
	vec_t		max, v;
	vec3_t		org, vright, vup;
	winding_t	*w;

	// find the major axis
	max = -BOGUS_RANGE;
	x = -1;
	for (i=0 ; i<3; i++)
	{
		v = fabs(p->normal[i]);
		if (v > max)
		{
			x = i;
			max = v;
		}
	}

	if (x==-1)
		Error("BasePolyForPlane: no axis found");

	Math_VectorCopy(vec3_origin,vup);
	switch (x)
	{
	case 0:
	case 1:
		vup[2] = 1;
		break;
	case 2:
		vup[0] = 1;
		break;
	}


	v = Math_DotProduct(vup,p->normal);
	Math_VectorMA(vup,-v,p->normal,vup);
	Math_VectorNormalize(vup);

	Math_VectorScale(p->normal,p->dist,org);

	Math_CrossProduct(vup,p->normal,vright);

	Math_VectorScale(vup,8192,vup);
	Math_VectorScale(vright,8192,vright);

// project a really big	axis aligned box onto the plane
	w = NewWinding (4);

	Math_VectorSubtract(org,vright,w->points[0]);
	Math_VectorAdd(w->points[0],vup,w->points[0]);

	Math_VectorAdd(org,vright,w->points[1]);
	Math_VectorAdd(w->points[1],vup,w->points[1]);

	Math_VectorAdd(org,vright,w->points[2]);
	Math_VectorSubtract(w->points[2],vup,w->points[2]);

	Math_VectorSubtract(org,vright,w->points[3]);
	Math_VectorSubtract(w->points[3],vup,w->points[3]);

	w->numpoints = 4;

	return w;
}
Beispiel #5
0
static void
LoadPortals (char *name)
{
	const char *line;
	char       *err;
	int         numpoints, i, j, k;
	int         read_leafs = 0;
	int         clusternums[2];
	cluster_t  *cluster;
	plane_t     plane;
	portal_t   *portal;
	winding_t  *winding;
	QFile	   *f;

	if (!strcmp (name, "-"))
		f = Qdopen (0, "rt"); // create a QFile of stdin
	else {
		f = Qopen (name, "r");
		if (!f) {
			printf ("LoadPortals: couldn't read %s\n", name);
			printf ("No vising performed.\n");
			exit (1);
		}
	}

	line = Qgetline (f);

	if (line && (!strcmp (line, PORTALFILE "\n")
				 || !strcmp (line, PORTALFILE "\r\n"))) {
		line = Qgetline (f);
		if (!line || sscanf (line, "%i\n", &portalclusters) != 1)
			Sys_Error ("LoadPortals: failed to read header");
		line = Qgetline (f);
		if (!line || sscanf (line, "%i\n", &numportals) != 1)
			Sys_Error ("LoadPortals: failed to read header");
		numrealleafs = portalclusters;
	} else if (line && (!strcmp (line, PORTALFILE_AM "\n")
						|| !strcmp (line, PORTALFILE_AM "\r\n"))) {
		line = Qgetline (f);
		if (!line || sscanf (line, "%i\n", &portalclusters) != 1)
			Sys_Error ("LoadPortals: failed to read header");
		line = Qgetline (f);
		if (!line || sscanf (line, "%i\n", &numportals) != 1)
			Sys_Error ("LoadPortals: failed to read header");
		line = Qgetline (f);
		if (!line || sscanf (line, "%i\n", &numrealleafs) != 1)
			Sys_Error ("LoadPortals: failed to read header");
		read_leafs = 1;
	} else {
		Sys_Error ("LoadPortals: not a portal file");
	}

	if (options.verbosity >= 0) {
		printf ("%4i portalclusters\n", portalclusters);
		printf ("%4i numportals\n", numportals);
		printf ("%4i numrealleafs\n", numrealleafs);
	}

	bitbytes = ((portalclusters + 63) & ~63) >> 3;
	bitlongs = bitbytes / sizeof (long);

	bitbytes_l = ((numrealleafs + 63) & ~63) >> 3;

	// each file portal is split into two memory portals, one for each
	// direction
	portals = calloc (2 * numportals, sizeof (portal_t));

	clusters = calloc (portalclusters, sizeof (cluster_t));

	originalvismapsize = numrealleafs * ((numrealleafs + 7) / 8);

	for (i = 0, portal = portals; i < numportals; i++) {
		line = Qgetline (f);
		if (!line)
			Sys_Error ("LoadPortals: reading portal %i", i);

		numpoints = strtol (line, &err, 10);
		if (err == line)
			Sys_Error ("LoadPortals: reading portal %i", i);
		line = err;
		for (j = 0; j < 2; j++) {
			clusternums[j] = strtol (line, &err, 10);
			if (err == line)
				Sys_Error ("LoadPortals: reading portal %i", i);
			line = err;
		}

		if (numpoints > MAX_POINTS_ON_WINDING)
			Sys_Error ("LoadPortals: portal %i has too many points", i);
		if ((unsigned) clusternums[0] > (unsigned) portalclusters
			|| (unsigned) clusternums[1] > (unsigned) portalclusters)
			Sys_Error ("LoadPortals: reading portal %i", i);

		winding = portal->winding = NewWinding (numpoints);
		winding->original = true;
		winding->numpoints = numpoints;

		for (j = 0; j < numpoints; j++) {
			// (%ld %ld %ld)
			while (isspace ((byte) *line))
				line++;
			if (*line++ != '(')
				Sys_Error ("LoadPortals: reading portal %i", i);

			for (k = 0; k < 3; k++) {
				winding->points[j][k] = strtod (line, &err);
				if (err == line)
					Sys_Error ("LoadPortals: reading portal %i", i);
				line = err;
			}

			while (isspace ((byte) *line))
				line++;
			if (*line++ != ')')
				Sys_Error ("LoadPortals: reading portal %i", i);
		}

		// calc plane
		PlaneFromWinding (winding, &plane);

		// create forward portal
		cluster = &clusters[clusternums[0]];
		if (cluster->numportals == MAX_PORTALS_ON_CLUSTER)
			Sys_Error ("Cluster with too many portals");
		cluster->portals[cluster->numportals] = portal;
		cluster->numportals++;

		portal->winding = winding;
		VectorNegate (plane.normal, portal->plane.normal);
		portal->plane.dist = -plane.dist;
		portal->cluster = clusternums[1];
		portal++;

		// create backwards portal
		cluster = &clusters[clusternums[1]];
		if (cluster->numportals == MAX_PORTALS_ON_CLUSTER)
			Sys_Error ("Cluster with too many portals");
		cluster->portals[cluster->numportals] = portal;
		cluster->numportals++;

		portal->winding = winding;
		portal->plane = plane;
		portal->cluster = clusternums[0];
		portal++;
	}

	leafcluster = calloc (numrealleafs, sizeof (int));
	if (read_leafs) {
		for (i = 0; i < numrealleafs; i++) {
			line = Qgetline (f);
			if (sscanf (line, "%i\n", &leafcluster[i]) != 1)
				Sys_Error ("LoadPortals: parse error in leaf->cluster "
						   "mappings");
		}
	} else {
		for (i = 0; i < numrealleafs; i++)
			leafcluster[i] = i;
	}
	Qclose (f);
}
Beispiel #6
0
winding_t *
BaseWindingForPlane (const plane_t *p)
{
	int         i, x;
	vec_t       max, v;
	vec3_t      org, vright, vup;
	winding_t  *w;

	// find the major axis

	max = -BOGUS;
	x = -1;
	for (i = 0; i < 3; i++) {
		v = fabs (p->normal[i]);
		if (v > max) {
			x = i;
			max = v;
		}
	}
	if (x == -1)
		Sys_Error ("BaseWindingForPlane: no axis found");

	VectorZero (vup);
	switch (x) {
		case 0:
		case 1:
			vup[2] = 1;
			break;
		case 2:
			vup[0] = 1;
			break;
	}

	v = DotProduct (vup, p->normal);
	VectorMultSub (vup, v, p->normal, vup);
	_VectorNormalize (vup);

	VectorScale (p->normal, p->dist, org);

	CrossProduct (vup, p->normal, vright);

	VectorScale (vup, BOGUS, vup);
	VectorScale (vright, BOGUS, vright);

	// project a really big axis aligned box onto the plane
	w = NewWinding (4);

	VectorSubtract (org, vright, w->points[0]);
	VectorAdd (w->points[0], vup, w->points[0]);

	VectorAdd (org, vright, w->points[1]);
	VectorAdd (w->points[1], vup, w->points[1]);

	VectorAdd (org, vright, w->points[2]);
	VectorSubtract (w->points[2], vup, w->points[2]);

	VectorSubtract (org, vright, w->points[3]);
	VectorSubtract (w->points[3], vup, w->points[3]);

	w->numpoints = 4;

	return w;
}
Beispiel #7
0
winding_t *
ClipWinding (winding_t *in, plane_t *split, qboolean keepon)
{
	int         maxpts, i, j;
	int        *sides;
	int         counts[3];
	vec_t       dot;
	vec_t      *dists;
	vec_t      *p1, *p2;
	vec3_t      mid;
	winding_t  *neww;

	counts[0] = counts[1] = counts[2] = 0;

	// +1 for duplicating the first point
	sides = alloca ((in->numpoints + 1) * sizeof (int));
	dists = alloca ((in->numpoints + 1) * sizeof (vec_t));

	// determine sides for each point
	for (i = 0; i < in->numpoints; i++) {
		dot = DotProduct (in->points[i], split->normal);
		dot -= split->dist;
		dists[i] = dot;
		if (dot > ON_EPSILON)
			sides[i] = SIDE_FRONT;
		else if (dot < -ON_EPSILON)
			sides[i] = SIDE_BACK;
		else {
			sides[i] = SIDE_ON;
		}
		counts[sides[i]]++;
	}
	// duplicate the first point
	sides[i] = sides[0];
	dists[i] = dists[0];

	if (keepon && !counts[SIDE_FRONT] && !counts[SIDE_BACK])
		return in;

	if (!counts[SIDE_FRONT]) {
		FreeWinding (in);
		return NULL;
	}
	if (!counts[SIDE_BACK])
		return in;
	for (maxpts = 0, i = 0; i < in->numpoints; i++) {
		if (!(sides[i] & 1))
			maxpts++;
		if ((sides[i] ^ 1) == sides[i + 1])
			maxpts++;
	}
	neww = NewWinding (maxpts);

	for (i = 0; i < in->numpoints; i++) {
		p1 = in->points[i];

		if (sides[i] == SIDE_ON) {
			if (neww->numpoints == maxpts)
				Sys_Error ("ClipWinding: points exceeded estimate");
			VectorCopy (p1, neww->points[neww->numpoints]);
			neww->numpoints++;
			continue;
		}

		if (sides[i] == SIDE_FRONT) {
			if (neww->numpoints == maxpts)
				Sys_Error ("ClipWinding: points exceeded estimate");
			VectorCopy (p1, neww->points[neww->numpoints]);
			neww->numpoints++;
		}

		if (sides[i + 1] == SIDE_ON || sides[i + 1] == sides[i])
			continue;

		if (neww->numpoints == maxpts)
			Sys_Error ("ClipWinding: points exceeded estimate");

		// generate a split point
		p2 = in->points[(i + 1) % in->numpoints];

		dot = dists[i] / (dists[i] - dists[i + 1]);
		for (j = 0; j < 3; j++) {		// avoid round off error when possible
			if (split->normal[j] == 1)
				mid[j] = split->dist;
			else if (split->normal[j] == -1)
				mid[j] = -split->dist;
			else
				mid[j] = p1[j] + dot * (p2[j] - p1[j]);
		}

		VectorCopy (mid, neww->points[neww->numpoints]);
		neww->numpoints++;
	}

	// free the original winding
	FreeWinding (in);

	return neww;
}
Beispiel #8
0
/*
==================
DivideWinding

Divides a winding by a plane, producing one or two windings.  The
original winding is not damaged or freed.  If only on one side, the
returned winding will be the input winding.  If on both sides, two
new windings will be created.
==================
*/
void	DivideWinding (winding_t *in, plane_t *split, winding_t **front, winding_t **back)
{
	vec_t	dists[MAX_POINTS_ON_WINDING];
	int		sides[MAX_POINTS_ON_WINDING];
	int		counts[3];
	vec_t	dot;
	int		i, j;
	vec_t	*p1, *p2;
	vec3_t	mid;
	winding_t	*f, *b;
	int		maxpts;
	
	counts[0] = counts[1] = counts[2] = 0;

// determine sides for each point
	for (i=0 ; i<in->numpoints ; i++)
	{
		dot = DotProduct (in->points[i], split->normal);
		dot -= split->dist;
		dists[i] = dot;
		if (dot > ON_EPSILON)
			sides[i] = SIDE_FRONT;
		else if (dot < -ON_EPSILON)
			sides[i] = SIDE_BACK;
		else
		{
			sides[i] = SIDE_ON;
		}
		counts[sides[i]]++;
	}
	sides[i] = sides[0];
	dists[i] = dists[0];
	
	*front = *back = NULL;

	if (!counts[0])
	{
		*back = in;
		return;
	}
	if (!counts[1])
	{
		*front = in;
		return;
	}

	maxpts = in->numpoints+4;	// can't use counts[0]+2 because
								// of fp grouping errors

	*front = f = NewWinding (maxpts);
	*back = b = NewWinding (maxpts);
		
	for (i=0 ; i<in->numpoints ; i++)
	{
		p1 = in->points[i];
		
		if (sides[i] == SIDE_ON)
		{
			VectorCopy (p1, f->points[f->numpoints]);
			f->numpoints++;
			VectorCopy (p1, b->points[b->numpoints]);
			b->numpoints++;
			continue;
		}
	
		if (sides[i] == SIDE_FRONT)
		{
			VectorCopy (p1, f->points[f->numpoints]);
			f->numpoints++;
		}
		if (sides[i] == SIDE_BACK)
		{
			VectorCopy (p1, b->points[b->numpoints]);
			b->numpoints++;
		}

		if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
			continue;
			
	// generate a split point
		p2 = in->points[(i+1)%in->numpoints];
		
		dot = dists[i] / (dists[i]-dists[i+1]);
		for (j=0 ; j<3 ; j++)
		{	// avoid round off error when possible
			if (split->normal[j] == 1)
				mid[j] = split->dist;
			else if (split->normal[j] == -1)
				mid[j] = -split->dist;
			else
				mid[j] = p1[j] + dot*(p2[j]-p1[j]);
		}
			
		VectorCopy (mid, f->points[f->numpoints]);
		f->numpoints++;
		VectorCopy (mid, b->points[b->numpoints]);
		b->numpoints++;
	}
	
	if (f->numpoints > maxpts || b->numpoints > maxpts)
		Error ("ClipWinding: points exceeded estimate");
}
Beispiel #9
0
/*
 * @brief
 */
static void LoadPortals(const char *filename) {
	uint32_t i;
	portal_t *p;
	leaf_t *l;
	char magic[80];
	char *buffer, *s;
	int32_t len;
	int32_t num_points;
	winding_t *w;
	int32_t leaf_nums[2];
	plane_t plane;

	if (Fs_Load(filename, (void **) &buffer) == -1)
		Com_Error(ERR_FATAL, "Could not open %s\n", filename);

	s = buffer;

	memset(&map_vis, 0, sizeof(map_vis));

	if (sscanf(s, "%79s\n%u\n%u\n%n", magic, &map_vis.portal_clusters, &map_vis.num_portals, &len)
			!= 3)
		Com_Error(ERR_FATAL, "Failed to read header: %s\n", filename);
	s += len;

	if (g_strcmp0(magic, PORTALFILE))
		Com_Error(ERR_FATAL, "Not a portal file: %s\n", filename);

	Com_Verbose("Loading %4u portals, %4u clusters from %s...\n", map_vis.num_portals,
			map_vis.portal_clusters, filename);

	// these counts should take advantage of 64 bit systems automatically
	map_vis.leaf_bytes = ((map_vis.portal_clusters + 63) & ~63) >> 3;
	map_vis.leaf_longs = map_vis.leaf_bytes / sizeof(long);

	map_vis.portal_bytes = ((map_vis.num_portals * 2 + 63) & ~63) >> 3;
	map_vis.portal_longs = map_vis.portal_bytes / sizeof(long);

	// each file portal is split into two memory portals
	map_vis.portals = Mem_Malloc(2 * map_vis.num_portals * sizeof(portal_t));

	// allocate the leafs
	map_vis.leafs = Mem_Malloc(map_vis.portal_clusters * sizeof(leaf_t));

	map_vis.uncompressed_size = map_vis.portal_clusters * map_vis.leaf_bytes;
	map_vis.uncompressed = Mem_Malloc(map_vis.uncompressed_size);

	map_vis.base = map_vis.pointer = d_bsp.vis_data;
	d_vis->num_clusters = map_vis.portal_clusters;
	map_vis.pointer = (byte *) &d_vis->bit_offsets[map_vis.portal_clusters];

	map_vis.end = map_vis.base + MAX_BSP_VISIBILITY;

	for (i = 0, p = map_vis.portals; i < map_vis.num_portals; i++) {
		int32_t j;

		if (sscanf(s, "%i %i %i %n", &num_points, &leaf_nums[0], &leaf_nums[1], &len) != 3) {
			Com_Error(ERR_FATAL, "Failed to read portal %i\n", i);
		}
		s += len;

		if (num_points > MAX_POINTS_ON_WINDING) {
			Com_Error(ERR_FATAL, "Portal %i has too many points\n", i);
		}

		if ((uint32_t) leaf_nums[0] > map_vis.portal_clusters || (uint32_t) leaf_nums[1]
				> map_vis.portal_clusters) {
			Com_Error(ERR_FATAL, "Portal %i has invalid leafs\n", i);
		}

		w = p->winding = NewWinding(num_points);
		w->original = true;
		w->num_points = num_points;

		for (j = 0; j < num_points; j++) {
			double v[3];
			int32_t k;

			// scanf into double, then assign to vec_t
			// so we don't care what size vec_t is
			if (sscanf(s, "(%lf %lf %lf ) %n", &v[0], &v[1], &v[2], &len) != 3)
				Com_Error(ERR_FATAL, "Failed to read portal vertex definition %i:%i\n", i, j);
			s += len;

			for (k = 0; k < 3; k++)
				w->points[j][k] = v[k];
		}
		if (sscanf(s, "\n%n", &len)) {
			s += len;
		}

		// calc plane
		PlaneFromWinding(w, &plane);

		// create forward portal
		l = &map_vis.leafs[leaf_nums[0]];
		if (l->num_portals == MAX_PORTALS_ON_LEAF)
			Com_Error(ERR_FATAL, "MAX_PORTALS_ON_LEAF\n");
		l->portals[l->num_portals] = p;
		l->num_portals++;

		p->winding = w;
		VectorSubtract(vec3_origin, plane.normal, p->plane.normal);
		p->plane.dist = -plane.dist;
		p->leaf = leaf_nums[1];
		SetPortalSphere(p);
		p++;

		// create backwards portal
		l = &map_vis.leafs[leaf_nums[1]];
		if (l->num_portals == MAX_PORTALS_ON_LEAF)
			Com_Error(ERR_FATAL, "MAX_PORTALS_ON_LEAF\n");
		l->portals[l->num_portals] = p;
		l->num_portals++;

		p->winding = NewWinding(w->num_points);
		p->winding->num_points = w->num_points;
		for (j = 0; j < w->num_points; j++) {
			VectorCopy(w->points[w->num_points - 1 - j], p->winding->points[j]);
		}

		p->plane = plane;
		p->leaf = leaf_nums[0];
		SetPortalSphere(p);
		p++;
	}

	Fs_Free(buffer);
}
Beispiel #10
0
/*
   ============
   LoadPortals
   ============
 */
void LoadPortals( char *name ){
	int i, j;
	portal_t    *p;
	leaf_t      *l;
	char magic[80];
	FILE        *f;
	int numpoints;
	winding_t   *w;
	int leafnums[2];
	plane_t plane;

	if ( !strcmp( name,"-" ) ) {
		f = stdin;
	}
	else
	{
		f = fopen( name, "r" );
		if ( !f ) {
			Error( "LoadPortals: couldn't read %s\n",name );
		}
	}

	if ( fscanf( f,"%79s\n%i\n%i\n",magic, &portalclusters, &numportals ) != 3 ) {
		Error( "LoadPortals: failed to read header" );
	}
	if ( strcmp( magic,PORTALFILE ) ) {
		Error( "LoadPortals: not a portal file" );
	}

	Sys_Printf( "%4i portalclusters\n", portalclusters );
	Sys_Printf( "%4i numportals\n", numportals );

	// these counts should take advantage of 64 bit systems automatically
	leafbytes = ( ( portalclusters + 63 ) & ~63 ) >> 3;
	leaflongs = leafbytes / sizeof( long );

	portalbytes = ( ( numportals * 2 + 63 ) & ~63 ) >> 3;
	portallongs = portalbytes / sizeof( long );

// each file portal is split into two memory portals
	portals = malloc( 2 * numportals * sizeof( portal_t ) );
	memset( portals, 0, 2 * numportals * sizeof( portal_t ) );

	leafs = malloc( portalclusters * sizeof( leaf_t ) );
	memset( leafs, 0, portalclusters * sizeof( leaf_t ) );

	originalvismapsize = portalclusters * leafbytes;
	uncompressedvis = malloc( originalvismapsize );

	vismap = vismap_p = dvisdata;
	dvis->numclusters = portalclusters;
	vismap_p = (byte *)&dvis->bitofs[portalclusters];

	vismap_end = vismap + MAX_MAP_VISIBILITY;

	for ( i = 0, p = portals ; i < numportals ; i++ )
	{
		if ( fscanf( f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1] )
			 != 3 ) {
			Error( "LoadPortals: reading portal %i", i );
		}
		if ( numpoints > MAX_POINTS_ON_WINDING ) {
			Error( "LoadPortals: portal %i has too many points", i );
		}
		if ( (unsigned)leafnums[0] > portalclusters
			 || (unsigned)leafnums[1] > portalclusters ) {
			Error( "LoadPortals: reading portal %i", i );
		}

		w = p->winding = NewWinding( numpoints );
		w->original = true;
		w->numpoints = numpoints;

		for ( j = 0 ; j < numpoints ; j++ )
		{
			double v[3];
			int k;

			// scanf into double, then assign to vec_t
			// so we don't care what size vec_t is
			if ( fscanf( f, "(%lf %lf %lf ) "
						 , &v[0], &v[1], &v[2] ) != 3 ) {
				Error( "LoadPortals: reading portal %i", i );
			}
			for ( k = 0 ; k < 3 ; k++ )
				w->points[j][k] = v[k];
		}
		fscanf( f, "\n" );

		// calc plane
		PlaneFromWinding( w, &plane );

		// create forward portal
		l = &leafs[leafnums[0]];
		if ( l->numportals == MAX_PORTALS_ON_LEAF ) {
			Error( "Leaf with too many portals" );
		}
		l->portals[l->numportals] = p;
		l->numportals++;

		p->winding = w;
		VectorSubtract( vec3_origin, plane.normal, p->plane.normal );
		p->plane.dist = -plane.dist;
		p->leaf = leafnums[1];
		SetPortalSphere( p );
		p++;

		// create backwards portal
		l = &leafs[leafnums[1]];
		if ( l->numportals == MAX_PORTALS_ON_LEAF ) {
			Error( "Leaf with too many portals" );
		}
		l->portals[l->numportals] = p;
		l->numportals++;

		p->winding = NewWinding( w->numpoints );
		p->winding->numpoints = w->numpoints;
		for ( j = 0 ; j < w->numpoints ; j++ )
		{
			VectorCopy( w->points[w->numpoints - 1 - j], p->winding->points[j] );
		}

		p->plane = plane;
		p->leaf = leafnums[0];
		SetPortalSphere( p );
		p++;

	}

	fclose( f );
}
Beispiel #11
0
/*
============
LoadPortals
============
*/
void LoadPortals (char *name)
{
    int			i, j;
    portal_t	*p;
    leaf_t		*l;
    char		magic[80];
    int			numpoints;
    winding_t	*w;
    int			leafnums[2];
    plane_t		plane;

    FILE *f;

    // Open the portal file.
    if ( g_bUseMPI )
    {
        // If we're using MPI, copy off the file to a temporary first. This will download the file
        // from the MPI master, then we get to use nice functions like fscanf on it.
        char tempPath[MAX_PATH], tempFile[MAX_PATH];
        if ( GetTempPath( sizeof( tempPath ), tempPath ) == 0 )
        {
            Error( "LoadPortals: GetTempPath failed.\n" );
        }

        if ( GetTempFileName( tempPath, "vvis_portal_", 0, tempFile ) == 0 )
        {
            Error( "LoadPortals: GetTempFileName failed.\n" );
        }

        // Read all the data from the network file into memory.
        FileHandle_t hFile = g_pFileSystem->Open(name, "r");
        if ( hFile == FILESYSTEM_INVALID_HANDLE )
            Error( "LoadPortals( %s ): couldn't get file from master.\n", name );

        CUtlVector<char> data;
        data.SetSize( g_pFileSystem->Size( hFile ) );
        g_pFileSystem->Read( data.Base(), data.Count(), hFile );
        g_pFileSystem->Close( hFile );

        // Dump it into a temp file.
        f = fopen( tempFile, "wt" );
        fwrite( data.Base(), 1, data.Count(), f );
        fclose( f );

        // Open the temp file up.
        f = fopen( tempFile, "rSTD" ); // read only, sequential, temporary, delete on close
    }
    else
    {
        f = fopen( name, "r" );
    }

    if ( !f )
        Error ("LoadPortals: couldn't read %s\n",name);

    if (fscanf (f,"%79s\n%i\n%i\n",magic, &portalclusters, &g_numportals) != 3)
        Error ("LoadPortals: failed to read header");
    if (stricmp(magic,PORTALFILE))
        Error ("LoadPortals: not a portal file");

    Msg ("%4i portalclusters\n", portalclusters);
    Msg ("%4i numportals\n", g_numportals);

    if (g_numportals * 2 >= MAX_PORTALS)
    {
        Error("The map overflows the max portal count (%d of max %d)!\n", g_numportals, MAX_PORTALS / 2 );
    }

    // these counts should take advantage of 64 bit systems automatically
    leafbytes = ((portalclusters+63)&~63)>>3;
    leaflongs = leafbytes/sizeof(long);

    portalbytes = ((g_numportals*2+63)&~63)>>3;
    portallongs = portalbytes/sizeof(long);

// each file portal is split into two memory portals
    portals = (portal_t*)malloc(2*g_numportals*sizeof(portal_t));
    memset (portals, 0, 2*g_numportals*sizeof(portal_t));

    leafs = (leaf_t*)malloc(portalclusters*sizeof(leaf_t));
    memset (leafs, 0, portalclusters*sizeof(leaf_t));

    originalvismapsize = portalclusters*leafbytes;
    uncompressedvis = (byte*)malloc(originalvismapsize);

    vismap = vismap_p = dvisdata;
    dvis->numclusters = portalclusters;
    vismap_p = (byte *)&dvis->bitofs[portalclusters];

    vismap_end = vismap + MAX_MAP_VISIBILITY;

    for (i=0, p=portals ; i<g_numportals ; i++)
    {
        if (fscanf (f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1])
                != 3)
            Error ("LoadPortals: reading portal %i", i);
        if (numpoints > MAX_POINTS_ON_WINDING)
            Error ("LoadPortals: portal %i has too many points", i);
        if ( (unsigned)leafnums[0] > portalclusters
                || (unsigned)leafnums[1] > portalclusters)
            Error ("LoadPortals: reading portal %i", i);

        w = p->winding = NewWinding (numpoints);
        w->original = true;
        w->numpoints = numpoints;

        for (j=0 ; j<numpoints ; j++)
        {
            double	v[3];
            int		k;

            // scanf into double, then assign to vec_t
            // so we don't care what size vec_t is
            if (fscanf (f, "(%lf %lf %lf ) "
                        , &v[0], &v[1], &v[2]) != 3)
                Error ("LoadPortals: reading portal %i", i);
            for (k=0 ; k<3 ; k++)
                w->points[j][k] = v[k];
        }
        fscanf (f, "\n");

        // calc plane
        PlaneFromWinding (w, &plane);

        // create forward portal
        l = &leafs[leafnums[0]];
        if (l->numportals == MAX_PORTALS_ON_LEAF)
            Error ("Leaf %d (portal %d) with too many portals. Use vbsp -glview to compile, then glview -portal -portalhighlight X or -leafhighlight L to view the problem.", leafnums[0], i );
        l->portals[l->numportals] = p;
        l->numportals++;

        p->winding = w;
        VectorSubtract (vec3_origin, plane.normal, p->plane.normal);
        p->plane.dist = -plane.dist;
        p->leaf = leafnums[1];
        SetPortalSphere (p);
        p++;

        // create backwards portal
        l = &leafs[leafnums[1]];
        if (l->numportals == MAX_PORTALS_ON_LEAF)
            Error ("Leaf %d (portal %d) with too many portals. Use vbsp -glview to compile, then glview -portal -portalhighlight X or -leafhighlight L to view the problem.", leafnums[1], i );
        l->portals[l->numportals] = p;
        l->numportals++;

        p->winding = NewWinding(w->numpoints);
        p->winding->numpoints = w->numpoints;
        for (j=0 ; j<w->numpoints ; j++)
        {
            VectorCopy (w->points[w->numpoints-1-j], p->winding->points[j]);
        }

        p->plane = plane;
        p->leaf = leafnums[0];
        SetPortalSphere (p);
        p++;

    }

    fclose (f);
}
Beispiel #12
0
/*
  ============
  LoadPortals
  ============
*/
void
LoadPortals(char *name, bsp2_t *bsp)
{
    int i, j, count;
    portal_t *p;
    leaf_t *l;
    char magic[80];
    FILE *f;
    int numpoints;
    winding_t *w;
    int leafnums[2];
    plane_t plane;

    if (!strcmp(name, "-"))
        f = stdin;
    else {
        f = fopen(name, "r");
        if (!f) {
            logprint("%s: couldn't read %s\n", __func__, name);
            logprint("No vising performed.\n");
            exit(1);
        }
    }

    /*
     * Parse the portal file header
     */
    count = fscanf(f, "%79s\n", magic);
    if (count != 1)
        Error("%s: unknown header: %s\n", __func__, magic);

    if (!strcmp(magic, PORTALFILE)) {
        count = fscanf(f, "%i\n%i\n", &portalleafs, &numportals);
        if (count != 2)
            Error("%s: unable to parse %s HEADER\n", __func__, PORTALFILE);
        portalleafs_real = portalleafs;
        logprint("%6d leafs\n", portalleafs);
        logprint("%6d portals\n", numportals);
    } else if (!strcmp(magic, PORTALFILE2)) {
        count = fscanf(f, "%i\n%i\n%i\n", &portalleafs_real, &portalleafs,
                       &numportals);
        if (count != 3)
            Error("%s: unable to parse %s HEADER\n", __func__, PORTALFILE);
        logprint("%6d leafs\n", portalleafs_real);
        logprint("%6d clusters\n", portalleafs);
        logprint("%6d portals\n", numportals);
    } else {
        Error("%s: unknown header: %s\n", __func__, magic);
    }

    leafbytes = ((portalleafs + 63) & ~63) >> 3;
    leaflongs = leafbytes / sizeof(long);
    leafbytes_real = ((portalleafs_real + 63) & ~63) >> 3;

// each file portal is split into two memory portals
    portals = malloc(2 * numportals * sizeof(portal_t));
    memset(portals, 0, 2 * numportals * sizeof(portal_t));

    leafs = malloc(portalleafs * sizeof(leaf_t));
    memset(leafs, 0, portalleafs * sizeof(leaf_t));

    originalvismapsize = portalleafs_real * ((portalleafs_real + 7) / 8);

    // FIXME - more intelligent allocation?
    bsp->dvisdata = malloc(MAX_MAP_VISIBILITY);
    if (!bsp->dvisdata)
        Error("%s: dvisdata allocation failed (%i bytes)", __func__,
              MAX_MAP_VISIBILITY);
    memset(bsp->dvisdata, 0, MAX_MAP_VISIBILITY);

    vismap = vismap_p = bsp->dvisdata;
    vismap_end = vismap + MAX_MAP_VISIBILITY;

    for (i = 0, p = portals; i < numportals; i++) {
        if (fscanf(f, "%i %i %i ", &numpoints, &leafnums[0], &leafnums[1])
            != 3)
            Error("%s: reading portal %i", __func__, i);
        if (numpoints > MAX_WINDING)
            Error("%s: portal %i has too many points", __func__, i);
        if ((unsigned)leafnums[0] > (unsigned)portalleafs
            || (unsigned)leafnums[1] > (unsigned)portalleafs)
            Error("%s: reading portal %i", __func__, i);

        w = p->winding = NewWinding(numpoints);
        w->numpoints = numpoints;

        for (j = 0; j < numpoints; j++) {
            double v[3];
            int k;

            // scanf into double, then assign to vec_t
            if (fscanf(f, "(%lf %lf %lf ) ", &v[0], &v[1], &v[2]) != 3)
                Error("%s: reading portal %i", __func__, i);
            for (k = 0; k < 3; k++)
                w->points[j][k] = (vec_t)v[k];
        }
        fscanf(f, "\n");

        // calc plane
        PlaneFromWinding(w, &plane);

        // create forward portal
        l = &leafs[leafnums[0]];
        if (l->numportals == MAX_PORTALS_ON_LEAF)
            Error("Leaf with too many portals");
        l->portals[l->numportals] = p;
        l->numportals++;

        p->winding = w;
        VectorSubtract(vec3_origin, plane.normal, p->plane.normal);
        p->plane.dist = -plane.dist;
        p->leaf = leafnums[1];
        SetWindingSphere(p->winding);
        p++;

        // create backwards portal
        l = &leafs[leafnums[1]];
        if (l->numportals == MAX_PORTALS_ON_LEAF)
            Error("Leaf with too many portals");
        l->portals[l->numportals] = p;
        l->numportals++;

        // Create a reverse winding
        p->winding = NewWinding(numpoints);
        p->winding->numpoints = numpoints;
        for (j = 0; j < numpoints; ++j)
            VectorCopy(w->points[numpoints - (j + 1)], p->winding->points[j]);

        //p->winding = w;
        p->plane = plane;
        p->leaf = leafnums[0];
        SetWindingSphere(p->winding);
        p++;
    }

    /* Load the cluster expansion map if needed */
    if (portalleafs != portalleafs_real) {
        clustermap = malloc(portalleafs_real * sizeof(int));
        for (i = 0; i < portalleafs; i++) {
            while (1) {
                int leafnum;
                count = fscanf(f, "%i", &leafnum);
                if (!count || count == EOF)
                    break;
                if (leafnum < 0)
                    break;
                if (leafnum >= portalleafs_real)
                    Error("Invalid leaf number in cluster map (%d >= %d",
                          leafnum, portalleafs_real);
                clustermap[leafnum] = i;
            }
            if (count == EOF)
                break;
        }
        if (i < portalleafs)
            Error("Couldn't read cluster map (%d / %d)\n", i, portalleafs);
    }

    fclose(f);
}