/* * 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( BoundsIntersect( 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; }
/* ================= R_TraceLine ================= */ msurface_t *R_TransformedTraceLine( trace_t *tr, const vec3_t start, const vec3_t end, ref_entity_t *test, int umask ) { ref_model_t *model; r_fragmentframecount++; // for multi-check avoidance // fill in a default trace Mem_Set( tr, 0, sizeof( trace_t )); trace_surface = NULL; trace_umask = umask; trace_fraction = 1; VectorCopy( end, trace_impact ); Mem_Set( &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_world || model->type == mod_brush ) { mbrushmodel_t *bmodel = ( mbrushmodel_t * )model->extradata; vec3_t temp, start_l, end_l, axis[3]; bool rotated = !Matrix3x3_Compare( test->axis, matrix3x3_identity ); // transform VectorSubtract( start, test->origin, start_l ); VectorSubtract( end, test->origin, end_l ); if( rotated ) { VectorCopy( start_l, temp ); Matrix3x3_Transform( test->axis, temp, start_l ); VectorCopy( end_l, temp ); Matrix3x3_Transform( 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->type == mod_world ) R_RecursiveHullCheck( bmodel->nodes, start_l, end_l ); else if( BoundsIntersect( model->mins, model->maxs, trace_absmins, trace_absmaxs ) ) R_TraceAgainstBmodel( bmodel ); // transform back if( rotated && trace_fraction != 1 ) { Matrix3x3_Transpose( axis, test->axis ); VectorCopy( tr->vecPlaneNormal, temp ); Matrix3x3_Transform( axis, temp, trace_plane.normal ); } } } // calculate the impact plane, if any if( trace_fraction < 1.0f ) { VectorNormalize( trace_plane.normal ); trace_plane.dist = DotProduct( trace_plane.normal, trace_impact ); CategorizePlane( &trace_plane ); tr->flPlaneDist = trace_plane.dist; VectorCopy( trace_plane.normal, tr->vecPlaneNormal ); tr->iContents = trace_surface->contents; tr->pHit = (edict_t *)test; } tr->flFraction = trace_fraction; VectorCopy( trace_impact, tr->vecEndPos ); return trace_surface; }