#+TITLE: Python CAD Tutorial 03 - Setup the camera for viewing our scene
#+DATE: 2013-10-03 12:00:00 UTC
#+DESCRIPTION: Setup the camera so we can see our models.
#+FILETAGS: GTK-3:python:cad:opengl
#+CATEGORY: python
#+SLUG: 03-setup-camera-for-viewing-your-scene
#+THUMBNAIL: ../../../images/cad/tut03-interface.png
#+BEGIN_COMMENT
.. title:  Python CAD Tutorial 03 - Setup the camera for viewing our scene
.. slug: 03-setup-camera-for-viewing-your-scene.org
.. date: 2013-10-03 12:00:00 UTC
.. tags: GTK-3, python, cad, opengl
.. category: python
.. description: Setup the camera so we can see our models.
.. type: text
#+END_COMMENT


#+BEGIN_SRC python

#+END_SRC

[[https://code.launchpad.net/~oly/fabricad/tut03][View/Download Code]]

[[../../../images/cad/tut03-interface.png]]



In this tutorial we will deal with setting up the camera to view our workspace. The camera can be positioned and adjusted to change what is visible in the application.
Look at the diagram below for the required parameters. The diagram uses the same name as the variables in the code, so you know what values to adjust to change the scene. Most should be self explanatory, for example 'camera location' and 'where we are looking'.
The near and far planes set the size of the visible area, we can only see objects positioned inside this space. The field of view is the viewing angle and will adjust the size of the far_plane accordingly, also changing how much is visible.
The only other parameters you need are the viewport width and height, which is basically the size of the screen or window. In our case, it's the size of the drawingarea widget.


web.images.create(web.template.path_image + '/cad/camera-view.svg', title='Camera View')

The code for this is mainly oriented around the two functions called 'gluPerspective' and 'gluLookAt'.

'gluLookAt' is relatively straight forward; it takes 3 x,y,z values: the position of the camera, the point we wish to look at and an up vector. In this case we are using the y axis as the up vector.

'gluPerspective' is where we set what is visible in the world. We pass in our near and far planes and field of view to set the view frustrum area. We need to call the update method whenever something changes like the cameras position.

#+BEGIN_SRC python

#+END_SRC

web.pre.create(load_partial(os.path.abspath(self.path_absolute + '../examples/tut03/cad/camera.py'), 0))
web.page.section(web.pre.render())
web.page.section(web.google_plus.render())

#+CAPTION: Setup the camera 
[[../../../images/cad/tut03-interface.png]]


In this tutorial we will deal with setting up the camera to view our workspace. The camera can be positioned and adjusted to change what is visible in the application.
Look at the diagram below for the required parameters. The diagram uses the same name as the variables in the code, so you know what values to adjust to change the scene. 
Most should be self explanatory, for example 'camera location' and 'where we are looking'.
The near and far planes set the size of the visible area, we can only see objects positioned inside this space. 
The field of view is the viewing angle and will adjust the size of the far_plane accordingly, also changing how much is visible.
The only other parameters you need are the viewport width and height, which is basically the size of the screen or window. In our case, it's the size of the drawingarea widget.

[[../../../images/cad/camera-view.svg]]

The code for this is mainly oriented around the two functions called 'gluPerspective' and 'gluLookAt'. 'gluLookAt' is relatively straight forward; it takes 3 x,y,z values: the position of the camera, the point we wish to look at and an up vector. In this case we are using the y axis as the up vector. 'gluPerspective' is where we set what is visible in the world. We pass in our near and far planes and field of view to set the view frustrum area. We need to call the update method whenever something changes like the cameras position.

#+BEGIN_SRC python
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL import GLX
from OpenGL import GL
from ctypes import *
from point import createpoint


class createcamera:
    #your visible area in 2d space, cordinates of screen or window view space
    viewport = 400, 400
    viewport_aspect = viewport[0] / viewport[1]

    #how much of the world can we see, how wide is our sight
    field_of_view = 110

    #camera parameters position look direction rotation
    lookat = createpoint((0.0, 0.0, 100.0))
    location = createpoint((0.0, 0.0, 0.0))
    camera_rotation = 0.0

    #viewing depth of the camera, also know as the frustrum near and far planes
    near_plane = 10.0
    far_plane = 100.0

    #view frustrum / camera visible area properties,
    def __init__(self, width, height):
        self.viewport = width, height
        self.viewport_aspect = self.viewport[0] / self.viewport[1]

    def draw(self):
        pass

    #the window has been resized so recalculate display
    #also used in initial setup of screen
    def update(self):
        """call this when ever the screen is updated,
        calculates what's visible and where the camera exists in space.
        also set what we are loking at in the world"""
        glViewport(0, 0, self.viewport[0], self.viewport[1])
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()

        #setup camera parameters field of view, size of camera (ie the view window size)
        #set the frustrum parameters
        gluPerspective(self.field_of_view,
                       1.0 * self.viewport[0] / self.viewport[1],
                       self.near_plane, self.far_plane)

        #position the camera and look at something
        gluLookAt(self.location.x, self.location.y, self.location.z,
                  self.lookat.x, self.lookat.y, self.lookat.z,
                  0.0, 1.0, 0.0)

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()
#+END_SRC


