Ejemplo n.º 1
0
/*
 * @brief
 */
static void CalcVis(void) {
	uint32_t i;

	RunThreadsOn(map_vis.num_portals * 2, true, BaseVis);

	SortPortals();

	// fast vis just uses migh_tsee for a very loose bound
	if (fastvis) {
		for (i = 0; i < map_vis.num_portals * 2; i++) {
			map_vis.portals[i].vis = map_vis.portals[i].flood;
			map_vis.portals[i].status = stat_done;
		}
	} else {
		RunThreadsOn(map_vis.num_portals * 2, true, FinalVis);
	}

	// assemble the leaf vis lists by OR-ing and compressing the portal lists
	for (i = 0; i < map_vis.portal_clusters; i++)
		ClusterMerge(i);

	if (map_vis.portal_clusters)
		Com_Print("Average clusters visible: %i\n", visibility_count / map_vis.portal_clusters);
	else
		Com_Print("Average clusters visible: 0\n");
}
Ejemplo n.º 2
0
void MakeAllScales (void)
{
	strcpy(transferfile, source);
	StripExtension( transferfile );
	DefaultExtension( transferfile, ".r2" );

	if ( !incremental
	  || !IsIncremental(incrementfile)
	  || (unsigned)readtransfers(transferfile, num_patches) != num_patches )
	{
		// determine visibility between patches
		BuildVisMatrix ();

		RunThreadsOn (num_patches, true, MakeScales);
		if ( incremental )
			writetransfers(transferfile, num_patches);
		else
			unlink(transferfile);

		// release visibility matrix
		FreeVisMatrix ();
	}

	qprintf ("transfer lists: %5.1f megs\n"
		, (float)total_transfer * sizeof(transfer_t) / (1024*1024));
}
Ejemplo n.º 3
0
/*
 * =============
 *  LightWorld
 * =============
 */
static void
LightWorld(void)
{
    if (dlightdata)
	free(dlightdata);

    if (colored)
	lightdatasize = MAX_MAP_LIGHTING;
    else
	lightdatasize = MAX_MAP_LIGHTING / 4;
    dlightdata = malloc(lightdatasize + 16); /* for alignment */
    if (!dlightdata)
	Error("%s: allocation of %i bytes failed.", __func__, lightdatasize);
    memset(dlightdata, 0, lightdatasize + 16);

    if (litfile)
	lightdatasize /= 4;

    /* align filebase to a 4 byte boundary */
    filebase = file_p = (byte *)(((unsigned long)dlightdata + 3) & ~3);
    file_end = filebase + lightdatasize;

    if (colored && litfile) {
	/* litfile data stored in dlightdata, after the white light */
	lit_filebase = file_end + 12 - ((unsigned long)file_end % 12);
	lit_file_p = lit_filebase;
	lit_file_end = lit_filebase + 3 * (MAX_MAP_LIGHTING / 4);
    }

    RunThreadsOn(0, numfaces, LightThread);
    logprint("Lighting Completed.\n\n");

    lightdatasize = file_p - filebase;
    logprint("lightdatasize: %i\n", lightdatasize);
}
Ejemplo n.º 4
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int))
{
	if (numthreads == -1)
		ThreadSetDefault ();
	workfunction = func;
	RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction);
} //end of the function RunThreadsOnIndividual
Ejemplo n.º 5
0
/*
  ==================
  CalcPortalVis
  ==================
*/
void
CalcPortalVis(const bsp2_t *bsp)
{
    int i, startcount;
    portal_t *p;

// fastvis just uses mightsee for a very loose bound
    if (fastvis) {
        for (i = 0; i < numportals * 2; i++) {
            portals[i].visbits = portals[i].mightsee;
            portals[i].status = pstat_done;
        }
        return;
    }

    /*
     * Count the already completed portals in case we loaded previous state
     */
    startcount = 0;
    for (i = 0, p = portals; i < numportals * 2; i++, p++) {
        if (p->status == pstat_done)
            startcount++;
    }
    RunThreadsOn(startcount, numportals * 2, LeafThread, NULL);

    if (verbose) {
        logprint("portalcheck: %i  portaltest: %i  portalpass: %i\n",
                 c_portalcheck, c_portaltest, c_portalpass);
        logprint("c_vistest: %i  c_mighttest: %i  c_mightseeupdate %i\n",
                 c_vistest, c_mighttest, c_mightseeupdate);
    }
}
Ejemplo n.º 6
0
/*
=============
LightWorld
=============
*/
void LightWorld (void)
{
	// Allocate max lightdata
	if (dlightdata1 != NULL)
		free (dlightdata1);

	if (dlightdata3 != NULL)
		free (dlightdata3);

	dlightdata1 = malloc (MAX_MAP_LIGHTING);
	dlightdata3 = malloc (MAX_MAP_LIGHTING * 3);

	lightdatasize1 = MAX_MAP_LIGHTING;
	lightdatasize3 = MAX_MAP_LIGHTING * 3;

	filebase1 = file_p1 = dlightdata1;
	file_end1 = filebase1 + MAX_MAP_LIGHTING;

	filebase3 = file_p3 = dlightdata3;
	file_end3 = filebase3 + MAX_MAP_LIGHTING * 3;

	RunThreadsOn (LightThread);

	lightdatasize1 = file_p1 - filebase1;
	lightdatasize3 = file_p3 - filebase3;

	logprintf ("lightdatasize: %s\n", PrtSize (lightdatasize1));
}
Ejemplo n.º 7
0
// run threads on individual numbers
void RunThreadsOnIndividual(int workcnt, qboolean showpacifier, void(*func)(int))
{
	if( numthreads <= 0 )
		ThreadSetDefault();
	if ( threaded == qtrue )
		Error("RunThreadsOnIndividual: recursively entered!");

	workfunction = func;
	RunThreadsOn(workcnt, showpacifier, RunThreadsOnIndividualThread);
}
Ejemplo n.º 8
0
/**
 * @brief Entry point for all thread work requests.
 */
