[OpenSCAD] Light source and default camera position different on command line

nop head nop.head at gmail.com
Sat Sep 15 08:18:27 EDT 2018


Changing the lights as follows seems to get back to the original GUI
lighting.

-  GLfloat light_position0[] = {-1.0, -1.0, +1.0, 0.0};
-  GLfloat light_position1[] = {+1.0, +1.0, -1.0, 0.0};
+  GLfloat light_position0[] = {+1.0, -1.0, -1.0, 0.0};
+  GLfloat light_position1[] = {-1.0, +1.0, +1.0, 0.0};

Had to change the sign of both X and Z, which I think means its rotated 180
around the Y axis. I have no idea why this is needed.

The few tests that failed now pass and all the vector camera tests fail,
about 40% of the total. Is there a quick way of updating all the test
images or do I have to manually dig them out and replace them all?

On 15 September 2018 at 12:28, nop head <nop.head at gmail.com> wrote:

> Actually a few of the tests do now fail due to light changes. Those which
> use use the Gimbal camera mode.
>
> openscad-camrot_camera-tests
> Expected image Actual image
>
>
>
> 1108/1124 Testing: openscad-camrot_camera-tests
> 1108/1124 Test: openscad-camrot_camera-tests
> Command: "C:/msys64/mingw64/bin/python.exe" "C:/msys64/home/ChrisP/openscad/tests/test_cmdline_tool.py" "--comparator=" "-c" "C:/msys64/mingw64/bin/convert.exe" "-s" "png" "-t" "openscad-camrot" "-f" "camera-tests" "C:/msys64/home/ChrisP/openscad/tests/../Release/openscad.exe" "C:/msys64/home/ChrisP/openscad/tests/../testdata/scad/3D/misc/camera-tests.scad" "--imgsize=500,500" "--camera=0,0,0,440,337.5,315,200" "-o"
> Directory: C:/msys64/home/ChrisP/openscad/tests
> "openscad-camrot_camera-tests" start time: Sep 15 12:23 GMT Daylight Time
> Output:
>
>
> So I think the correct fix is to change the lights so these pass and then
> regenerate all the test results for the vector camera tests.
>
>
> On 15 September 2018 at 12:23, nop head <nop.head at gmail.com> wrote:
>
>> From here: https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/
>> xhtml/glLight.xml for GL_POSITION it says "params contains four integer
>> or floating-point values that specify the position of the light in
>> homogeneous object coordinates." and "The position is transformed by the
>> modelview matrix when glLight is called (just as if it were a point), and
>> it is stored in eye coordinates."
>>
>> glLight is called before the camera is set up so it should be consistent
>> in eye coordinates, i.e. fixed relative to the camera, not the world. This
>> is certainly true in the GUI gimbal mode. When you rotate around the world
>> the light is always coming from over your left shoulder.
>>
>> Both camera modes call gluLookat(), with the same up vector. In gimbal
>> mode it always looks down the Y axis and then rotates the world. The vector
>> mode just looks along an arbitrary vector. Since the light positions have
>> been previously baked into eye coordinates I don't understand how they end
>> up different in vector mode. They both set up the projection matrix with
>> the same calls, just slightly different parameters. Yes the gimbal mode
>> then messes with the MODELVIEW matrix but we can see that doesn't affect
>> the lighting relative to the camera.
>>
>> I refactored setupCamera() to use the same code for both cameras:
>> void GLView::setupCamera()
>> {
>>     glMatrixMode(GL_PROJECTION);
>>     glLoadIdentity();
>>     const bool gimbal = cam.type == Camera::CameraType::GIMBAL;
>>     auto center = gimbal ? Vector3d(0.0,0.0,0.0)                :
>> cam.center;
>>     auto eye    = gimbal ? Vector3d(0.0, -cam.zoomValue(), 0.0) : cam.eye;
>>     auto dist   = (center - eye).norm();
>>     switch (this->cam.projection) {
>>         case Camera::ProjectionType::PERSPECTIVE: {
>>             gluPerspective(cam.fov, aspectratio, 0.1*dist, 100*dist);
>>             break;
>>         }
>>         case Camera::ProjectionType::ORTHOGONAL: {
>>             auto height = dist * tan(cam.fov/2*M_PI/180);
>>             glOrtho(-height*aspectratio, height*aspectratio,
>>                     -height, height,
>>                     -100*dist, +100*dist);
>>             break;
>>         }
>>     }
>>     Vector3d dir(eye - center);
>>     Vector3d up(0.0,0.0,1.0);
>>     if (dir.cross(up).norm() < 0.001) { // View direction is ~parallel
>> with up vector
>>         up << 0.0,1.0,0.0;
>>     }
>>
>>     glMatrixMode(GL_MODELVIEW);
>>     glLoadIdentity();
>>     gluLookAt(eye[0], eye[1], eye[2],
>>               center[0], center[1], center[2],
>>               up[0], up[1], up[2]);
>>
>>     if(gimbal) {
>>         glRotated(cam.object_rot.x(), 1.0, 0.0, 0.0);
>>         glRotated(cam.object_rot.y(), 0.0, 1.0, 0.0);
>>         glRotated(cam.object_rot.z(), 0.0, 0.0, 1.0);
>>     }
>> }
>>
>> If the Camera class maintained correct values in object_rot, eye and
>> centre it wouldn't even need a type. The different modes are just different
>> ways of setting those properties.
>>
>> All the test still pass but the GUI now looks the same as the tests, i.e.
>> lit from below. The difference is the position of glLoadIdentity()relative
>> to gluLookAt(). I think gluLookAt just sets the model view matrix, so
>> calling glLoadIdentity after it erases its effect.
>>
>> So without really understanding the bug I can fix it by unifying the
>> camera modes. The problem is the lights from below are not ideal. I can
>> probably change the light setup to make the GUI mode the same as it was,
>> but then half the tests will fail.
>>
>>
>> On 15 September 2018 at 03:20, Marius Kintel <marius at kintel.net> wrote:
>>
>>> > On Sep 10, 2018, at 8:47 AM, nop head <nop.head at gmail.com> wrote:
>>> >
>>> > But the lighting code is already the same for both cameras. I don't
>>> understand why it comes out different. Are the lighting positions relative
>>> to the world or the camera?
>>> >
>>> The two cameras have slightly different ways of managing OpenGL matrices
>>> (https://github.com/openscad/openscad/blob/master/src/GLView.cc#L91):
>>> * The gimbal camera sets up the camera parameters in GL_PROJECTION mode,
>>> then resets the MODELVIEW matrix and rotates the scene
>>> * The vector camera set up the camera projection in GL_PROJECTION mode,
>>> then does a gluLookat().
>>>
>>> Without looking at this in great detail, I’d guess that the gimbal mode
>>> is messing with stuff it shouldn’t do with the PROJECTION matrix, causing
>>> the lights to have different relative directions in gimbal and vector modes.
>>>
>>> Setting up OpenGL cameras and lights using these low-level functions can
>>> be tricky and is error prone...
>>>
>>>  -Marius
>>>
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> Discuss at lists.openscad.org
>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20180915/c2c3940c/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 18903 bytes
Desc: not available
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20180915/c2c3940c/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 16325 bytes
Desc: not available
URL: <http://lists.openscad.org/pipermail/discuss_lists.openscad.org/attachments/20180915/c2c3940c/attachment-0001.png>


More information about the Discuss mailing list