/* ================ R_FindMirrors Build mirror chains for this frame ================ */ void R_FindMirrors( const ref_params_t *fd ) { vec3_t viewOrg, viewAng; if( !world.has_mirrors || RI.drawOrtho || !RI.drawWorld || RI.refdef.onlyClientDraw || !cl.worldmodel ) return; RI.refdef = *fd; // build the transformation matrix for the given view angles if( cl.thirdperson ) { vec3_t cam_ofs, vpn; clgame.dllFuncs.CL_CameraOffset( cam_ofs ); viewAng[PITCH] = cam_ofs[PITCH]; viewAng[YAW] = cam_ofs[YAW]; viewAng[ROLL] = 0; AngleVectors( viewAng, vpn, NULL, NULL ); VectorMA( RI.refdef.vieworg, -cam_ofs[ROLL], vpn, viewOrg ); } else { VectorCopy( RI.refdef.vieworg, viewOrg ); VectorCopy( RI.refdef.viewangles, viewAng ); } // build the transformation matrix for the given view angles VectorCopy( viewOrg, RI.vieworg ); AngleVectors( viewAng, RI.vforward, RI.vright, RI.vup ); VectorCopy( RI.vieworg, RI.pvsorigin ); if( !r_lockcull->integer ) { VectorCopy( RI.vieworg, RI.cullorigin ); VectorCopy( RI.vforward, RI.cull_vforward ); VectorCopy( RI.vright, RI.cull_vright ); VectorCopy( RI.vup, RI.cull_vup ); } R_FindViewLeaf(); R_SetupFrustum(); R_MarkLeaves (); VectorCopy( RI.cullorigin, tr.modelorg ); RI.currententity = clgame.entities; RI.currentmodel = RI.currententity->model; R_RecursiveMirrorNode( cl.worldmodel->nodes, RI.clipFlags ); R_CheckEntitiesOnList(); }
/* ================ R_FindMirrors Build mirror chains for this frame ================ */ void R_FindMirrors( const ref_params_t *fd ) { if( !world.has_mirrors || RI.drawOrtho || !RI.drawWorld || RI.refdef.onlyClientDraw || !cl.worldmodel ) return; RI.refdef = *fd; // build the transformation matrix for the given view angles VectorCopy( RI.refdef.vieworg, RI.vieworg ); AngleVectors( RI.refdef.viewangles, RI.vforward, RI.vright, RI.vup ); R_FindViewLeaf(); R_SetupFrustum(); R_MarkLeaves (); VectorCopy( RI.cullorigin, tr.modelorg ); RI.currententity = clgame.entities; RI.currentmodel = RI.currententity->model; R_RecursiveMirrorNode( cl.worldmodel->nodes, RI.clipFlags ); R_CheckEntitiesOnList(); }
/* ================ R_RecursiveMirrorNode ================ */ void R_RecursiveMirrorNode( mnode_t *node, uint clipflags ) { mextrasurf_t *extrasurf; const mplane_t *clipplane; int i, clipped; msurface_t *surf, **mark; mleaf_t *pleaf; int c, side; float dot; if( node->contents == CONTENTS_SOLID ) return; // hit a solid leaf if( node->visframe != tr.visframecount ) return; if( clipflags ) { for( i = 0, clipplane = RI.frustum; i < 6; i++, clipplane++ ) { if(!( clipflags & ( 1<<i ))) continue; clipped = BoxOnPlaneSide( node->minmaxs, node->minmaxs + 3, clipplane ); if( clipped == 2 ) return; if( clipped == 1 ) clipflags &= ~(1<<i); } } // if a leaf node, draw stuff if( node->contents < 0 ) { pleaf = (mleaf_t *)node; mark = pleaf->firstmarksurface; c = pleaf->nummarksurfaces; if( c ) { do { (*mark)->visframe = tr.framecount; mark++; } while( --c ); } return; } // node is just a decision point, so go down the apropriate sides // find which side of the node we are on dot = PlaneDiff( tr.modelorg, node->plane ); side = (dot >= 0) ? 0 : 1; // recurse down the children, front side first R_RecursiveMirrorNode( node->children[side], clipflags ); // draw stuff for( c = node->numsurfaces, surf = cl.worldmodel->surfaces + node->firstsurface; c; c--, surf++ ) { if(!( surf->flags & SURF_REFLECT )) continue; if( R_CullSurface( surf, clipflags )) continue; extrasurf = SURF_INFO( surf, RI.currentmodel ); extrasurf->mirrorchain = tr.mirror_entities[0].chain; tr.mirror_entities[0].chain = extrasurf; } // recurse down the back side R_RecursiveMirrorNode( node->children[!side], clipflags ); }