/* ================= R_SetupFrustum Set up the culling frustum planes for the current view using the results we got from computing the first two rows of the projection matrix. ================= */ void R_SetupFrustum (viewParms_t *dest, float xmin, float xmax, float ymax, float zProj, float stereoSep) { vec3_t ofsorigin; float oppleg, adjleg, length; int i; if(stereoSep == 0 && xmin == -xmax) { // symmetric case can be simplified VectorCopy(dest->or.origin, ofsorigin); length = sqrt(xmax * xmax + zProj * zProj); oppleg = xmax / length; adjleg = zProj / length; VectorScale(dest->or.axis[0], oppleg, dest->frustum[0].normal); VectorMA(dest->frustum[0].normal, adjleg, dest->or.axis[1], dest->frustum[0].normal); VectorScale(dest->or.axis[0], oppleg, dest->frustum[1].normal); VectorMA(dest->frustum[1].normal, -adjleg, dest->or.axis[1], dest->frustum[1].normal); } else { // In stereo rendering, due to the modification of the projection matrix, dest->or.origin is not the // actual origin that we're rendering so offset the tip of the view pyramid. VectorMA(dest->or.origin, stereoSep, dest->or.axis[1], ofsorigin); oppleg = xmax + stereoSep; length = sqrt(oppleg * oppleg + zProj * zProj); VectorScale(dest->or.axis[0], oppleg / length, dest->frustum[0].normal); VectorMA(dest->frustum[0].normal, zProj / length, dest->or.axis[1], dest->frustum[0].normal); oppleg = xmin + stereoSep; length = sqrt(oppleg * oppleg + zProj * zProj); VectorScale(dest->or.axis[0], -oppleg / length, dest->frustum[1].normal); VectorMA(dest->frustum[1].normal, -zProj / length, dest->or.axis[1], dest->frustum[1].normal); } length = sqrt(ymax * ymax + zProj * zProj); oppleg = ymax / length; adjleg = zProj / length; VectorScale(dest->or.axis[0], oppleg, dest->frustum[2].normal); VectorMA(dest->frustum[2].normal, adjleg, dest->or.axis[2], dest->frustum[2].normal); VectorScale(dest->or.axis[0], oppleg, dest->frustum[3].normal); VectorMA(dest->frustum[3].normal, -adjleg, dest->or.axis[2], dest->frustum[3].normal); for (i=0 ; i<4 ; i++) { dest->frustum[i].type = PLANE_NON_AXIAL; dest->frustum[i].dist = DotProduct (ofsorigin, dest->frustum[i].normal); SetPlaneSignbits( &dest->frustum[i] ); } // farplane VectorScale( dest->or.axis[0], -1, dest->frustum[4].normal ); dest->frustum[4].dist = DotProduct( dest->or.origin, dest->frustum[4].normal ) - dest->zFar; dest->frustum[4].type = PLANE_NON_AXIAL; SetPlaneSignbits( &dest->frustum[4] ); }
/* ================= R_SetupFrustum Setup that culling frustum planes for the current view ================= */ void R_SetupFrustum (void) { int i; float xs, xc; float ang; ang = tr.viewParms.fovX / 180 * M_PI * 0.5f; xs = sin( ang ); xc = cos( ang ); VectorScale( tr.viewParms.ori.axis[0], xs, tr.viewParms.frustum[0].normal ); VectorMA( tr.viewParms.frustum[0].normal, xc, tr.viewParms.ori.axis[1], tr.viewParms.frustum[0].normal ); VectorScale( tr.viewParms.ori.axis[0], xs, tr.viewParms.frustum[1].normal ); VectorMA( tr.viewParms.frustum[1].normal, -xc, tr.viewParms.ori.axis[1], tr.viewParms.frustum[1].normal ); ang = tr.viewParms.fovY / 180 * M_PI * 0.5f; xs = sin( ang ); xc = cos( ang ); VectorScale( tr.viewParms.ori.axis[0], xs, tr.viewParms.frustum[2].normal ); VectorMA( tr.viewParms.frustum[2].normal, xc, tr.viewParms.ori.axis[2], tr.viewParms.frustum[2].normal ); VectorScale( tr.viewParms.ori.axis[0], xs, tr.viewParms.frustum[3].normal ); VectorMA( tr.viewParms.frustum[3].normal, -xc, tr.viewParms.ori.axis[2], tr.viewParms.frustum[3].normal ); for (i=0 ; i<4 ; i++) { tr.viewParms.frustum[i].type = PLANE_NON_AXIAL; tr.viewParms.frustum[i].dist = DotProduct (tr.viewParms.ori.origin, tr.viewParms.frustum[i].normal); SetPlaneSignbits( &tr.viewParms.frustum[i] ); } }
/* ================= CG_SetupFrustum ================= */ void CG_SetupFrustum(void) { int i; float xs, xc; float ang; ang = cg.refdef.fov_x / 180 * M_PI * 0.5f; xs = sin(ang); xc = cos(ang); VectorScale(cg.refdef.viewaxis[0], xs, frustum[0].normal); VectorMA(frustum[0].normal, xc, cg.refdef.viewaxis[1], frustum[0].normal); VectorScale(cg.refdef.viewaxis[0], xs, frustum[1].normal); VectorMA(frustum[1].normal, -xc, cg.refdef.viewaxis[1], frustum[1].normal); ang = cg.refdef.fov_y / 180 * M_PI * 0.5f; xs = sin(ang); xc = cos(ang); VectorScale(cg.refdef.viewaxis[0], xs, frustum[2].normal); VectorMA(frustum[2].normal, xc, cg.refdef.viewaxis[2], frustum[2].normal); VectorScale(cg.refdef.viewaxis[0], xs, frustum[3].normal); VectorMA(frustum[3].normal, -xc, cg.refdef.viewaxis[2], frustum[3].normal); for(i = 0; i < 4; i++) { frustum[i].dist = DotProduct(cg.refdef.vieworg, frustum[i].normal); frustum[i].type = PLANE_NON_AXIAL; SetPlaneSignbits(&frustum[i]); } }
/* ================= R_SetupFrustum Setup that culling frustum planes for the current view ================= */ void R_SetupFrustum (void) { int i; float xs, xc; float ang; ang = tr.viewParms.fovX / 180 * M_PI * 0.5; xs = sin( ang ); xc = cos( ang ); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[0].normal ); VectorMA( tr.viewParms.frustum[0].normal, xc, tr.viewParms.or.axis[1], tr.viewParms.frustum[0].normal ); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[1].normal ); VectorMA( tr.viewParms.frustum[1].normal, -xc, tr.viewParms.or.axis[1], tr.viewParms.frustum[1].normal ); ang = tr.viewParms.fovY / 180 * M_PI * 0.5; xs = sin( ang ); xc = cos( ang ); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[2].normal ); VectorMA( tr.viewParms.frustum[2].normal, xc, tr.viewParms.or.axis[2], tr.viewParms.frustum[2].normal ); VectorScale( tr.viewParms.or.axis[0], xs, tr.viewParms.frustum[3].normal ); VectorMA( tr.viewParms.frustum[3].normal, -xc, tr.viewParms.or.axis[2], tr.viewParms.frustum[3].normal ); // this is the far plane VectorScale( tr.viewParms.or.axis[0],-1.0f, tr.viewParms.frustum[4].normal ); for (i=0 ; i<5 ; i++) { tr.viewParms.frustum[i].type = PLANE_NON_AXIAL; tr.viewParms.frustum[i].dist = DotProduct (tr.viewParms.or.origin, tr.viewParms.frustum[i].normal); if (i==4) { // far plane does not go through the view point, it goes alot farther.. tr.viewParms.frustum[i].dist -= tr.distanceCull*1.02f; // a little slack so we don't cull stuff } SetPlaneSignbits( &tr.viewParms.frustum[i] ); } }
/* =============== ParseFace =============== */ static void ParseFace( dsurface_t *ds, mapVert_t *verts, msurface_t *surf, int *indexes, byte *&pFaceDataBuffer) { int i, j, k; srfSurfaceFace_t *cv; int numPoints, numIndexes; int lightmapNum[MAXLIGHTMAPS]; int sfaceSize, ofsIndexes; for(i=0; i<MAXLIGHTMAPS; i++) { lightmapNum[i] = LittleLong( ds->lightmapNum[i] ); } // get fog volume surf->fogIndex = LittleLong( ds->fogNum ) + 1; // get shader value surf->shader = ShaderForShaderNum( ds->shaderNum, lightmapNum, ds->lightmapStyles, ds->vertexStyles ); if ( r_singleShader->integer && !surf->shader->isSky ) { surf->shader = tr.defaultShader; } numPoints = LittleLong( ds->numVerts ); if (numPoints > MAX_FACE_POINTS) { ri.Printf( PRINT_DEVELOPER, "MAX_FACE_POINTS exceeded: %i\n", numPoints); } numIndexes = LittleLong( ds->numIndexes ); // create the srfSurfaceFace_t sfaceSize = ( int ) &((srfSurfaceFace_t *)0)->points[numPoints]; ofsIndexes = sfaceSize; sfaceSize += sizeof( int ) * numIndexes; cv = (srfSurfaceFace_t *) pFaceDataBuffer;//ri.Hunk_Alloc( sfaceSize ); pFaceDataBuffer += sfaceSize; // :-) cv->surfaceType = SF_FACE; cv->numPoints = numPoints; cv->numIndices = numIndexes; cv->ofsIndices = ofsIndexes; verts += LittleLong( ds->firstVert ); for ( i = 0 ; i < numPoints ; i++ ) { for ( j = 0 ; j < 3 ; j++ ) { cv->points[i][j] = LittleFloat( verts[i].xyz[j] ); } for ( j = 0 ; j < 2 ; j++ ) { cv->points[i][3+j] = LittleFloat( verts[i].st[j] ); for(k=0; k<MAXLIGHTMAPS; k++) { cv->points[i][VERTEX_LM+j+(k*2)] = LittleFloat( verts[i].lightmap[k][j] ); } } for(k=0; k<MAXLIGHTMAPS; k++) { R_ColorShiftLightingBytes( verts[i].color[k], (byte *)&cv->points[i][VERTEX_COLOR+k] ); } } indexes += LittleLong( ds->firstIndex ); for ( i = 0 ; i < numIndexes ; i++ ) { ((int *)((byte *)cv + cv->ofsIndices ))[i] = LittleLong( indexes[ i ] ); } // take the plane information from the lightmap vector for ( i = 0 ; i < 3 ; i++ ) { cv->plane.normal[i] = LittleFloat( ds->lightmapVecs[2][i] ); } cv->plane.dist = DotProduct( cv->points[0], cv->plane.normal ); SetPlaneSignbits( &cv->plane ); cv->plane.type = PlaneTypeForNormal( cv->plane.normal ); surf->data = (surfaceType_t *)cv; }