Skip to content

Commit

Permalink
Refactor|Map Renderer: Updated FakeRadio wrt changes to Vertex
Browse files Browse the repository at this point in the history
Also cleaned up some of the math, taking advantage of de::VectorN<>.
  • Loading branch information
danij-deng committed Apr 22, 2013
1 parent ef172b3 commit 024d456
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 80 deletions.
88 changes: 45 additions & 43 deletions doomsday/client/src/render/r_fakeradio.cpp
Expand Up @@ -19,7 +19,8 @@
*/

#include <de/memoryzone.h>
#include <de/vector1.h>
#include <de/vector1.h> /// @todo remove me
#include <de/Vector>

#include <de/Error>
#include <de/Log>
Expand Down Expand Up @@ -69,67 +70,73 @@ LineSideRadioData &Rend_RadioDataForLineSide(Line::Side &side)

/**
* Given two lines "connected" by shared origin coordinates (0, 0) at a "corner"
* vertex, calculate the point which lies @a dist1 away from @a line1 and also
* @a dist2 from @a line2. The point should also be the nearest point to the
* vertex, calculate the point which lies @a distA away from @a lineA and also
* @a distB from @a lineB. The point should also be the nearest point to the
* origin (in case of parallel lines).
*
* @param line1 Direction vector for the "left" line.
* @param line2 Direction vector for the "right" line.
* @param dist1 Distance from @a line1 to offset the corner point.
* @param dist2 Distance from @a line2 to offset the corner point.
* @param lineA Direction vector for the "left" line.
* @param lineB Direction vector for the "right" line.
* @param distA Distance from @a lineA to offset the corner point.
* @param distB Distance from @a lineB to offset the corner point.
*
* Return values:
* @param point Coordinates for the corner point are written here. Can be @c 0.
* @param lp Coordinates for the "extended" point are written here. Can be @c 0.
*/
static void cornerNormalPoint(const_pvec2d_t line1, double dist1, const_pvec2d_t line2,
double dist2, pvec2d_t point, pvec2d_t lp)
static void cornerNormalPoint(Vector2d const &lineADirection, double dist1,
Vector2d const &lineBDirection, double dist2,
Vector2d *point, Vector2d *lp)
{
// Any work to be done?
if(!point && !lp) return;

// Length of both lines.
double len1 = V2d_Length(line1);
double len2 = V2d_Length(line2);
double len1 = lineADirection.length();
double len2 = lineBDirection.length();

// Calculate normals for both lines.
vec2d_t norm1; V2d_Set(norm1, -line1[VY] / len1 * dist1, line1[VX] / len1 * dist1);
vec2d_t norm2; V2d_Set(norm2, line2[VY] / len2 * dist2, -line2[VX] / len2 * dist2);
Vector2d norm1(-lineADirection.y / len1 * dist1, lineADirection.x / len1 * dist1);
Vector2d norm2( lineBDirection.y / len2 * dist2, -lineBDirection.x / len2 * dist2);

// Do we need to calculate the extended points, too? Check that
// the extension does not bleed too badly outside the legal shadow
// area.
if(lp)
{
V2d_Set(lp, line2[VX] / len2 * dist2, line2[VY] / len2 * dist2);
*lp = lineBDirection / len2 * dist2;
}

// Are the lines parallel? If so, they won't connect at any
// point, and it will be impossible to determine a corner point.
if(V2d_IsParallel(line1, line2))
// Do we need to determine the intercept point?
if(!point) return;

// Normal shift to produce the lines we need to find the intersection.
Partition lineA(norm1, lineADirection);
Partition lineB(norm2, lineBDirection);

if(!lineA.isParallelTo(lineB))
{
// Just use a normal as the point.
if(point)
V2d_Copy(point, norm1);
*point = lineA.intercept(lineB);
return;
}

// Find the intersection of normal-shifted lines. That'll be our
// corner point.
if(point)
V2d_Intersection(norm1, line1, norm2, line2, point);
// Special case: parallel
// There will be no intersection at any point therefore it will not be
// possible to determine our corner point (so just use a normal as the
// point instead).
*point = norm1;
}

