Esempio n. 1
0
/*
============
idBox::GetParallelProjectionSilhouetteVerts
============
*/
int idBox::GetParallelProjectionSilhouetteVerts( const idVec3& projectionDir, idVec3 silVerts[6] ) const
{
	float f;
	int i, planeBits, *index;
	idVec3 points[8];
	
	ToPoints( points );
	
	planeBits = 0;
	f = projectionDir * axis[0];
	if( IEEE_FLT_ISNOTZERO( f ) )
	{
		planeBits = 1 << IEEE_FLT_SIGNBITSET( f );
	}
	f = projectionDir * axis[1];
	if( IEEE_FLT_ISNOTZERO( f ) )
	{
		planeBits |= 4 << IEEE_FLT_SIGNBITSET( f );
	}
	f = projectionDir * axis[2];
	if( IEEE_FLT_ISNOTZERO( f ) )
	{
		planeBits |= 16 << IEEE_FLT_SIGNBITSET( f );
	}
	
	index = boxPlaneBitsSilVerts[planeBits];
	for( i = 0; i < index[0]; i++ )
	{
		silVerts[i] = points[index[i + 1]];
	}
	
	return index[0];
}
Esempio n. 2
0
/*
=============
idWinding2D::PlaneDistance
=============
*/
float idWinding2D::PlaneDistance( const idVec3 &plane ) const {
	int		i;
	float	d, min, max;

	min = idMath::INFINITY;
	max = -min;
	for ( i = 0; i < numPoints; i++ ) {
		d = plane.x * p[i].x + plane.y * p[i].y + plane.z;
		if ( d < min ) {
			min = d;
			if ( IEEE_FLT_SIGNBITSET( min ) & IEEE_FLT_SIGNBITNOTSET( max ) ) {
				return 0.0f;
			}
		}
		if ( d > max ) {
			max = d;
			if ( IEEE_FLT_SIGNBITSET( min ) & IEEE_FLT_SIGNBITNOTSET( max ) ) {
				return 0.0f;
			}
		}
	}
	if ( IEEE_FLT_SIGNBITNOTSET( min ) ) {
		return min;
	}
	if ( IEEE_FLT_SIGNBITSET( max ) ) {
		return max;
	}
	return 0.0f;
}
Esempio n. 3
0
/*
============
idBox::GetProjectionSilhouetteVerts
============
*/
int idBox::GetProjectionSilhouetteVerts( const idVec3& projectionOrigin, idVec3 silVerts[6] ) const
{
	float f;
	int i, planeBits, *index;
	idVec3 points[8], dir1, dir2;
	
	ToPoints( points );
	
	dir1 = points[0] - projectionOrigin;
	dir2 = points[6] - projectionOrigin;
	f = dir1 * axis[0];
	planeBits = IEEE_FLT_SIGNBITNOTSET( f );
	f = dir2 * axis[0];
	planeBits |= IEEE_FLT_SIGNBITSET( f ) << 1;
	f = dir1 * axis[1];
	planeBits |= IEEE_FLT_SIGNBITNOTSET( f ) << 2;
	f = dir2 * axis[1];
	planeBits |= IEEE_FLT_SIGNBITSET( f ) << 3;
	f = dir1 * axis[2];
	planeBits |= IEEE_FLT_SIGNBITNOTSET( f ) << 4;
	f = dir2 * axis[2];
	planeBits |= IEEE_FLT_SIGNBITSET( f ) << 5;
	
	index = boxPlaneBitsSilVerts[planeBits];
	for( i = 0; i < index[0]; i++ )
	{
		silVerts[i] = points[index[i + 1]];
	}
	
	return index[0];
}
Esempio n. 4
0
/*
============
idAASLocal::EdgeSplitPoint

  calculates split point of the edge with the plane
  returns true if the split point is between the edge vertices
============
*/
bool idAASLocal::EdgeSplitPoint( idVec3 &split, int edgeNum, const idPlane &plane ) const {
	const aasEdge_t *edge;
	idVec3 v1, v2;
	float d1, d2;

	edge = &file->GetEdge( edgeNum );
	v1 = file->GetVertex( edge->vertexNum[0] );
	v2 = file->GetVertex( edge->vertexNum[1] );
	d1 = v1 * plane.Normal() - plane.Dist();
	d2 = v2 * plane.Normal() - plane.Dist();

	//if ( (d1 < CM_CLIP_EPSILON && d2 < CM_CLIP_EPSILON) || (d1 > -CM_CLIP_EPSILON && d2 > -CM_CLIP_EPSILON) ) {
	if ( IEEE_FLT_SIGNBITSET( d1 ) == IEEE_FLT_SIGNBITSET( d2 ) ) {
		return false;
	}
	split = v1 + (d1 / (d1 - d2)) * (v2 - v1);
	return true;
}
Esempio n. 5
0
/*
============
GetAxialBevel
============
*/
bool GetAxialBevel( const idVec3 &plane1, const idVec3 &plane2, const idVec2 &point, idVec3 &bevel ) {
	if ( IEEE_FLT_SIGNBITSET( plane1.x ) ^ IEEE_FLT_SIGNBITSET( plane2.x ) ) {
		if ( idMath::Fabs( plane1.x ) > 0.1f && idMath::Fabs( plane2.x ) > 0.1f ) {
			bevel.x = 0.0f;
			if ( IEEE_FLT_SIGNBITSET( plane1.y ) ) {
				bevel.y = -1.0f;
			}
			else {
				bevel.y = 1.0f;
			}
			bevel.z = - ( point.x * bevel.x + point.y * bevel.y );
			return true;
		}
	}
	if ( IEEE_FLT_SIGNBITSET( plane1.y ) ^ IEEE_FLT_SIGNBITSET( plane2.y ) ) {
		if ( idMath::Fabs( plane1.y ) > 0.1f && idMath::Fabs( plane2.y ) > 0.1f ) {
			bevel.y = 0.0f;
			if ( IEEE_FLT_SIGNBITSET( plane1.x ) ) {
				bevel.x = -1.0f;
			}
			else {
				bevel.x = 1.0f;
			}
			bevel.z = - ( point.x * bevel.x + point.y * bevel.y );
			return true;
		}
	}
	return false;
}
Esempio n. 6
0
/*
============
idWinding2D::ExpandForAxialBox
============
*/
void idWinding2D::ExpandForAxialBox( const idVec2 bounds[2] ) {
	int i, j, numPlanes;
	idVec2 v;
	idVec3 planes[MAX_POINTS_ON_WINDING_2D], plane, bevel;

	// get planes for the edges and add bevels
	for ( numPlanes = i = 0; i < numPoints; i++ ) {
		j = (i+1) % numPoints;
		if ( ( p[j] - p[i] ).LengthSqr() < 0.01f ) {
			continue;
		}
		plane = Plane2DFromPoints( p[i], p[j], true );
		if ( i ) {
			if ( GetAxialBevel( planes[numPlanes-1], plane, p[i], bevel ) ) {
				planes[numPlanes++] = bevel;
			}
		}
		assert( numPlanes < MAX_POINTS_ON_WINDING_2D );
		planes[numPlanes++] = plane;
	}
	assert( numPlanes < MAX_POINTS_ON_WINDING_2D && numPlanes > 0 );
	if ( GetAxialBevel( planes[numPlanes-1], planes[0], p[0], bevel ) ) {
		planes[numPlanes++] = bevel;
	}

	// expand the planes
	for ( i = 0; i < numPlanes; i++ ) {
		v.x = bounds[ IEEE_FLT_SIGNBITSET( planes[i].x ) ].x;
		v.y = bounds[ IEEE_FLT_SIGNBITSET( planes[i].y ) ].y;
		planes[i].z += v.x * planes[i].x + v.y * planes[i].y;
	}

	// get intersection points of the planes
	for ( numPoints = i = 0; i < numPlanes; i++ ) {
		if ( Plane2DIntersection( planes[(i+numPlanes-1) % numPlanes], planes[i], p[numPoints] ) ) {
			numPoints++;
		}
	}
}
Esempio n. 7
0
/*
================
idBrittleFracture::ProjectDecal
================
*/
void idBrittleFracture::ProjectDecal( const idVec3& point, const idVec3& dir, const int time, const char* damageDefName )
{
	int i, j, bits, clipBits;
	float a, c, s;
	idVec2 st[MAX_POINTS_ON_WINDING];
	idVec3 origin;
	idMat3 axis, axistemp;
	idPlane textureAxis[2];
	
	if( common->IsServer() )
	{
		idBitMsg	msg;
		byte		msgBuf[MAX_EVENT_PARAM_SIZE];
		
		msg.InitWrite( msgBuf, sizeof( msgBuf ) );
		msg.BeginWriting();
		msg.WriteFloat( point[0] );
		msg.WriteFloat( point[1] );
		msg.WriteFloat( point[2] );
		msg.WriteFloat( dir[0] );
		msg.WriteFloat( dir[1] );
		msg.WriteFloat( dir[2] );
		ServerSendEvent( EVENT_PROJECT_DECAL, &msg, true );
	}
	
	// store the event so we can rebuilt the fracture after loading a save
	fractureEvent_s fractureEvent;
	fractureEvent.eventType = EVENT_PROJECT_DECAL;
	fractureEvent.point = point;
	fractureEvent.vector = dir;
	storedEvents.Append( fractureEvent );
	
	if( time >= gameLocal.time )
	{
		// try to get the sound from the damage def
		const idDeclEntityDef* damageDef = NULL;
		const idSoundShader* sndShader = NULL;
		if( damageDefName )
		{
			damageDef = gameLocal.FindEntityDef( damageDefName, false );
			if( damageDef )
			{
				const char* sndName = damageDef->dict.GetString( "snd_shatter", "" );
				if( sndName[0] != 0 )
				{
					sndShader = declManager->FindSound( sndName );
				}
			}
		}
		
		if( sndShader )
		{
			StartSoundShader( sndShader, SND_CHANNEL_ANY, 0, false, NULL );
		}
		else
		{
			StartSound( "snd_bullethole", SND_CHANNEL_ANY, 0, false, NULL );
		}
	}
	
	a = gameLocal.random.RandomFloat() * idMath::TWO_PI;
	c = cos( a );
	s = -sin( a );
	
	axis[2] = -dir;
	axis[2].Normalize();
	axis[2].NormalVectors( axistemp[0], axistemp[1] );
	axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * s;
	axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -c;
	
	textureAxis[0] = axis[0] * ( 1.0f / decalSize );
	textureAxis[0][3] = -( point * textureAxis[0].Normal() ) + 0.5f;
	
	textureAxis[1] = axis[1] * ( 1.0f / decalSize );
	textureAxis[1][3] = -( point * textureAxis[1].Normal() ) + 0.5f;
	
	for( i = 0; i < shards.Num(); i++ )
	{
		idFixedWinding& winding = shards[i]->winding;
		origin = shards[i]->clipModel->GetOrigin();
		axis = shards[i]->clipModel->GetAxis();
		float d0, d1;
		
		clipBits = -1;
		for( j = 0; j < winding.GetNumPoints(); j++ )
		{
			idVec3 p = origin + winding[j].ToVec3() * axis;
			
			st[j].x = d0 = textureAxis[0].Distance( p );
			st[j].y = d1 = textureAxis[1].Distance( p );
			
			bits = IEEE_FLT_SIGNBITSET( d0 );
			d0 = 1.0f - d0;
			bits |= IEEE_FLT_SIGNBITSET( d1 ) << 2;
			d1 = 1.0f - d1;
			bits |= IEEE_FLT_SIGNBITSET( d0 ) << 1;
			bits |= IEEE_FLT_SIGNBITSET( d1 ) << 3;
			
			clipBits &= bits;
		}
		
		if( clipBits )
		{
			continue;
		}
		
		idFixedWinding* decal = new( TAG_PARTICLE ) idFixedWinding;
		shards[i]->decals.Append( decal );
		
		decal->SetNumPoints( winding.GetNumPoints() );
		for( j = 0; j < winding.GetNumPoints(); j++ )
		{
			( *decal )[j].ToVec3() = winding[j].ToVec3();
			( *decal )[j].s = st[j].x;
			( *decal )[j].t = st[j].y;
		}
	}
	
	BecomeActive( TH_UPDATEVISUALS );
}
Esempio n. 8
0
/*
=================
idSurface::Split
=================
*/
int idSurface::Split( const idPlane& plane, const float epsilon, idSurface** front, idSurface** back, int* frontOnPlaneEdges, int* backOnPlaneEdges ) const
{
	float* 			dists;
	float			f;
	byte* 			sides;
	int				counts[3];
	int* 			edgeSplitVertex;
	int				numEdgeSplitVertexes;
	int* 			vertexRemap[2];
	int				vertexIndexNum[2][2];
	int* 			vertexCopyIndex[2];
	int* 			indexPtr[2];
	int				indexNum[2];
	int* 			index;
	int* 			onPlaneEdges[2];
	int				numOnPlaneEdges[2];
	int				maxOnPlaneEdges;
	int				i;
	idSurface* 		surface[2];
	idDrawVert		v;
	
	dists = ( float* ) _alloca( verts.Num() * sizeof( float ) );
	sides = ( byte* ) _alloca( verts.Num() * sizeof( byte ) );
	
	counts[0] = counts[1] = counts[2] = 0;
	
	// determine side for each vertex
	for( i = 0; i < verts.Num(); i++ )
	{
		dists[i] = f = plane.Distance( verts[i].xyz );
		if( f > epsilon )
		{
			sides[i] = SIDE_FRONT;
		}
		else if( f < -epsilon )
		{
			sides[i] = SIDE_BACK;
		}
		else
		{
			sides[i] = SIDE_ON;
		}
		counts[sides[i]]++;
	}
	
	*front = *back = NULL;
	
	// if coplanar, put on the front side if the normals match
	if( !counts[SIDE_FRONT] && !counts[SIDE_BACK] )
	{
	
		f = ( verts[indexes[1]].xyz - verts[indexes[0]].xyz ).Cross( verts[indexes[0]].xyz - verts[indexes[2]].xyz ) * plane.Normal();
		if( IEEE_FLT_SIGNBITSET( f ) )
		{
			*back = new( TAG_IDLIB_SURFACE ) idSurface( *this );
			return SIDE_BACK;
		}
		else
		{
			*front = new( TAG_IDLIB_SURFACE ) idSurface( *this );
			return SIDE_FRONT;
		}
	}
	// if nothing at the front of the clipping plane
	if( !counts[SIDE_FRONT] )
	{
		*back = new( TAG_IDLIB_SURFACE ) idSurface( *this );
		return SIDE_BACK;
	}
	// if nothing at the back of the clipping plane
	if( !counts[SIDE_BACK] )
	{
		*front = new( TAG_IDLIB_SURFACE ) idSurface( *this );
		return SIDE_FRONT;
	}
	
	// allocate front and back surface
	*front = surface[0] = new( TAG_IDLIB_SURFACE ) idSurface();
	*back = surface[1] = new( TAG_IDLIB_SURFACE ) idSurface();
	
	edgeSplitVertex = ( int* ) _alloca( edges.Num() * sizeof( int ) );
	numEdgeSplitVertexes = 0;
	
	maxOnPlaneEdges = 4 * counts[SIDE_ON];
	counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0;
	
	// split edges
	for( i = 0; i < edges.Num(); i++ )
	{
		int v0 = edges[i].verts[0];
		int v1 = edges[i].verts[1];
		int sidesOr = ( sides[v0] | sides[v1] );
		
		// if both vertexes are on the same side or one is on the clipping plane
		if( !( sides[v0] ^ sides[v1] ) || ( sidesOr & SIDE_ON ) )
		{
			edgeSplitVertex[i] = -1;
			counts[sidesOr & SIDE_BACK]++;
			counts[SIDE_ON] += ( sidesOr & SIDE_ON ) >> 1;
		}
		else
		{
Esempio n. 9
0
/*
====================
R_OverlayPointCullSkinned
====================
*/
static void R_OverlayPointCullSkinned( byte* cullBits, halfFloat_t* texCoordS, halfFloat_t* texCoordT, const idPlane* planes, const idDrawVert* verts, const int numVerts, const idJointMat* joints )
{
	assert_16_byte_aligned( cullBits );
	assert_16_byte_aligned( texCoordS );
	assert_16_byte_aligned( texCoordT );
	assert_16_byte_aligned( verts );
	
#if defined(USE_INTRINSICS)
	idODSStreamedArray< idDrawVert, 16, SBT_DOUBLE, 4 > vertsODS( verts, numVerts );
	
	const __m128 vector_float_zero	= { 0.0f, 0.0f, 0.0f, 0.0f };
	const __m128 vector_float_one	= { 1.0f, 1.0f, 1.0f, 1.0f };
	const __m128i vector_int_mask0	= _mm_set1_epi32( 1 << 0 );
	const __m128i vector_int_mask1	= _mm_set1_epi32( 1 << 1 );
	const __m128i vector_int_mask2	= _mm_set1_epi32( 1 << 2 );
	const __m128i vector_int_mask3	= _mm_set1_epi32( 1 << 3 );
	
	const __m128 p0 = _mm_loadu_ps( planes[0].ToFloatPtr() );
	const __m128 p1 = _mm_loadu_ps( planes[1].ToFloatPtr() );
	
	const __m128 p0X = _mm_splat_ps( p0, 0 );
	const __m128 p0Y = _mm_splat_ps( p0, 1 );
	const __m128 p0Z = _mm_splat_ps( p0, 2 );
	const __m128 p0W = _mm_splat_ps( p0, 3 );
	
	const __m128 p1X = _mm_splat_ps( p1, 0 );
	const __m128 p1Y = _mm_splat_ps( p1, 1 );
	const __m128 p1Z = _mm_splat_ps( p1, 2 );
	const __m128 p1W = _mm_splat_ps( p1, 3 );
	
	for( int i = 0; i < numVerts; )
	{
	
		const int nextNumVerts = vertsODS.FetchNextBatch() - 4;
		
		for( ; i <= nextNumVerts; i += 4 )
		{
			const __m128 v0 = LoadSkinnedDrawVertPosition( vertsODS[i + 0], joints );
			const __m128 v1 = LoadSkinnedDrawVertPosition( vertsODS[i + 1], joints );
			const __m128 v2 = LoadSkinnedDrawVertPosition( vertsODS[i + 2], joints );
			const __m128 v3 = LoadSkinnedDrawVertPosition( vertsODS[i + 3], joints );
			
			const __m128 r0 = _mm_unpacklo_ps( v0, v2 );	// v0.x, v2.x, v0.z, v2.z
			const __m128 r1 = _mm_unpackhi_ps( v0, v2 );	// v0.y, v2.y, v0.w, v2.w
			const __m128 r2 = _mm_unpacklo_ps( v1, v3 );	// v1.x, v3.x, v1.z, v3.z
			const __m128 r3 = _mm_unpackhi_ps( v1, v3 );	// v1.y, v3.y, v1.w, v3.w
			
			const __m128 vX = _mm_unpacklo_ps( r0, r2 );	// v0.x, v1.x, v2.x, v3.x
			const __m128 vY = _mm_unpackhi_ps( r0, r2 );	// v0.y, v1.y, v2.y, v3.y
			const __m128 vZ = _mm_unpacklo_ps( r1, r3 );	// v0.z, v1.z, v2.z, v3.z
			
			const __m128 d0 = _mm_madd_ps( vX, p0X, _mm_madd_ps( vY, p0Y, _mm_madd_ps( vZ, p0Z, p0W ) ) );
			const __m128 d1 = _mm_madd_ps( vX, p1X, _mm_madd_ps( vY, p1Y, _mm_madd_ps( vZ, p1Z, p1W ) ) );
			const __m128 d2 = _mm_sub_ps( vector_float_one, d0 );
			const __m128 d3 = _mm_sub_ps( vector_float_one, d1 );
			
			__m128i flt16S = FastF32toF16( __m128c( d0 ) );
			__m128i flt16T = FastF32toF16( __m128c( d1 ) );
			
			_mm_storel_epi64( ( __m128i* )&texCoordS[i], flt16S );
			_mm_storel_epi64( ( __m128i* )&texCoordT[i], flt16T );
			
			__m128i c0 = __m128c( _mm_cmplt_ps( d0, vector_float_zero ) );
			__m128i c1 = __m128c( _mm_cmplt_ps( d1, vector_float_zero ) );
			__m128i c2 = __m128c( _mm_cmplt_ps( d2, vector_float_zero ) );
			__m128i c3 = __m128c( _mm_cmplt_ps( d3, vector_float_zero ) );
			
			c0 = _mm_and_si128( c0, vector_int_mask0 );
			c1 = _mm_and_si128( c1, vector_int_mask1 );
			c2 = _mm_and_si128( c2, vector_int_mask2 );
			c3 = _mm_and_si128( c3, vector_int_mask3 );
			
			c0 = _mm_or_si128( c0, c1 );
			c2 = _mm_or_si128( c2, c3 );
			c0 = _mm_or_si128( c0, c2 );
			
			c0 = _mm_packs_epi32( c0, c0 );
			c0 = _mm_packus_epi16( c0, c0 );
			
			*( unsigned int* )&cullBits[i] = _mm_cvtsi128_si32( c0 );
		}
	}
	
#else
	
	idODSStreamedArray< idDrawVert, 16, SBT_DOUBLE, 1 > vertsODS( verts, numVerts );
	
	for( int i = 0; i < numVerts; )
	{
	
		const int nextNumVerts = vertsODS.FetchNextBatch() - 1;
	
		for( ; i <= nextNumVerts; i++ )
		{
			const idVec3 transformed = Scalar_LoadSkinnedDrawVertPosition( vertsODS[i], joints );
	
			const float d0 = planes[0].Distance( transformed );
			const float d1 = planes[1].Distance( transformed );
			const float d2 = 1.0f - d0;
			const float d3 = 1.0f - d1;
	
			halfFloat_t s = Scalar_FastF32toF16( d0 );
			halfFloat_t t = Scalar_FastF32toF16( d1 );
	
			texCoordS[i] = s;
			texCoordT[i] = t;
	
			byte bits;
			bits  = IEEE_FLT_SIGNBITSET( d0 ) << 0;
			bits |= IEEE_FLT_SIGNBITSET( d1 ) << 1;
			bits |= IEEE_FLT_SIGNBITSET( d2 ) << 2;
			bits |= IEEE_FLT_SIGNBITSET( d3 ) << 3;
	
			cullBits[i] = bits;
		}
	}
	
#endif
}