From b6e8069a56676f7248bb599cd2f475b8b466b123 Mon Sep 17 00:00:00 2001 From: danij Date: Wed, 9 Apr 2008 01:42:16 +0000 Subject: [PATCH] Optimize: Replaced the method used to determine the alpha delta for "soft" surfaces; project the viewer onto the line being tested and then calculate the approximate distance to the resultant point. --- doomsday/engine/portable/include/m_misc.h | 2 +- doomsday/engine/portable/src/m_misc.c | 12 ++-- doomsday/engine/portable/src/rend_main.c | 71 ++++++++++------------- 3 files changed, 41 insertions(+), 44 deletions(-) diff --git a/doomsday/engine/portable/include/m_misc.h b/doomsday/engine/portable/include/m_misc.h index f783818794..7532b580e1 100644 --- a/doomsday/engine/portable/include/m_misc.h +++ b/doomsday/engine/portable/include/m_misc.h @@ -104,7 +104,7 @@ void M_PointCrossProduct(const float* v1, const float* v2, float M_TriangleArea(const float* v1, const float* v2, const float* v3); void M_RotateVector(float vec[3], float degYaw, float degPitch); -void M_ProjectPointOnLine(const float* point, const float* linepoint, +float M_ProjectPointOnLine(const float* point, const float* linepoint, const float* delta, float gap, float* result); void M_ProjectViewRelativeLine2D(const float center[2], diff --git a/doomsday/engine/portable/src/m_misc.c b/doomsday/engine/portable/src/m_misc.c index 898d01a8b1..2d51ad5a84 100644 --- a/doomsday/engine/portable/src/m_misc.c +++ b/doomsday/engine/portable/src/m_misc.c @@ -664,9 +664,8 @@ float M_PointLineDistance(const float *a, const float *b, const float *c) /** * Gap is the distance left between the line and the projected point. */ -void M_ProjectPointOnLine(const float *point, const float *linepoint, - const float *delta, - float gap, float *result) +float M_ProjectPointOnLine(const float* point, const float* linepoint, + const float* delta, float gap, float* result) { #define DOTPROD(a,b) (a[VX]*b[VX] + a[VY]*b[VY]) float pointvec[2]; @@ -674,12 +673,15 @@ void M_ProjectPointOnLine(const float *point, const float *linepoint, float diff[2], dist; if(!div) - return; + return 0; pointvec[0] = point[VX] - linepoint[VX]; pointvec[1] = point[VY] - linepoint[VY]; div = DOTPROD(pointvec, delta) / div; + if(!result) + return div; + result[VX] = linepoint[VX] + delta[VX] * div; result[VY] = linepoint[VY] + delta[VY] * div; @@ -696,6 +698,8 @@ void M_ProjectPointOnLine(const float *point, const float *linepoint, result[i] -= diff[i] / dist * gap; } } + + return div; } void M_ProjectViewRelativeLine2D(const float center[2], diff --git a/doomsday/engine/portable/src/rend_main.c b/doomsday/engine/portable/src/rend_main.c index 09b2607dd0..f9daa04870 100644 --- a/doomsday/engine/portable/src/rend_main.c +++ b/doomsday/engine/portable/src/rend_main.c @@ -976,29 +976,6 @@ static void getColorsForSegSection(const seg_t* seg, segsection_t section, } } -/** - * Calculate 2D distance to line. - * \fixme Too accurate? - */ -static void lineDistanceAlpha(const float *point, float radius, - const float *from, const float *to, - float *alpha) -{ - float distance; - - distance = M_PointLineDistance(from, to, point); - - if(radius <= 0) - radius = 1; - - if(distance < radius) - { - // Fade it out the closer the viewPlayer gets and clamp. - *alpha = (*alpha / radius) * distance; - *alpha = MINMAX_OF(0, *alpha, 1); - } -} - typedef struct { boolean isWall; float length; @@ -1287,7 +1264,7 @@ static boolean doRenderSeg(seg_t* seg, segsection_t section, surface_t* surface, float bottom, float top, float alpha, float texXOffset, float texYOffset, sector_t* frontsec, boolean skyMask, - boolean softSurface, short sideFlags) + short sideFlags) { rendsegsection_params_t params; rvertex_t rvertices[4]; @@ -1357,7 +1334,7 @@ static boolean doRenderSeg(seg_t* seg, segsection_t section, params.texOffset[VX] = texXOffset; params.texOffset[VY] = texYOffset; - if(section == SEG_MIDDLE && softSurface) + if(section == SEG_MIDDLE) { // Blendmode. if(surface->blendMode == BM_NORMAL && noSpriteTrans) @@ -1538,18 +1515,36 @@ static boolean renderSegSection(seg_t* seg, segsection_t section, * opaque waterfall). */ - if(mo->subsector->sector == frontsec && - viewZ > bottom && viewZ < top) + if(viewZ > bottom && viewZ < top) { - float c[2]; + float delta[2], pos, result[2]; + linedef_t* lineDef = seg->lineDef; + + delta[0] = lineDef->dX; + delta[1] = lineDef->dY; + + pos = M_ProjectPointOnLine(mo->pos, lineDef->L_v1pos, delta, 0, + result); + if(pos > 0 && pos < 1) + { + float distance; + float minDistance = mo->radius * .8f; + + delta[VX] = mo->pos[VX] - result[VX]; + delta[VY] = mo->pos[VY] - result[VY]; - c[VX] = mo->pos[VX]; - c[VY] = mo->pos[VY]; + distance = M_ApproxDistancef(delta[VX], delta[VY]); - lineDistanceAlpha(c, mo->radius * .8f, - seg->SG_v1pos, seg->SG_v2pos, &alpha); - if(alpha < 1) - solidSeg = false; + if(distance < minDistance) + { + // Fade it out the closer the viewPlayer gets and clamp. + alpha = (alpha / minDistance) * distance; + alpha = MINMAX_OF(0, alpha, 1); + } + + if(alpha < 1) + solidSeg = false; + } } } @@ -1557,7 +1552,7 @@ static boolean renderSegSection(seg_t* seg, segsection_t section, { solidSeg = doRenderSeg(seg, section, surface, bottom, top, alpha, texXOffset, texYOffset, frontsec, - skyMask, softSurface, sideFlags); + skyMask, sideFlags); } } @@ -1705,10 +1700,8 @@ static boolean Rend_RenderWallSeg(seg_t* seg, subsector_t* ssec) (ldef->flags & DDLF_DONTPEGBOTTOM)? true : false)) { // Can we make this a soft surface? - if((!(ldef->flags & DDLF_BLOCKING) || - !(viewPlayer->shared.flags & DDPF_NOCLIP)) && - vL_ZTop >= top && vL_ZBottom <= bottom && - vR_ZTop >= top && vR_ZBottom <= bottom) + if((viewPlayer->shared.flags & (DDPF_NOCLIP|DDPF_CAMERA)) || + !(ldef->flags & DDLF_BLOCKING)) { softSurface = true; }