Skip to content

Commit

Permalink
Optimize: Replaced the method used to determine the alpha delta for "…
Browse files Browse the repository at this point in the history
…soft" surfaces; project the viewer onto the line being tested and then calculate the approximate distance to the resultant point.
  • Loading branch information
danij committed Apr 9, 2008
1 parent e15f755 commit b6e8069
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 44 deletions.
2 changes: 1 addition & 1 deletion doomsday/engine/portable/include/m_misc.h
Expand Up @@ -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],
Expand Down
12 changes: 8 additions & 4 deletions doomsday/engine/portable/src/m_misc.c
Expand Up @@ -664,22 +664,24 @@ 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];
float div = DOTPROD(delta, delta);
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;

Expand All @@ -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],
Expand Down
71 changes: 32 additions & 39 deletions doomsday/engine/portable/src/rend_main.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1538,26 +1515,44 @@ 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;
}
}
}

if(alpha > 0)
{
solidSeg = doRenderSeg(seg, section, surface, bottom, top,
alpha, texXOffset, texYOffset, frontsec,
skyMask, softSurface, sideFlags);
skyMask, sideFlags);
}
}

Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit b6e8069

Please sign in to comment.