aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision
diff options
context:
space:
mode:
authorrichiesams2013-08-14 18:05:13 -0500
committerrichiesams2013-08-15 14:15:30 -0500
commitc0305d9534763d69223cb6a5ea20d20101236401 (patch)
tree87affbd04e73310c5473e4c2cd7ddc039e40ae41 /engines/zvision
parent95d1ef68ab55920fb45923c974499529268fad67 (diff)
downloadscummvm-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.cpp26
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;
}
}
}