/**
* @return The width (world units) of the shadow edge. It is scaled depending on
* the length of @a edge.
*/
static double shadowEdgeWidth(pvec2d_t const edge)
static double shadowEdgeWidth(Vector2d const &edge)
{
double const normalWidth = 20; //16;
double const maxWidth = 60;

// A long edge?
double length = V2d_Length(edge);
double length = edge.length();
if(length > 600)
{
double w = length - 600;
Expand All @@ -145,7 +152,7 @@ void Rend_RadioUpdateVertexShadowOffsets(Vertex &vtx)
{
if(!vtx.lineOwnerCount()) return;

vec2d_t leftDir, rightDir;
Vector2d leftDir, rightDir;

LineOwner *base = vtx.firstLineOwner();
LineOwner *own = base;
Expand All @@ -156,33 +163,29 @@ void Rend_RadioUpdateVertexShadowOffsets(Vertex &vtx)

if(&lineB.v1() == &vtx)
{
rightDir[VX] = lineB.direction().x;
rightDir[VY] = lineB.direction().y;
rightDir = lineB.direction();
}
else
{
rightDir[VX] = -lineB.direction().x;
rightDir[VY] = -lineB.direction().y;
rightDir = -lineB.direction();
}

if(&lineA.v1() == &vtx)
{
leftDir[VX] = -lineA.direction().x;
leftDir[VY] = -lineA.direction().y;
leftDir = -lineA.direction();
}
else
{
leftDir[VX] = lineA.direction().x;
leftDir[VY] = lineA.direction().y;
leftDir = lineA.direction();
}

// The left side is always flipped.
V2d_Scale(leftDir, -1);
leftDir *= -1;

cornerNormalPoint(leftDir, shadowEdgeWidth(leftDir),
rightDir, shadowEdgeWidth(rightDir),
own->_shadowOffsets.inner,
own->_shadowOffsets.extended);
&own->_shadowOffsets.inner,
&own->_shadowOffsets.extended);

own = &own->next();
} while(own != base);
Expand Down Expand Up @@ -256,7 +259,6 @@ void Rend_RadioInitForMap()

ShadowLinkerParms parms;
AABoxd bounds;
vec2d_t point;

foreach(Line *line, theMap->lines())
{
Expand All @@ -277,11 +279,11 @@ void Rend_RadioInitForMap()
V2d_CopyBox(bounds.arvec2, line->aaBox().arvec2);

// Use the extended points, they are wider than inoffsets.
V2d_Sum(point, vtx0.origin(), vo0.extendedShadowOffset());
V2d_AddToBox(bounds.arvec2, point);
Vector2d point = vtx0.origin() + vo0.extendedShadowOffset();
V2d_AddToBoxXY(bounds.arvec2, point.x, point.y);

V2d_Sum(point, vtx1.origin(), vo1.extendedShadowOffset());
V2d_AddToBox(bounds.arvec2, point);
point = vtx1.origin() + vo1.extendedShadowOffset();
V2d_AddToBoxXY(bounds.arvec2, point.x, point.y);

parms.line = line;
parms.side = i;
Expand Down
70 changes: 33 additions & 37 deletions doomsday/client/src/render/rend_fakeradio.cpp
Expand Up @@ -1233,9 +1233,10 @@ static uint radioEdgeHackType(Line const *line, Sector const *front, Sector cons
/**
* Construct and write a new shadow polygon to the rendering lists.
*/
static void addShadowEdge(vec2d_t inner[2], vec2d_t outer[2], coord_t innerLeftZ,
coord_t innerRightZ, coord_t outerLeftZ, coord_t outerRightZ, float const sideOpen[2],
float const edgeOpen[2], boolean isFloor, float const shadowRGB[3], float shadowDark)
static void addShadowEdge(Vector2d const inner[2], Vector2d const outer[2],
coord_t innerLeftZ, coord_t innerRightZ, coord_t outerLeftZ, coord_t outerRightZ,
float const sideOpen[2], float const edgeOpen[2], boolean isFloor,
float const shadowRGB[3], float shadowDark)
{
static uint const floorIndices[][4] = {{0, 1, 2, 3}, {1, 2, 3, 0}};
static uint const ceilIndices[][4] = {{0, 3, 2, 1}, {1, 0, 3, 2}};
Expand All @@ -1247,7 +1248,7 @@ static void addShadowEdge(vec2d_t inner[2], vec2d_t outer[2], coord_t innerLeftZ

// What vertex winding order? (0 = left, 1 = right)
// (for best results, the cross edge should always be the shortest).
uint winding = (V2d_Distance(inner[1], outer[1]) > V2d_Distance(inner[0], outer[0])? 1 : 0);
uint winding = (Vector2d(outer[1] - inner[1]).length() > Vector2d(inner[0] - outer[0]).length()? 1 : 0);
uint const *idx = (isFloor ? floorIndices[winding] : ceilIndices[winding]);

rvertex_t rvertices[4];
Expand Down Expand Up @@ -1327,7 +1328,7 @@ static void processEdgeShadow(BspLeaf const &bspLeaf, Line const *line,
// Determine the openness of the line. If this edge is edgeOpen,
// there won't be a shadow at all. Open neighbours cause some
// changes in the polygon corner vertices (placement, colour).
vec2d_t inner[2], outer[2];
Vector2d inner[2], outer[2];
vec2f_t edgeOpen, sideOpen;
Sector const *front = 0;
Sector const *back = 0;
Expand Down Expand Up @@ -1404,19 +1405,19 @@ static void processEdgeShadow(BspLeaf const &bspLeaf, Line const *line,
vo = line->vertexOwner(i^side);
if(i) vo = &vo->prev();

V2d_Sum(inner[i], line->vertexOrigin(i^side), vo->innerShadowOffset());
inner[i] = line->vertexOrigin(i^side) + vo->innerShadowOffset();
}
else
{
V2d_Sum(inner[i], line->vertexOrigin(i^side), vo->extendedShadowOffset());
inner[i] = line->vertexOrigin(i^side) + vo->extendedShadowOffset();
}
}

V2d_Copy(outer[0], line->vertexOrigin(side));
V2d_Copy(outer[1], line->vertexOrigin(side^1));
outer[0] = line->vertexOrigin(side);
outer[1] = line->vertexOrigin(side^1);

// Shadows are black
vec3f_t shadowRGB;
V3f_Set(shadowRGB, 0, 0, 0);
vec3f_t shadowRGB; V3f_Set(shadowRGB, 0, 0, 0);

addShadowEdge(inner, outer, plnHeight, plnHeight, plnHeight, plnHeight, sideOpen, edgeOpen,
suf->normal()[VZ] > 0, shadowRGB, shadowDark);
Expand Down Expand Up @@ -1522,27 +1523,24 @@ void Rend_RadioBspLeafEdges(BspLeaf &bspLeaf)
}

#ifdef DENG_DEBUG
static void drawPoint(coord_t pos[3], int radius, const float color[4])
static void drawPoint(Vector3d const &point, int radius, float const color[4])
{
viewdata_t const *viewData = R_ViewData(viewPlayer - ddPlayers);

// viewData->sideVec is to the left.
coord_t leftOff[3], rightOff[3], viewToCenter[3];
Vector3d leftOff, rightOff, viewToCenter;
for(int i = 0; i < 3; ++i)
{
leftOff[i] = viewData->upVec[i] + viewData->sideVec[i];
rightOff[i] = viewData->upVec[i] - viewData->sideVec[i];

viewToCenter[i] = pos[i] - vOrigin[i];
viewToCenter[i] = point[i] - vOrigin[i];
}

//float scale = float(V3d_DotProductf(viewToCenter, viewData->frontVec)) /
// V3f_DotProduct(viewData->frontVec, viewData->frontVec);

coord_t finalPos[3];
finalPos[VX] = pos[VX];
finalPos[VY] = pos[VZ];
finalPos[VZ] = pos[VY];
Vector3d finalPos( point.x, point.z, point.y );

// The final radius.
float radX = radius * 1;
Expand All @@ -1555,21 +1553,21 @@ static void drawPoint(coord_t pos[3], int radius, const float color[4])

glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex3d(finalPos[VX] + radX * leftOff[VX],
finalPos[VY] + radY * leftOff[VY],
finalPos[VZ] + radX * leftOff[VZ]);
glVertex3d(finalPos.x + radX * leftOff.x,
finalPos.y + radY * leftOff.y,
finalPos.z + radX * leftOff.z);
glTexCoord2f(1, 0);
glVertex3d(finalPos[VX] + radX * rightOff[VX],
finalPos[VY] + radY * rightOff[VY],
finalPos[VZ] + radX * rightOff[VZ]);
glVertex3d(finalPos.x + radX * rightOff.x,
finalPos.y + radY * rightOff.y,
finalPos.z + radX * rightOff.z);
glTexCoord2f(1, 1);
glVertex3d(finalPos[VX] - radX * leftOff[VX],
finalPos[VY] - radY * leftOff[VY],
finalPos[VZ] - radX * leftOff[VZ]);
glVertex3d(finalPos.x - radX * leftOff.x,
finalPos.y - radY * leftOff.y,
finalPos.z - radX * leftOff.z);
glTexCoord2f(0, 1);
glVertex3d(finalPos[VX] - radX * rightOff[VX],
finalPos[VY] - radY * rightOff[VY],
finalPos[VZ] - radX * rightOff[VZ]);
glVertex3d(finalPos.x - radX * rightOff.x,
finalPos.y - radY * rightOff.y,
finalPos.z - radX * rightOff.z);
glEnd();
}

Expand Down Expand Up @@ -1598,14 +1596,12 @@ void Rend_DrawShadowOffsetVerts()
LineOwner const *own = base;
do
{
coord_t pos[3];
pos[VZ] = own->line().frontSector().floor().visHeight();

V2d_Sum(pos, vtx.origin(), own->extendedShadowOffset());
drawPoint(pos, 1, yellow);
Vector2d xy = vtx.origin() + own->extendedShadowOffset();
coord_t z = own->line().frontSector().floor().visHeight();
drawPoint(Vector3d(xy.x, xy.y, z), 1, yellow);

V2d_Sum(pos, vtx.origin(), own->innerShadowOffset());
drawPoint(pos, 1, red);
xy = vtx.origin() + own->innerShadowOffset();
drawPoint(Vector3d(xy.x, xy.y, z), 1, red);

own = &own->next();
} while(own != base);
Expand Down

0 comments on commit 024d456

Please sign in to comment.