mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
stereo rendering
This commit is contained in:
parent
5daca17ee6
commit
ffb92db022
@ -746,7 +746,8 @@ class ShowBase(DirectObject.DirectObject):
|
||||
return aspectRatio
|
||||
|
||||
def makeCamera(self, win, sort = 0, scene = None,
|
||||
displayRegion = (0, 1, 0, 1), aspectRatio = None,
|
||||
displayRegion = (0, 1, 0, 1), stereoChannel = None,
|
||||
aspectRatio = None,
|
||||
lens = None, camName = 'cam'):
|
||||
"""
|
||||
Makes a new 3-d camera associated with the indicated window,
|
||||
@ -755,6 +756,9 @@ class ShowBase(DirectObject.DirectObject):
|
||||
dr = win.makeDisplayRegion(*displayRegion)
|
||||
dr.setSort(sort)
|
||||
|
||||
if stereoChannel != None:
|
||||
dr.setStereoChannel(stereoChannel)
|
||||
|
||||
if scene == None:
|
||||
scene = self.render
|
||||
|
||||
|
@ -52,6 +52,20 @@ get_sort() const {
|
||||
return cdata->_sort;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::get_stereo_channel
|
||||
// Access: Published
|
||||
// Description: Returns whether the DisplayRegion is specified as the
|
||||
// left or right channel of a stereo pair, or whether it
|
||||
// is a normal, monocular image. See
|
||||
// set_stereo_channel().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Lens::StereoChannel DisplayRegion::
|
||||
get_stereo_channel() {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_stereo_channel;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::set_cube_map_index
|
||||
// Access: Published
|
||||
|
@ -75,7 +75,7 @@ operator = (const DisplayRegion&) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::Destructor
|
||||
// Access: Public
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DisplayRegion::
|
||||
@ -305,8 +305,7 @@ set_active(bool active) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DisplayRegion::
|
||||
set_sort(int sort) {
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
nassertv(pipeline_stage == 0);
|
||||
nassertv(Thread::get_current_pipeline_stage() == 0);
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
if (sort != cdata->_sort) {
|
||||
@ -316,6 +315,53 @@ set_sort(int sort) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::set_stereo_channel
|
||||
// Access: Published
|
||||
// Description: Specifies whether the DisplayRegion represents the
|
||||
// left or right channel of a stereo pair, or whether it
|
||||
// is a normal, monocular image. See
|
||||
// set_stereo_channel().
|
||||
//
|
||||
// This controls which direction--to the left or the
|
||||
// right--the view from a PerspectiveLens is shifted
|
||||
// when it is used to render into this DisplayRegion.
|
||||
// Also see Lens::set_interocular_distance() and
|
||||
// Lens::set_convergence_distance().
|
||||
//
|
||||
// Normally you would create at least two DisplayRegions
|
||||
// for a stereo window, one for each of the left and
|
||||
// right channels. The two DisplayRegions may share the
|
||||
// same camera (and thus the same lens); this parameter
|
||||
// is used to control the exact properties of the lens
|
||||
// when it is used to render into this DisplayRegion.
|
||||
//
|
||||
// When the DisplayRegion is attached to a stereo window
|
||||
// (one in which FrameBufferProperties::FM_stereo is
|
||||
// set), this also specifies which physical channel the
|
||||
// DisplayRegion renders to.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DisplayRegion::
|
||||
set_stereo_channel(Lens::StereoChannel stereo_channel) {
|
||||
nassertv(Thread::get_current_pipeline_stage() == 0);
|
||||
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_stereo_channel = stereo_channel;
|
||||
switch (stereo_channel) {
|
||||
case Lens::SC_left:
|
||||
cdata->_draw_buffer_mask = ~(RenderBuffer::T_front_right | RenderBuffer::T_back_right);
|
||||
break;
|
||||
|
||||
case Lens::SC_right:
|
||||
cdata->_draw_buffer_mask = ~(RenderBuffer::T_front_left | RenderBuffer::T_back_left);
|
||||
break;
|
||||
|
||||
case Lens::SC_both:
|
||||
cdata->_draw_buffer_mask = ~0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::compute_pixels
|
||||
// Access: Published
|
||||
@ -624,6 +670,33 @@ get_screenshot(PNMImage &image) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::get_screenshot_buffer_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the RenderBuffer that should be used for
|
||||
// capturing screenshots from this particular
|
||||
// DrawableRegion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DisplayRegion::
|
||||
get_screenshot_buffer_type() const {
|
||||
CDReader cdata(_cycler);
|
||||
return _screenshot_buffer_type & cdata->_draw_buffer_mask;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::get_draw_buffer_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the RenderBuffer into which the GSG should
|
||||
// issue draw commands. Normally, this is the back
|
||||
// buffer for double-buffered windows, and the front
|
||||
// buffer for single-buffered windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DisplayRegion::
|
||||
get_draw_buffer_type() const {
|
||||
CDReader cdata(_cycler);
|
||||
return _draw_buffer_type & cdata->_draw_buffer_mask;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::win_display_regions_changed
|
||||
// Access: Private
|
||||
@ -686,6 +759,8 @@ CData() :
|
||||
_camera_node((Camera *)NULL),
|
||||
_active(true),
|
||||
_sort(0),
|
||||
_stereo_channel(Lens::SC_both),
|
||||
_draw_buffer_mask(~0),
|
||||
_cube_map_index(-1)
|
||||
{
|
||||
}
|
||||
@ -711,6 +786,8 @@ CData(const DisplayRegion::CData ©) :
|
||||
_camera_node(copy._camera_node),
|
||||
_active(copy._active),
|
||||
_sort(copy._sort),
|
||||
_stereo_channel(copy._stereo_channel),
|
||||
_draw_buffer_mask(copy._draw_buffer_mask),
|
||||
_cube_map_index(copy._cube_map_index)
|
||||
{
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "cycleDataStageWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "config_display.h"
|
||||
#include "lens.h"
|
||||
|
||||
#include "plist.h"
|
||||
|
||||
@ -63,7 +64,7 @@ private:
|
||||
void operator = (const DisplayRegion ©);
|
||||
|
||||
public:
|
||||
~DisplayRegion();
|
||||
virtual ~DisplayRegion();
|
||||
void cleanup();
|
||||
|
||||
INLINE bool operator < (const DisplayRegion &other) const;
|
||||
@ -88,6 +89,9 @@ PUBLISHED:
|
||||
void set_sort(int sort);
|
||||
INLINE int get_sort() const;
|
||||
|
||||
void set_stereo_channel(Lens::StereoChannel stereo_channel);
|
||||
INLINE Lens::StereoChannel get_stereo_channel();
|
||||
|
||||
INLINE void set_cube_map_index(int cube_map_index);
|
||||
INLINE int get_cube_map_index() const;
|
||||
|
||||
@ -114,6 +118,9 @@ public:
|
||||
INLINE CullResult *get_cull_result() const;
|
||||
INLINE SceneSetup *get_scene_setup() const;
|
||||
|
||||
virtual int get_screenshot_buffer_type() const;
|
||||
virtual int get_draw_buffer_type() const;
|
||||
|
||||
private:
|
||||
class CData;
|
||||
|
||||
@ -155,6 +162,8 @@ private:
|
||||
|
||||
bool _active;
|
||||
int _sort;
|
||||
Lens::StereoChannel _stereo_channel;
|
||||
int _draw_buffer_mask;
|
||||
int _cube_map_index;
|
||||
};
|
||||
|
||||
|
@ -202,28 +202,3 @@ INLINE bool DrawableRegion::
|
||||
is_any_clear_active() const {
|
||||
return (_flags & F_clear_all) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DrawableRegion::get_draw_buffer_type
|
||||
// Access: Public
|
||||
// Description: Returns the RenderBuffer into which the GSG should
|
||||
// issue draw commands. Normally, this is the back
|
||||
// buffer for double-buffered windows, and the front
|
||||
// buffer for single-buffered windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DrawableRegion::
|
||||
get_draw_buffer_type() const {
|
||||
return _draw_buffer_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DrawableRegion::get_screenshot_buffer_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the RenderBuffer that should be used for
|
||||
// capturing screenshots from this particular
|
||||
// DrawableRegion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DrawableRegion::
|
||||
get_screenshot_buffer_type() const {
|
||||
return _screenshot_buffer_type;
|
||||
}
|
||||
|
@ -17,3 +17,38 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "drawableRegion.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DrawableRegion::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DrawableRegion::
|
||||
~DrawableRegion() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DrawableRegion::get_screenshot_buffer_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the RenderBuffer that should be used for
|
||||
// capturing screenshots from this particular
|
||||
// DrawableRegion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DrawableRegion::
|
||||
get_screenshot_buffer_type() const {
|
||||
return _screenshot_buffer_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DrawableRegion::get_draw_buffer_type
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the RenderBuffer into which the GSG should
|
||||
// issue draw commands. Normally, this is the back
|
||||
// buffer for double-buffered windows, and the front
|
||||
// buffer for single-buffered windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DrawableRegion::
|
||||
get_draw_buffer_type() const {
|
||||
return _draw_buffer_type;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
INLINE DrawableRegion();
|
||||
INLINE DrawableRegion(const DrawableRegion ©);
|
||||
INLINE void operator = (const DrawableRegion ©);
|
||||
virtual ~DrawableRegion();
|
||||
|
||||
INLINE void copy_clear_settings(const DrawableRegion ©);
|
||||
|
||||
@ -57,8 +58,8 @@ PUBLISHED:
|
||||
INLINE bool is_any_clear_active() const;
|
||||
|
||||
public:
|
||||
INLINE int get_screenshot_buffer_type() const;
|
||||
INLINE int get_draw_buffer_type() const;
|
||||
virtual int get_screenshot_buffer_type() const;
|
||||
virtual int get_draw_buffer_type() const;
|
||||
|
||||
protected:
|
||||
int _screenshot_buffer_type;
|
||||
|
@ -574,7 +574,7 @@ set_scene(SceneSetup *scene_setup) {
|
||||
if (_current_lens == (Lens *)NULL) {
|
||||
return false;
|
||||
}
|
||||
return prepare_lens();
|
||||
return prepare_lens(scene_setup->get_display_region()->get_stereo_channel());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -625,7 +625,7 @@ clear(DrawableRegion *clearable) {
|
||||
// false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
prepare_lens() {
|
||||
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "displayRegionStack.h"
|
||||
#include "lensStack.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
|
||||
#include "lens.h"
|
||||
#include "graphicsStateGuardianBase.h"
|
||||
#include "graphicsThreadingModel.h"
|
||||
#include "graphicsPipe.h"
|
||||
@ -161,7 +161,7 @@ public:
|
||||
INLINE void clear(DisplayRegion *dr);
|
||||
|
||||
virtual void prepare_display_region()=0;
|
||||
virtual bool prepare_lens();
|
||||
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||
|
||||
INLINE int force_normals();
|
||||
INLINE int undo_force_normals();
|
||||
|
@ -609,7 +609,7 @@ prepare_display_region() {
|
||||
// false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian8::
|
||||
prepare_lens() {
|
||||
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||
if (_current_lens == (Lens *)NULL) {
|
||||
return false;
|
||||
}
|
||||
@ -619,7 +619,7 @@ prepare_lens() {
|
||||
}
|
||||
|
||||
// Start with the projection matrix from the lens.
|
||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
|
||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel);
|
||||
|
||||
// The projection matrix must always be left-handed Y-up internally,
|
||||
// to match DirectX's convention, even if our coordinate system of
|
||||
@ -1301,7 +1301,8 @@ end_draw_primitives() {
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
// Restore the projection matrix that we wiped out above.
|
||||
prepare_lens();
|
||||
_d3d_device->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)_projection_mat.get_data());
|
||||
}
|
||||
|
||||
GraphicsStateGuardian::end_draw_primitives();
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
virtual void do_clear(const RenderBuffer &buffer);
|
||||
|
||||
virtual void prepare_display_region();
|
||||
virtual bool prepare_lens();
|
||||
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||
|
||||
virtual bool begin_frame();
|
||||
virtual bool begin_scene();
|
||||
|
@ -826,7 +826,7 @@ prepare_display_region() {
|
||||
// false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian9::
|
||||
prepare_lens() {
|
||||
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||
if (_current_lens == (Lens *)NULL) {
|
||||
return false;
|
||||
}
|
||||
@ -836,7 +836,7 @@ prepare_lens() {
|
||||
}
|
||||
|
||||
// Start with the projection matrix from the lens.
|
||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
|
||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel);
|
||||
|
||||
// The projection matrix must always be left-handed Y-up internally,
|
||||
// to match DirectX's convention, even if our coordinate system of
|
||||
@ -1716,7 +1716,8 @@ end_draw_primitives() {
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
// Restore the projection matrix that we wiped out above.
|
||||
prepare_lens();
|
||||
_d3d_device->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)_projection_mat.get_data());
|
||||
}
|
||||
|
||||
GraphicsStateGuardian::end_draw_primitives();
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
virtual void do_clear(const RenderBuffer &buffer);
|
||||
|
||||
virtual void prepare_display_region();
|
||||
virtual bool prepare_lens();
|
||||
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||
|
||||
virtual bool begin_frame();
|
||||
virtual bool begin_scene();
|
||||
|
@ -794,6 +794,7 @@ reset() {
|
||||
GLP(Disable)(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
_stereo = ((get_properties().get_frame_buffer_mode() & FrameBufferProperties::FM_stereo) != 0);
|
||||
|
||||
// Set up all the enabled/disabled flags to GL's known initial
|
||||
// values: everything off.
|
||||
@ -984,6 +985,7 @@ prepare_display_region() {
|
||||
GLsizei width = GLsizei(w);
|
||||
GLsizei height = GLsizei(h);
|
||||
|
||||
set_draw_buffer(get_render_buffer(_actual_display_region->get_draw_buffer_type()));
|
||||
enable_scissor(true);
|
||||
GLP(Scissor)(x, y, width, height);
|
||||
GLP(Viewport)(x, y, width, height);
|
||||
@ -1006,7 +1008,7 @@ prepare_display_region() {
|
||||
// false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
prepare_lens() {
|
||||
prepare_lens(Lens::StereoChannel stereo_channel) {
|
||||
if (_current_lens == (Lens *)NULL) {
|
||||
return false;
|
||||
}
|
||||
@ -1015,7 +1017,7 @@ prepare_lens() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat();
|
||||
const LMatrix4f &lens_mat = _current_lens->get_projection_mat(stereo_channel);
|
||||
|
||||
// The projection matrix must always be right-handed Y-up, even if
|
||||
// our coordinate system of choice is otherwise, because certain GL
|
||||
@ -3732,19 +3734,35 @@ set_draw_buffer(const RenderBuffer &rb) {
|
||||
break;
|
||||
|
||||
case RenderBuffer::T_front_right:
|
||||
GLP(DrawBuffer)(GL_FRONT_RIGHT);
|
||||
if (_stereo) {
|
||||
GLP(DrawBuffer)(GL_FRONT_RIGHT);
|
||||
} else {
|
||||
GLP(DrawBuffer)(GL_FRONT);
|
||||
}
|
||||
break;
|
||||
|
||||
case RenderBuffer::T_front_left:
|
||||
GLP(DrawBuffer)(GL_FRONT_LEFT);
|
||||
if (_stereo) {
|
||||
GLP(DrawBuffer)(GL_FRONT_LEFT);
|
||||
} else {
|
||||
GLP(DrawBuffer)(GL_FRONT);
|
||||
}
|
||||
break;
|
||||
|
||||
case RenderBuffer::T_back_right:
|
||||
GLP(DrawBuffer)(GL_BACK_RIGHT);
|
||||
if (_stereo) {
|
||||
GLP(DrawBuffer)(GL_BACK_RIGHT);
|
||||
} else {
|
||||
GLP(DrawBuffer)(GL_BACK);
|
||||
}
|
||||
break;
|
||||
|
||||
case RenderBuffer::T_back_left:
|
||||
GLP(DrawBuffer)(GL_BACK_LEFT);
|
||||
if (_stereo) {
|
||||
GLP(DrawBuffer)(GL_BACK_LEFT);
|
||||
} else {
|
||||
GLP(DrawBuffer)(GL_BACK);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
virtual void do_clear(const RenderBuffer &buffer);
|
||||
|
||||
virtual void prepare_display_region();
|
||||
virtual bool prepare_lens();
|
||||
virtual bool prepare_lens(Lens::StereoChannel stereo_channel);
|
||||
|
||||
virtual bool begin_frame();
|
||||
virtual void end_frame();
|
||||
@ -282,6 +282,8 @@ protected:
|
||||
MM_alpha_mask = 0x0004,
|
||||
};
|
||||
|
||||
bool _stereo;
|
||||
|
||||
int _multisample_mode;
|
||||
bool _line_smooth_enabled;
|
||||
bool _point_smooth_enabled;
|
||||
|
@ -66,6 +66,13 @@ operator = (const Lens ©) {
|
||||
_aspect_ratio = copy._aspect_ratio;
|
||||
_near_distance = copy._near_distance;
|
||||
_far_distance = copy._far_distance;
|
||||
|
||||
_view_hpr = copy._view_hpr;
|
||||
_view_vector = copy._view_vector;
|
||||
_interocular_distance = copy._interocular_distance;
|
||||
_convergence_distance = copy._convergence_distance;
|
||||
_keystone = copy._keystone;
|
||||
|
||||
_user_flags = copy._user_flags;
|
||||
_comp_flags = 0;
|
||||
|
||||
@ -105,7 +112,8 @@ clear() {
|
||||
_view_hpr.set(0.0f, 0.0f, 0.0f);
|
||||
_view_vector.set(0.0f, 1.0f, 0.0f);
|
||||
_up_vector.set(0.0f, 0.0f, 1.0f);
|
||||
_iod_offset = 0.0f;
|
||||
_interocular_distance = 0.0f;
|
||||
_convergence_distance = 0.0f;
|
||||
_keystone.set(0.0f, 0.0f);
|
||||
|
||||
_user_flags = 0;
|
||||
@ -432,7 +440,7 @@ set_view_hpr(const LVecBase3f &view_hpr) {
|
||||
_view_hpr = view_hpr;
|
||||
adjust_user_flags(UF_view_vector | UF_view_mat,
|
||||
UF_view_hpr);
|
||||
adjust_comp_flags(CF_mat | CF_view_vector | CF_iod_offset,
|
||||
adjust_comp_flags(CF_mat | CF_view_vector,
|
||||
CF_view_hpr);
|
||||
throw_change_event();
|
||||
}
|
||||
@ -465,7 +473,7 @@ set_view_vector(const LVector3f &view_vector, const LVector3f &up_vector) {
|
||||
_up_vector = up_vector;
|
||||
adjust_user_flags(UF_view_hpr | UF_view_mat,
|
||||
UF_view_vector);
|
||||
adjust_comp_flags(CF_mat | CF_view_hpr | CF_iod_offset,
|
||||
adjust_comp_flags(CF_mat | CF_view_hpr,
|
||||
CF_view_vector);
|
||||
throw_change_event();
|
||||
}
|
||||
@ -509,39 +517,71 @@ get_nodal_point() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::set_iod_offset
|
||||
// Function: Lens::set_interocular_distance
|
||||
// Access: Published
|
||||
// Description: Sets the amount by which the lens is shifted to the
|
||||
// right, perpendicular to its view vector and up
|
||||
// vector. This is normally used to shift one or both
|
||||
// lens of a stereo camera to generate parallax. You
|
||||
// can also simply set a complete transformation matrix
|
||||
// (via set_view_mat()) that includes an arbitrary
|
||||
// translation.
|
||||
// Description: Sets the distance between the left and right eyes of
|
||||
// a stereo camera. This distance is used to apply a
|
||||
// stereo effect when the lens is rendered on a stereo
|
||||
// display region. It only has an effect on a
|
||||
// PerspectiveLens.
|
||||
//
|
||||
// Also see set_interocular_distance(), which relates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lens::
|
||||
set_iod_offset(float iod_offset) {
|
||||
_iod_offset = iod_offset;
|
||||
adjust_user_flags(UF_view_mat,
|
||||
UF_iod_offset);
|
||||
adjust_comp_flags(CF_mat | CF_view_hpr | CF_view_vector,
|
||||
CF_iod_offset);
|
||||
set_interocular_distance(float interocular_distance) {
|
||||
_interocular_distance = interocular_distance;
|
||||
if (_interocular_distance == 0.0f) {
|
||||
adjust_user_flags(UF_interocular_distance, 0);
|
||||
} else {
|
||||
adjust_user_flags(0, UF_interocular_distance);
|
||||
}
|
||||
|
||||
adjust_comp_flags(CF_mat, 0);
|
||||
throw_change_event();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_iod_offset
|
||||
// Function: Lens::get_interocular_distance
|
||||
// Access: Published
|
||||
// Description: Returns the aspect ratio of the Lens. This is
|
||||
// determined based on the indicated film size; see
|
||||
// set_film_size().
|
||||
// Description: See set_interocular_distance().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float Lens::
|
||||
get_iod_offset() const {
|
||||
if ((_comp_flags & CF_iod_offset) == 0) {
|
||||
((Lens *)this)->compute_iod_offset();
|
||||
get_interocular_distance() const {
|
||||
return _interocular_distance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::set_convergence_distance
|
||||
// Access: Published
|
||||
// Description: Sets the distance between the left and right eyes of
|
||||
// a stereo camera. This distance is used to apply a
|
||||
// stereo effect when the lens is rendered on a stereo
|
||||
// display region. It only has an effect on a
|
||||
// PerspectiveLens.
|
||||
//
|
||||
// Also see set_interocular_distance(), which relates.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lens::
|
||||
set_convergence_distance(float convergence_distance) {
|
||||
_convergence_distance = convergence_distance;
|
||||
if (_convergence_distance == 0.0f) {
|
||||
adjust_user_flags(UF_convergence_distance, 0);
|
||||
} else {
|
||||
adjust_user_flags(0, UF_convergence_distance);
|
||||
}
|
||||
return _iod_offset;
|
||||
|
||||
adjust_comp_flags(CF_mat, 0);
|
||||
throw_change_event();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_convergence_distance
|
||||
// Access: Published
|
||||
// Description: See set_convergence_distance().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float Lens::
|
||||
get_convergence_distance() const {
|
||||
return _convergence_distance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -549,7 +589,7 @@ get_iod_offset() const {
|
||||
// Access: Published
|
||||
// Description: Sets an arbitrary transformation on the lens. This
|
||||
// replaces the individual transformation components
|
||||
// like set_view_hpr() or set_iod_offset().
|
||||
// like set_view_hpr().
|
||||
//
|
||||
// Setting a transformation here will have a slightly
|
||||
// different effect than putting one on the LensNode
|
||||
@ -562,9 +602,11 @@ get_iod_offset() const {
|
||||
void Lens::
|
||||
set_view_mat(const LMatrix4f &view_mat) {
|
||||
_lens_mat = view_mat;
|
||||
adjust_user_flags(UF_view_vector | UF_view_hpr | UF_iod_offset,
|
||||
adjust_user_flags(UF_view_vector | UF_view_hpr,
|
||||
UF_view_mat);
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_lens_mat_inv | CF_view_hpr | CF_view_vector | CF_iod_offset,
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||
CF_lens_mat_inv | CF_view_hpr | CF_view_vector,
|
||||
CF_lens_mat);
|
||||
throw_change_event();
|
||||
}
|
||||
@ -590,8 +632,10 @@ get_view_mat() const {
|
||||
void Lens::
|
||||
clear_view_mat() {
|
||||
_lens_mat = LMatrix4f::ident_mat();
|
||||
adjust_user_flags(0, UF_view_vector | UF_view_hpr | UF_iod_offset | UF_view_mat);
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_lens_mat_inv | CF_view_hpr | CF_view_vector | CF_iod_offset,
|
||||
adjust_user_flags(0, UF_view_vector | UF_view_hpr | UF_view_mat);
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||
CF_lens_mat_inv | CF_view_hpr | CF_view_vector,
|
||||
CF_lens_mat);
|
||||
throw_change_event();
|
||||
}
|
||||
@ -617,7 +661,9 @@ void Lens::
|
||||
set_keystone(const LVecBase2f &keystone) {
|
||||
_keystone = keystone;
|
||||
adjust_user_flags(0, UF_keystone);
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0);
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||
CF_film_mat | CF_film_mat_inv, 0);
|
||||
throw_change_event();
|
||||
}
|
||||
|
||||
@ -630,7 +676,9 @@ void Lens::
|
||||
clear_keystone() {
|
||||
_keystone.set(0.0f, 0.0f);
|
||||
adjust_user_flags(UF_keystone, 0);
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv | CF_film_mat | CF_film_mat_inv, 0);
|
||||
adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv |
|
||||
CF_projection_mat_left_inv | CF_projection_mat_right_inv |
|
||||
CF_film_mat | CF_film_mat_inv, 0);
|
||||
throw_change_event();
|
||||
}
|
||||
|
||||
@ -642,9 +690,9 @@ clear_keystone() {
|
||||
// PerspectiveLens, but it may be called for other kinds
|
||||
// of lenses as well.
|
||||
//
|
||||
// The frustum will be rooted at the origin (or offset
|
||||
// by iod_offset, or by whatever translation might have
|
||||
// been specified in a previous call to set_view_mat).
|
||||
// The frustum will be rooted at the origin (or by
|
||||
// whatever translation might have been specified in a
|
||||
// previous call to set_view_mat).
|
||||
//
|
||||
// It is legal for the four points not to be arranged in
|
||||
// a rectangle; if this is the case, the frustum will be
|
||||
@ -699,8 +747,7 @@ set_frustum_from_corners(const LVecBase3f &ul, const LVecBase3f &ur,
|
||||
int flags) {
|
||||
// We'll need to know the pre-existing eyepoint translation from the
|
||||
// center, so we can preserve it in the new frustum. This is
|
||||
// usually just a shift along the x axis, if anything at all, for
|
||||
// the iod offset, but it could be an arbitrary vector.
|
||||
// usually (0, 0, 0), but it could be an arbitrary vector.
|
||||
const LMatrix4f &lens_mat_inv = get_lens_mat_inv();
|
||||
LVector3f eye_offset;
|
||||
lens_mat_inv.get_row3(eye_offset, 3);
|
||||
@ -1018,22 +1065,59 @@ make_bounds() const {
|
||||
// nonlinear.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_projection_mat() const {
|
||||
get_projection_mat(StereoChannel channel) const {
|
||||
if ((_comp_flags & CF_projection_mat) == 0) {
|
||||
((Lens *)this)->compute_projection_mat();
|
||||
}
|
||||
|
||||
switch (channel) {
|
||||
case SC_left:
|
||||
return _projection_mat_left;
|
||||
case SC_right:
|
||||
return _projection_mat_right;
|
||||
case SC_both:
|
||||
return _projection_mat;
|
||||
}
|
||||
|
||||
return _projection_mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_projection_mat_inv
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that transforms from a 2-d point
|
||||
// on the film to a 3-d vector in space, if such a
|
||||
// matrix exists.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_projection_mat_inv() const {
|
||||
get_projection_mat_inv(StereoChannel stereo_channel) const {
|
||||
switch (stereo_channel) {
|
||||
case SC_left:
|
||||
{
|
||||
if ((_comp_flags & CF_projection_mat_left_inv) == 0) {
|
||||
Lens *non_const = (Lens *)this;
|
||||
const LMatrix4f &projection_mat_left = get_projection_mat(SC_left);
|
||||
non_const->_projection_mat_left_inv.invert_from(projection_mat_left);
|
||||
non_const->adjust_comp_flags(0, CF_projection_mat_left_inv);
|
||||
}
|
||||
}
|
||||
return _projection_mat_left_inv;
|
||||
|
||||
case SC_right:
|
||||
{
|
||||
if ((_comp_flags & CF_projection_mat_right_inv) == 0) {
|
||||
Lens *non_const = (Lens *)this;
|
||||
const LMatrix4f &projection_mat_right = get_projection_mat(SC_right);
|
||||
non_const->_projection_mat_right_inv.invert_from(projection_mat_right);
|
||||
non_const->adjust_comp_flags(0, CF_projection_mat_right_inv);
|
||||
}
|
||||
}
|
||||
return _projection_mat_right_inv;
|
||||
|
||||
case SC_both:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((_comp_flags & CF_projection_mat_inv) == 0) {
|
||||
Lens *non_const = (Lens *)this;
|
||||
const LMatrix4f &projection_mat = get_projection_mat();
|
||||
@ -1043,6 +1127,68 @@ get_projection_mat_inv() const {
|
||||
return _projection_mat_inv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_film_mat
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that transforms from a point
|
||||
// behind the lens to a point on the film.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_film_mat() const {
|
||||
if ((_comp_flags & CF_film_mat) == 0) {
|
||||
((Lens *)this)->compute_film_mat();
|
||||
}
|
||||
return _film_mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_film_mat_inv
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that transforms from a point on
|
||||
// the film to a point behind the lens.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_film_mat_inv() const {
|
||||
if ((_comp_flags & CF_film_mat_inv) == 0) {
|
||||
Lens *non_const = (Lens *)this;
|
||||
const LMatrix4f &film_mat = get_film_mat();
|
||||
non_const->_film_mat_inv.invert_from(film_mat);
|
||||
non_const->adjust_comp_flags(0, CF_film_mat_inv);
|
||||
}
|
||||
return _film_mat_inv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_lens_mat
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that transforms from a point
|
||||
// in front of the lens to a point in space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_lens_mat() const {
|
||||
if ((_comp_flags & CF_lens_mat) == 0) {
|
||||
((Lens *)this)->compute_lens_mat();
|
||||
}
|
||||
return _lens_mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_lens_mat_inv
|
||||
// Access: Published
|
||||
// Description: Returns the matrix that transforms from a point in
|
||||
// space to a point in front of the lens.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_lens_mat_inv() const {
|
||||
if ((_comp_flags & CF_lens_mat_inv) == 0) {
|
||||
Lens *non_const = (Lens *)this;
|
||||
const LMatrix4f &lens_mat = get_lens_mat();
|
||||
non_const->_lens_mat_inv.invert_from(lens_mat);
|
||||
non_const->adjust_comp_flags(0, CF_lens_mat_inv);
|
||||
}
|
||||
return _lens_mat_inv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::output
|
||||
// Access: Published, Virtual
|
||||
@ -1091,68 +1237,6 @@ throw_change_event() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_film_mat
|
||||
// Access: Protected
|
||||
// Description: Returns the matrix that transforms from a point
|
||||
// behind the lens to a point on the film.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_film_mat() const {
|
||||
if ((_comp_flags & CF_film_mat) == 0) {
|
||||
((Lens *)this)->compute_film_mat();
|
||||
}
|
||||
return _film_mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_film_mat_inv
|
||||
// Access: Protected
|
||||
// Description: Returns the matrix that transforms from a point on
|
||||
// the film to a point behind the lens.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_film_mat_inv() const {
|
||||
if ((_comp_flags & CF_film_mat_inv) == 0) {
|
||||
Lens *non_const = (Lens *)this;
|
||||
const LMatrix4f &film_mat = get_film_mat();
|
||||
non_const->_film_mat_inv.invert_from(film_mat);
|
||||
non_const->adjust_comp_flags(0, CF_film_mat_inv);
|
||||
}
|
||||
return _film_mat_inv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_lens_mat
|
||||
// Access: Protected
|
||||
// Description: Returns the matrix that transforms from a point
|
||||
// in front of the lens to a point in space.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_lens_mat() const {
|
||||
if ((_comp_flags & CF_lens_mat) == 0) {
|
||||
((Lens *)this)->compute_lens_mat();
|
||||
}
|
||||
return _lens_mat;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::get_lens_mat_inv
|
||||
// Access: Protected
|
||||
// Description: Returns the matrix that transforms from a point in
|
||||
// space to a point in front of the lens.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const LMatrix4f &Lens::
|
||||
get_lens_mat_inv() const {
|
||||
if ((_comp_flags & CF_lens_mat_inv) == 0) {
|
||||
Lens *non_const = (Lens *)this;
|
||||
const LMatrix4f &lens_mat = get_lens_mat();
|
||||
non_const->_lens_mat_inv.invert_from(lens_mat);
|
||||
non_const->adjust_comp_flags(0, CF_lens_mat_inv);
|
||||
}
|
||||
return _lens_mat_inv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::extrude_impl
|
||||
// Access: Protected, Virtual
|
||||
@ -1411,23 +1495,6 @@ compute_view_vector() {
|
||||
adjust_comp_flags(0, CF_view_vector);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::compute_iod_offset
|
||||
// Access: Protected, Virtual
|
||||
// Description: Computes the IOD offset: the translation along the
|
||||
// "right" axis.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lens::
|
||||
compute_iod_offset() {
|
||||
if ((_user_flags & UF_iod_offset) == 0) {
|
||||
const LMatrix4f &lens_mat_inv = get_lens_mat_inv();
|
||||
LVector3f translate;
|
||||
lens_mat_inv.get_row3(translate, 3);
|
||||
_iod_offset = -translate.dot(LVector3f::right(_cs));
|
||||
}
|
||||
adjust_comp_flags(0, CF_iod_offset);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Lens::compute_projection_mat
|
||||
// Access: Protected, Virtual
|
||||
@ -1436,9 +1503,15 @@ compute_iod_offset() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Lens::
|
||||
compute_projection_mat() {
|
||||
_projection_mat = LMatrix4f::ident_mat();
|
||||
_projection_mat_inv = _projection_mat;
|
||||
adjust_comp_flags(0, CF_projection_mat | CF_projection_mat_inv);
|
||||
_projection_mat =
|
||||
_projection_mat_left =
|
||||
_projection_mat_right =
|
||||
_projection_mat_inv =
|
||||
_projection_mat_left_inv =
|
||||
_projection_mat_right_inv =
|
||||
LMatrix4f::ident_mat();
|
||||
adjust_comp_flags(0, CF_projection_mat | CF_projection_mat_inv |
|
||||
CF_projection_mat_left_inv |CF_projection_mat_right_inv);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1498,11 +1571,6 @@ compute_lens_mat() {
|
||||
} else {
|
||||
_lens_mat = LMatrix4f::ident_mat();
|
||||
}
|
||||
|
||||
if ((_user_flags & UF_iod_offset) != 0) {
|
||||
LVector3f iod_vector = _iod_offset * LVector3f::right(_cs);
|
||||
_lens_mat = LMatrix4f::translate_mat(iod_vector) * _lens_mat;
|
||||
}
|
||||
}
|
||||
adjust_comp_flags(CF_lens_mat_inv,
|
||||
CF_lens_mat);
|
||||
|
@ -49,6 +49,12 @@ public:
|
||||
void operator = (const Lens ©);
|
||||
|
||||
PUBLISHED:
|
||||
enum StereoChannel {
|
||||
SC_left = 0x01,
|
||||
SC_right = 0x02,
|
||||
SC_both = 0x03, // == SC_left | SC_right
|
||||
};
|
||||
|
||||
virtual PT(Lens) make_copy() const=0;
|
||||
|
||||
INLINE bool extrude(const LPoint2f &point2d,
|
||||
@ -107,8 +113,11 @@ PUBLISHED:
|
||||
const LVector3f &get_view_vector() const;
|
||||
const LVector3f &get_up_vector() const;
|
||||
LPoint3f get_nodal_point() const;
|
||||
void set_iod_offset(float offset);
|
||||
float get_iod_offset() const;
|
||||
|
||||
void set_interocular_distance(float interocular_distance);
|
||||
float get_interocular_distance() const;
|
||||
void set_convergence_distance(float convergence_distance);
|
||||
float get_convergence_distance() const;
|
||||
|
||||
void set_view_mat(const LMatrix4f &view_mat);
|
||||
const LMatrix4f &get_view_mat() const;
|
||||
@ -142,8 +151,14 @@ PUBLISHED:
|
||||
|
||||
virtual PT(BoundingVolume) make_bounds() const;
|
||||
|
||||
const LMatrix4f &get_projection_mat() const;
|
||||
const LMatrix4f &get_projection_mat_inv() const;
|
||||
const LMatrix4f &get_projection_mat(StereoChannel channel = SC_both) const;
|
||||
const LMatrix4f &get_projection_mat_inv(StereoChannel channel = SC_both) const;
|
||||
|
||||
const LMatrix4f &get_film_mat() const;
|
||||
const LMatrix4f &get_film_mat_inv() const;
|
||||
|
||||
const LMatrix4f &get_lens_mat() const;
|
||||
const LMatrix4f &get_lens_mat_inv() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level = 0) const;
|
||||
@ -157,12 +172,6 @@ protected:
|
||||
|
||||
void throw_change_event();
|
||||
|
||||
const LMatrix4f &get_film_mat() const;
|
||||
const LMatrix4f &get_film_mat_inv() const;
|
||||
|
||||
const LMatrix4f &get_lens_mat() const;
|
||||
const LMatrix4f &get_lens_mat_inv() const;
|
||||
|
||||
virtual bool extrude_impl(const LPoint3f &point2d,
|
||||
LPoint3f &near_point, LPoint3f &far_point) const;
|
||||
virtual bool extrude_vec_impl(const LPoint3f &point2d, LVector3f &vec) const;
|
||||
@ -174,7 +183,6 @@ protected:
|
||||
virtual void compute_aspect_ratio();
|
||||
virtual void compute_view_hpr();
|
||||
virtual void compute_view_vector();
|
||||
virtual void compute_iod_offset();
|
||||
virtual void compute_projection_mat();
|
||||
virtual void compute_film_mat();
|
||||
virtual void compute_lens_mat();
|
||||
@ -206,26 +214,30 @@ protected:
|
||||
|
||||
LVecBase3f _view_hpr;
|
||||
LVector3f _view_vector, _up_vector;
|
||||
float _iod_offset;
|
||||
float _interocular_distance;
|
||||
float _convergence_distance;
|
||||
LVecBase2f _keystone;
|
||||
|
||||
LMatrix4f _film_mat, _film_mat_inv;
|
||||
LMatrix4f _lens_mat, _lens_mat_inv;
|
||||
LMatrix4f _projection_mat, _projection_mat_inv;
|
||||
LMatrix4f _projection_mat_left, _projection_mat_left_inv;
|
||||
LMatrix4f _projection_mat_right, _projection_mat_right_inv;
|
||||
|
||||
enum UserFlags {
|
||||
// Parameters the user may have explicitly specified.
|
||||
UF_film_width = 0x0001,
|
||||
UF_film_height = 0x0002,
|
||||
UF_focal_length = 0x0004,
|
||||
UF_hfov = 0x0008,
|
||||
UF_vfov = 0x0010,
|
||||
UF_aspect_ratio = 0x0020,
|
||||
UF_view_hpr = 0x0040,
|
||||
UF_view_vector = 0x0080,
|
||||
UF_iod_offset = 0x0100,
|
||||
UF_view_mat = 0x0200,
|
||||
UF_keystone = 0x0400,
|
||||
UF_film_width = 0x0001,
|
||||
UF_film_height = 0x0002,
|
||||
UF_focal_length = 0x0004,
|
||||
UF_hfov = 0x0008,
|
||||
UF_vfov = 0x0010,
|
||||
UF_aspect_ratio = 0x0020,
|
||||
UF_view_hpr = 0x0040,
|
||||
UF_view_vector = 0x0080,
|
||||
UF_interocular_distance = 0x0100,
|
||||
UF_convergence_distance = 0x0200,
|
||||
UF_view_mat = 0x0400,
|
||||
UF_keystone = 0x0800,
|
||||
};
|
||||
|
||||
enum CompFlags {
|
||||
@ -236,15 +248,16 @@ protected:
|
||||
CF_lens_mat_inv = 0x0008,
|
||||
CF_projection_mat = 0x0010,
|
||||
CF_projection_mat_inv = 0x0020,
|
||||
CF_mat = 0x003f, // all of the above.
|
||||
CF_projection_mat_left_inv = 0x0040,
|
||||
CF_projection_mat_right_inv = 0x0080,
|
||||
CF_mat = 0x00ff, // all of the above.
|
||||
|
||||
CF_focal_length = 0x0040,
|
||||
CF_fov = 0x0080,
|
||||
CF_film_size = 0x0100,
|
||||
CF_aspect_ratio = 0x0200,
|
||||
CF_view_hpr = 0x0400,
|
||||
CF_view_vector = 0x0800,
|
||||
CF_iod_offset = 0x1000,
|
||||
CF_focal_length = 0x1000,
|
||||
CF_fov = 0x2000,
|
||||
};
|
||||
short _user_flags;
|
||||
short _comp_flags;
|
||||
|
@ -119,9 +119,11 @@ compute_projection_mat() {
|
||||
canonical = LMatrix4f::ident_mat();
|
||||
}
|
||||
|
||||
|
||||
_projection_mat = get_lens_mat_inv() * canonical * get_film_mat();
|
||||
adjust_comp_flags(CF_projection_mat_inv,
|
||||
_projection_mat_left = _projection_mat_right = _projection_mat;
|
||||
|
||||
adjust_comp_flags(CF_projection_mat_inv | CF_projection_mat_left_inv |
|
||||
CF_projection_mat_right_inv,
|
||||
CF_projection_mat);
|
||||
}
|
||||
|
||||
|
@ -76,8 +76,8 @@ compute_projection_mat() {
|
||||
float a = (fFar + fNear);
|
||||
float b = -2.0f * fFar * fNear;
|
||||
|
||||
a/=far_minus_near;
|
||||
b/=far_minus_near;
|
||||
a /= far_minus_near;
|
||||
b /= far_minus_near;
|
||||
|
||||
LMatrix4f canonical;
|
||||
switch (cs) {
|
||||
@ -115,9 +115,29 @@ compute_projection_mat() {
|
||||
canonical = LMatrix4f::ident_mat();
|
||||
}
|
||||
|
||||
|
||||
_projection_mat = get_lens_mat_inv() * canonical * get_film_mat();
|
||||
adjust_comp_flags(CF_projection_mat_inv,
|
||||
|
||||
if ((_user_flags & UF_interocular_distance) == 0) {
|
||||
_projection_mat_left = _projection_mat_right = _projection_mat;
|
||||
|
||||
} else {
|
||||
// Compute the left and right projection matrices in case this
|
||||
// lens is assigned to a stereo DisplayRegion.
|
||||
|
||||
LVector3f iod = _interocular_distance * 0.5f * LVector3f::left(_cs);
|
||||
_projection_mat_left = get_lens_mat_inv() * LMatrix4f::translate_mat(-iod) * canonical * get_film_mat();
|
||||
_projection_mat_right = get_lens_mat_inv() * LMatrix4f::translate_mat(iod) * canonical * get_film_mat();
|
||||
|
||||
if (_user_flags & UF_convergence_distance) {
|
||||
nassertv(_convergence_distance != 0.0f);
|
||||
LVector3f cd = (0.25f / _convergence_distance) * LVector3f::left(_cs);
|
||||
_projection_mat_left *= LMatrix4f::translate_mat(cd);
|
||||
_projection_mat_right *= LMatrix4f::translate_mat(-cd);
|
||||
}
|
||||
}
|
||||
|
||||
adjust_comp_flags(CF_projection_mat_inv | CF_projection_mat_left_inv |
|
||||
CF_projection_mat_right_inv,
|
||||
CF_projection_mat);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user