/* ================ R_PlaneForMirror Get transformed mirrorplane and entity matrix ================ */ void R_PlaneForMirror( msurface_t *surf, mplane_t *out, matrix4x4 m ) { cl_entity_t *ent; ASSERT( out != NULL ); ent = RI.currententity; // setup mirror plane *out = *surf->plane; if( surf->flags & SURF_PLANEBACK ) { VectorNegate( out->normal, out->normal ); out->dist = -out->dist; } if( !VectorIsNull( ent->origin ) || !VectorIsNull( ent->angles )) { mplane_t tmp; if( !VectorIsNull( ent->angles )) Matrix4x4_CreateFromEntity( m, ent->angles, ent->origin, 1.0f ); else Matrix4x4_CreateFromEntity( m, vec3_origin, ent->origin, 1.0f ); tmp = *out; // transform mirror plane by entity matrix Matrix4x4_TransformPositivePlane( m, tmp.normal, tmp.dist, out->normal, &out->dist ); } else Matrix4x4_LoadIdentity( m ); }
/* ============= R_LoadIdentity ============= */ void R_LoadIdentity( void ) { if( tr.modelviewIdentity ) return; Matrix4x4_LoadIdentity( RI.objectMatrix ); Matrix4x4_Copy( RI.modelviewMatrix, RI.worldviewMatrix ); pglMatrixMode( GL_MODELVIEW ); GL_LoadMatrix( RI.modelviewMatrix ); tr.modelviewIdentity = true; }
/* ================ R_BeginDrawMirror Setup texture matrix for mirror texture ================ */ void R_BeginDrawMirror( msurface_t *fa ) { matrix4x4 m1, m2, matrix; GLfloat genVector[4][4]; mextrasurf_t *es; int i; es = SURF_INFO( fa, RI.currentmodel ); Matrix4x4_Copy( matrix, es->mirrormatrix ); Matrix4x4_LoadIdentity( m1 ); Matrix4x4_ConcatScale( m1, 0.5f ); Matrix4x4_Concat( m2, m1, matrix ); Matrix4x4_LoadIdentity( m1 ); Matrix4x4_ConcatTranslate( m1, 0.5f, 0.5f, 0.5f ); Matrix4x4_Concat( matrix, m1, m2 ); for( i = 0; i < 4; i++ ) { genVector[0][i] = i == 0 ? 1 : 0; genVector[1][i] = i == 1 ? 1 : 0; genVector[2][i] = i == 2 ? 1 : 0; genVector[3][i] = i == 3 ? 1 : 0; } GL_TexGen( GL_S, GL_OBJECT_LINEAR ); GL_TexGen( GL_T, GL_OBJECT_LINEAR ); GL_TexGen( GL_R, GL_OBJECT_LINEAR ); GL_TexGen( GL_Q, GL_OBJECT_LINEAR ); pglTexGenfv( GL_S, GL_OBJECT_PLANE, genVector[0] ); pglTexGenfv( GL_T, GL_OBJECT_PLANE, genVector[1] ); pglTexGenfv( GL_R, GL_OBJECT_PLANE, genVector[2] ); pglTexGenfv( GL_Q, GL_OBJECT_PLANE, genVector[3] ); GL_LoadTexMatrix( matrix ); }
/* ============= R_SetupModelviewMatrix ============= */ static void R_SetupModelviewMatrix( const ref_params_t *fd, matrix4x4 m ) { #if 0 Matrix4x4_LoadIdentity( m ); Matrix4x4_ConcatRotate( m, -90, 1, 0, 0 ); Matrix4x4_ConcatRotate( m, 90, 0, 0, 1 ); #else Matrix4x4_CreateModelview( m ); #endif Matrix4x4_ConcatRotate( m, -fd->viewangles[2], 1, 0, 0 ); Matrix4x4_ConcatRotate( m, -fd->viewangles[0], 0, 1, 0 ); Matrix4x4_ConcatRotate( m, -fd->viewangles[1], 0, 0, 1 ); Matrix4x4_ConcatTranslate( m, -fd->vieworg[0], -fd->vieworg[1], -fd->vieworg[2] ); }
/* ================= R_FindBmodelMirrors Check all bmodel surfaces and make personal mirror chain ================= */ void R_FindBmodelMirrors( cl_entity_t *e, qboolean static_entity ) { mextrasurf_t *extrasurf; vec3_t mins, maxs; msurface_t *psurf; model_t *clmodel; qboolean rotated; int i, clipFlags; clmodel = e->model; if( static_entity ) { Matrix4x4_LoadIdentity( RI.objectMatrix ); if( R_CullBox( clmodel->mins, clmodel->maxs, RI.clipFlags )) return; VectorCopy( RI.cullorigin, tr.modelorg ); clipFlags = RI.clipFlags; } else { if( !VectorIsNull( e->angles )) { for( i = 0; i < 3; i++ ) { mins[i] = e->origin[i] - clmodel->radius; maxs[i] = e->origin[i] + clmodel->radius; } rotated = true; } else { VectorAdd( e->origin, clmodel->mins, mins ); VectorAdd( e->origin, clmodel->maxs, maxs ); rotated = false; } if( R_CullBox( mins, maxs, RI.clipFlags )) return; if( !VectorIsNull( e->origin ) || !VectorIsNull( e->angles )) { if( rotated ) Matrix4x4_CreateFromEntity( RI.objectMatrix, e->angles, e->origin, 1.0f ); else Matrix4x4_CreateFromEntity( RI.objectMatrix, vec3_origin, e->origin, 1.0f ); } else Matrix4x4_LoadIdentity( RI.objectMatrix ); e->visframe = tr.framecount; // visible if( rotated ) Matrix4x4_VectorITransform( RI.objectMatrix, RI.cullorigin, tr.modelorg ); else VectorSubtract( RI.cullorigin, e->origin, tr.modelorg ); clipFlags = 0; } psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ ) { if(!( psurf->flags & SURF_REFLECT )) continue; if( R_CullSurface( psurf, clipFlags )) continue; extrasurf = SURF_INFO( psurf, RI.currentmodel ); extrasurf->mirrorchain = tr.mirror_entities[tr.num_mirror_entities].chain; tr.mirror_entities[tr.num_mirror_entities].chain = extrasurf; } // store new mirror entity if( !static_entity && tr.mirror_entities[tr.num_mirror_entities].chain != NULL ) { tr.mirror_entities[tr.num_mirror_entities].ent = RI.currententity; tr.num_mirror_entities++; } }