Exemple #1
0
void WritePortalFile_r (node_t *node)
{
	int		i;	
	portal_t	*p;
	winding_t	*w;
	dplane_t		*pl, plane2;

	if (!node->contents)
	{
		WritePortalFile_r (node->children[0]);
		WritePortalFile_r (node->children[1]);
		return;
	}
	
	if (node->contents == CONTENTS_SOLID)
		return;

	for (p = node->portals ; p ; )
	{
		w = p->winding;
		if (w && p->nodes[0] == node)
		{
			if ( (watervis && p->nodes[0]->contents != CONTENTS_SOLID && p->nodes[1]->contents != CONTENTS_SOLID) 
				|| (p->nodes[0]->contents == p->nodes[1]->contents) )
			{
			// write out to the file
			
			// sometimes planes get turned around when they are very near
			// the changeover point between different axis.  interpret the
			// plane the same way vis will, and flip the side orders if needed
				PlaneFromWinding (w, &plane2);
				if ( DotProduct (p->plane.normal, plane2.normal) < 1.0-ON_EPSILON )
				{	// backwards...
					fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->visleafnum, p->nodes[0]->visleafnum);
				}
				else
					fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->visleafnum, p->nodes[1]->visleafnum);
				for (i=0 ; i<w->numpoints ; i++)
				{
					fprintf (pf,"(");
					WriteFloat (pf, w->points[i][0]);
					WriteFloat (pf, w->points[i][1]);
					WriteFloat (pf, w->points[i][2]);
					fprintf (pf,") ");
				}
				fprintf (pf,"\n");
			}
		}

		if (p->nodes[0] == node)
			p = p->next[0];
		else
			p = p->next[1];
	}

}
static void WritePortalFile_r (node_t *node)
{
	int		i;
	portal_t	*p;
	winding_t	*w;
	plane_t		*pl, plane2;

	if (!node->contents)
	{
		WritePortalFile_r (node->children[0]);
		WritePortalFile_r (node->children[1]);
		return;
	}

	if (node->contents == BSP_CONTENTS_SOLID)
		return;

	for (p = node->portals ; p ; )
	{
		w = p->winding;
		// LordHavoc: transparent water support
		if (w && p->nodes[0] == node && PortalSidesVisible (p))
		{
			// write out to the file

			// sometimes planes get turned around when they are very near
			// the changeover point between different axis. interpret the
			// plane the same way vis will, and flip the side orders if needed
			pl = &mapplanes[p->planenum];
			PlaneFromWinding (w, &plane2);
			if ( DotProduct (pl->normal, plane2.normal) < 0.99 ) // backwards...
				fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->visleafnum, p->nodes[0]->visleafnum);
			else
				fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->visleafnum, p->nodes[1]->visleafnum);

			// Vic: proper float output
			for (i=0 ; i<w->numpoints ; i++)
			{
				fprintf (pf, "(");
				WriteFloatToPortalFile (w->points[i][0]);
				fprintf (pf, " ");
				WriteFloatToPortalFile (w->points[i][1]);
				fprintf (pf, " ");
				WriteFloatToPortalFile (w->points[i][2]);
				fprintf (pf, ")");
				fprintf (pf, i == w->numpoints-1 ? "\n" : " ");
			}
		}

		if (p->nodes[0] == node)
			p = p->next[0];
		else
			p = p->next[1];
	}
}
Exemple #3
0
static void
WritePortalFile_r(node_t *node)
{
    int i;
    portal_t *p;
    winding_t *w;
    plane_t *pl, plane2;

    if (!node->contents) {
	WritePortalFile_r(node->children[0]);
	WritePortalFile_r(node->children[1]);
	return;
    }

    if (node->contents == CONTENTS_SOLID)
	return;

    for (p = node->portals; p;) {
	w = p->winding;
	if (w && p->nodes[0] == node
	    && SameContent(p->nodes[0]->contents, p->nodes[1]->contents)) {
	    /*
	     * sometimes planes get turned around when they are very near
	     * the changeover point between different axis.  interpret the
	     * plane the same way vis will, and flip the side orders if needed
	     */
	    pl = &pPlanes[p->planenum];
	    PlaneFromWinding(w, &plane2);

	    if (DotProduct(pl->normal, plane2.normal) < 1.0 - ANGLEEPSILON) {
		/* backwards... */
		fprintf(PortalFile, "%i %i %i ", w->numpoints,
			p->nodes[1]->visleafnum, p->nodes[0]->visleafnum);
	    } else
		fprintf(PortalFile, "%i %i %i ", w->numpoints,
			p->nodes[0]->visleafnum, p->nodes[1]->visleafnum);
	    for (i = 0; i < w->numpoints; i++) {
		fprintf(PortalFile, "(");
		WriteFloat(w->points[i][0]);
		WriteFloat(w->points[i][1]);
		WriteFloat(w->points[i][2]);
		fprintf(PortalFile, ") ");
	    }
	    fprintf(PortalFile, "\n");
	}

	if (p->nodes[0] == node)
	    p = p->next[0];
	else
	    p = p->next[1];
    }
}
Exemple #4
0
void CheckLeafPortalConsistancy (node_t *node)
{
	int			side, side2;
	portal_t	*p, *p2;
	dplane_t	plane, plane2;
	int			i;
	winding_t	*w;
	float		dist;

	side = side2 = 0;		// quiet compiler warning

	for (p = node->portals ; p ; p = p->next[side])	
	{
		if (p->nodes[0] == node)
			side = 0;
		else if (p->nodes[1] == node)
			side = 1;
		else
			Error ("CutNodePortals_r: mislinked portal");
		CheckWindingInNode (p->winding, node);
		CheckWindingArea (p->winding);

	// check that the side orders are correct
		plane = p->plane;
 		PlaneFromWinding (p->winding, &plane2);
		
		for (p2 = node->portals ; p2 ; p2 = p2->next[side2])	
		{
			if (p2->nodes[0] == node)
				side2 = 0;
			else if (p2->nodes[1] == node)
				side2 = 1;
			else
				Error ("CutNodePortals_r: mislinked portal");
			w = p2->winding;
			for (i=0 ; i<w->numpoints ; i++)
			{
				dist = DotProduct (w->points[i], plane.normal) - plane.dist;
				if ( (side == 0 && dist < -1) || (side == 1 && dist > 1) )
				{
					printf ("WARNING: portal siding direction is wrong\n");
					return;
				}
			}
			
		}
	}
}
Exemple #5
0
static void
CheckLeafPortalConsistancy(node_t *node)
{
    int side, side2;
    portal_t *p, *p2;
    plane_t plane, plane2;
    int i;
    winding_t *w;
    vec_t dist;

    side = side2 = 0;		// quiet compiler warning

    for (p = node->portals; p; p = p->next[side]) {
	if (p->nodes[0] == node)
	    side = 0;
	else if (p->nodes[1] == node)
	    side = 1;
	else
	    Message(msgError, errMislinkedPortal);
	CheckWindingInNode(p->winding, node);
	CheckWindingArea(p->winding);

	// check that the side orders are correct
	plane = pPlanes[p->planenum];
	PlaneFromWinding(p->winding, &plane2);

	for (p2 = node->portals; p2; p2 = p2->next[side2]) {
	    if (p2->nodes[0] == node)
		side2 = 0;
	    else if (p2->nodes[1] == node)
		side2 = 1;
	    else
		Message(msgError, errMislinkedPortal);
	    w = p2->winding;
	    for (i = 0; i < w->numpoints; i++) {
		dist = DotProduct(w->points[i], plane.normal) - plane.dist;
		if ((side == 0 && dist < -1) || (side == 1 && dist > 1)) {
		    Message(msgWarning, warnBadPortalDirection);
		    return;
		}
	    }
	}
    }
}
Exemple #6
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);
}
Exemple #7
0
/*
============
LoadPortals
============
*/
void LoadPortals(char *name)
{
	int             i, j, hint;
	vportal_t      *p;
	leaf_t         *l;
	char            magic[80];
	FILE           *f;
	int             numpoints;
	fixedWinding_t *w;
	int             leafnums[2];
	visPlane_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%i\n", magic, &portalclusters, &numportals, &numfaces) != 4)
		Error("LoadPortals: failed to read header");
	if(strcmp(magic, PORTALFILE))
		Error("LoadPortals: not a portal file");

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

	if(numportals > MAX_PORTALS)
		Error("MAX_PORTALS");

	// 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 = safe_malloc(2 * numportals * sizeof(vportal_t));
	memset(portals, 0, 2 * numportals * sizeof(vportal_t));

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

	for(i = 0; i < portalclusters; i++)
		leafs[i].merged = -1;

	numBSPVisBytes = VIS_HEADER_SIZE + portalclusters * leafbytes;

	if(numBSPVisBytes > MAX_MAP_VISIBILITY)
		Error("MAX_MAP_VISIBILITY exceeded");

	((int *)bspVisBytes)[0] = portalclusters;
	((int *)bspVisBytes)[1] = leafbytes;

	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);
		if(fscanf(f, "%i ", &hint) != 1)
			Error("LoadPortals: reading hint state");

		w = p->winding = NewFixedWinding(numpoints);
		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->num = i + 1;
		p->hint = hint;
		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->num = i + 1;
		p->hint = hint;
		p->winding = NewFixedWinding(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++;

	}

	faces = safe_malloc(2 * numfaces * sizeof(vportal_t));
	memset(faces, 0, 2 * numfaces * sizeof(vportal_t));

	faceleafs = safe_malloc(portalclusters * sizeof(leaf_t));
	memset(faceleafs, 0, portalclusters * sizeof(leaf_t));

	for(i = 0, p = faces; i < numfaces; i++)
	{
		if(fscanf(f, "%i %i ", &numpoints, &leafnums[0]) != 2)
			Error("LoadPortals: reading portal %i", i);

		w = p->winding = NewFixedWinding(numpoints);
		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);

		l = &faceleafs[leafnums[0]];
		l->merged = -1;
		if(l->numportals == MAX_PORTALS_ON_LEAF)
			Error("Leaf with too many faces");
		l->portals[l->numportals] = p;
		l->numportals++;

		p->num = i + 1;
		p->winding = w;
		// normal pointing out of the leaf
		VectorSubtract(vec3_origin, plane.normal, p->plane.normal);
		p->plane.dist = -plane.dist;
		p->leaf = -1;
		SetPortalSphere(p);
		p++;
	}

	fclose(f);
}
Exemple #8
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);
}
Exemple #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);
}
Exemple #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 );
}
Exemple #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);
}
Exemple #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);
}
/*
==================
CheckWinding

Check for possible errors
==================
*/
void CheckWinding( winding_t *w )
{
	int		i, j;
	vec_t	*p1, *p2;
	vec_t	d, edgedist;
	vec3_t	dir, edgenormal;
	plane_t	facenormal;

	PlaneFromWinding ( w, &facenormal );

	if (w->numpoints < 3)
	{
		printf( "CheckWinding: too few points to form a triangle at %f %f %f\n", w->points[0][0], w->points[0][1], w->points[0][2] );
		w->numpoints = 0;
		return;
	}

	// try repeatedly if an error is corrected
	// (fixing one may expose another)
	do
	{
		for( i = 0; i < w->numpoints; i++ )
		{
			p1 = w->points[i];
			p2 = w->points[(i + 1) % w->numpoints];

			for( j = 0; j < 3; j++ )
				if( p1[j] >= BOGUS_RANGE || p1[j] <= -BOGUS_RANGE )
					Error( "CheckWinding: BOGUS_RANGE: %f %f %f\n", p1[0], p1[1], p1[2] );

			// check the point is on the face plane
			d = DotProduct( p1, facenormal.normal ) - facenormal.dist;
			if( d < -WINDING_EPSILON || d > WINDING_EPSILON )
			{
				printf( "CheckWinding: point off plane at %f %f %f, attempting to fix\n", p1[0], p1[1], p1[2] );
				VectorMA(p1, -d, facenormal.normal, p1);
				break;
			}

			// check the edge isn't degenerate
			VectorSubtract( p2, p1, dir );
			if( VectorLength( dir ) < WINDING_EPSILON )
			{
				printf( "CheckWinding: healing degenerate edge at %f %f %f\n", p2[0], p2[1], p2[2] );
				for (j = i + 1;j < w->numpoints;j++)
					VectorCopy(w->points[j - 1], w->points[j]);
				w->numpoints--;
				break;
			}

			// calculate edge plane to check for concavity
			CrossProduct( facenormal.normal, dir, edgenormal );
			VectorNormalize( edgenormal );
			edgedist = DotProduct( p1, edgenormal );

			// all other points must be on front side
			for( j = 0; j < w->numpoints; j++ )
			{
				d = DotProduct( w->points[j], edgenormal );
				if( d > edgedist + WINDING_EPSILON )
				{
					printf( "CheckWinding: non-convex polygon at %f %f %f, attempting to heal\n", w->points[j][0], w->points[j][1], w->points[j][2] );
					VectorMA(w->points[j], -d, edgenormal, w->points[j]);
					break;
				}
			}
			if (j < w->numpoints)
				break;
		}
	}
	while (i < w->numpoints);
}