Пример #1
0
void CEntityMiscModel::Rotate( const vec3_t pivot, const vec3_t rotation ){
	m4x4_t rotation_matrix;

	m4x4_identity( rotation_matrix );
	m4x4_pivoted_rotate_by_vec3( rotation_matrix, rotation, eXYZ, pivot );
	m4x4_transform_point( rotation_matrix, m_translate );

	VectorIncrement( rotation, m_euler );

	UpdateCachedData();
}
Пример #2
0
void aabb_orthogonal_transform(aabb_t* dst, const aabb_t* src, const m4x4_t transform)
{
  VectorCopy(src->origin, dst->origin);
  m4x4_transform_point(transform, dst->origin);

  dst->extents[0] = (vec_t)(fabs(transform[0]  * src->extents[0])
                          + fabs(transform[4]  * src->extents[1])
                          + fabs(transform[8]  * src->extents[2]));
  dst->extents[1] = (vec_t)(fabs(transform[1]  * src->extents[0])
                          + fabs(transform[5]  * src->extents[1])
                          + fabs(transform[9]  * src->extents[2]));
  dst->extents[2] = (vec_t)(fabs(transform[2]  * src->extents[0])
                          + fabs(transform[6]  * src->extents[1])
                          + fabs(transform[10] * src->extents[2]));
}
Пример #3
0
void bbox_for_oriented_aabb(bbox_t *bbox, const aabb_t *aabb, const m4x4_t matrix, const vec3_t euler, const vec3_t scale)
{
	double rad[3];
	double pi_180 = Q_PI / 180;
  double A, B, C, D, E, F, AD, BD;
  
	VectorCopy(aabb->origin, bbox->aabb.origin);
	
  m4x4_transform_point(matrix, bbox->aabb.origin);

	bbox->aabb.extents[0] = aabb->extents[0] * scale[0];
	bbox->aabb.extents[1] = aabb->extents[1] * scale[1];
	bbox->aabb.extents[2] = aabb->extents[2] * scale[2];

  rad[0] = euler[0] * pi_180;
	rad[1] = euler[1] * pi_180;
	rad[2] = euler[2] * pi_180;

  A       = cos(rad[0]);
  B       = sin(rad[0]);
  C       = cos(rad[1]);
  D       = sin(rad[1]);
  E       = cos(rad[2]);
  F       = sin(rad[2]);

  AD      =   A * -D;
  BD      =   B * -D;

	bbox->axes[0][0] = (vec_t)(C*E);
	bbox->axes[0][1] = (vec_t)(-BD*E + A*F);
	bbox->axes[0][2] = (vec_t)(AD*E + B*F);
	bbox->axes[1][0] = (vec_t)(-C*F);
	bbox->axes[1][1] = (vec_t)(BD*F + A*E);
	bbox->axes[1][2] = (vec_t)(-AD*F + B*E);
	bbox->axes[2][0] = (vec_t)D;
	bbox->axes[2][1] = (vec_t)(-B*C);
	bbox->axes[2][2] = (vec_t)(A*C);

  bbox_update_radius(bbox);
}
Пример #4
0
void aabb_for_transformed_aabb(aabb_t* dst, const aabb_t* src, const m4x4_t transform)
{
  if(src->extents[0] < 0
    || src->extents[1] < 0
    || src->extents[2] < 0)
  {
    aabb_clear(dst);
    return;
  }

  VectorCopy(src->origin, dst->origin);
  m4x4_transform_point(transform, dst->origin);

  dst->extents[0] = (vec_t)(fabs(transform[0]  * src->extents[0])
                          + fabs(transform[4]  * src->extents[1])
                          + fabs(transform[8]  * src->extents[2]));
  dst->extents[1] = (vec_t)(fabs(transform[1]  * src->extents[0])
                          + fabs(transform[5]  * src->extents[1])
                          + fabs(transform[9]  * src->extents[2]));
  dst->extents[2] = (vec_t)(fabs(transform[2]  * src->extents[0])
                          + fabs(transform[6]  * src->extents[1])
                          + fabs(transform[10] * src->extents[2]));
}
Пример #5
0
void ray_transform( ray_t *ray, const m4x4_t matrix ){
	m4x4_transform_point( matrix, ray->origin );
	m4x4_transform_normal( matrix, ray->direction );
}
Пример #6
0
static void PopulateWithBSPModel( bspModel_t *model, m4x4_t transform ){
	int i, j, x, y, pw[ 5 ], r, nodeNum;
	bspDrawSurface_t    *ds;
	surfaceInfo_t       *info;
	bspDrawVert_t       *verts;
	int                 *indexes;
	mesh_t srcMesh, *mesh, *subdivided;
	traceInfo_t ti;
	traceWinding_t tw;


	/* dummy check */
	if ( model == NULL || transform == NULL ) {
		return;
	}

	/* walk the list of surfaces in this model and fill out the info structs */
	for ( i = 0; i < model->numBSPSurfaces; i++ )
	{
		/* get surface and info */
		ds = &bspDrawSurfaces[ model->firstBSPSurface + i ];
		info = &surfaceInfos[ model->firstBSPSurface + i ];
		if ( info->si == NULL ) {
			continue;
		}

		/* no shadows */
		if ( !info->castShadows ) {
			continue;
		}

		/* patchshadows? */
		if ( ds->surfaceType == MST_PATCH && patchShadows == qfalse ) {
			continue;
		}

		/* some surfaces in the bsp might have been tagged as nodraw, with a bogus shader */
		if ( ( bspShaders[ ds->shaderNum ].contentFlags & noDrawContentFlags ) ||
			 ( bspShaders[ ds->shaderNum ].surfaceFlags & noDrawSurfaceFlags ) ) {
			continue;
		}

		/* translucent surfaces that are neither alphashadow or lightfilter don't cast shadows */
		if ( ( info->si->compileFlags & C_NODRAW ) ) {
			continue;
		}
		if ( ( info->si->compileFlags & C_TRANSLUCENT ) &&
			 !( info->si->compileFlags & C_ALPHASHADOW ) &&
			 !( info->si->compileFlags & C_LIGHTFILTER ) ) {
			continue;
		}

		/* setup trace info */
		ti.si = info->si;
		ti.castShadows = info->castShadows;
		ti.surfaceNum = model->firstBSPBrush + i;
		ti.skipGrid = ( ds->surfaceType == MST_PATCH );

		/* choose which node (normal or skybox) */
		if ( info->parentSurfaceNum >= 0 ) {
			nodeNum = skyboxNodeNum;

			/* sky surfaces in portal skies are ignored */
			if ( info->si->compileFlags & C_SKY ) {
				continue;
			}
		}
		else{
			nodeNum = headNodeNum;
		}

		/* setup trace winding */
		memset( &tw, 0, sizeof( tw ) );
		tw.infoNum = AddTraceInfo( &ti );
		tw.numVerts = 3;

		/* switch on type */
		switch ( ds->surfaceType )
		{
		/* handle patches */
		case MST_PATCH:
			/* subdivide the surface */
			srcMesh.width = ds->patchWidth;
			srcMesh.height = ds->patchHeight;
			srcMesh.verts = &bspDrawVerts[ ds->firstVert ];
			//%	subdivided = SubdivideMesh( srcMesh, 8, 512 );
			subdivided = SubdivideMesh2( srcMesh, info->patchIterations );

			/* fit it to the curve and remove colinear verts on rows/columns */
			PutMeshOnCurve( *subdivided );
			mesh = RemoveLinearMeshColumnsRows( subdivided );
			FreeMesh( subdivided );

			/* set verts */
			verts = mesh->verts;

			/* subdivide each quad to place the models */
			for ( y = 0; y < ( mesh->height - 1 ); y++ )
			{
				for ( x = 0; x < ( mesh->width - 1 ); x++ )
				{
					/* set indexes */
					pw[ 0 ] = x + ( y * mesh->width );
					pw[ 1 ] = x + ( ( y + 1 ) * mesh->width );
					pw[ 2 ] = x + 1 + ( ( y + 1 ) * mesh->width );
					pw[ 3 ] = x + 1 + ( y * mesh->width );
					pw[ 4 ] = x + ( y * mesh->width );      /* same as pw[ 0 ] */

					/* set radix */
					r = ( x + y ) & 1;

					/* make first triangle */
					VectorCopy( verts[ pw[ r + 0 ] ].xyz, tw.v[ 0 ].xyz );
					Vector2Copy( verts[ pw[ r + 0 ] ].st, tw.v[ 0 ].st );
					VectorCopy( verts[ pw[ r + 1 ] ].xyz, tw.v[ 1 ].xyz );
					Vector2Copy( verts[ pw[ r + 1 ] ].st, tw.v[ 1 ].st );
					VectorCopy( verts[ pw[ r + 2 ] ].xyz, tw.v[ 2 ].xyz );
					Vector2Copy( verts[ pw[ r + 2 ] ].st, tw.v[ 2 ].st );
					m4x4_transform_point( transform, tw.v[ 0 ].xyz );
					m4x4_transform_point( transform, tw.v[ 1 ].xyz );
					m4x4_transform_point( transform, tw.v[ 2 ].xyz );
					FilterTraceWindingIntoNodes_r( &tw, nodeNum );

					/* make second triangle */
					VectorCopy( verts[ pw[ r + 0 ] ].xyz, tw.v[ 0 ].xyz );
					Vector2Copy( verts[ pw[ r + 0 ] ].st, tw.v[ 0 ].st );
					VectorCopy( verts[ pw[ r + 2 ] ].xyz, tw.v[ 1 ].xyz );
					Vector2Copy( verts[ pw[ r + 2 ] ].st, tw.v[ 1 ].st );
					VectorCopy( verts[ pw[ r + 3 ] ].xyz, tw.v[ 2 ].xyz );
					Vector2Copy( verts[ pw[ r + 3 ] ].st, tw.v[ 2 ].st );
					m4x4_transform_point( transform, tw.v[ 0 ].xyz );
					m4x4_transform_point( transform, tw.v[ 1 ].xyz );
					m4x4_transform_point( transform, tw.v[ 2 ].xyz );
					FilterTraceWindingIntoNodes_r( &tw, nodeNum );
				}
			}

			/* free the subdivided mesh */
			FreeMesh( mesh );
			break;

		/* handle triangle surfaces */
		case MST_TRIANGLE_SOUP:
		case MST_PLANAR:
			/* set verts and indexes */
			verts = &bspDrawVerts[ ds->firstVert ];
			indexes = &bspDrawIndexes[ ds->firstIndex ];

			/* walk the triangle list */
			for ( j = 0; j < ds->numIndexes; j += 3 )
			{
				VectorCopy( verts[ indexes[ j ] ].xyz, tw.v[ 0 ].xyz );
				Vector2Copy( verts[ indexes[ j ] ].st, tw.v[ 0 ].st );
				VectorCopy( verts[ indexes[ j + 1 ] ].xyz, tw.v[ 1 ].xyz );
				Vector2Copy( verts[ indexes[ j + 1 ] ].st, tw.v[ 1 ].st );
				VectorCopy( verts[ indexes[ j + 2 ] ].xyz, tw.v[ 2 ].xyz );
				Vector2Copy( verts[ indexes[ j + 2 ] ].st, tw.v[ 2 ].st );
				m4x4_transform_point( transform, tw.v[ 0 ].xyz );
				m4x4_transform_point( transform, tw.v[ 1 ].xyz );
				m4x4_transform_point( transform, tw.v[ 2 ].xyz );
				FilterTraceWindingIntoNodes_r( &tw, nodeNum );
			}
			break;

		/* other surface types do not cast shadows */
		default:
			break;
		}
	}
}
Пример #7
0
static void PopulateWithPicoModel( int castShadows, picoModel_t *model, m4x4_t transform ){
	int i, j, k, numSurfaces, numIndexes;
	picoSurface_t       *surface;
	picoShader_t        *shader;
	picoVec_t           *xyz, *st;
	picoIndex_t         *indexes;
	traceInfo_t ti;
	traceWinding_t tw;


	/* dummy check */
	if ( model == NULL || transform == NULL ) {
		return;
	}

	/* get info */
	numSurfaces = PicoGetModelNumSurfaces( model );

	/* walk the list of surfaces in this model and fill out the info structs */
	for ( i = 0; i < numSurfaces; i++ )
	{
		/* get surface */
		surface = PicoGetModelSurface( model, i );
		if ( surface == NULL ) {
			continue;
		}

		/* only handle triangle surfaces initially (fixme: support patches) */
		if ( PicoGetSurfaceType( surface ) != PICO_TRIANGLES ) {
			continue;
		}

		/* get shader (fixme: support shader remapping) */
		shader = PicoGetSurfaceShader( surface );
		if ( shader == NULL ) {
			continue;
		}
		ti.si = ShaderInfoForShaderNull( PicoGetShaderName( shader ) );
		if ( ti.si == NULL ) {
			continue;
		}

		/* translucent surfaces that are neither alphashadow or lightfilter don't cast shadows */
		if ( ( ti.si->compileFlags & C_NODRAW ) ) {
			continue;
		}
		if ( ( ti.si->compileFlags & C_TRANSLUCENT ) &&
			 !( ti.si->compileFlags & C_ALPHASHADOW ) &&
			 !( ti.si->compileFlags & C_LIGHTFILTER ) ) {
			continue;
		}

		/* setup trace info */
		ti.castShadows = castShadows;
		ti.surfaceNum = -1;
		ti.skipGrid = qtrue; // also ignore picomodels when skipping patches

		/* setup trace winding */
		memset( &tw, 0, sizeof( tw ) );
		tw.infoNum = AddTraceInfo( &ti );
		tw.numVerts = 3;

		/* get info */
		numIndexes = PicoGetSurfaceNumIndexes( surface );
		indexes = PicoGetSurfaceIndexes( surface, 0 );

		/* walk the triangle list */
		for ( j = 0; j < numIndexes; j += 3, indexes += 3 )
		{
			for ( k = 0; k < 3; k++ )
			{
				xyz = PicoGetSurfaceXYZ( surface, indexes[ k ] );
				st = PicoGetSurfaceST( surface, 0, indexes[ k ] );
				VectorCopy( xyz, tw.v[ k ].xyz );
				Vector2Copy( st, tw.v[ k ].st );
				m4x4_transform_point( transform, tw.v[ k ].xyz );
			}
			FilterTraceWindingIntoNodes_r( &tw, headNodeNum );
		}
	}
}