void RunSingleThreadOn (void (*func)(unsigned int), int unsigned workcount, qboolean progress, const char *id)
{
	int saved_numthreads = threadstate.numthreads;

	threadstate.numthreads = 1;

	RunThreadsOn(func, workcount, progress, id);

	threadstate.numthreads = saved_numthreads;
}
Ejemplo n.º 9
0
/*
=============
LightWorld
=============
*/
void LightWorld (void)
{
	filebase = file_p = dlightdata;
	file_end = filebase + MAX_MAP_LIGHTING;

	RunThreadsOn (LightThread);

	lightdatasize = file_p - filebase;
	
	printf ("lightdatasize: %i\n", lightdatasize);
}
Ejemplo n.º 10
0
/*
==================
CalcVis
==================
*/
void CalcVis (void)
{
	int		i;
	
	RunThreadsOn (numportals*2, true, BasePortalVis);
	
	CalcPortalVis ();

//
// assemble the leaf vis lists by oring and compressing the portal lists
//
	for (i=0 ; i<portalleafs ; i++)
		LeafFlow (i);
		
	printf ("average leafs visible: %i\n", totalvis / portalleafs);
}
Ejemplo n.º 11
0
/*
==================
CalcPortalVis
==================
*/
void CalcPortalVis (void)
{
	int		i;

// fastvis just uses the flood result for a very loose bound
	if (fastvis)
	{
		for (i=0 ; i<numportals*2 ; i++)
		{
			portals[i].portalvis = portals[i].portalflood;
			portals[i].status = stat_done;
		}
		return;
	}
	
	RunThreadsOn(numportals*2, true, PortalFlow);
}
Ejemplo n.º 12
0
/*
==================
CalcVis
==================
*/
void CalcVis (void)
{
	int		i;

	RunThreadsOn (numportals*2, true, BasePortalVis);

	SortPortals ();
	
	CalcPortalVis ();

//
// assemble the leaf vis lists by oring and compressing the portal lists
//
	for (i=0 ; i<portalclusters ; i++)
		ClusterMerge (i);
		
	Con_Print("Average clusters visible: %i\n", totalvis / portalclusters);
}
Ejemplo n.º 13
0
/*
==================
CalcPortalVis
==================
*/
void CalcPortalVis (void)
{
	int		i;

// fastvis just uses mightsee for a very loose bound
	if (fastvis)
	{
		for (i=0 ; i<numportals*2 ; i++)
		{
			portals[i].visbits = portals[i].mightsee;
			portals[i].status = stat_done;
		}
		return;
	}
	
	leafon = 0;
	
	RunThreadsOn (numportals*2, true, LeafThread);

	qprintf ("portalcheck: %i  portaltest: %i  portalpass: %i\n",c_portalcheck, c_portaltest, c_portalpass);
	qprintf ("c_vistest: %i  c_mighttest: %i\n",c_vistest, c_mighttest);
}
Ejemplo n.º 14
0
/*
=============
BounceLight
=============
*/
void BounceLight (void)
{
	unsigned i;
	vec3_t	added;
	char	name[64];

	for (i=0 ; i<num_patches ; i++)
		VectorScale( patches[i].totallight, TRANSFER_SCALE, emitlight[i] );

	for (i=0 ; i<numbounce ; i++)
	{
		RunThreadsOn (num_patches, true, GatherLight);
		CollectLight( added );

		qprintf ("\tBounce #%i added RGB(%.0f, %.0f, %.0f)\n", i+1, added[0], added[1], added[2] );
		if ( dumppatches && (i==0 || i == (unsigned)numbounce-1) )
		{
			sprintf (name, "bounce%i.txt", i);
			WriteWorld (name);
		}
	}
}
void ComputePerLeafAmbientLighting()
{
	// Figure out which lights should go in the per-leaf ambient cubes.
	int nInAmbientCube = 0;
	int nSurfaceLights = 0;
	for ( int i=0; i < *pNumworldlights; i++ )
	{
		dworldlight_t *wl = &dworldlights[i];
		
		if ( IsLeafAmbientSurfaceLight( wl ) )
			wl->flags |= DWL_FLAGS_INAMBIENTCUBE;
		else
			wl->flags &= ~DWL_FLAGS_INAMBIENTCUBE;
	
		if ( wl->type == emit_surface )
			++nSurfaceLights;

		if ( wl->flags & DWL_FLAGS_INAMBIENTCUBE )
			++nInAmbientCube;
	}

	Msg( "%d of %d (%d%% of) surface lights went in leaf ambient cubes.\n", nInAmbientCube, nSurfaceLights, nSurfaceLights ? ((nInAmbientCube*100) / nSurfaceLights) : 0 );

	g_LeafAmbientSamples.SetCount(numleafs);

	if ( g_bUseMPI )
	{
		// Distribute the work among the workers.
		VMPI_SetCurrentStage( "ComputeLeafAmbientLighting" );
		DistributeWork( numleafs, VMPI_DISTRIBUTEWORK_PACKETID, VMPI_ProcessLeafAmbient, VMPI_ReceiveLeafAmbientResults );
	}
	else
	{
		RunThreadsOn(numleafs, true, ThreadComputeLeafAmbient);
	}

	// now write out the data
	Msg("Writing leaf ambient...");
	g_pLeafAmbientIndex->RemoveAll();
	g_pLeafAmbientLighting->RemoveAll();
	g_pLeafAmbientIndex->SetCount( numleafs );
	g_pLeafAmbientLighting->EnsureCapacity( numleafs*4 );
	for ( int leafID = 0; leafID < numleafs; leafID++ )
	{
		const CUtlVector<ambientsample_t> &list = g_LeafAmbientSamples[leafID];
		g_pLeafAmbientIndex->Element(leafID).ambientSampleCount = list.Count();
		if ( !list.Count() )
		{
			g_pLeafAmbientIndex->Element(leafID).firstAmbientSample = 0;
		}
		else
		{
			g_pLeafAmbientIndex->Element(leafID).firstAmbientSample = g_pLeafAmbientLighting->Count();
			// compute the samples in disk format.  Encode the positions in 8-bits using leaf bounds fractions
			for ( int i = 0; i < list.Count(); i++ )
			{
				int outIndex = g_pLeafAmbientLighting->AddToTail();
				dleafambientlighting_t &light = g_pLeafAmbientLighting->Element(outIndex);

				light.x = Fixed8Fraction( list[i].pos.x, dleafs[leafID].mins[0], dleafs[leafID].maxs[0] );
				light.y = Fixed8Fraction( list[i].pos.y, dleafs[leafID].mins[1], dleafs[leafID].maxs[1] );
				light.z = Fixed8Fraction( list[i].pos.z, dleafs[leafID].mins[2], dleafs[leafID].maxs[2] );
				light.pad = 0;
				for ( int side = 0; side < 6; side++ )
				{
					VectorToColorRGBExp32( list[i].cube[side], light.cube.m_Color[side] );
				}
			}
		}
	}
	for ( int i = 0; i < numleafs; i++ )
	{
		// UNDONE: Do this dynamically in the engine instead.  This will allow us to sample across leaf
		// boundaries always which should improve the quality of lighting in general
		if ( g_pLeafAmbientIndex->Element(i).ambientSampleCount == 0 )
		{
			if ( !(dleafs[i].contents & CONTENTS_SOLID) )
			{
				Msg("Bad leaf ambient for leaf %d\n", i );
			}

			int refLeaf = NearestNeighborWithLight(i);
			g_pLeafAmbientIndex->Element(i).ambientSampleCount = 0;
			g_pLeafAmbientIndex->Element(i).firstAmbientSample = refLeaf;
		}
	}
	Msg("done\n");
}
Ejemplo n.º 16
0
/*
 * ProcessWorldModel
 */
