static void
cpSweep1DSegmentQuery(cpSweep1D *sweep, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpatialIndexSegmentQueryFunc func, void *data)
{
	cpBB bb = cpBBExpand(cpBBNew(a.x, a.y, a.x, a.y), b);
	Bounds bounds = BBToBounds(sweep, bb);
	
	TableCell *table = sweep->table;
	for(int i=0, count=sweep->num; i<count; i++){
		TableCell cell = table[i];
		if(BoundsOverlap(bounds, cell.bounds)) func(obj, cell.obj, data);
	}
}
static void
cpSweep1DQuery(cpSweep1D *sweep, void *obj, cpBB bb, cpSpatialIndexQueryFunc func, void *data)
{
	// Implementing binary search here would allow you to find an upper limit
	// but not a lower limit. Probably not worth the hassle.
	
	Bounds bounds = BBToBounds(sweep, bb);
	
	TableCell *table = sweep->table;
	for(int i=0, count=sweep->num; i<count; i++){
		TableCell cell = table[i];
		if(BoundsOverlap(bounds, cell.bounds) && obj != cell.obj) func(obj, cell.obj, data);
	}
}
Exemple #3
0
/*
* R_TraceLine
*/
static msurface_t *R_TransformedTraceLine( rtrace_t *tr, const vec3_t start, const vec3_t end,
										   entity_t *test, int surfumask ) {
	model_t *model;

	r_traceframecount++;    // for multi-check avoidance

	// fill in a default trace
	memset( tr, 0, sizeof( *tr ) );

	trace_surface = NULL;
	trace_umask = surfumask;
	trace_fraction = 1;
	VectorCopy( end, trace_impact );
	memset( &trace_plane, 0, sizeof( trace_plane ) );

	ClearBounds( trace_absmins, trace_absmaxs );
	AddPointToBounds( start, trace_absmins, trace_absmaxs );
	AddPointToBounds( end, trace_absmins, trace_absmaxs );

	model = test->model;
	if( model ) {
		if( model->type == mod_brush ) {
			mbrushmodel_t *bmodel = ( mbrushmodel_t * )model->extradata;
			vec3_t temp, start_l, end_l;
			mat3_t axis;
			bool rotated = !Matrix3_Compare( test->axis, axis_identity );

			// transform
			VectorSubtract( start, test->origin, start_l );
			VectorSubtract( end, test->origin, end_l );
			if( rotated ) {
				VectorCopy( start_l, temp );
				Matrix3_TransformVector( test->axis, temp, start_l );
				VectorCopy( end_l, temp );
				Matrix3_TransformVector( test->axis, temp, end_l );
			}

			VectorCopy( start_l, trace_start );
			VectorCopy( end_l, trace_end );

			// world uses a recursive approach using BSP tree, submodels
			// just walk the list of surfaces linearly
			if( test->model == rsh.worldModel ) {
				R_RecursiveHullCheck( bmodel->nodes, start_l, end_l );
			} else if( BoundsOverlap( model->mins, model->maxs, trace_absmins, trace_absmaxs ) ) {
				R_TraceAgainstBmodel( bmodel );
			}

			// transform back
			if( rotated && trace_fraction != 1 ) {
				Matrix3_Transpose( test->axis, axis );
				VectorCopy( tr->plane.normal, temp );
				Matrix3_TransformVector( axis, temp, trace_plane.normal );
			}
		}
	}

	// calculate the impact plane, if any
	if( trace_fraction < 1 && trace_surface != NULL ) {
		VectorNormalize( trace_plane.normal );
		trace_plane.dist = DotProduct( trace_plane.normal, trace_impact );
		CategorizePlane( &trace_plane );

		tr->shader = trace_surface->shader;
		tr->plane = trace_plane;
		tr->surfFlags = trace_surface->flags;
		tr->ent = R_ENT2NUM( test );
	}

	tr->fraction = trace_fraction;
	VectorCopy( trace_impact, tr->endpos );

	return trace_surface;
}