[vlc-commits] viewpoint: rotate 360 sphere and cube to -pi/2
Alexandre Janniaux
git at videolan.org
Wed Jan 13 16:35:49 UTC 2021
vlc | branch: master | Alexandre Janniaux <ajanni at videolabs.io> | Sat Jan 9 15:10:47 2021 +0100| [6de1ecbfb39c9926d04a5b959bf4a97539f38b72] | committer: Alexandre Janniaux
viewpoint: rotate 360 sphere and cube to -pi/2
Renderers in OpenGL and D3D11 were adding +pi/2 to yaw when generating
the View matrix. This additional +pi/2 is ought to be understood as a
-pi/2 angle on yaw instead since the matrix is written transposed.
This additional angle stems from the sphere coordinates being mapped
from 0 to 2.pi while the texture itself is conceived to be mapped on
the segment [-pi/2; 3.pi/2] instead.
This patch "hardcode" the -pi/2 rotation in the sphere mesh by matching
the generated coordinates with the ones expected for the texture
mapping, thus removing the pi/2 rotation in the View matrix.
The rotation was initially added in the following commit:
08207425d8d260a6650a332c4c7c7b040ff48b15
No additional rotation is done for D3D11 cube because it was already
accidentally rotated in ec0b151f397bf4470f58aa55daa9f7b2068113a4.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6de1ecbfb39c9926d04a5b959bf4a97539f38b72
---
modules/video_output/opengl/renderer.c | 64 +++++++++++++++++++--------------
modules/video_output/win32/d3d11_quad.c | 4 +--
src/misc/viewpoint.c | 2 +-
3 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/modules/video_output/opengl/renderer.c b/modules/video_output/opengl/renderer.c
index 795754f900..a6d1b65508 100644
--- a/modules/video_output/opengl/renderer.c
+++ b/modules/video_output/opengl/renderer.c
@@ -494,18 +494,30 @@ static int BuildSphere(GLfloat **vertexCoord, GLfloat **textureCoord, unsigned *
sincosf(theta, &sinTheta, &cosTheta);
- for (unsigned lon = 0; lon <= nbLonBands; lon++) {
- float phi = lon * 2 * (float) M_PI / nbLonBands;
+ for (unsigned int lon = 0; lon <= nbLonBands; lon++) {
+ float phi = 2.f * (float)M_PI * (float)lon / nbLonBands;
float sinPhi, cosPhi;
sincosf(phi, &sinPhi, &cosPhi);
- float x = cosPhi * sinTheta;
+ /* The camera is centered on the Z axis when yaw = 0, while the
+ * front part of the equirectangular texture is located at u=0.5.
+ * To have the camera at the correct location, phi is
+ * shifted +pi/2 to have u=0.5 fall at the correct location.
+ *
+ * Another way to interpret the shift is to interpret the shift
+ * as a shift in texture coordinate. Considering the initial
+ * orientation of the camera to Z which accounts as a pi/2
+ * rotation, adding pi/2 maps the first and last coordinate to the
+ * meridian, pi radians after the camera, so that u=0 amd u=1, ie.
+ * the back face, is mapped to the back of the initial orientation
+ * of the camera. */
+ float x = -sinPhi * sinTheta;
float y = cosTheta;
- float z = sinPhi * sinTheta;
+ float z = cosPhi * sinTheta;
unsigned off1 = (lat * (nbLonBands + 1) + lon) * 3;
- (*vertexCoord)[off1] = SPHERE_RADIUS * x;
+ (*vertexCoord)[off1 + 0] = SPHERE_RADIUS * x;
(*vertexCoord)[off1 + 1] = SPHERE_RADIUS * y;
(*vertexCoord)[off1 + 2] = SPHERE_RADIUS * z;
@@ -568,15 +580,15 @@ static int BuildCube(float padW, float padH,
swap(value, 1.f, 1.f), \
swap(value, 1.f, -1.f)
-#define X_FACE(v, a, b) (v), (a), (b)
+#define X_FACE(v, a, b) (v), (b), (a)
#define Y_FACE(v, a, b) (a), (v), (b)
#define Z_FACE(v, a, b) (a), (b), (v)
static const GLfloat coord[] = {
- CUBEFACE(X_FACE, -1.f), // FRONT
- CUBEFACE(X_FACE, +1.f), // BACK
- CUBEFACE(Z_FACE, +1.f), // LEFT
- CUBEFACE(Z_FACE, -1.f), // RIGHT
+ CUBEFACE(Z_FACE, -1.f), // FRONT
+ CUBEFACE(Z_FACE, +1.f), // BACK
+ CUBEFACE(X_FACE, -1.f), // LEFT
+ CUBEFACE(X_FACE, +1.f), // RIGHT
CUBEFACE(Y_FACE, -1.f), // BOTTOM
CUBEFACE(Y_FACE, +1.f), // TOP
};
@@ -592,15 +604,15 @@ static int BuildCube(float padW, float padH,
float row[] = {0.f, 1.f/2, 1.0};
const GLfloat tex[] = {
- col[1] + padW, row[0] - padH, // front
- col[2] + padW, row[0] + padH,
- col[1] - padW, row[1] - padH,
- col[2] - padW, row[1] + padH,
-
- col[3] - padW, row[0] - padH, // back
+ col[1] + padW, row[1] - padH, // front
+ col[1] + padW, row[0] + padH,
+ col[2] - padW, row[1] - padH,
col[2] - padW, row[0] + padH,
- col[3] + padW, row[1] - padH,
- col[2] + padW, row[1] + padH,
+
+ col[3] - padW, row[1] - padH, // back
+ col[3] - padW, row[0] + padH,
+ col[2] + padW, row[1] - padH,
+ col[2] + padW, row[0] + padH,
col[2] - padW, row[2] - padH, // left
col[2] - padW, row[1] + padH,
@@ -612,15 +624,15 @@ static int BuildCube(float padW, float padH,
col[1] - padW, row[2] - padH,
col[1] - padW, row[1] + padH,
- col[0] + padW, row[1] + padH, // bottom
- col[1] + padW, row[1] - padH,
- col[0] - padW, row[0] + padH,
- col[1] - padW, row[0] - padH,
+ col[0] + padW, row[0] + padH, // bottom
+ col[0] + padW, row[1] - padH,
+ col[1] - padW, row[0] + padH,
+ col[1] - padW, row[1] - padH,
- col[2] + padW, row[1] - padH, // top
- col[3] + padW, row[1] + padH,
- col[2] - padW, row[2] - padH,
- col[3] - padW, row[2] + padH,
+ col[2] + padW, row[2] - padH, // top
+ col[2] + padW, row[1] + padH,
+ col[3] - padW, row[2] - padH,
+ col[3] - padW, row[1] + padH,
};
memcpy(*textureCoord, tex,
diff --git a/modules/video_output/win32/d3d11_quad.c b/modules/video_output/win32/d3d11_quad.c
index 1caf64635f..0928155fea 100644
--- a/modules/video_output/win32/d3d11_quad.c
+++ b/modules/video_output/win32/d3d11_quad.c
@@ -427,9 +427,9 @@ static void SetupQuadSphere(d3d_vertex_t *dst_data, const RECT *output,
sincosf(phi, &sinPhi, &cosPhi);
- float x = cosPhi * sinTheta;
+ float x = -sinPhi * sinTheta;
float y = cosTheta;
- float z = sinPhi * sinTheta;
+ float z = cosPhi * sinTheta;
unsigned off1 = lat * (nbLonBands + 1) + lon;
dst_data[off1].position.x = SPHERE_RADIUS * x;
diff --git a/src/misc/viewpoint.c b/src/misc/viewpoint.c
index c4b6aa4f04..6d5aeaf2bd 100644
--- a/src/misc/viewpoint.c
+++ b/src/misc/viewpoint.c
@@ -28,7 +28,7 @@
void vlc_viewpoint_to_4x4( const vlc_viewpoint_t *vp, float *m )
{
- float yaw = -vp->yaw * (float)M_PI / 180.f + (float)M_PI_2;
+ float yaw = -vp->yaw * (float)M_PI / 180.f;
float pitch = -vp->pitch * (float)M_PI / 180.f;
float roll = -vp->roll * (float)M_PI / 180.f;
More information about the vlc-commits
mailing list