static void ProcessWorldModel(void){
	entity_t *e;
	tree_t *tree;
	boolean_t leaked;
	boolean_t optimize;

	e = &entities[entity_num];

	brush_start = e->first_brush;
	brush_end = brush_start + e->num_brushes;
	leaked = false;

	// perform per-block operations
	if(block_xh * 1024 > map_maxs[0])
		block_xh = floor(map_maxs[0] / 1024.0);
	if((block_xl + 1) * 1024 < map_mins[0])
		block_xl = floor(map_mins[0] / 1024.0);
	if(block_yh * 1024 > map_maxs[1])
		block_yh = floor(map_maxs[1] / 1024.0);
	if((block_yl + 1) * 1024 < map_mins[1])
		block_yl = floor(map_mins[1] / 1024.0);

	if(block_xl < -4)
		block_xl = -4;
	if(block_yl < -4)
		block_yl = -4;
	if(block_xh > 3)
		block_xh = 3;
	if(block_yh > 3)
		block_yh = 3;

	for(optimize = false; optimize <= true; optimize++){
		Com_Verbose("--------------------------------------------\n");

		RunThreadsOn((block_xh - block_xl + 1) * (block_yh - block_yl + 1),
				!verbose, ProcessBlock_Thread);

		// build the division tree
		// oversizing the blocks guarantees that all the boundaries
		// will also get nodes.

		Com_Verbose("--------------------------------------------\n");

		tree = AllocTree();
		tree->head_node = BlockTree(block_xl - 1, block_yl - 1, block_xh + 1, block_yh + 1);

		tree->mins[0] = (block_xl) * 1024;
		tree->mins[1] = (block_yl) * 1024;
		tree->mins[2] = map_mins[2] - 8;

		tree->maxs[0] = (block_xh + 1) * 1024;
		tree->maxs[1] = (block_yh + 1) * 1024;
		tree->maxs[2] = map_maxs[2] + 8;

		// perform the global operations
		MakeTreePortals(tree);

		if(FloodEntities(tree))
			FillOutside(tree->head_node);
		else {
			leaked = true;
			LeakFile(tree);

			if(leaktest){
				Com_Error(ERR_FATAL, "--- MAP LEAKED, ABORTING LEAKTEST ---\n");
			}
			Com_Verbose("**** leaked ****\n");
		}

		MarkVisibleSides(tree, brush_start, brush_end);
		if(noopt || leaked)
			break;
		if(!optimize){
			FreeTree(tree);
		}
	}

	FloodAreas(tree);
	MakeFaces(tree->head_node);
	FixTjuncs(tree->head_node);

	if(!noprune)
		PruneNodes(tree->head_node);

	WriteBSP(tree->head_node);

	if(!leaked)
		WritePortalFile(tree);

	FreeTree(tree);
}
Ejemplo n.º 17
0
void            RunThreadsOnIndividual(int workcnt, bool showpacifier, q_threadfunction func)
{
    workfunction = func;
    RunThreadsOn(workcnt, showpacifier, ThreadWorkerFunction);
}