public class Camera extends Eye implements Copyable
Eye
abstract class. This class
API aims to conform that of the great
libQGLViewer
Camera.
The Camera type()
can be ORTHOGRAPHIC
or PERSPECTIVE
(
fieldOfView()
is meaningless in the latter case).
The near and far planes of the Camera are fitted to the scene and determined from the
AbstractScene.radius()
,
AbstractScene.center()
and
zClippingCoefficient()
by the zNear()
and zFar()
. Reasonable
values on the scene extends thus have to be provided to the Scene in order for the
Camera to correctly display the scene. High level positioning methods also use this
information (Eye.showEntireScene()
, Eye.centerScene()
, ...).
Stereo display is possible on devices with quad buffer capabilities (with
PERSPECTIVE
type()
only).
Attention: the Eye.frame()
Frame.magnitude()
is used to set the
fieldOfView()
or compute Eye.getBoundaryWidthHeight()
if the camera
type()
is PERSPECTIVE
or ORTHOGRAPHIC
, respectively. The
Camera magnitude is thus generally different from that of the scene. Use
Eye.eyeCoordinatesOf(Vec)
and Eye.worldCoordinatesOf(Vec)
(or any of the
powerful Frame transformations (
Frame.coordinatesOf(Vec)
,
Frame.transformOf(Vec)
, ...)) to convert to and from
the Eye Eye.frame()
coordinate system.
Modifier and Type | Class and Description |
---|---|
static class |
Camera.Type
Enumerates the two possible types of Camera.
|
Eye.Visibility
Modifier and Type | Field and Description |
---|---|
boolean |
cadRotationIsReversed |
anchorFlag, lastNonFrameUpdate, pupFlag, pupVec
Constructor and Description |
---|
Camera(AbstractScene scn)
Main constructor.
|
Modifier and Type | Method and Description |
---|---|
Vec |
at()
2D Windows return the postion.
|
Eye.Visibility |
ballVisibility(Vec center,
float radius)
Returns
Eye.Visibility.VISIBLE ,
Eye.Visibility.INVISIBLE , or
Eye.Visibility.SEMIVISIBLE , depending whether the
sphere (of radius radius and center center ) is visible, invisible, or
semi-visible, respectively. |
Eye.Visibility |
boxVisibility(Vec p1,
Vec p2)
Returns
Eye.Visibility.VISIBLE ,
Eye.Visibility.INVISIBLE , or
Eye.Visibility.SEMIVISIBLE , depending whether the
axis aligned box (defined by corners p1 and p2 ) is visible,
invisible, or semi-visible, respectively. |
float[][] |
computeBoundaryEquations()
Convenience function that in 2D simply returns
computeFrustumPlanesCoefficients(new float [4][3]) and in 3D
computeFrustumPlanesCoefficients(new float [6][4]) . |
float[][] |
computeBoundaryEquations(float[][] coef)
Fills
coef with the 6 plane equations of the camera frustum and returns it. |
void |
computeProjection()
Computes the projection matrix associated with the Eye.
|
void |
computeView()
Computes the View matrix associated with the Eye's
Eye.position() and
Eye.orientation() . |
void |
convertClickToLine(Point pixelInput,
Vec orig,
Vec dir)
Gives the coefficients of a 3D half-line passing through the Camera eye and pixel
(x,y).
|
float |
distanceToAnchor()
Returns the Eye
Eye.position() to Eye.anchor() distance in Scene units. |
float |
distanceToSceneCenter()
Returns the Eye
Eye.position() to Eye.sceneCenter() distance in Scene
units. |
float |
fieldOfView()
Returns the vertical field of view of the Camera (in radians) computed as
2.0f * (float) Math.atan(frame().magnitude()) . |
void |
fitBall(Vec center,
float radius)
Moves the Eye so that the ball defined by
center and radius is
visible and fits the window. |
void |
fitBoundingBox(Vec min,
Vec max)
Moves the Eye so that the (world axis aligned) bounding box (
min ,
max ) is entirely visible, using Eye.fitBall(Vec, float) . |
void |
fitScreenRegion(Rect rectangle)
Moves the Eye so that the rectangular screen region defined by
rectangle
(pixel units, with origin in the upper left corner) fits the screen. |
float |
focusDistance()
Returns the focus distance used by stereo display, expressed in virtual world units.
|
void |
fromView(Mat mv,
boolean recompute)
Sets the Eye
Eye.position() and Eye.orientation() from an OpenGL-like View
matrix. |
Camera |
get()
Returns a deep copy of the object.
|
float |
horizontalFieldOfView()
Returns the horizontal field of view of the Camera (in radians).
|
void |
interpolateToZoomOnPixel(Point pixel)
Makes the Eye smoothly zoom on the
pointUnderPixel(Point) pixel and
returns the world coordinates of the
pointUnderPixel(Point) . |
float |
IODistance()
Returns the user's inter-ocular distance (in meters).
|
boolean |
isConeBackFacing(Vec vertex,
ArrayList<Vec> normals)
Returns
true if the given cone is back-facing the camera and false
otherwise. |
boolean |
isConeBackFacing(Vec vertex,
Vec[] normals)
Returns
true if the given cone is back-facing the camera and false
otherwise. |
boolean |
isConeBackFacing(Vec vertex,
Vec axis,
float angle)
Returns
true if the given cone is back-facing the camera and false
otherwise. |
boolean |
isConeFrontFacing(Vec vertex,
ArrayList<Vec> normals)
Same as
return !isConeBackFacing(vertex, normals) . |
boolean |
isConeFrontFacing(Vec vertex,
Vec[] normals)
Same as
!isConeBackFacing(vertex, normals) . |
boolean |
isConeFrontFacing(Vec vertex,
Vec axis,
float angle)
Same as
return !isConeBackFacing(vertex, axis, angle) . |
boolean |
isFaceBackFacing(Vec vertex,
Vec normal)
Returns
true if the given face is back-facing the camera. |
boolean |
isFaceBackFacing(Vec a,
Vec b,
Vec c)
Returns
true if the given face is back-facing the camera. |
boolean |
isFaceFrontFacing(Vec vertex,
Vec normal)
Same as
return !isFaceBackFacing(vertex, normal) . |
boolean |
isFaceFrontFacing(Vec a,
Vec b,
Vec c)
Same as
return !isFaceBackFacing(a, b, c) . |
boolean |
isPointVisible(float x,
float y,
float z)
Same as
return isPointVisible(new Vec(x, y, z)) . |
boolean |
isPointVisible(Vec point)
Returns
true if point is visible (i.e, lies within the Eye boundary)
and false otherwise. |
void |
lookAt(float x,
float y,
float z)
Same as
lookAt(new Vec(x,y,z)) . |
void |
lookAt(Vec target)
2D Windows simply call
frame().setPosition(target.x(), target.y()) . |
float |
physicalDistanceToScreen()
Returns the physical distance between the user's eyes and the screen (in meters).
|
float |
physicalScreenWidth()
Returns the physical screen width, in meters.
|
Vec |
pointUnderPixel(Point pixel)
Returns the coordinates of the 3D point located at
pixel (x,y) on screen. |
float |
rescalingOrthoFactor()
Returns a value proportional to the Camera (z projected) distance to the
Eye.anchor() so that when zooming on the object, the ortho Camera is translated
forward and its boundary is narrowed, making the object appear bigger on screen, as
intuitively expected. |
float |
sceneToPixelRatio(Vec position)
Returns the ratio of scene (units) to pixel at
position . |
void |
setAnchor(float x,
float y,
float z)
Same as
setAnchor(new Vec(x,y,z)) . |
void |
setAnchor(Vec rap)
Sets the
Eye.anchor() , defined in the world coordinate system. |
boolean |
setAnchorFromPixel(Point pixel)
The
Eye.anchor() is set to the point located under pixel on screen. |
void |
setFieldOfView(float fov)
Sets the vertical
fieldOfView() of the Camera (in radians). |
void |
setFocusDistance(float distance)
Sets the focusDistance(), in virtual scene units.
|
void |
setFOVToFitScene()
Changes the Camera
fieldOfView() so that the entire scene (defined by
AbstractScene.center() and
AbstractScene.radius() is visible from the Camera
Eye.position() . |
void |
setHorizontalFieldOfView(float hfov)
Sets the
horizontalFieldOfView() of the Camera (in radians). |
void |
setIODistance(float distance)
Sets the
IODistance() . |
void |
setOrientation(float theta,
float phi)
Sets the
Eye.orientation() of the Camera using polar coordinates. |
void |
setOrientation(Rotation q)
Sets the Eye
Eye.orientation() , defined in the world coordinate system. |
void |
setPhysicalDistanceToScreen(float distance)
Sets the
physicalDistanceToScreen() . |
void |
setPhysicalScreenWidth(float width)
Sets the physical screen (monitor or projected wall) width (in meters).
|
void |
setPosition(float x,
float y,
float z)
Same as
setPosition(new Vec(x,y,z)) . |
void |
setSceneBoundingBox(Vec min,
Vec max)
Similar to
Eye.setSceneRadius(float) and Eye.setSceneCenter(Vec) , but the
scene limits are defined by a (world axis aligned) bounding box. |
boolean |
setSceneCenterFromPixel(Point pixel)
The
Eye.sceneCenter() is set to the point located under pixel on screen. |
void |
setSceneRadius(float radius)
Sets the
Eye.sceneRadius() value in scene (world) units. |
void |
setType(Camera.Type type)
Defines the Camera
type() . |
void |
setUpVector(float x,
float y,
float z)
Same as
setUpVector(new Vec(x,y,z)) . |
void |
setUpVector(float x,
float y,
float z,
boolean noMove)
Same as
setUpVector(new Vec(x,y,z), boolean noMove) . |
void |
setUpVector(Vec up,
boolean noMove)
Rotates the Eye so that its
Eye.upVector() becomes up (defined in the
world coordinate system). |
void |
setViewDirection(float x,
float y,
float z)
Same as
setViewDirection(new Vec(x, y, z)) . |
void |
setViewDirection(Vec direction)
Rotates the Camera so that its
viewDirection() is direction (defined
in the world coordinate system). |
void |
setZClippingCoefficient(float coef)
Sets the
zClippingCoefficient() value. |
void |
setZNearCoefficient(float coef)
Sets the
zNearCoefficient() value. |
Camera.Type |
type()
Returns the Camera.Type.
|
Vec |
viewDirection()
Returns the normalized view direction of the Eye, defined in the world coordinate
system.
|
float |
zClippingCoefficient()
Returns the coefficient used to position the near and far clipping planes.
|
float |
zFar()
Returns the far clipping plane distance used by the Camera projection matrix in scene
(world) units.
|
float |
zNear()
Returns the near clipping plane distance used by the Camera projection matrix in
scene (world) units.
|
float |
zNearCoefficient()
Returns the coefficient which is used to set
zNear() when the Camera is
inside the sphere defined by Eye.sceneCenter() and
zClippingCoefficient() * Eye.sceneRadius() . |
addKeyFrameToPath, anchor, anyInterpolationStarted, areBoundaryEquationsEnabled, aspectRatio, centerScene, deletePath, distanceToBoundary, enableBoundaryEquations, eyeCoordinatesOf, flip, flySpeed, frame, fromView, getBoundaryEquations, getBoundaryWidthHeight, getBoundaryWidthHeight, getOrthoWidthHeight, getOrthoWidthHeight, getProjection, getProjection, getProjection, getProjection, getView, getView, getView, getView, getViewport, getViewport, interpolateTo, interpolateTo, interpolateToFitScene, interpolateToZoomOnPixel, interpolateToZoomOnRegion, keyFrameInterpolator, keyFrameInterpolatorArray, keyFrameInterpolatorList, keyFrameInterpolatorMap, lastNonFrameUpdate, lastUpdate, orientation, pixelToSceneRatio, playPath, position, project, project, projectedCoordinatesOf, projectedCoordinatesOf, projectedCoordinatesOf, projectedCoordinatesOf, resetPath, rightVector, rotationSensitivity, scalingSensitivity, scene, sceneCenter, sceneRadius, screenHeight, screenWidth, setAnchorFromPixel, setAspectRatio, setFlySpeed, setFrame, setKeyFrameInterpolator, setPosition, setProjection, setProjection, setProjection, setRotationSensitivity, setScalingSensitivity, setSceneCenter, setSceneCenterFromPixel, setScreenWidthAndHeight, setSpinningSensitivity, setTranslationSensitivity, setUpVector, showEntireScene, spinningSensitivity, stopInterpolations, translationSensitivity, unproject, unproject, unprojectedCoordinatesOf, unprojectedCoordinatesOf, unprojectedCoordinatesOf, unprojectedCoordinatesOf, updateBoundaryEquations, upVector, worldCoordinatesOf
public Camera(AbstractScene scn)
Eye.sceneCenter()
is set to (0,0,0) and Eye.sceneRadius()
is set to 100.
type()
Camera.PERSPECTIVE, with a PI/3
fieldOfView()
(same
value used in P5 by default).
Camera matrices (projection and view) are created and computed according to remaining default Camera parameters.
See IODistance()
, physicalDistanceToScreen()
,
physicalScreenWidth()
and focusDistance()
documentations for
default stereo parameter values.
public Camera get()
Copyable
Typical implementation should simple look like: return new Object(this)
.
public void setUpVector(Vec up, boolean noMove)
Eye
Eye.upVector()
becomes up
(defined in the
world coordinate system).
The Eye is rotated around an axis orthogonal to up
and to the current
Eye.upVector()
direction.
Use this method in order to define the Eye horizontal plane.
When noMove
is set to false
, the orientation modification is
compensated by a translation, so that the Eye.anchor()
stays projected at the
same position on screen. This is especially useful when the Eye is an observer of the
scene (default action binding).
When noMove
is true, the Eye Eye.position()
is left unchanged, which is
an intuitive behavior when the Eye is in first person mode.
setUpVector
in class Eye
Eye.lookAt(Vec)
,
Eye.setOrientation(Rotation)
public void setUpVector(float x, float y, float z)
setUpVector(new Vec(x,y,z))
.Eye.setUpVector(Vec)
public void setUpVector(float x, float y, float z, boolean noMove)
setUpVector(new Vec(x,y,z), boolean noMove)
.setUpVector(Vec, boolean)
public void setPosition(float x, float y, float z)
setPosition(new Vec(x,y,z))
.Eye.setPosition(Vec)
public Vec viewDirection()
Eye
Eye.frame()
(
frame().inverseTransformOf(new Vec(0.0f, 0.0f, -1.0f))
) whih in 2D always is
(0,0,-1)
In 3D change this value using
setViewDirection(Vec)
, Eye.lookAt(Vec)
or
Eye.setOrientation(Rotation)
. It is orthogonal to Eye.upVector()
and to
Eye.rightVector()
.
viewDirection
in class Eye
public void setViewDirection(Vec direction)
viewDirection()
is direction
(defined
in the world coordinate system).
The Camera Eye.position()
is not modified. The Camera is rotated so that the
horizon (defined by its Eye.upVector()
) is preserved.
lookAt(Vec)
,
Eye.setUpVector(Vec)
public void setViewDirection(float x, float y, float z)
setViewDirection(new Vec(x, y, z))
.setViewDirection(Vec)
public void setOrientation(float theta, float phi)
Eye.orientation()
of the Camera using polar coordinates.
theta
rotates the Camera around its Y axis, and then phi
rotates it
around its X axis.
The polar coordinates are defined in the world coordinates system:
theta = phi = 0
means that the Camera is directed towards the world Z axis.
Both angles are expressed in radians.
The Eye.position()
of the Camera is unchanged, you may want to call
Eye.showEntireScene()
after this method to move the Camera.
Eye.setUpVector(Vec)
public void setOrientation(Rotation q)
Eye
Eye.orientation()
, defined in the world coordinate system.setOrientation
in class Eye
public final Camera.Type type()
Set by setType(Type)
.
A Camera.Type.PERSPECTIVE
Camera uses a classical
projection mainly defined by its fieldOfView()
.
With a Camera.Type.ORTHOGRAPHIC
type()
, the
fieldOfView()
is meaningless and the width and height of the Camera frustum
are inferred from the distance to the Eye.anchor()
using
Eye.getBoundaryWidthHeight()
.
Both types use zNear()
and zFar()
(to define their clipping planes)
and Eye.aspectRatio()
(for frustum shape).
public final void setType(Camera.Type type)
type()
.
Changing the Camera Type alters the viewport and the objects' size can be changed.
This method guarantees that the two frustum match in a plane normal to
viewDirection()
, passing through the arcball reference point.
public float fieldOfView()
2.0f * (float) Math.atan(frame().magnitude())
.
Value is set using setFieldOfView(float)
. Default value is pi/3 radians.
This value is meaningless if the Camera type()
is
Camera.Type.ORTHOGRAPHIC
.
The field of view corresponds the one used in gluPerspective
(see manual). It
sets the Y (vertical) aperture of the Camera. The X (horizontal) angle is inferred
from the window aspect ratio (see Eye.aspectRatio()
and
horizontalFieldOfView()
).
Use setFOVToFitScene()
to adapt the fieldOfView()
to a given scene.
setFieldOfView(float)
public void setFieldOfView(float fov)
fieldOfView()
of the Camera (in radians). The
fieldOfView()
is encapsulated as the camera
Frame.magnitude()
using the following expression:
frame().setMagnitude((float) Math.tan(fov / 2.0f))
.
Note that focusDistance()
is set to Eye.sceneRadius()
/ tan(
fieldOfView()
/2) by this method.
fieldOfView()
public void setFOVToFitScene()
fieldOfView()
so that the entire scene (defined by
AbstractScene.center()
and
AbstractScene.radius()
is visible from the Camera
Eye.position()
.
The Eye.position()
and Eye.orientation()
of the Camera are not modified and
you first have to orientate the Camera in order to actually see the scene (see
lookAt(Vec)
, Eye.showEntireScene()
or fitBall(Vec, float)
).
This method is especially useful for shadow maps computation. Use the Camera
positioning tools ( Eye.setPosition(Vec)
, lookAt(Vec)
) to position a
Camera at the light position. Then use this method to define the
fieldOfView()
so that the shadow map resolution is optimally used:
// The light camera needs size hints in order to optimize its
fieldOfView
lightCamera.setSceneRadius(sceneRadius());
lightCamera.setSceneCenter(sceneCenter());
// Place the light camera
lightCamera.setPosition(lightFrame.position());
lightCamera.lookAt(sceneCenter());
lightCamera.setFOVToFitScene();
Attention: The fieldOfView()
is clamped to M_PI/2.0. This happens
when the Camera is at a distance lower than sqrt(2.0) * sceneRadius() from the
sceneCenter(). It optimizes the shadow map resolution, although it may miss some
parts of the scene.
public float horizontalFieldOfView()
Value is set using setHorizontalFieldOfView(float)
or
setFieldOfView(float)
. These values are always linked by:
horizontalFieldOfView() = 2.0 * atan ( tan(fieldOfView()/2.0) * aspectRatio() )
.
public void setHorizontalFieldOfView(float hfov)
horizontalFieldOfView()
of the Camera (in radians).
horizontalFieldOfView()
and fieldOfView()
are linked by the
Eye.aspectRatio()
. This method actually calls
setFieldOfView(( 2.0 * atan (tan(hfov / 2.0) / aspectRatio()) ))
so that a
call to horizontalFieldOfView()
returns the expected value.
public float zNear()
The clipping planes' positions depend on the Eye.sceneRadius()
and
Eye.sceneCenter()
rather than being fixed small-enough and large-enough values.
A good scene dimension approximation will hence result in an optimal precision of the
z-buffer.
The near clipping plane is positioned at a distance equal to
zClippingCoefficient()
* Eye.sceneRadius()
in front of the
Eye.sceneCenter()
: distanceToSceneCenter() -
zClippingCoefficient() * sceneRadius()
In order to prevent negative or too small zNear()
values (which would
degrade the z precision), zNearCoefficient()
is used when the Camera is
inside the Eye.sceneRadius()
sphere:
zMin = zNearCoefficient() * zClippingCoefficient() * sceneRadius();
zNear = zMin;
// With an ORTHOGRAPHIC type, the value is simply clamped to 0.0
See also the zFar()
, zClippingCoefficient()
and
zNearCoefficient()
documentations.
If you need a completely different zNear computation, overload the zNear()
and zFar()
methods in a new class that publicly inherits from Camera and use
AbstractScene.setEye(Eye)
.
Attention: The value is always positive although the clipping plane is
positioned at a negative z value in the Camera coordinate system. This follows the
gluPerspective
standard.
zFar()
public float zFar()
The far clipping plane is positioned at a distance equal to
zClippingCoefficient() * sceneRadius()
behind the Eye.sceneCenter()
:
zFar = distanceToSceneCenter() + zClippingCoefficient()*sceneRadius()
zNear()
public float zNearCoefficient()
zNear()
when the Camera is
inside the sphere defined by Eye.sceneCenter()
and
zClippingCoefficient()
* Eye.sceneRadius()
.
In that case, the zNear()
value is set to
zNearCoefficient() * zClippingCoefficient() * sceneRadius()
. See the
zNear()
documentation for details.
Default value is 0.005, which is appropriate for most applications. In case you need a high dynamic ZBuffer precision, you can increase this value (~0.1). A lower value will prevent clipping of very close objects at the expense of a worst Z precision.
Only meaningful when Camera type is PERSPECTIVE.
public void setZNearCoefficient(float coef)
zNearCoefficient()
value.public float zClippingCoefficient()
The near (resp. far) clipping plane is positioned at a distance equal to
zClippingCoefficient() * sceneRadius()
in front of (resp. behind) the
Eye.sceneCenter()
. This guarantees an optimal use of the z-buffer range and
minimizes aliasing. See the zNear()
and zFar()
documentations.
Default value is square root of 3.0 (so that a cube of size 2*Eye.sceneRadius()
is not clipped).
However, since the Eye.sceneRadius()
is used for other purposes (see
showEntireScene(), flySpeed(), ...) and you may want to change this value to define
more precisely the location of the clipping planes. See also
zNearCoefficient()
.
public void setZClippingCoefficient(float coef)
zClippingCoefficient()
value.public float sceneToPixelRatio(Vec position)
Eye
position
.
A line of n * sceneToPixelRatio()
scene units, located at position
in
the world coordinates system, will be projected with a length of n
pixels on
screen.
Use this method to scale objects so that they have a constant pixel size on screen.
The following code will draw a 20 pixel line, starting at Eye.sceneCenter()
and
always directed along the screen vertical direction:
beginShape(LINES);
vertex(sceneCenter().x, sceneCenter().y, sceneCenter().z);
Vec v = Vec.add(sceneCenter(), Vec.mult(upVector(), 20 * sceneToPixelRatio(sceneCenter())));
vertex(v.x, v.y, v.z);
endShape();
sceneToPixelRatio
in class Eye
public boolean isPointVisible(Vec point)
Eye
true
if point
is visible (i.e, lies within the Eye boundary)
and false
otherwise.
Attention: The Eye boundary plane equations should be updated before calling
this method. You may compute them explicitly (by calling
Eye.computeBoundaryEquations()
) or enable them to be automatic updated in your
Scene setup (with
AbstractScene.enableBoundaryEquations()
).
public boolean isPointVisible(float x, float y, float z)
return isPointVisible(new Vec(x, y, z))
.isPointVisible(Vec)
public Eye.Visibility ballVisibility(Vec center, float radius)
Eye
Eye.Visibility.VISIBLE
,
Eye.Visibility.INVISIBLE
, or
Eye.Visibility.SEMIVISIBLE
, depending whether the
sphere (of radius radius
and center center
) is visible, invisible, or
semi-visible, respectively.
Attention: The Eye boundary plane equations should be updated before calling
this method. You may compute them explicitly (by calling
Eye.computeBoundaryEquations()
) or enable them to be automatic updated in your
Scene setup (with
AbstractScene.enableBoundaryEquations()
).
public Eye.Visibility boxVisibility(Vec p1, Vec p2)
Eye
Eye.Visibility.VISIBLE
,
Eye.Visibility.INVISIBLE
, or
Eye.Visibility.SEMIVISIBLE
, depending whether the
axis aligned box (defined by corners p1
and p2
) is visible,
invisible, or semi-visible, respectively.
Attention: The Eye boundary plane equations should be updated before calling
this method. You may compute them explicitly (by calling
Eye.computeBoundaryEquations()
) or enable them to be automatic updated in your
Scene setup (with
AbstractScene.enableBoundaryEquations()
).
public float[][] computeBoundaryEquations()
Eye
computeFrustumPlanesCoefficients(new float [4][3])
and in 3D
computeFrustumPlanesCoefficients(new float [6][4])
.
Attention: You should not call this method explicitly, unless you need the
frustum equations to be updated only occasionally (rare). Use
AbstractScene.enableBoundaryEquations()
which
automatically update the frustum equations every frame instead.
computeBoundaryEquations
in class Eye
Eye.computeBoundaryEquations(float[][])
public float[][] computeBoundaryEquations(float[][] coef)
Eye
coef
with the 6 plane equations of the camera frustum and returns it.
In 2D the four 4-component vectors of coef
respectively correspond to the
left, right, top and bottom Window boundary lines. Each vector holds a plane equation
of the form:
a*x + b*y + c = 0
where a
, b
and c
are the 3
components of each vector, in that order.
In 3D the six 4-component vectors of coef
respectively correspond to the
left, right, near, far, top and bottom Camera frustum planes. Each vector holds a
plane equation of the form:
a*x + b*y + c*z + d = 0
where a
, b
, c
and d
are the 4 components of each
vector, in that order.
This format is compatible with the gl.glClipPlane()
function. One camera
frustum plane can hence be applied in an other viewer to visualize the culling
results:
// Retrieve place equations
float [][] coef =
mainViewer.camera().getFrustumPlanesCoefficients();
// These two additional clipping planes (which must have been enabled)
// will reproduce the mainViewer's near and far clipping.
gl.glClipPlane(GL.GL_CLIP_PLANE0, coef[2]);
gl.glClipPlane(GL.GL_CLIP_PLANE1, coef[3]);
Attention: You should not call this method explicitly, unless you need the
frustum equations to be updated only occasionally (rare). Use
AbstractScene.enableBoundaryEquations()
which
automatically update the frustum equations every frame instead.
computeBoundaryEquations
in class Eye
Eye.computeBoundaryEquations()
public boolean isFaceFrontFacing(Vec a, Vec b, Vec c)
return !isFaceBackFacing(a, b, c)
.isFaceBackFacing(Vec, Vec, Vec)
public boolean isFaceBackFacing(Vec a, Vec b, Vec c)
true
if the given face is back-facing the camera. Otherwise returns
false
.
Vertices must given in clockwise order if
AbstractScene.isLeftHanded()
or in counter-clockwise
order if AbstractScene.isRightHanded()
.
a
- first face vertexb
- second face vertexc
- third face vertexisFaceBackFacing(Vec, Vec)
,
isConeBackFacing(Vec, Vec, float)
public boolean isFaceFrontFacing(Vec vertex, Vec normal)
return !isFaceBackFacing(vertex, normal)
.isFaceBackFacing(Vec, Vec)
public boolean isFaceBackFacing(Vec vertex, Vec normal)
true
if the given face is back-facing the camera. Otherwise returns
false
.vertex
- belonging to the facenormal
- face normalisFaceBackFacing(Vec, Vec, Vec)
,
isConeBackFacing(Vec, Vec, float)
public boolean isConeFrontFacing(Vec vertex, ArrayList<Vec> normals)
return !isConeBackFacing(vertex, normals)
.isConeBackFacing(Vec, ArrayList)
public boolean isConeBackFacing(Vec vertex, ArrayList<Vec> normals)
true
if the given cone is back-facing the camera and false
otherwise.vertex
- Cone vertexnormals
- ArrayList of normals defining the cone.isConeBackFacing(Vec, Vec[])
,
isConeBackFacing(Vec, Vec, float)
public boolean isConeFrontFacing(Vec vertex, Vec[] normals)
!isConeBackFacing(vertex, normals)
.isConeBackFacing(Vec, Vec[])
public boolean isConeBackFacing(Vec vertex, Vec[] normals)
true
if the given cone is back-facing the camera and false
otherwise.vertex
- Cone vertexnormals
- Array of normals defining the cone.isConeBackFacing(Vec, ArrayList)
,
isConeBackFacing(Vec, Vec, float)
public boolean isConeFrontFacing(Vec vertex, Vec axis, float angle)
return !isConeBackFacing(vertex, axis, angle)
.isConeBackFacing(Vec, Vec, float)
public boolean isConeBackFacing(Vec vertex, Vec axis, float angle)
true
if the given cone is back-facing the camera and false
otherwise.vertex
- Cone vertexaxis
- Cone axisangle
- Cone anglepublic void setSceneRadius(float radius)
Eye
Eye.sceneRadius()
value in scene (world) units. Negative values are
ignored. It also sets Eye.flySpeed()
to 1% of Eye.sceneRadius()
Attention: 3d Camera also sets
focusDistance()
to
sceneRadius() / tan(fieldOfView()/2)
.
setSceneRadius
in class Eye
public float distanceToSceneCenter()
Eye
Eye.position()
to Eye.sceneCenter()
distance in Scene
units.
3D Cameras return the projected Eye Eye.position()
to Eye.sceneCenter()
distance along the Camera Z axis and use it in
zNear()
and
zFar()
to optimize the Z range.
distanceToSceneCenter
in class Eye
public float distanceToAnchor()
Eye
Eye.position()
to Eye.anchor()
distance in Scene units.
3D Cameras return the projected Eye Eye.position()
to Eye.anchor()
distance
along the Camera Z axis and use it in Eye.getBoundaryWidthHeight(float[])
so
that when the Camera is translated forward then its frustum is narrowed, making the
object appear bigger on screen, as intuitively expected.
distanceToAnchor
in class Eye
public void setSceneBoundingBox(Vec min, Vec max)
Eye
Eye.setSceneRadius(float)
and Eye.setSceneCenter(Vec)
, but the
scene limits are defined by a (world axis aligned) bounding box.setSceneBoundingBox
in class Eye
public boolean setAnchorFromPixel(Point pixel)
Eye
Eye.anchor()
is set to the point located under pixel
on screen.
2D windows always returns true.
3D Cameras returns true
if a point was found under pixel
and
false
if none was found (in this case no Eye.anchor()
is set).
setAnchorFromPixel
in class Eye
public boolean setSceneCenterFromPixel(Point pixel)
Eye
Eye.sceneCenter()
is set to the point located under pixel
on screen.
2D windows always returns true.
3D Cameras returns true
if a point was found under pixel
and
false
if none was found (in this case no Eye.sceneCenter()
is set).
setSceneCenterFromPixel
in class Eye
public Vec pointUnderPixel(Point pixel)
pixel
(x,y) on screen. May
be null if no point is found under pixel.
Override this method in your jogl-based camera class.
Current implementation always returns WorlPoint.found = false
(dummy value),
meaning that no point was found under pixel.
public void computeView()
Eye
Eye.position()
and
Eye.orientation()
.
This matrix converts from the world coordinates system to the Eye coordinates system,
so that coordinates can then be projected on screen using the projection matrix (see
Eye.computeProjection()
).
Use Eye.getView()
to retrieve this matrix.
Note: You must call this method if your Eye is not associated with a Scene and
is used for offscreen computations (using projectedCoordinatesOf()
for
instance).
computeView
in class Eye
public float rescalingOrthoFactor()
Eye.anchor()
so that when zooming on the object, the ortho Camera is translated
forward and its boundary is narrowed, making the object appear bigger on screen, as
intuitively expected.
Value is computed as: 2 * distanceToAnchor() / screenHeight()
.
rescalingOrthoFactor
in class Eye
Eye.getBoundaryWidthHeight(float[])
public void setAnchor(Vec rap)
Eye
Eye.anchor()
, defined in the world coordinate system.public void setAnchor(float x, float y, float z)
setAnchor(new Vec(x,y,z))
.AbstractScene.setAnchor(Vec)
public void computeProjection()
Eye
If Eye is a 3D PERSPECTIVE Camera, defines a projection matrix using the
fieldOfView()
, Eye.aspectRatio()
,
zNear()
and
zFar()
parameters. If Eye is a 3D ORTHOGRAPHIC
Camera, the frustum's width and height are set using
Eye.getBoundaryWidthHeight()
. Both types use
zNear()
and
zFar()
to place clipping planes. These values
are determined from sceneRadius() and sceneCenter() so that they best fit the scene
size.
Use Eye.getProjection()
to retrieve this matrix.
Note: You must call this method if your Eye is not associated with a Scene and
is used for offscreen computations (using projectedCoordinatesOf()
for
instance).
computeProjection
in class Eye
Eye.setProjection(Mat)
public void fromView(Mat mv, boolean recompute)
Eye
Eye.position()
and Eye.orientation()
from an OpenGL-like View
matrix.
After this method has been called, Eye.getView()
returns a matrix equivalent to
mv
. Only the Eye.position()
and Eye.orientation()
of the Eye are
modified.
public void convertClickToLine(Point pixelInput, Vec orig, Vec dir)
Eye.screenHeight()
- y to locate the
origin at the lower left corner.
The origin of the half line (eye position) is stored in orig
, while
dir
contains the properly oriented and normalized direction of the half line.
This method is useful for analytical intersection in a selection method.
public void lookAt(Vec target)
Eye
frame().setPosition(target.x(), target.y())
. 3D
Cameras set Eye.orientation()
, so that it looks at point target
defined
in the world coordinate system (The Camera Eye.position()
is not modified.
Simply setViewDirection(Vec)
).lookAt
in class Eye
Eye.at()
,
Eye.setUpVector(Vec)
,
Eye.setOrientation(Rotation)
,
Eye.showEntireScene()
,
Eye.fitBall(Vec, float)
,
Eye.fitBoundingBox(Vec, Vec)
public void lookAt(float x, float y, float z)
lookAt(new Vec(x,y,z))
.lookAt(Vec)
public Vec at()
Eye
Eye.viewDirection()
). Useful for setting the Processing camera() which uses a
similar approach of that found in gluLookAt.at
in class Eye
Eye.lookAt(Vec)
public void fitBall(Vec center, float radius)
Eye
center
and radius
is
visible and fits the window.
In 3D the Camera is simply translated along its Eye.viewDirection()
so that the
sphere fits the screen. Its Eye.orientation()
and its
fieldOfView()
are unchanged. You should
therefore orientate the Camera before you call this method.
fitBall
in class Eye
Eye.lookAt(Vec)
,
Eye.setOrientation(Rotation)
,
Eye.setUpVector(Vec, boolean)
public void fitBoundingBox(Vec min, Vec max)
Eye
min
,
max
) is entirely visible, using Eye.fitBall(Vec, float)
.fitBoundingBox
in class Eye
public void fitScreenRegion(Rect rectangle)
Eye
rectangle
(pixel units, with origin in the upper left corner) fits the screen.
in 3D the Camera is translated (its Eye.orientation()
is unchanged) so that
rectangle
is entirely visible. Since the pixel coordinates only define a
frustum in 3D, it's the intersection of this frustum with a plane (orthogonal
to the Eye.viewDirection()
and passing through the Eye.sceneCenter()
) that
is used to define the 3D rectangle that is eventually fitted.
fitScreenRegion
in class Eye
public void interpolateToZoomOnPixel(Point pixel)
Eye
pointUnderPixel(Point)
pixel
and
returns the world coordinates of the
pointUnderPixel(Point)
.
In 3D nothing happens if no
pointUnderPixel(Point)
is found. Otherwise a
KeyFrameInterpolator is created that animates the Camera on a one second path that
brings the Camera closer to the point under pixel
.
interpolateToZoomOnPixel
in class Eye
Eye.interpolateToFitScene()
public float IODistance()
setIODistance(float)
public void setIODistance(float distance)
IODistance()
.public float physicalDistanceToScreen()
Default value is 0.5m.
Value is set using setPhysicalDistanceToScreen(float)
.
physicalDistanceToScreen() and focusDistance()
represent the same distance.
The first one is expressed in physical real world units, while the latter is
expressed in virtual world units. Use their ratio to convert distances between these
worlds.
public void setPhysicalDistanceToScreen(float distance)
physicalDistanceToScreen()
.public float physicalScreenWidth()
Used for stereo display only. Set using setPhysicalScreenWidth(float)
.
See physicalDistanceToScreen()
for reality center automatic configuration.
public void setPhysicalScreenWidth(float width)
public float focusDistance()
This is the distance in the virtual world between the Camera and the plane where the horizontal stereo parallax is null (the stereo left and right images are superimposed).
This distance is the virtual world equivalent of the real-world
physicalDistanceToScreen()
.
attention: This value is modified by Scene.setSceneRadius(), setSceneRadius()
and setFieldOfView(float)
. When one of these values is modified,
focusDistance()
is set to Eye.sceneRadius()
/ tan(
fieldOfView()
/2), which provides good results.
public void setFocusDistance(float distance)
Processing Library proscene by Jean Pierre Charalambos. (c) 2014-2017 National University of Colombia