diff options
author | richiesams | 2013-08-14 18:05:13 -0500 |
---|---|---|
committer | richiesams | 2013-08-15 14:15:30 -0500 |
commit | c0305d9534763d69223cb6a5ea20d20101236401 (patch) | |
tree | 87affbd04e73310c5473e4c2cd7ddc039e40ae41 /engines/zvision | |
parent | 95d1ef68ab55920fb45923c974499529268fad67 (diff) | |
download | scummvm-rg350-c0305d9534763d69223cb6a5ea20d20101236401.tar.gz scummvm-rg350-c0305d9534763d69223cb6a5ea20d20101236401.tar.bz2 scummvm-rg350-c0305d9534763d69223cb6a5ea20d20101236401.zip |
ZVISION: Rename variables and add comments to clarify the math behind panorama warping
Diffstat (limited to 'engines/zvision')
-rw-r--r-- | engines/zvision/render_table.cpp | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/engines/zvision/render_table.cpp b/engines/zvision/render_table.cpp index aab4735d81..3bd0103054 100644 --- a/engines/zvision/render_table.cpp +++ b/engines/zvision/render_table.cpp @@ -149,26 +149,32 @@ void RenderTable::generatePanoramaLookupTable() { float halfWidth = (float)_numColumns / 2.0f; float halfHeight = (float)_numRows / 2.0f; - float fovRadians = (_panoramaOptions.fieldOfView * M_PI / 180.0f); - float halfHeightOverTan = halfHeight / tan(fovRadians); - float tanOverHalfHeight = tan(fovRadians) / halfHeight; + float fovInRadians = (_panoramaOptions.fieldOfView * M_PI / 180.0f); + float cylinderRadius = halfHeight / tan(fovInRadians); // TODO: Change the algorithm to write a whole row at a time instead of a whole column at a time. AKA: for(y) { for(x) {}} instead of for(x) { for(y) {}} for (uint x = 0; x < _numColumns; x++) { // Add an offset of 0.01 to overcome zero tan/atan issue (vertical line on half of screen) - float temp = atan(tanOverHalfHeight * ((float)x - halfWidth + 0.01f)); + // Alpha represents the horizontal angle between the viewer at the center of a cylinder and x + float alpha = atan(((float)x - halfWidth + 0.01f) / cylinderRadius); - int32 newX = int32(floor((halfHeightOverTan * _panoramaOptions.linearScale * temp) + halfWidth)); - float cosX = cos(temp); + // To get x in cylinder coordinates, we just need to calculate the arc length + // We also scale it by _panoramaOptions.linearScale + int32 xInCylinderCoords = int32(floor((cylinderRadius * _panoramaOptions.linearScale * alpha) + halfWidth)); + + + float cosAlpha = cos(alpha); for (uint y = 0; y < _numRows; y++) { - int32 newY = int32(floor(halfHeight + ((float)y - halfHeight) * cosX)); + // To calculate y in cylinder coordinates, we can do similar triangles comparison, + // comparing the triangle from the center to the screen and from the center to the edge of the cylinder + int32 yInCylinderCoords = int32(floor(halfHeight + ((float)y - halfHeight) * cosAlpha)); uint32 index = y * _numColumns + x; - // Only store the x,y offsets instead of the absolute positions - _internalBuffer[index].x = newX - x; - _internalBuffer[index].y = newY - y; + // Only store the (x,y) offsets instead of the absolute positions + _internalBuffer[index].x = xInCylinderCoords - x; + _internalBuffer[index].y = yInCylinderCoords - y; } } } |