source files: [xc]cmr.[ch]
(SEND <camera> :GET <:PROPERTY> [<default-value>]) (SEND <camera> :SET <:PROPERTY> <value>) (SEND <camera> :REMPROP <:PROPERTY>) (SEND <camera> :PROPERTY-LIST-LENGTH) (SEND <camera> :PROPERTY-LIST-NTH <fix:index> [<default-value>])
These calls are used both to fetch/store arbitrary properties for user purposes, and to fetch/store properties with special significance to the CAMERA class.
If :GET does not find the requested property, it returns <default-value> if one was provided, otherwise signals an error.
:REMPROP removes the given property from the propertylist, returning (:PROPERTY . <val>) if the property was successfully removed, else NIL.
:PROPERTY-LIST-LENGTH and :PROPERTY-LIST-NTH are provided to allow iteration through all properties on object, the latter's <default-value> works just as on :GET.
The properties with special significance are:
:TRANSFORM This returns the viewing transform that positions the camera. :PROJECTION-TRANSFORM This returns the transform that controls perspective angle. :LOCATION :TARGET :UP :DIAMETER :RADIANS :DEGREES :LEFT :RIGHT :TOP :BOTTOM :NEAR :FAR These merely get passed through to the viewing transform. See section :GET :SET etc. :FRAME-NUMBER This integer starts at zero and gets incremented each time the zbuffer is cleared. You may not set it. It is mostly used internally, to make sure certain tasks are done exactly once per frame. This value is global to the entire program -- it will be the same for all cameras. :SCRIPT-TIME This float represents the current 'time' within the animation script. Since the user may scroll back and forth within script time, or freeze a scene and edit it, you may *NOT* assume that script time increases monotonically from frame to frame, or even that it changes at all. :SCRIPT-TIME should be used by moving things to compute their current location. You *may* set this value ... but, obviously, it will normally only be set by the central animation controller. This value is global to the entire program -- changing it in one camera changes it in all cameras. This value is also returned by the convenience function XG.3D-SCRIPT-TIME. :SCRIPT-RATE This float represents the quantum by which :SCRIPT-TIME 'time' advances within the animation script each time the :NEXT-FRAME message is sent. It is possible and normal for application code to muck with :SCRIPT-TIME 'time' in various ways, including making it stand still or run backwards -- application code should *not* assume that :SCRIPT-TIME 'time' goes by :SCRIPT-RATE steps, or that :SCRIPT-RATE is nonzero or whatever. But :SCRIPT-RATE *is* a convenient mechanism for those times when one wants time to flow smoothly for awhile. The :SCRIPT-RATE value is global to the entire program -- changing it in one camera changes it in all cameras. :VIEWPORT-SPOT-COL This property controls the pixel location of the left side of the viewport on the output window. The viewport is the area which the camera will fill with its image. :VIEWPORT-SPOT-X Like :VIEWPORT-MIN-COL, this property controls the location of the left side of the viewport on the output window, but the location is expressed as a number in [0,1], scaled to current size of window. (To avoid having small floating-point errors crash the program, values in [-0.01,0.0) are rounded up to 0.0, and values in (1.0,1.01] are rounded down to 1.0.) :VIEWPORT-SIZE-COLS This property controls the x-size-in-pixels of the viewport on the output window. :VIEWPORT-SIZE-X Like :VIEWPORT-SIZE-COLS, but uses values in [0,1] instead of pixels. (To avoid having small floating-point errors crash the program, values in [-0.01,0.0) are rounded up to 0.0, and values in (1.0,1.01] are rounded down to 1.0.) :VIEWPORT-SPOT-ROW This property controls the pixel location of the bottom side of the viewport on the output window. :VIEWPORT-SPOT-Y Like :VIEWPORT-SPOT-ROW, but uses values in [0,1] instead of pixels. :VIEWPORT-SIZE-ROWS This property controls the y-size-in-pixels of the viewport on the output window. :VIEWPORT-SIZE-Y Like :VIEWPORT-SUZE-ROWS, but uses values in [0,1] instead of pixels.
If :RADIANS or :DEGREES (which are identical in effect, differing only in unit) are set nonzero, a perspective projection matrix will be used with the given angle of view. The specific viewing volume may then be set directly using :LOCATION, :TARGET and :UP, or indirectly using the :FRAME-THINGS message.
If :RADIANS or :DEGREES is set to zero, an orthographic projection matrix will be used. The specific viewing volume may be set up using the :FRAME-THINGS message; It may also be specified using the :NEAR :FAR :TOP :BOTTOM :LEFT RIGHT keywords.
If you wish to use exclusively these six keywords to control
the viewing volume, you should set :LOCATION to
(0,0,0), and :TARGET to
:UP to the default (0,1,0). For example, to
obtain an identity viewing matrix which simply displays the
volume bounded by
[-1,1] on each axis, do:
(setq my-camera (:new class-camera :radians 0.0 ; 360 degrees :location '(0.0 0.0 0.0) :target '(0.0 0.0 1.0) ; Look along Z axis :up '(0.0 1.0 0.0) ; Positive Y is up. :near -1.0 :far 1.0 :left -1.0 :right 1.0 :bottom -1.0 :top 1.0 ) )
One common reason for using orthographic projection is a need to match vector or polygon graphics with an underlying pixel image. To establish a camera allowing display of a 256x256 pixel image, also followedy by overlaid stroke or polygon graphics in a matching 0.0->255.0 coordinate system, do
(setq my-camera (:new class-camera :radians 0.0 ; 360 degrees :location '(0.0 0.0 0.0) :target '(0.0 0.0 1.0) ; Look along Z axis :up '(0.0 1.0 0.0) ; Positive Y is up. :viewport-size-cols 256 :viewport-size-rows 256 :near -1.0 :far 1.0 :left 0.5 :right 255.5 :bottom 0.5 :top 255.5 ) )
Then draw the background image first on each frame (using a pixel-relation), followed by drawing the overlying graphics (using the usual point-relation and facet-relation).
Note the 0.5 added to :LEFT :RIGHT BOTTOM TOP! These are needed to keep floating point rounding errors from throwing results off by a pixel after truncation in the graphics pipeline.
(To deactivate the six :LEFT, :RIGHT, ... parameters, set them equal to zero.)
Other properties which you :SET or :GET are simply passively stored on the property list.