diff --git a/panda/src/distort/cylindricalLens.cxx b/panda/src/distort/cylindricalLens.cxx index bc87ff6e02..08460b1a44 100644 --- a/panda/src/distort/cylindricalLens.cxx +++ b/panda/src/distort/cylindricalLens.cxx @@ -34,7 +34,7 @@ make_copy() const { } //////////////////////////////////////////////////////////////////// -// Function: CylindricalLens::extrude_impl +// Function: CylindricalLens::do_extrude // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -51,12 +51,13 @@ make_copy() const { // otherwise. //////////////////////////////////////////////////////////////////// bool CylindricalLens:: -extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { +do_extrude(const Lens::CData *lens_cdata, + const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { // Undo the shifting from film offsets, etc. This puts the point // into the range [-film_size/2, film_size/2] in x and y. - LPoint3 f = point2d * get_film_mat_inv(); + LPoint3 f = point2d * do_get_film_mat_inv(lens_cdata); - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); PN_stdfloat angle = f[0] * cylindrical_k / focal_length; PN_stdfloat sinAngle, cosAngle; csincos(deg_2_rad(angle), &sinAngle, &cosAngle); @@ -67,15 +68,15 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // And we'll need to account for the lens's rotations, etc. at the // end of the day. - const LMatrix4 &lens_mat = get_lens_mat(); + const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); - near_point = (v * get_near()) * lens_mat; - far_point = (v * get_far()) * lens_mat; + near_point = (v * do_get_near(lens_cdata)) * lens_mat; + far_point = (v * do_get_far(lens_cdata)) * lens_mat; return true; } //////////////////////////////////////////////////////////////////// -// Function: CylindricalLens::extrude_vec_impl +// Function: CylindricalLens::do_extrude_vec // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -95,23 +96,23 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // otherwise. //////////////////////////////////////////////////////////////////// bool CylindricalLens:: -extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const { +do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &vec) const { // Undo the shifting from film offsets, etc. This puts the point // into the range [-film_size/2, film_size/2] in x and y. - LPoint3 f = point2d * get_film_mat_inv(); + LPoint3 f = point2d * do_get_film_mat_inv(lens_cdata); - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); PN_stdfloat angle = f[0] * cylindrical_k / focal_length; PN_stdfloat sinAngle, cosAngle; csincos(deg_2_rad(angle), &sinAngle, &cosAngle); - vec = LVector3(sinAngle, cosAngle, 0.0f) * get_lens_mat(); + vec = LVector3(sinAngle, cosAngle, 0.0f) * do_get_lens_mat(lens_cdata); return true; } //////////////////////////////////////////////////////////////////// -// Function: CylindricalLens::project_impl +// Function: CylindricalLens::do_project // Access: Protected, Virtual // Description: Given a 3-d point in space, determine the 2-d point // this maps to, in the range (-1,1) in both dimensions, @@ -128,9 +129,9 @@ extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const { // is filled in), or false otherwise. //////////////////////////////////////////////////////////////////// bool CylindricalLens:: -project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { +do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { // First, account for any rotations, etc. on the lens. - LPoint3 p = point3d * get_lens_mat_inv(); + LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata); // To compute the x position on the frame, we only need to consider // the angle of the vector about the Z axis. Project the vector @@ -145,7 +146,7 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { return false; } - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); point2d.set ( @@ -155,12 +156,12 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { // distance. p[2] * focal_length / pdist, // Z is the perspective distance scaled into the range (1, -1). - (get_near() - pdist) / (get_far() - get_near()) + (do_get_near(lens_cdata) - pdist) / (do_get_far(lens_cdata) - do_get_near(lens_cdata)) ); // Now we have to transform the point according to the film // adjustments. - point2d = point2d * get_film_mat(); + point2d = point2d * do_get_film_mat(lens_cdata); return point2d[0] >= -1.0f && point2d[0] <= 1.0f && diff --git a/panda/src/distort/cylindricalLens.h b/panda/src/distort/cylindricalLens.h index f104f9954c..9a7492e9ca 100644 --- a/panda/src/distort/cylindricalLens.h +++ b/panda/src/distort/cylindricalLens.h @@ -49,10 +49,12 @@ public: virtual PT(Lens) make_copy() const; protected: - virtual bool extrude_impl(const LPoint3 &point2d, - LPoint3 &near_point, LPoint3 &far_point) const; - virtual bool extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const; - virtual bool project_impl(const LPoint3 &point3d, LPoint3 &point2d) const; + virtual bool do_extrude(const Lens::CData *lens_cdata, const LPoint3 &point2d, + LPoint3 &near_point, LPoint3 &far_point) const; + virtual bool do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, + LVector3 &vec) const; + virtual bool do_project(const Lens::CData *lens_cdata, + const LPoint3 &point3d, LPoint3 &point2d) const; virtual PN_stdfloat fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool horiz) const; virtual PN_stdfloat fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool horiz) const; diff --git a/panda/src/distort/fisheyeLens.cxx b/panda/src/distort/fisheyeLens.cxx index 603a51c947..46122246d0 100644 --- a/panda/src/distort/fisheyeLens.cxx +++ b/panda/src/distort/fisheyeLens.cxx @@ -47,7 +47,7 @@ make_copy() const { } //////////////////////////////////////////////////////////////////// -// Function: FisheyeLens::extrude_impl +// Function: FisheyeLens::do_extrude // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -64,10 +64,11 @@ make_copy() const { // otherwise. //////////////////////////////////////////////////////////////////// bool FisheyeLens:: -extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { +do_extrude(const Lens::CData *lens_cdata, + const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { // Undo the shifting from film offsets, etc. This puts the point // into the range [-film_size/2, film_size/2] in x and y. - LPoint3 f = point2d * get_film_mat_inv(); + LPoint3 f = point2d * do_get_film_mat_inv(lens_cdata); // First, get the vector from the center of the film to the point, // and normalize it. @@ -84,7 +85,7 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co v2 /= r; // Now get the point r units around the circle in the YZ plane. - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); PN_stdfloat angle = r * fisheye_k / focal_length; PN_stdfloat sinAngle, cosAngle; csincos(deg_2_rad(angle), &sinAngle, &cosAngle); @@ -99,15 +100,15 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // And we'll need to account for the lens's rotations, etc. at the // end of the day. - const LMatrix4 &lens_mat = get_lens_mat(); + const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); - near_point = (v * get_near()) * lens_mat; - far_point = (v * get_far()) * lens_mat; + near_point = (v * do_get_near(lens_cdata)) * lens_mat; + far_point = (v * do_get_far(lens_cdata)) * lens_mat; return true; } //////////////////////////////////////////////////////////////////// -// Function: FisheyeLens::extrude_vec_impl +// Function: FisheyeLens::do_extrude_vec // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -127,9 +128,9 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // otherwise. //////////////////////////////////////////////////////////////////// bool FisheyeLens:: -extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const { +do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, LVector3 &vec) const { LPoint3 near_point, far_point; - if (!extrude_impl(point2d, near_point, far_point)) { + if (!do_extrude(lens_cdata, point2d, near_point, far_point)) { return false; } @@ -139,7 +140,7 @@ extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const { } //////////////////////////////////////////////////////////////////// -// Function: FisheyeLens::project_impl +// Function: FisheyeLens::do_project // Access: Protected, Virtual // Description: Given a 3-d point in space, determine the 2-d point // this maps to, in the range (-1,1) in both dimensions, @@ -156,9 +157,9 @@ extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const { // is filled in), or false otherwise. //////////////////////////////////////////////////////////////////// bool FisheyeLens:: -project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { +do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { // First, account for any rotations, etc. on the lens. - LVector3 v2 = point3d * get_lens_mat_inv(); + LVector3 v2 = point3d * do_get_lens_mat_inv(lens_cdata); // A fisheye lens projection has the property that the distance from // the center point to any other point on the projection is @@ -181,7 +182,7 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { // Special case. This point is either directly ahead or directly // behind. point2d.set(0.0f, 0.0f, - (get_near() - dist) / (get_far() - get_near())); + (do_get_near(lens_cdata) - dist) / (do_get_far(lens_cdata) - do_get_near(lens_cdata))); return v2[1] >= 0.0f; } @@ -193,19 +194,19 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { // along the great circle to the point. PN_stdfloat r = 90.0f - rad_2_deg(catan2(x[0], x[1])); - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); PN_stdfloat factor = r * focal_length / fisheye_k; point2d.set (y[0] * factor, y[1] * factor, // Z is the distance scaled into the range (1, -1). - (get_near() - dist) / (get_far() - get_near()) + (do_get_near(lens_cdata) - dist) / (do_get_far(lens_cdata) - do_get_near(lens_cdata)) ); // Now we have to transform the point according to the film // adjustments. - point2d = point2d * get_film_mat(); + point2d = point2d * do_get_film_mat(lens_cdata); return point2d[0] >= -1.0f && point2d[0] <= 1.0f && diff --git a/panda/src/distort/fisheyeLens.h b/panda/src/distort/fisheyeLens.h index 6ae27b5ee4..84c6573833 100644 --- a/panda/src/distort/fisheyeLens.h +++ b/panda/src/distort/fisheyeLens.h @@ -39,10 +39,12 @@ public: virtual PT(Lens) make_copy() const; protected: - virtual bool extrude_impl(const LPoint3 &point2d, - LPoint3 &near_point, LPoint3 &far_point) const; - virtual bool extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const; - virtual bool project_impl(const LPoint3 &point3d, LPoint3 &point2d) const; + virtual bool do_extrude(const Lens::CData *lens_cdata, const LPoint3 &point2d, + LPoint3 &near_point, LPoint3 &far_point) const; + virtual bool do_extrude_vec(const Lens::CData *lens_cdata, const LPoint3 &point2d, + LVector3 &vec) const; + virtual bool do_project(const Lens::CData *lens_cdata, + const LPoint3 &point3d, LPoint3 &point2d) const; virtual PN_stdfloat fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool horiz) const; virtual PN_stdfloat fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool horiz) const; diff --git a/panda/src/distort/oSphereLens.cxx b/panda/src/distort/oSphereLens.cxx index fd084e09f2..38144828b0 100755 --- a/panda/src/distort/oSphereLens.cxx +++ b/panda/src/distort/oSphereLens.cxx @@ -34,7 +34,7 @@ make_copy() const { } //////////////////////////////////////////////////////////////////// -// Function: OSphereLens::extrude_impl +// Function: OSphereLens::do_extrude // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -51,12 +51,13 @@ make_copy() const { // otherwise. //////////////////////////////////////////////////////////////////// bool OSphereLens:: -extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { +do_extrude(const Lens::CData *lens_cdata, + const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { // Undo the shifting from film offsets, etc. This puts the point // into the range [-film_size/2, film_size/2] in x and y. - LPoint3 f = point2d * get_film_mat_inv(); + LPoint3 f = point2d * do_get_film_mat_inv(lens_cdata); - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); PN_stdfloat angle = f[0] * cylindrical_k / focal_length; PN_stdfloat sinAngle, cosAngle; csincos(deg_2_rad(angle), &sinAngle, &cosAngle); @@ -65,14 +66,14 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // this point. LPoint3 v(sinAngle, cosAngle, 0.0f); - near_point = (v * get_near()); - far_point = (v * get_far()); + near_point = (v * do_get_near(lens_cdata)); + far_point = (v * do_get_far(lens_cdata)); near_point[2] = f[1] / focal_length; far_point[2] = f[1] / focal_length; // And we'll need to account for the lens's rotations, etc. at the // end of the day. - const LMatrix4 &lens_mat = get_lens_mat(); + const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); near_point = near_point * lens_mat; far_point = far_point * lens_mat; @@ -80,7 +81,7 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co } //////////////////////////////////////////////////////////////////// -// Function: OSphereLens::project_impl +// Function: OSphereLens::do_project // Access: Protected, Virtual // Description: Given a 3-d point in space, determine the 2-d point // this maps to, in the range (-1,1) in both dimensions, @@ -97,9 +98,9 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // is filled in), or false otherwise. //////////////////////////////////////////////////////////////////// bool OSphereLens:: -project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { +do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { // First, account for any rotations, etc. on the lens. - LPoint3 p = point3d * get_lens_mat_inv(); + LPoint3 p = point3d * do_get_lens_mat_inv(lens_cdata); PN_stdfloat dist = p.length(); if (dist == 0.0f) { point2d.set(0.0f, 0.0f, 0.0f); @@ -108,7 +109,7 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { LPoint3 v3 = p / dist; - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); // To compute the x position on the frame, we only need to consider // the angle of the vector about the Z axis. Project the vector @@ -123,12 +124,12 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { // distance. p[2] * focal_length, // Z is the distance scaled into the range (1, -1). - (get_near() - dist) / (get_far() - get_near()) + (do_get_near(lens_cdata) - dist) / (do_get_far(lens_cdata) - do_get_near(lens_cdata)) ); // Now we have to transform the point according to the film // adjustments. - point2d = point2d * get_film_mat(); + point2d = point2d * do_get_film_mat(lens_cdata); return point2d[0] >= -1.0f && point2d[0] <= 1.0f && diff --git a/panda/src/distort/oSphereLens.h b/panda/src/distort/oSphereLens.h index ee400f9267..acc884f884 100755 --- a/panda/src/distort/oSphereLens.h +++ b/panda/src/distort/oSphereLens.h @@ -43,9 +43,10 @@ public: virtual PT(Lens) make_copy() const; protected: - virtual bool extrude_impl(const LPoint3 &point2d, - LPoint3 &near_point, LPoint3 &far_point) const; - virtual bool project_impl(const LPoint3 &point3d, LPoint3 &point2d) const; + virtual bool do_extrude(const Lens::CData *lens_cdata, const LPoint3 &point2d, + LPoint3 &near_point, LPoint3 &far_point) const; + virtual bool do_project(const Lens::CData *lens_cdata, + const LPoint3 &point3d, LPoint3 &point2d) const; virtual PN_stdfloat fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool horiz) const; virtual PN_stdfloat fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool horiz) const; diff --git a/panda/src/distort/pSphereLens.cxx b/panda/src/distort/pSphereLens.cxx index d159abb7fe..5e0159a1f7 100644 --- a/panda/src/distort/pSphereLens.cxx +++ b/panda/src/distort/pSphereLens.cxx @@ -33,7 +33,7 @@ make_copy() const { } //////////////////////////////////////////////////////////////////// -// Function: PSphereLens::extrude_impl +// Function: PSphereLens::do_extrude // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -50,12 +50,13 @@ make_copy() const { // otherwise. //////////////////////////////////////////////////////////////////// bool PSphereLens:: -extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { +do_extrude(const Lens::CData *lens_cdata, + const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { // Undo the shifting from film offsets, etc. This puts the point // into the range [-film_size/2, film_size/2] in x and y. - LPoint3 f = point2d * get_film_mat_inv(); + LPoint3 f = point2d * do_get_film_mat_inv(lens_cdata); - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); // Rotate the forward vector through the rotation angles // corresponding to this point. @@ -65,15 +66,15 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // And we'll need to account for the lens's rotations, etc. at the // end of the day. - const LMatrix4 &lens_mat = get_lens_mat(); + const LMatrix4 &lens_mat = do_get_lens_mat(lens_cdata); - near_point = (v * get_near()) * lens_mat; - far_point = (v * get_far()) * lens_mat; + near_point = (v * do_get_near(lens_cdata)) * lens_mat; + far_point = (v * do_get_far(lens_cdata)) * lens_mat; return true; } //////////////////////////////////////////////////////////////////// -// Function: PSphereLens::project_impl +// Function: PSphereLens::do_project // Access: Protected, Virtual // Description: Given a 3-d point in space, determine the 2-d point // this maps to, in the range (-1,1) in both dimensions, @@ -90,9 +91,9 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // is filled in), or false otherwise. //////////////////////////////////////////////////////////////////// bool PSphereLens:: -project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { +do_project(const Lens::CData *lens_cdata, const LPoint3 &point3d, LPoint3 &point2d) const { // First, account for any rotations, etc. on the lens. - LVector3 v3 = point3d * get_lens_mat_inv(); + LVector3 v3 = point3d * do_get_lens_mat_inv(lens_cdata); PN_stdfloat dist = v3.length(); if (dist == 0.0f) { point2d.set(0.0f, 0.0f, 0.0f); @@ -101,7 +102,7 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { v3 /= dist; - PN_stdfloat focal_length = get_focal_length(); + PN_stdfloat focal_length = do_get_focal_length(lens_cdata); // To compute the x position on the frame, we only need to consider // the angle of the vector about the Z axis. Project the vector @@ -120,12 +121,12 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { // The y position is the angle about the X axis. rad_2_deg(catan2(yz[1], yz[0])) * focal_length / pspherical_k, // Z is the distance scaled into the range (1, -1). - (get_near() - dist) / (get_far() - get_near()) + (do_get_near(lens_cdata) - dist) / (do_get_far(lens_cdata) - do_get_near(lens_cdata)) ); // Now we have to transform the point according to the film // adjustments. - point2d = point2d * get_film_mat(); + point2d = point2d * do_get_film_mat(lens_cdata); return point2d[0] >= -1.0f && point2d[0] <= 1.0f && diff --git a/panda/src/distort/pSphereLens.h b/panda/src/distort/pSphereLens.h index 1ef91fee20..0277d05563 100644 --- a/panda/src/distort/pSphereLens.h +++ b/panda/src/distort/pSphereLens.h @@ -47,9 +47,10 @@ public: virtual PT(Lens) make_copy() const; protected: - virtual bool extrude_impl(const LPoint3 &point2d, - LPoint3 &near_point, LPoint3 &far_point) const; - virtual bool project_impl(const LPoint3 &point3d, LPoint3 &point2d) const; + virtual bool do_extrude(const Lens::CData *lens_cdata, const LPoint3 &point2d, + LPoint3 &near_point, LPoint3 &far_point) const; + virtual bool do_project(const Lens::CData *lens_cdata, + const LPoint3 &point3d, LPoint3 &point2d) const; virtual PN_stdfloat fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool horiz) const; virtual PN_stdfloat fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool horiz) const; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 7bef6cdd39..8ecde159f9 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3596,7 +3596,10 @@ bool CLP(GraphicsStateGuardian):: apply_vertex_buffer(VertexBufferContext *vbc, const GeomVertexArrayDataHandle *reader, bool force) { nassertr(_supports_buffers, false); - nassertr(reader->get_modified() != UpdateSeq::initial(), false); + if (reader->get_modified() == UpdateSeq::initial()) { + // No need to re-apply. + return true; + } CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc); @@ -3785,7 +3788,10 @@ apply_index_buffer(IndexBufferContext *ibc, const GeomPrimitivePipelineReader *reader, bool force) { nassertr(_supports_buffers, false); - nassertr(reader->get_modified() != UpdateSeq::initial(), false); + if (reader->get_modified() == UpdateSeq::initial()) { + // No need to re-apply. + return true; + } CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc); diff --git a/panda/src/gobj/lens.I b/panda/src/gobj/lens.I index 06c5413736..0fa6533ffe 100644 --- a/panda/src/gobj/lens.I +++ b/panda/src/gobj/lens.I @@ -30,8 +30,9 @@ //////////////////////////////////////////////////////////////////// INLINE bool Lens:: extrude(const LPoint2 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { - return extrude_impl(LPoint3(point2d[0], point2d[1], 0.0f), - near_point, far_point); + CDReader cdata(_cycler); + return do_extrude(cdata, LPoint3(point2d[0], point2d[1], 0.0f), + near_point, far_point); } //////////////////////////////////////////////////////////////////// @@ -53,7 +54,8 @@ extrude(const LPoint2 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { //////////////////////////////////////////////////////////////////// INLINE bool Lens:: extrude(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { - return extrude_impl(point2d, near_point, far_point); + CDReader cdata(_cycler); + return do_extrude(cdata, point2d, near_point, far_point); } //////////////////////////////////////////////////////////////////// @@ -76,7 +78,8 @@ extrude(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { //////////////////////////////////////////////////////////////////// INLINE bool Lens:: extrude_vec(const LPoint2 &point2d, LVector3 &vec) const { - return extrude_vec_impl(LPoint3(point2d[0], point2d[1], 0.0f), vec); + CDReader cdata(_cycler); + return do_extrude_vec(cdata, LPoint3(point2d[0], point2d[1], 0.0f), vec); } //////////////////////////////////////////////////////////////////// @@ -101,7 +104,8 @@ extrude_vec(const LPoint2 &point2d, LVector3 &vec) const { //////////////////////////////////////////////////////////////////// INLINE bool Lens:: extrude_vec(const LPoint3 &point2d, LVector3 &vec) const { - return extrude_vec_impl(point2d, vec); + CDReader cdata(_cycler); + return do_extrude_vec(cdata, point2d, vec); } //////////////////////////////////////////////////////////////////// @@ -120,8 +124,9 @@ extrude_vec(const LPoint3 &point2d, LVector3 &vec) const { //////////////////////////////////////////////////////////////////// INLINE bool Lens:: project(const LPoint3 &point3d, LPoint2 &point2d) const { + CDReader cdata(_cycler); LPoint3 result; - bool okflag = project_impl(point3d, result); + bool okflag = do_project(cdata, point3d, result); point2d.set(result[0], result[1]); return okflag; } @@ -146,7 +151,8 @@ project(const LPoint3 &point3d, LPoint2 &point2d) const { //////////////////////////////////////////////////////////////////// INLINE bool Lens:: project(const LPoint3 &point3d, LPoint3 &point2d) const { - return project_impl(point3d, point2d); + CDReader cdata(_cycler); + return do_project(cdata, point3d, point2d); } //////////////////////////////////////////////////////////////////// @@ -163,7 +169,8 @@ project(const LPoint3 &point3d, LPoint3 &point2d) const { //////////////////////////////////////////////////////////////////// INLINE void Lens:: set_change_event(const string &event) { - _change_event = event; + CDWriter cdata(_cycler, true); + cdata->_change_event = event; } //////////////////////////////////////////////////////////////////// @@ -175,7 +182,8 @@ set_change_event(const string &event) { //////////////////////////////////////////////////////////////////// INLINE const string &Lens:: get_change_event() const { - return _change_event; + CDReader cdata(_cycler); + return cdata->_change_event; } //////////////////////////////////////////////////////////////////// @@ -187,7 +195,22 @@ get_change_event() const { //////////////////////////////////////////////////////////////////// INLINE CoordinateSystem Lens:: get_coordinate_system() const { - return _cs; + CDReader cdata(_cycler); + return cdata->_cs; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_film_size +// Access: Published +// Description: Sets the horizontal size of the film without changing +// its shape. The aspect ratio remains unchanged; this +// computes the vertical size of the film to +// automatically maintain the aspect ratio. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_film_size(PN_stdfloat width) { + CDWriter cdata(_cycler, true); + do_set_film_size(cdata, width); } //////////////////////////////////////////////////////////////////// @@ -216,6 +239,45 @@ set_film_size(PN_stdfloat width, PN_stdfloat height) { set_film_size(LVecBase2(width, height)); } +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_film_size +// Access: Published +// Description: Sets the size and shape of the "film" within the +// lens. This both establishes the units used by +// calls like set_focal_length(), and establishes the +// aspect ratio of the frame. +// +// In a physical camera, the field of view of a lens is +// determined by the lens' focal length and by the size +// of the film area exposed by the lens. For instance, +// a 35mm camera exposes a rectangle on the film about +// 24mm x 36mm, which means a 50mm lens gives about a +// 40-degree horizontal field of view. +// +// In the virtual camera, you may set the film size to +// any units here, and specify a focal length in the +// same units to simulate the same effect. Or, you may +// ignore this parameter, and specify the field of view +// and aspect ratio of the lens directly. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_film_size(const LVecBase2 &film_size) { + CDWriter cdata(_cycler, true); + do_set_film_size(cdata, film_size); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_film_size +// Access: Published +// Description: Returns the horizontal and vertical film size of +// the virtual film. See set_film_size(). +//////////////////////////////////////////////////////////////////// +INLINE const LVecBase2 &Lens:: +get_film_size() const { + CDReader cdata(_cycler); + return do_get_film_size(cdata); +} + //////////////////////////////////////////////////////////////////// // Function: Lens::set_film_offset // Access: Published @@ -241,9 +303,8 @@ set_film_offset(PN_stdfloat x, PN_stdfloat y) { //////////////////////////////////////////////////////////////////// INLINE void Lens:: set_film_offset(const LVecBase2 &film_offset) { - _film_offset = film_offset; - adjust_comp_flags(CF_mat, 0); - throw_change_event(); + CDWriter cdata(_cycler, true); + do_set_film_offset(cdata, film_offset); } //////////////////////////////////////////////////////////////////// @@ -254,7 +315,52 @@ set_film_offset(const LVecBase2 &film_offset) { //////////////////////////////////////////////////////////////////// INLINE const LVector2 &Lens:: get_film_offset() const { - return _film_offset; + CDReader cdata(_cycler); + return do_get_film_offset(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_focal_length +// Access: Published +// Description: Sets the focal length of the lens. This may adjust +// the field-of-view correspondingly, and is an +// alternate way to specify field of view. +// +// For certain kinds of lenses (e.g. OrthographicLens), +// the focal length has no meaning. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_focal_length(PN_stdfloat focal_length) { + CDWriter cdata(_cycler, true); + do_set_focal_length(cdata, focal_length); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_focal_length +// Access: Published +// Description: Returns the focal length of the lens. This may have +// been set explicitly by a previous call to +// set_focal_length(), or it may be computed based on +// the lens' fov and film_size. For certain kinds of +// lenses, the focal length has no meaning. +//////////////////////////////////////////////////////////////////// +INLINE PN_stdfloat Lens:: +get_focal_length() const { + CDReader cdata(_cycler); + return do_get_focal_length(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_fov +// Access: Published +// Description: Sets the horizontal field of view of the lens without +// changing the aspect ratio. The vertical field of +// view is adjusted to maintain the same aspect ratio. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_fov(PN_stdfloat hfov) { + CDWriter cdata(_cycler, true); + do_set_fov(cdata, hfov); } //////////////////////////////////////////////////////////////////// @@ -274,6 +380,36 @@ set_fov(PN_stdfloat hfov, PN_stdfloat vfov) { set_fov(LVecBase2(hfov, vfov)); } +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_fov +// Access: Published +// Description: Sets the field of view of the lens in both +// dimensions. This establishes both the field of view +// and the aspect ratio of the lens. This is one way to +// specify the field of view of a lens; +// set_focal_length() is another way. +// +// For certain kinds of lenses (like OrthographicLens), +// the field of view has no meaning. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_fov(const LVecBase2 &fov) { + CDWriter cdata(_cycler, true); + do_set_fov(cdata, fov); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_fov +// Access: Published +// Description: Returns the horizontal and vertical film size of +// the virtual film. See set_fov(). +//////////////////////////////////////////////////////////////////// +INLINE const LVecBase2 &Lens:: +get_fov() const { + CDReader cdata(_cycler); + return do_get_fov(cdata); +} + //////////////////////////////////////////////////////////////////// // Function: Lens::get_hfov // Access: Published @@ -296,6 +432,33 @@ get_vfov() const { return get_fov()[1]; } +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_aspect_ratio +// Access: Published +// Description: Sets the aspect ratio of the lens. This is the ratio +// of the height to the width of the generated image. +// Setting this overrides the two-parameter fov or film +// size setting. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_aspect_ratio(PN_stdfloat aspect_ratio) { + CDWriter cdata(_cycler, true); + do_set_aspect_ratio(cdata, aspect_ratio); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_aspect_ratio +// Access: Published +// Description: Returns the aspect ratio of the Lens. This is +// determined based on the indicated film size; see +// set_film_size(). +//////////////////////////////////////////////////////////////////// +INLINE PN_stdfloat Lens:: +get_aspect_ratio() const { + CDReader cdata(_cycler); + return do_get_aspect_ratio(cdata); +} + //////////////////////////////////////////////////////////////////// // Function: Lens::set_near // Access: Published @@ -305,9 +468,8 @@ get_vfov() const { //////////////////////////////////////////////////////////////////// INLINE void Lens:: set_near(PN_stdfloat near_distance) { - _near_distance = near_distance; - adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv, 0); - throw_change_event(); + CDWriter cdata(_cycler, true); + do_set_near(cdata, near_distance); } //////////////////////////////////////////////////////////////////// @@ -318,7 +480,8 @@ set_near(PN_stdfloat near_distance) { //////////////////////////////////////////////////////////////////// INLINE PN_stdfloat Lens:: get_near() const { - return _near_distance; + CDReader cdata(_cycler); + return do_get_near(cdata); } //////////////////////////////////////////////////////////////////// @@ -330,9 +493,8 @@ get_near() const { //////////////////////////////////////////////////////////////////// INLINE void Lens:: set_far(PN_stdfloat far_distance) { - _far_distance = far_distance; - adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv, 0); - throw_change_event(); + CDWriter cdata(_cycler, true); + do_set_far(cdata, far_distance); } //////////////////////////////////////////////////////////////////// @@ -343,7 +505,8 @@ set_far(PN_stdfloat far_distance) { //////////////////////////////////////////////////////////////////// INLINE PN_stdfloat Lens:: get_far() const { - return _far_distance; + CDReader cdata(_cycler); + return do_get_far(cdata); } //////////////////////////////////////////////////////////////////// @@ -353,10 +516,8 @@ get_far() const { //////////////////////////////////////////////////////////////////// INLINE void Lens:: set_near_far(PN_stdfloat near_distance, PN_stdfloat far_distance) { - _near_distance = near_distance; - _far_distance = far_distance; - adjust_comp_flags(CF_projection_mat | CF_projection_mat_inv, 0); - throw_change_event(); + CDWriter cdata(_cycler, true); + do_set_near_far(cdata, near_distance, far_distance); } //////////////////////////////////////////////////////////////////// @@ -373,6 +534,7 @@ INLINE void Lens:: set_view_hpr(PN_stdfloat h, PN_stdfloat p, PN_stdfloat r) { set_view_hpr(LVecBase3(h, p, r)); } + //////////////////////////////////////////////////////////////////// // Function: Lens::set_view_vector // Access: Published @@ -387,6 +549,111 @@ set_view_vector(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat i, PN_s set_view_vector(LVector3(x, y, z), LVector3(i, j, k)); } +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_interocular_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. +// +// The left eye and the right eye are each offset along +// the X axis by half of this distance, so that this +// parameter specifies the total distance between them. +// +// Also see set_convergence_distance(), which relates. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_interocular_distance(PN_stdfloat interocular_distance) { + CDWriter cdata(_cycler, true); + do_set_interocular_distance(cdata, interocular_distance); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_interocular_distance +// Access: Published +// Description: See set_interocular_distance(). +//////////////////////////////////////////////////////////////////// +INLINE PN_stdfloat Lens:: +get_interocular_distance() const { + CDReader cdata(_cycler); + return cdata->_interocular_distance; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_convergence_distance +// Access: Published +// Description: Sets the distance between between the camera plane +// and the point in the distance that the left and right +// eyes are both looking at. 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. +// +// This parameter must be greater than 0, but may be as +// large as you like. It controls the amount to which +// the two eyes are directed inwards towards each other, +// which is a normal property of stereo vision. It is a +// distance, not an angle; normally this should be set +// to the distance from the camera to the area of +// interest in your scene. If you want to simulate +// parallel stereo, set this value to a very large +// number. +// +// Also see set_interocular_distance(), which relates. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_convergence_distance(PN_stdfloat convergence_distance) { + CDWriter cdata(_cycler, true); + do_set_convergence_distance(cdata, convergence_distance); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_convergence_distance +// Access: Published +// Description: See set_convergence_distance(). +//////////////////////////////////////////////////////////////////// +INLINE PN_stdfloat Lens:: +get_convergence_distance() const { + CDReader cdata(_cycler); + return cdata->_convergence_distance; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::set_view_mat +// Access: Published +// Description: Sets an arbitrary transformation on the lens. This +// replaces the individual transformation components +// like set_view_hpr(). +// +// Setting a transformation here will have a slightly +// different effect than putting one on the LensNode +// that contains this lens. In particular, lighting and +// other effects computations will still be performed on +// the lens in its untransformed (facing forward) +// position, but the actual projection matrix will be +// transformed by this matrix. +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +set_view_mat(const LMatrix4 &view_mat) { + CDWriter cdata(_cycler, true); + do_set_view_mat(cdata, view_mat); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_view_mat +// Access: Published +// Description: Returns the direction in which the lens is facing. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4 &Lens:: +get_view_mat() const { + CDReader cdata(_cycler); + return do_get_view_mat(cdata); +} + //////////////////////////////////////////////////////////////////// // Function: Lens::get_keystone // Access: Published @@ -395,7 +662,83 @@ set_view_vector(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z, PN_stdfloat i, PN_s //////////////////////////////////////////////////////////////////// INLINE const LVecBase2 &Lens:: get_keystone() const { - return _keystone; + CDReader cdata(_cycler); + return cdata->_keystone; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_projection_mat +// Access: Published +// Description: Returns the complete transformation matrix from a 3-d +// point in space to a point on the film, if such a +// matrix exists, or the identity matrix if the lens is +// nonlinear. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4 &Lens:: +get_projection_mat(StereoChannel channel) const { + CDReader cdata(_cycler); + return do_get_projection_mat(cdata, channel); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::get_projection_mat_inv +// 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. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4 &Lens:: +get_projection_mat_inv(StereoChannel stereo_channel) const { + CDReader cdata(_cycler); + return do_get_projection_mat_inv(cdata, stereo_channel); +} + +//////////////////////////////////////////////////////////////////// +// 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. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4 &Lens:: +get_film_mat() const { + CDReader cdata(_cycler); + return do_get_film_mat(cdata); +} + +//////////////////////////////////////////////////////////////////// +// 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. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4 &Lens:: +get_film_mat_inv() const { + CDReader cdata(_cycler); + return do_get_film_mat_inv(cdata); +} + +//////////////////////////////////////////////////////////////////// +// 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. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4 &Lens:: +get_lens_mat() const { + CDReader cdata(_cycler); + return do_get_lens_mat(cdata); +} + +//////////////////////////////////////////////////////////////////// +// 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. +//////////////////////////////////////////////////////////////////// +INLINE const LMatrix4 &Lens:: +get_lens_mat_inv() const { + CDReader cdata(_cycler); + return do_get_lens_mat_inv(cdata); } //////////////////////////////////////////////////////////////////// @@ -408,29 +751,109 @@ get_keystone() const { //////////////////////////////////////////////////////////////////// INLINE const UpdateSeq &Lens:: get_last_change() const { - return _last_change; + CDReader cdata(_cycler); + return cdata->_last_change; } //////////////////////////////////////////////////////////////////// -// Function: Lens::adjust_user_flags +// Function: Lens::do_adjust_user_flags // Access: Protected // Description: Clears from _user_flags the bits in the first // parameter, and sets the bits in the second parameter. //////////////////////////////////////////////////////////////////// INLINE void Lens:: -adjust_user_flags(int clear_flags, int set_flags) { - _user_flags = (_user_flags & ~clear_flags) | set_flags; +do_adjust_user_flags(CData *cdata, int clear_flags, int set_flags) { + cdata->_user_flags = (cdata->_user_flags & ~clear_flags) | set_flags; } //////////////////////////////////////////////////////////////////// -// Function: Lens::adjust_comp_flags +// Function: Lens::do_adjust_comp_flags // Access: Protected // Description: Clears from _comp_flags the bits in the first // parameter, and sets the bits in the second parameter. //////////////////////////////////////////////////////////////////// INLINE void Lens:: -adjust_comp_flags(int clear_flags, int set_flags) { - _comp_flags = (_comp_flags & ~clear_flags) | set_flags; +do_adjust_comp_flags(CData *cdata, int clear_flags, int set_flags) { + cdata->_comp_flags = (cdata->_comp_flags & ~clear_flags) | set_flags; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_film_offset +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +do_set_film_offset(CData *cdata, const LVecBase2 &film_offset) { + cdata->_film_offset = film_offset; + do_adjust_comp_flags(cdata, CF_mat, 0); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_film_offset +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE const LVector2 &Lens:: +do_get_film_offset(const CData *cdata) const { + return cdata->_film_offset; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_near +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +do_set_near(CData *cdata, PN_stdfloat near_distance) { + cdata->_near_distance = near_distance; + do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_near +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PN_stdfloat Lens:: +do_get_near(const CData *cdata) const { + return cdata->_near_distance; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_far +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +do_set_far(CData *cdata, PN_stdfloat far_distance) { + cdata->_far_distance = far_distance; + do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_far +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PN_stdfloat Lens:: +do_get_far(const CData *cdata) const { + return cdata->_far_distance; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_near_far +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void Lens:: +do_set_near_far(CData *cdata, PN_stdfloat near_distance, PN_stdfloat far_distance) { + cdata->_near_distance = near_distance; + cdata->_far_distance = far_distance; + do_adjust_comp_flags(cdata, CF_projection_mat | CF_projection_mat_inv, 0); + do_throw_change_event(cdata); } INLINE ostream & diff --git a/panda/src/gobj/lens.cxx b/panda/src/gobj/lens.cxx index 69a79148f3..1abb7f009c 100644 --- a/panda/src/gobj/lens.cxx +++ b/panda/src/gobj/lens.cxx @@ -25,6 +25,7 @@ #include "plane.h" TypeHandle Lens::_type_handle; +TypeHandle Lens::CData::_type_handle; //////////////////////////////////////////////////////////////////// // Function: Lens::Constructor @@ -42,8 +43,10 @@ Lens() { // Description: //////////////////////////////////////////////////////////////////// Lens:: -Lens(const Lens ©) { - (*this) = copy; +Lens(const Lens ©) : _cycler(copy._cycler) { + // We don't copy the _geom_data. That's unique to each Lens. + CDWriter cdata(_cycler, true); + cdata->_geom_data = NULL; } //////////////////////////////////////////////////////////////////// @@ -53,30 +56,11 @@ Lens(const Lens ©) { //////////////////////////////////////////////////////////////////// void Lens:: operator = (const Lens ©) { - _change_event = copy._change_event; - _cs = copy._cs; - _film_size = copy._film_size; - _film_offset = copy._film_offset; - _focal_length = copy._focal_length; - _fov = copy._fov; - _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; - - _focal_length_seq = copy._focal_length_seq; - _fov_seq = copy._fov_seq; - _film_size_seq = copy._film_size_seq; + _cycler = copy._cycler; // We don't copy the _geom_data. That's unique to each Lens. + CDWriter cdata(_cycler, true); + cdata->_geom_data = NULL; } //////////////////////////////////////////////////////////////////// @@ -88,8 +72,10 @@ operator = (const Lens ©) { //////////////////////////////////////////////////////////////////// void Lens:: set_coordinate_system(CoordinateSystem cs) { - _cs = cs; - adjust_comp_flags(CF_mat | CF_view_hpr | CF_view_vector, 0); + CDWriter cdata(_cycler, true); + cdata->_cs = cs; + do_adjust_comp_flags(cdata, CF_mat | CF_view_hpr | CF_view_vector, 0); + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -100,187 +86,12 @@ set_coordinate_system(CoordinateSystem cs) { //////////////////////////////////////////////////////////////////// void Lens:: clear() { - _change_event = ""; - _cs = CS_default; - _film_size.set(1.0f, 1.0f); - _film_offset.set(0.0f, 0.0f); - _focal_length = 1.0f; - _fov.set(default_fov, default_fov); - _aspect_ratio = 1.0f; - _near_distance = default_near; - _far_distance = default_far; - _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); - _keystone.set(0.0f, 0.0f); + CDWriter cdata(_cycler, true); + cdata->clear(); - _user_flags = 0; - _comp_flags = CF_fov; - - set_interocular_distance(default_iod); - set_convergence_distance(default_converge); - - if (default_keystone.has_value()) { - _keystone.set(default_keystone[0], default_keystone[1]); - _user_flags |= UF_keystone; - } - - // Assign an initial arbitrary sequence to these three. - _film_size_seq = 0; - _focal_length_seq = 1; - _fov_seq = 2; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_film_size -// Access: Published -// Description: Sets the horizontal size of the film without changing -// its shape. The aspect ratio remains unchanged; this -// computes the vertical size of the film to -// automatically maintain the aspect ratio. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_film_size(PN_stdfloat width) { - nassertv(!cnan(width)); - _film_size.set(width, width / get_aspect_ratio()); - - // We can't specify all three of focal length, fov, and film size. - // Throw out the oldest one. - resequence_fov_triad(_film_size_seq, _focal_length_seq, _fov_seq); - - if (_fov_seq == 0) { - // Throw out fov if it's oldest. - adjust_user_flags(UF_hfov | UF_vfov | UF_min_fov | UF_film_height, - UF_film_width); - } else { - // Otherwise, throw out focal length. - nassertv(_focal_length_seq == 0); - adjust_user_flags(UF_focal_length | UF_film_height, - UF_film_width); - } - adjust_comp_flags(CF_mat | CF_focal_length | CF_fov, - CF_film_size); - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_film_size -// Access: Published -// Description: Sets the size and shape of the "film" within the -// lens. This both establishes the units used by -// calls like set_focal_length(), and establishes the -// aspect ratio of the frame. -// -// In a physical camera, the field of view of a lens is -// determined by the lens' focal length and by the size -// of the film area exposed by the lens. For instance, -// a 35mm camera exposes a rectangle on the film about -// 24mm x 36mm, which means a 50mm lens gives about a -// 40-degree horizontal field of view. -// -// In the virtual camera, you may set the film size to -// any units here, and specify a focal length in the -// same units to simulate the same effect. Or, you may -// ignore this parameter, and specify the field of view -// and aspect ratio of the lens directly. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_film_size(const LVecBase2 &film_size) { - nassertv(!film_size.is_nan()); - _film_size = film_size; - - // We can't specify all three of focal length, fov, and film size. - // Throw out the oldest one. - resequence_fov_triad(_film_size_seq, _focal_length_seq, _fov_seq); - - if (_fov_seq == 0) { - // Throw out fov if it's oldest. - adjust_user_flags(UF_hfov | UF_vfov | UF_min_fov | UF_aspect_ratio, - UF_film_width | UF_film_height); - } else { - // Otherwise, throw out focal length. - nassertv(_focal_length_seq == 0); - adjust_user_flags(UF_focal_length | UF_vfov | UF_aspect_ratio, - UF_film_width | UF_film_height); - } - adjust_comp_flags(CF_mat | CF_focal_length | CF_fov | CF_aspect_ratio, - CF_film_size); - - // Also, the user has implicitly specified an aspect ratio. Make it - // stick until the user tells us something different. - compute_aspect_ratio(); - adjust_user_flags(0, UF_aspect_ratio); - - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_film_size -// Access: Published -// Description: Returns the horizontal and vertical film size of -// the virtual film. See set_film_size(). -//////////////////////////////////////////////////////////////////// -const LVecBase2 &Lens:: -get_film_size() const { - if ((_comp_flags & CF_film_size) == 0) { - // We pretend this is a const method, even though it may call a - // non-const method to recompute the internal values. We can do - // this because this is just compute-on-demand. - ((Lens *)this)->compute_film_size(); - } - return _film_size; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_focal_length -// Access: Published -// Description: Sets the focal length of the lens. This may adjust -// the field-of-view correspondingly, and is an -// alternate way to specify field of view. -// -// For certain kinds of lenses (e.g. OrthographicLens), -// the focal length has no meaning. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_focal_length(PN_stdfloat focal_length) { - nassertv(!cnan(focal_length)); - _focal_length = focal_length; - - // We can't specify all three of focal length, fov, and film size. - // Throw out the oldest one. - resequence_fov_triad(_focal_length_seq, _film_size_seq, _fov_seq); - - if (_film_size_seq == 0) { - // Throw out film size if it's oldest. - adjust_user_flags(UF_film_width | UF_film_height, - UF_focal_length); - } else { - // Otherwise, throw out the fov. - nassertv(_fov_seq == 0); - adjust_user_flags(UF_hfov | UF_vfov | UF_min_fov, - UF_focal_length); - } - - adjust_comp_flags(CF_mat | CF_fov | CF_film_size, - CF_focal_length); - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_focal_length -// Access: Published -// Description: Returns the focal length of the lens. This may have -// been set explicitly by a previous call to -// set_focal_length(), or it may be computed based on -// the lens' fov and film_size. For certain kinds of -// lenses, the focal length has no meaning. -//////////////////////////////////////////////////////////////////// -PN_stdfloat Lens:: -get_focal_length() const { - if ((_comp_flags & CF_focal_length) == 0) { - ((Lens *)this)->compute_focal_length(); - } - return _focal_length; + do_set_interocular_distance(cdata, default_iod); + do_set_convergence_distance(cdata, default_converge); + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -301,124 +112,32 @@ get_focal_length() const { void Lens:: set_min_fov(PN_stdfloat min_fov) { nassertv(!cnan(min_fov)); - _min_fov = min_fov; + CDWriter cdata(_cycler, true); + cdata->_min_fov = min_fov; // We can't specify all three of focal length, fov, and film size. // Throw out the oldest one. - resequence_fov_triad(_fov_seq, _focal_length_seq, _film_size_seq); + do_resequence_fov_triad(cdata, cdata->_fov_seq, cdata->_focal_length_seq, cdata->_film_size_seq); - if (_focal_length_seq == 0) { + if (cdata->_focal_length_seq == 0) { // Throw out focal length if it's oldest. - adjust_user_flags(UF_focal_length | UF_vfov | UF_hfov, - UF_min_fov); + do_adjust_user_flags(cdata, UF_focal_length | UF_vfov | UF_hfov, + UF_min_fov); } else { // Otherwise, throw out film size. - nassertv(_film_size_seq == 0); + nassertv(cdata->_film_size_seq == 0); // Make sure we save the aspect ratio first. - compute_aspect_ratio(); - adjust_user_flags(UF_film_width | UF_film_height | UF_vfov | UF_hfov, - UF_min_fov); + do_compute_aspect_ratio(cdata); + do_adjust_user_flags(cdata, UF_film_width | UF_film_height | UF_vfov | UF_hfov, + UF_min_fov); } - adjust_comp_flags(CF_mat | CF_focal_length | CF_fov | CF_film_size, - 0); + do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov | CF_film_size, + 0); // We leave CF_fov off of comp_flags, because we will still need to // recompute the vertical fov. It's not exactly the same as hfov * // get_aspect_ratio(). - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_fov -// Access: Published -// Description: Sets the horizontal field of view of the lens without -// changing the aspect ratio. The vertical field of -// view is adjusted to maintain the same aspect ratio. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_fov(PN_stdfloat hfov) { - nassertv(!cnan(hfov)); - _fov[0] = hfov; - - // We can't specify all three of focal length, fov, and film size. - // Throw out the oldest one. - resequence_fov_triad(_fov_seq, _focal_length_seq, _film_size_seq); - - if (_focal_length_seq == 0) { - // Throw out focal length if it's oldest. - adjust_user_flags(UF_focal_length | UF_vfov | UF_min_fov, - UF_hfov); - } else { - // Otherwise, throw out film size. - nassertv(_film_size_seq == 0); - - // Make sure we save the aspect ratio first. - compute_aspect_ratio(); - adjust_user_flags(UF_film_width | UF_film_height | UF_vfov | UF_min_fov, - UF_hfov); - } - adjust_comp_flags(CF_mat | CF_focal_length | CF_fov | CF_film_size, - 0); - // We leave CF_fov off of comp_flags, because we will still need to - // recompute the vertical fov. It's not exactly the same as hfov * - // get_aspect_ratio(). - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_fov -// Access: Published -// Description: Sets the field of view of the lens in both -// dimensions. This establishes both the field of view -// and the aspect ratio of the lens. This is one way to -// specify the field of view of a lens; -// set_focal_length() is another way. -// -// For certain kinds of lenses (like OrthographicLens), -// the field of view has no meaning. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_fov(const LVecBase2 &fov) { - nassertv(!fov.is_nan()); - _fov = fov; - - // We can't specify all three of focal length, fov, and film size. - // Throw out the oldest one. - resequence_fov_triad(_fov_seq, _focal_length_seq, _film_size_seq); - - if (_focal_length_seq == 0) { - // Throw out focal length if it's oldest. - adjust_user_flags(UF_focal_length | UF_film_height | UF_min_fov | UF_aspect_ratio, - UF_hfov | UF_vfov); - } else { - // Otherwise, throw out film size. - nassertv(_film_size_seq == 0); - adjust_user_flags(UF_film_width | UF_film_height | UF_min_fov | UF_aspect_ratio, - UF_hfov | UF_vfov); - } - adjust_comp_flags(CF_mat | CF_focal_length | CF_film_size | CF_aspect_ratio, - CF_fov); - - // Also, the user has implicitly specified an aspect ratio. Make it - // stick until the user tells us something different. - compute_aspect_ratio(); - adjust_user_flags(0, UF_aspect_ratio); - - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_fov -// Access: Published -// Description: Returns the horizontal and vertical film size of -// the virtual film. See set_fov(). -//////////////////////////////////////////////////////////////////// -const LVecBase2 &Lens:: -get_fov() const { - if ((_comp_flags & CF_fov) == 0) { - ((Lens *)this)->compute_fov(); - } - return _fov; + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -429,47 +148,14 @@ get_fov() const { //////////////////////////////////////////////////////////////////// PN_stdfloat Lens:: get_min_fov() const { - if ((_comp_flags & CF_fov) == 0) { - ((Lens *)this)->compute_fov(); + CDReader cdata(_cycler); + + if ((cdata->_comp_flags & CF_fov) == 0) { + ((Lens *)this)->do_compute_fov((CData *)cdata.p()); } - return _min_fov; + return cdata->_min_fov; } - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_aspect_ratio -// Access: Published -// Description: Sets the aspect ratio of the lens. This is the ratio -// of the height to the width of the generated image. -// Setting this overrides the two-parameter fov or film -// size setting. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_aspect_ratio(PN_stdfloat aspect_ratio) { - nassertv(!cnan(aspect_ratio)); - _aspect_ratio = aspect_ratio; - adjust_user_flags(UF_film_height | UF_vfov, - UF_aspect_ratio); - adjust_comp_flags(CF_mat | CF_film_size | CF_fov | CF_focal_length, - CF_aspect_ratio); - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_aspect_ratio -// Access: Published -// Description: Returns the aspect ratio of the Lens. This is -// determined based on the indicated film size; see -// set_film_size(). -//////////////////////////////////////////////////////////////////// -PN_stdfloat Lens:: -get_aspect_ratio() const { - if ((_comp_flags & CF_aspect_ratio) == 0) { - ((Lens *)this)->compute_aspect_ratio(); - } - return _aspect_ratio; -} - //////////////////////////////////////////////////////////////////// // Function: Lens::get_default_near // Access: Published, Static @@ -507,12 +193,13 @@ get_default_far() { void Lens:: set_view_hpr(const LVecBase3 &view_hpr) { nassertv(!view_hpr.is_nan()); - _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_view_hpr); - throw_change_event(); + CDWriter cdata(_cycler, true); + cdata->_view_hpr = view_hpr; + do_adjust_user_flags(cdata, UF_view_vector | UF_view_mat, + UF_view_hpr); + do_adjust_comp_flags(cdata, CF_mat | CF_view_vector, + CF_view_hpr); + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -522,10 +209,11 @@ set_view_hpr(const LVecBase3 &view_hpr) { //////////////////////////////////////////////////////////////////// const LVecBase3 &Lens:: get_view_hpr() const { - if ((_comp_flags & CF_view_hpr) == 0) { - ((Lens *)this)->compute_view_hpr(); + CDReader cdata(_cycler); + if ((cdata->_comp_flags & CF_view_hpr) == 0) { + ((Lens *)this)->do_compute_view_hpr((CData *)cdata.p()); } - return _view_hpr; + return cdata->_view_hpr; } //////////////////////////////////////////////////////////////////// @@ -540,13 +228,14 @@ get_view_hpr() const { void Lens:: set_view_vector(const LVector3 &view_vector, const LVector3 &up_vector) { nassertv(!view_vector.is_nan()); - _view_vector = view_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_view_vector); - throw_change_event(); + CDWriter cdata(_cycler, true); + cdata->_view_vector = view_vector; + cdata->_up_vector = up_vector; + do_adjust_user_flags(cdata, UF_view_hpr | UF_view_mat, + UF_view_vector); + do_adjust_comp_flags(cdata, CF_mat | CF_view_hpr, + CF_view_vector); + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -556,10 +245,11 @@ set_view_vector(const LVector3 &view_vector, const LVector3 &up_vector) { //////////////////////////////////////////////////////////////////// const LVector3 &Lens:: get_view_vector() const { - if ((_comp_flags & CF_view_vector) == 0) { - ((Lens *)this)->compute_view_vector(); + CDReader cdata(_cycler); + if ((cdata->_comp_flags & CF_view_vector) == 0) { + ((Lens *)this)->do_compute_view_vector((CData *)cdata.p()); } - return _view_vector; + return cdata->_view_vector; } //////////////////////////////////////////////////////////////////// @@ -570,10 +260,11 @@ get_view_vector() const { //////////////////////////////////////////////////////////////////// const LVector3 &Lens:: get_up_vector() const { - if ((_comp_flags & CF_view_vector) == 0) { - ((Lens *)this)->compute_view_vector(); + CDReader cdata(_cycler); + if ((cdata->_comp_flags & CF_view_vector) == 0) { + ((Lens *)this)->do_compute_view_vector((CData *)cdata.p()); } - return _up_vector; + return cdata->_up_vector; } //////////////////////////////////////////////////////////////////// @@ -587,132 +278,6 @@ get_nodal_point() const { return get_view_mat().get_row3(3); } -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_interocular_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. -// -// The left eye and the right eye are each offset along -// the X axis by half of this distance, so that this -// parameter specifies the total distance between them. -// -// Also see set_convergence_distance(), which relates. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_interocular_distance(PN_stdfloat interocular_distance) { - nassertv(!cnan(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_interocular_distance -// Access: Published -// Description: See set_interocular_distance(). -//////////////////////////////////////////////////////////////////// -PN_stdfloat Lens:: -get_interocular_distance() const { - return _interocular_distance; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_convergence_distance -// Access: Published -// Description: Sets the distance between between the camera plane -// and the point in the distance that the left and right -// eyes are both looking at. 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. -// -// This parameter must be greater than 0, but may be as -// large as you like. It controls the amount to which -// the two eyes are directed inwards towards each other, -// which is a normal property of stereo vision. It is a -// distance, not an angle; normally this should be set -// to the distance from the camera to the area of -// interest in your scene. If you want to simulate -// parallel stereo, set this value to a very large -// number. -// -// Also see set_interocular_distance(), which relates. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_convergence_distance(PN_stdfloat convergence_distance) { - nassertv(!cnan(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); - } - - adjust_comp_flags(CF_mat, 0); - throw_change_event(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_convergence_distance -// Access: Published -// Description: See set_convergence_distance(). -//////////////////////////////////////////////////////////////////// -PN_stdfloat Lens:: -get_convergence_distance() const { - return _convergence_distance; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::set_view_mat -// Access: Published -// Description: Sets an arbitrary transformation on the lens. This -// replaces the individual transformation components -// like set_view_hpr(). -// -// Setting a transformation here will have a slightly -// different effect than putting one on the LensNode -// that contains this lens. In particular, lighting and -// other effects computations will still be performed on -// the lens in its untransformed (facing forward) -// position, but the actual projection matrix will be -// transformed by this matrix. -//////////////////////////////////////////////////////////////////// -void Lens:: -set_view_mat(const LMatrix4 &view_mat) { - nassertv(!view_mat.is_nan()); - _lens_mat = view_mat; - adjust_user_flags(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(); -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_view_mat -// Access: Published -// Description: Returns the direction in which the lens is facing. -//////////////////////////////////////////////////////////////////// -const LMatrix4 &Lens:: -get_view_mat() const { - if ((_comp_flags & CF_lens_mat) == 0) { - ((Lens *)this)->compute_lens_mat(); - } - return _lens_mat; -} - //////////////////////////////////////////////////////////////////// // Function: Lens::clear_view_mat // Access: Published @@ -720,13 +285,14 @@ get_view_mat() const { //////////////////////////////////////////////////////////////////// void Lens:: clear_view_mat() { - _lens_mat = LMatrix4::ident_mat(); - 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(); + CDWriter cdata(_cycler, true); + cdata->_lens_mat = LMatrix4::ident_mat(); + do_adjust_user_flags(cdata, 0, UF_view_vector | UF_view_hpr | UF_view_mat); + do_adjust_comp_flags(cdata, 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); + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -749,12 +315,13 @@ clear_view_mat() { void Lens:: set_keystone(const LVecBase2 &keystone) { nassertv(!keystone.is_nan()); - _keystone = keystone; - adjust_user_flags(0, UF_keystone); - 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(); + CDWriter cdata(_cycler, true); + cdata->_keystone = keystone; + do_adjust_user_flags(cdata, 0, UF_keystone); + do_adjust_comp_flags(cdata, 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); + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -764,12 +331,13 @@ set_keystone(const LVecBase2 &keystone) { //////////////////////////////////////////////////////////////////// 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_projection_mat_left_inv | CF_projection_mat_right_inv | - CF_film_mat | CF_film_mat_inv, 0); - throw_change_event(); + CDWriter cdata(_cycler, true); + cdata->_keystone.set(0.0f, 0.0f); + do_adjust_user_flags(cdata, UF_keystone, 0); + do_adjust_comp_flags(cdata, 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); + do_throw_change_event(cdata); } //////////////////////////////////////////////////////////////////// @@ -836,10 +404,12 @@ set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, const LVecBase3 &ll, const LVecBase3 &lr, int flags) { nassertv(!ul.is_nan() && !ur.is_nan() && !ll.is_nan() && !lr.is_nan()); + + CDWriter cdata(_cycler, true); // 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 (0, 0, 0), but it could be an arbitrary vector. - const LMatrix4 &lens_mat_inv = get_lens_mat_inv(); + const LMatrix4 &lens_mat_inv = do_get_lens_mat_inv(cdata); LVector3 eye_offset; lens_mat_inv.get_row3(eye_offset, 3); @@ -860,7 +430,7 @@ set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, // view vector is straight up, it is the vector perpendicular to // both the viewing axis and the top line. Otherwise, it is the // standard up axis. - LVector3 up_vector = LVector3::up(_cs); + LVector3 up_vector = LVector3::up(cdata->_cs); if (view_vector == up_vector || ((flags & FC_roll) != 0)) { LVector3 top = ul - ur; up_vector = view_vector.cross(top); @@ -909,7 +479,7 @@ set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, LMatrix4 view_mat; view_mat.invert_from(inv_view_mat); - set_view_mat(view_mat); + do_set_view_mat(cdata, view_mat); LPoint3 ful = inv_view_mat.xform_point(ul); LPoint3 fur = inv_view_mat.xform_point(ur); @@ -947,7 +517,7 @@ set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, z_spread = max(cabs(max_z), cabs(min_z)); } - PN_stdfloat aspect_ratio = get_aspect_ratio(); + PN_stdfloat aspect_ratio = do_get_aspect_ratio(cdata); nassertv(aspect_ratio != 0.0f); if ((flags & FC_aspect_ratio) == 0) { // If we must preserve the aspect ratio, then the x and z spreads @@ -964,19 +534,19 @@ set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, PN_stdfloat hfov = rad_2_deg(catan(x_spread)) * 2.0f; PN_stdfloat vfov = rad_2_deg(catan(z_spread)) * 2.0f; - set_fov(hfov, vfov); + do_set_fov(cdata, LVecBase2(hfov, vfov)); if ((flags & FC_aspect_ratio) == 0) { // If we must preserve the aspect ratio, store it one more time. // This is mainly in case we have a non-perspective lens with a // funny relationship between fov and aspect ratio. - set_aspect_ratio(aspect_ratio); + do_set_aspect_ratio(cdata, aspect_ratio); } - const LVecBase2 &film_size = get_film_size(); + const LVecBase2 &film_size = do_get_film_size(cdata); nassertv(x_spread != 0.0f && z_spread != 0.0f); - set_film_offset(film_size[0] * x_center / (x_spread * 2.0f), - film_size[1] * z_center / (z_spread * 2.0f)); + do_set_film_offset(cdata, LVecBase2(film_size[0] * x_center / (x_spread * 2.0f), + film_size[1] * z_center / (z_spread * 2.0f))); } @@ -989,7 +559,8 @@ set_frustum_from_corners(const LVecBase3 &ul, const LVecBase3 &ur, //////////////////////////////////////////////////////////////////// void Lens:: recompute_all() { - _comp_flags = 0; + CDWriter cdata(_cycler); + cdata->_comp_flags = 0; } //////////////////////////////////////////////////////////////////// @@ -1040,6 +611,8 @@ is_orthographic() const { //////////////////////////////////////////////////////////////////// PT(Geom) Lens:: make_geometry() { + CDWriter cdata(_cycler, true); + // The default behavior for make_geometry() will be to draw a // hexahedron around the eight vertices of the frustum. If the lens // is non-linear, the hexahedron will be curved; in that case, we'll @@ -1049,10 +622,10 @@ make_geometry() { // First, define all the points we'll use in this Geom. That's one // point at each corner of the near and far planes (and possibly // more points along the edges). - int num_segments = define_geom_data(); + int num_segments = do_define_geom_data(cdata); if (num_segments == 0) { // Can't do a frustum. - _geom_data.clear(); + cdata->_geom_data.clear(); return (Geom *)NULL; } @@ -1100,7 +673,7 @@ make_geometry() { line->add_vertex(num_segments * (4 * 2) + 1); line->close_primitive(); - PT(Geom) geom = new Geom(_geom_data); + PT(Geom) geom = new Geom(cdata->_geom_data); geom->add_primitive(line); return geom.p(); @@ -1116,174 +689,41 @@ make_geometry() { //////////////////////////////////////////////////////////////////// PT(BoundingVolume) Lens:: make_bounds() const { + CDReader cdata(_cycler); + // The default bounding volume is a hexahedron based on the eight // corners of the frustum. LPoint3 fll, flr, ful, fur; LPoint3 nll, nlr, nul, nur; - LPoint2 corner; + LPoint3 corner; // Upper left. - corner.set(-1.0f, 1.0f); - if (!extrude(corner, nul, ful)) { + corner.set(-1.0f, 1.0f, 0.0f); + if (!do_extrude(cdata, corner, nul, ful)) { return (BoundingVolume *)NULL; } // Upper right. - corner.set(1.0f, 1.0f); - if (!extrude(corner, nur, fur)) { + corner.set(1.0f, 1.0f, 0.0f); + if (!do_extrude(cdata, corner, nur, fur)) { return (BoundingVolume *)NULL; } // Lower right. - corner.set(1.0f, -1.0f); - if (!extrude(corner, nlr, flr)) { + corner.set(1.0f, -1.0f, 0.0f); + if (!do_extrude(cdata, corner, nlr, flr)) { return (BoundingVolume *)NULL; } // Lower left. - corner.set(-1.0f, -1.0f); - if (!extrude(corner, nll, fll)) { + corner.set(-1.0f, -1.0f, 0.0f); + if (!do_extrude(cdata, corner, nll, fll)) { return (BoundingVolume *)NULL; } return new BoundingHexahedron(fll, flr, fur, ful, nll, nlr, nur, nul); } -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_projection_mat -// Access: Published -// Description: Returns the complete transformation matrix from a 3-d -// point in space to a point on the film, if such a -// matrix exists, or the identity matrix if the lens is -// nonlinear. -//////////////////////////////////////////////////////////////////// -const LMatrix4 &Lens:: -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_mono: - case SC_stereo: - return _projection_mat; - } - - return _projection_mat; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lens::get_projection_mat_inv -// 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 LMatrix4 &Lens:: -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 LMatrix4 &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 LMatrix4 &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_mono: - case SC_stereo: - break; - } - - if ((_comp_flags & CF_projection_mat_inv) == 0) { - Lens *non_const = (Lens *)this; - const LMatrix4 &projection_mat = get_projection_mat(); - non_const->_projection_mat_inv.invert_from(projection_mat); - non_const->adjust_comp_flags(0, CF_projection_mat_inv); - } - 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 LMatrix4 &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 LMatrix4 &Lens:: -get_film_mat_inv() const { - if ((_comp_flags & CF_film_mat_inv) == 0) { - Lens *non_const = (Lens *)this; - const LMatrix4 &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 LMatrix4 &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 LMatrix4 &Lens:: -get_lens_mat_inv() const { - if ((_comp_flags & CF_lens_mat_inv) == 0) { - Lens *non_const = (Lens *)this; - const LMatrix4 &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 @@ -1305,35 +745,458 @@ write(ostream &out, int indent_level) const { } //////////////////////////////////////////////////////////////////// -// Function: Lens::throw_change_event +// Function: Lens::do_set_film_size +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_film_size(CData *cdata, PN_stdfloat width) { + nassertv(!cnan(width)); + cdata->_film_size.set(width, width / do_get_aspect_ratio(cdata)); + + // We can't specify all three of focal length, fov, and film size. + // Throw out the oldest one. + do_resequence_fov_triad(cdata, cdata->_film_size_seq, cdata->_focal_length_seq, cdata->_fov_seq); + + if (cdata->_fov_seq == 0) { + // Throw out fov if it's oldest. + do_adjust_user_flags(cdata, UF_hfov | UF_vfov | UF_min_fov | UF_film_height, + UF_film_width); + } else { + // Otherwise, throw out focal length. + nassertv(cdata->_focal_length_seq == 0); + do_adjust_user_flags(cdata, UF_focal_length | UF_film_height, + UF_film_width); + } + do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov, + CF_film_size); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_film_size +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_film_size(CData *cdata, const LVecBase2 &film_size) { + nassertv(!film_size.is_nan()); + cdata->_film_size = film_size; + + // We can't specify all three of focal length, fov, and film size. + // Throw out the oldest one. + do_resequence_fov_triad(cdata, cdata->_film_size_seq, cdata->_focal_length_seq, cdata->_fov_seq); + + if (cdata->_fov_seq == 0) { + // Throw out fov if it's oldest. + do_adjust_user_flags(cdata, UF_hfov | UF_vfov | UF_min_fov | UF_aspect_ratio, + UF_film_width | UF_film_height); + } else { + // Otherwise, throw out focal length. + nassertv(cdata->_focal_length_seq == 0); + do_adjust_user_flags(cdata, UF_focal_length | UF_vfov | UF_aspect_ratio, + UF_film_width | UF_film_height); + } + do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov | CF_aspect_ratio, + CF_film_size); + + // Also, the user has implicitly specified an aspect ratio. Make it + // stick until the user tells us something different. + do_compute_aspect_ratio(cdata); + do_adjust_user_flags(cdata, 0, UF_aspect_ratio); + + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_film_size +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase2 &Lens:: +do_get_film_size(const CData *cdata) const { + if ((cdata->_comp_flags & CF_film_size) == 0) { + // We pretend this is a const method, even though it may call a + // non-const method to recompute the internal values. We can do + // this because this is just compute-on-demand. + ((Lens *)this)->do_compute_film_size((CData *)cdata); + } + return cdata->_film_size; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_focal_length +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_focal_length(CData *cdata, PN_stdfloat focal_length) { + nassertv(!cnan(focal_length)); + cdata->_focal_length = focal_length; + + // We can't specify all three of focal length, fov, and film size. + // Throw out the oldest one. + do_resequence_fov_triad(cdata, cdata->_focal_length_seq, cdata->_film_size_seq, cdata->_fov_seq); + + if (cdata->_film_size_seq == 0) { + // Throw out film size if it's oldest. + do_adjust_user_flags(cdata, UF_film_width | UF_film_height, + UF_focal_length); + } else { + // Otherwise, throw out the fov. + nassertv(cdata->_fov_seq == 0); + do_adjust_user_flags(cdata, UF_hfov | UF_vfov | UF_min_fov, + UF_focal_length); + } + + do_adjust_comp_flags(cdata, CF_mat | CF_fov | CF_film_size, + CF_focal_length); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_focal_length +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +PN_stdfloat Lens:: +do_get_focal_length(const CData *cdata) const { + if ((cdata->_comp_flags & CF_focal_length) == 0) { + ((Lens *)this)->do_compute_focal_length((CData *)cdata); + } + return cdata->_focal_length; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_fov +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_fov(CData *cdata, PN_stdfloat hfov) { + nassertv(!cnan(hfov)); + cdata->_fov[0] = hfov; + + // We can't specify all three of focal length, fov, and film size. + // Throw out the oldest one. + do_resequence_fov_triad(cdata, cdata->_fov_seq, cdata->_focal_length_seq, cdata->_film_size_seq); + + if (cdata->_focal_length_seq == 0) { + // Throw out focal length if it's oldest. + do_adjust_user_flags(cdata, UF_focal_length | UF_vfov | UF_min_fov, + UF_hfov); + } else { + // Otherwise, throw out film size. + nassertv(cdata->_film_size_seq == 0); + + // Make sure we save the aspect ratio first. + do_compute_aspect_ratio(cdata); + do_adjust_user_flags(cdata, UF_film_width | UF_film_height | UF_vfov | UF_min_fov, + UF_hfov); + } + do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_fov | CF_film_size, + 0); + // We leave CF_fov off of comp_flags, because we will still need to + // recompute the vertical fov. It's not exactly the same as hfov * + // get_aspect_ratio(). + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_fov +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_fov(CData *cdata, const LVecBase2 &fov) { + nassertv(!fov.is_nan()); + cdata->_fov = fov; + + // We can't specify all three of focal length, fov, and film size. + // Throw out the oldest one. + do_resequence_fov_triad(cdata, cdata->_fov_seq, cdata->_focal_length_seq, cdata->_film_size_seq); + + if (cdata->_focal_length_seq == 0) { + // Throw out focal length if it's oldest. + do_adjust_user_flags(cdata, UF_focal_length | UF_film_height | UF_min_fov | UF_aspect_ratio, + UF_hfov | UF_vfov); + } else { + // Otherwise, throw out film size. + nassertv(cdata->_film_size_seq == 0); + do_adjust_user_flags(cdata, UF_film_width | UF_film_height | UF_min_fov | UF_aspect_ratio, + UF_hfov | UF_vfov); + } + do_adjust_comp_flags(cdata, CF_mat | CF_focal_length | CF_film_size | CF_aspect_ratio, + CF_fov); + + // Also, the user has implicitly specified an aspect ratio. Make it + // stick until the user tells us something different. + do_compute_aspect_ratio(cdata); + do_adjust_user_flags(cdata, 0, UF_aspect_ratio); + + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_fov +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase2 &Lens:: +do_get_fov(const CData *cdata) const { + if ((cdata->_comp_flags & CF_fov) == 0) { + ((Lens *)this)->do_compute_fov((CData *)cdata); + } + return cdata->_fov; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_aspect_ratio +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_aspect_ratio(CData *cdata, PN_stdfloat aspect_ratio) { + nassertv(!cnan(aspect_ratio)); + cdata->_aspect_ratio = aspect_ratio; + do_adjust_user_flags(cdata, UF_film_height | UF_vfov, + UF_aspect_ratio); + do_adjust_comp_flags(cdata, CF_mat | CF_film_size | CF_fov | CF_focal_length, + CF_aspect_ratio); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_aspect_ratio +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +PN_stdfloat Lens:: +do_get_aspect_ratio(const CData *cdata) const { + if ((cdata->_comp_flags & CF_aspect_ratio) == 0) { + ((Lens *)this)->do_compute_aspect_ratio((CData *)cdata); + } + return cdata->_aspect_ratio; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_projection_mat +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LMatrix4 &Lens:: +do_get_projection_mat(const CData *cdata, StereoChannel channel) const { + if ((cdata->_comp_flags & CF_projection_mat) == 0) { + ((Lens *)this)->do_compute_projection_mat((CData *)cdata); + } + + switch (channel) { + case SC_left: + return cdata->_projection_mat_left; + case SC_right: + return cdata->_projection_mat_right; + case SC_mono: + case SC_stereo: + return cdata->_projection_mat; + } + + return cdata->_projection_mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_projection_mat_inv +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LMatrix4 &Lens:: +do_get_projection_mat_inv(const CData *cdata, StereoChannel stereo_channel) const { + switch (stereo_channel) { + case SC_left: + { + if ((cdata->_comp_flags & CF_projection_mat_left_inv) == 0) { + const LMatrix4 &projection_mat_left = do_get_projection_mat(cdata, SC_left); + ((CData *)cdata)->_projection_mat_left_inv.invert_from(projection_mat_left); + ((Lens *)this)->do_adjust_comp_flags((CData *)cdata, 0, CF_projection_mat_left_inv); + } + } + return cdata->_projection_mat_left_inv; + + case SC_right: + { + if ((cdata->_comp_flags & CF_projection_mat_right_inv) == 0) { + const LMatrix4 &projection_mat_right = do_get_projection_mat(cdata, SC_right); + ((CData *)cdata)->_projection_mat_right_inv.invert_from(projection_mat_right); + ((Lens *)this)->do_adjust_comp_flags((CData *)cdata, 0, CF_projection_mat_right_inv); + } + } + return cdata->_projection_mat_right_inv; + + case SC_mono: + case SC_stereo: + break; + } + + if ((cdata->_comp_flags & CF_projection_mat_inv) == 0) { + const LMatrix4 &projection_mat = do_get_projection_mat(cdata); + ((CData *)cdata)->_projection_mat_inv.invert_from(projection_mat); + ((Lens *)this)->do_adjust_comp_flags((CData *)cdata, 0, CF_projection_mat_inv); + } + return cdata->_projection_mat_inv; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_film_mat +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LMatrix4 &Lens:: +do_get_film_mat(const CData *cdata) const { + if ((cdata->_comp_flags & CF_film_mat) == 0) { + ((Lens *)this)->do_compute_film_mat((CData *)cdata); + } + return cdata->_film_mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_film_mat_inv +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LMatrix4 &Lens:: +do_get_film_mat_inv(const CData *cdata) const { + if ((cdata->_comp_flags & CF_film_mat_inv) == 0) { + const LMatrix4 &film_mat = do_get_film_mat(cdata); + ((CData *)cdata)->_film_mat_inv.invert_from(film_mat); + ((Lens *)this)->do_adjust_comp_flags((CData *)cdata, 0, CF_film_mat_inv); + } + return cdata->_film_mat_inv; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_lens_mat +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LMatrix4 &Lens:: +do_get_lens_mat(const CData *cdata) const { + if ((cdata->_comp_flags & CF_lens_mat) == 0) { + ((Lens *)this)->do_compute_lens_mat((CData *)cdata); + } + return cdata->_lens_mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_lens_mat_inv +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LMatrix4 &Lens:: +do_get_lens_mat_inv(const CData *cdata) const { + if ((cdata->_comp_flags & CF_lens_mat_inv) == 0) { + const LMatrix4 &lens_mat = do_get_lens_mat(cdata); + ((CData *)cdata)->_lens_mat_inv.invert_from(lens_mat); + ((Lens *)this)->do_adjust_comp_flags((CData *)cdata, 0, CF_lens_mat_inv); + } + return cdata->_lens_mat_inv; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_interocular_distance +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_interocular_distance(CData *cdata, PN_stdfloat interocular_distance) { + nassertv(!cnan(interocular_distance)); + cdata->_interocular_distance = interocular_distance; + if (cdata->_interocular_distance == 0.0f) { + do_adjust_user_flags(cdata, UF_interocular_distance, 0); + } else { + do_adjust_user_flags(cdata, 0, UF_interocular_distance); + } + + do_adjust_comp_flags(cdata, CF_mat, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_convergence_distance +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_convergence_distance(CData *cdata, PN_stdfloat convergence_distance) { + nassertv(!cnan(convergence_distance)); + cdata->_convergence_distance = convergence_distance; + if (cdata->_convergence_distance == 0.0f) { + do_adjust_user_flags(cdata, UF_convergence_distance, 0); + } else { + do_adjust_user_flags(cdata, 0, UF_convergence_distance); + } + + do_adjust_comp_flags(cdata, CF_mat, 0); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_set_view_mat +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +void Lens:: +do_set_view_mat(CData *cdata, const LMatrix4 &view_mat) { + nassertv(!view_mat.is_nan()); + cdata->_lens_mat = view_mat; + do_adjust_user_flags(cdata, UF_view_vector | UF_view_hpr, + UF_view_mat); + do_adjust_comp_flags(cdata, 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); + do_throw_change_event(cdata); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_get_view_mat +// Access: Protected +// Description: +//////////////////////////////////////////////////////////////////// +const LMatrix4 &Lens:: +do_get_view_mat(const CData *cdata) const { + if ((cdata->_comp_flags & CF_lens_mat) == 0) { + ((Lens *)this)->do_compute_lens_mat((CData *)cdata); + } + return cdata->_lens_mat; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::do_throw_change_event // Access: Protected // Description: Throws the event associated with changing properties // on this Lens, if any. //////////////////////////////////////////////////////////////////// void Lens:: -throw_change_event() { - ++_last_change; +do_throw_change_event(CData *cdata) { + ++(cdata->_last_change); - if (!_change_event.empty()) { - throw_event(_change_event, this); + if (!cdata->_change_event.empty()) { + throw_event(cdata->_change_event, this); } - if (!_geom_data.is_null()) { - if (_geom_data->get_ref_count() == 1) { + if (!cdata->_geom_data.is_null()) { + if (cdata->_geom_data->get_ref_count() == 1) { // No one's using the data any more (there are no references to // it other than this one), so don't bother to recompute it; // just release it. - _geom_data.clear(); + cdata->_geom_data.clear(); } else { // Someone still has a handle to the data, so recompute it for // them. - define_geom_data(); + do_define_geom_data(cdata); } } } //////////////////////////////////////////////////////////////////// -// Function: Lens::extrude_impl +// Function: Lens::do_extrude // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -1350,8 +1213,9 @@ throw_change_event() { // otherwise. //////////////////////////////////////////////////////////////////// bool Lens:: -extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { - const LMatrix4 &projection_mat_inv = get_projection_mat_inv(); +do_extrude(const CData *cdata, + const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) const { + const LMatrix4 &projection_mat_inv = do_get_projection_mat_inv(cdata); { LVecBase4 full(point2d[0], point2d[1], -1.0f, 1.0f); full = projection_mat_inv.xform(full); @@ -1379,7 +1243,7 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co } //////////////////////////////////////////////////////////////////// -// Function: Lens::extrude_vec_impl +// Function: Lens::do_extrude_vec // Access: Protected, Virtual // Description: Given a 2-d point in the range (-1,1) in both // dimensions, where (0,0) is the center of the @@ -1408,13 +1272,13 @@ extrude_impl(const LPoint3 &point2d, LPoint3 &near_point, LPoint3 &far_point) co // otherwise. //////////////////////////////////////////////////////////////////// bool Lens:: -extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const { - vec = LVector3::forward(_cs) * get_lens_mat(); +do_extrude_vec(const CData *cdata, const LPoint3 &point2d, LVector3 &vec) const { + vec = LVector3::forward(cdata->_cs) * do_get_lens_mat(cdata); return true; } //////////////////////////////////////////////////////////////////// -// Function: Lens::project_impl +// Function: Lens::do_project // Access: Protected, Virtual // Description: Given a 3-d point in space, determine the 2-d point // this maps to, in the range (-1,1) in both dimensions, @@ -1432,8 +1296,8 @@ extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const { // or may not be meaningful). //////////////////////////////////////////////////////////////////// bool Lens:: -project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { - const LMatrix4 &projection_mat = get_projection_mat(); +do_project(const CData *cdata, const LPoint3 &point3d, LPoint3 &point2d) const { + const LMatrix4 &projection_mat = do_get_projection_mat(cdata); LVecBase4 full(point3d[0], point3d[1], point3d[2], 1.0f); full = projection_mat.xform(full); if (full[3] == 0.0f) { @@ -1449,111 +1313,111 @@ project_impl(const LPoint3 &point3d, LPoint3 &point2d) const { } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_film_size +// Function: Lens::do_compute_film_size // Access: Protected, Virtual // Description: Computes the size and shape of the film behind the // camera, based on the aspect ratio and fov. //////////////////////////////////////////////////////////////////// void Lens:: -compute_film_size() { - if ((_user_flags & (UF_min_fov | UF_focal_length)) == (UF_min_fov | UF_focal_length)) { +do_compute_film_size(CData *cdata) { + if ((cdata->_user_flags & (UF_min_fov | UF_focal_length)) == (UF_min_fov | UF_focal_length)) { // If we just have a min FOV and a focal length, that determines // the smaller of the two film_sizes, and the larger is simply // chosen according to the aspect ratio. - PN_stdfloat fs = fov_to_film(_min_fov, _focal_length, true); - nassertv((_user_flags & UF_aspect_ratio) != 0 || - (_comp_flags & CF_aspect_ratio) != 0); + PN_stdfloat fs = fov_to_film(cdata->_min_fov, cdata->_focal_length, true); + nassertv((cdata->_user_flags & UF_aspect_ratio) != 0 || + (cdata->_comp_flags & CF_aspect_ratio) != 0); - if (_aspect_ratio < 1.0f) { - _film_size[1] = fs / _aspect_ratio; - _film_size[0] = fs; + if (cdata->_aspect_ratio < 1.0f) { + cdata->_film_size[1] = fs / cdata->_aspect_ratio; + cdata->_film_size[0] = fs; } else { - _film_size[0] = fs * _aspect_ratio; - _film_size[1] = fs; + cdata->_film_size[0] = fs * cdata->_aspect_ratio; + cdata->_film_size[1] = fs; } } else { - if ((_user_flags & UF_film_width) == 0) { - if ((_user_flags & (UF_hfov | UF_focal_length)) == (UF_hfov | UF_focal_length)) { - _film_size[0] = fov_to_film(_fov[0], _focal_length, true); + if ((cdata->_user_flags & UF_film_width) == 0) { + if ((cdata->_user_flags & (UF_hfov | UF_focal_length)) == (UF_hfov | UF_focal_length)) { + cdata->_film_size[0] = fov_to_film(cdata->_fov[0], cdata->_focal_length, true); } else { - _film_size[0] = 1.0f; + cdata->_film_size[0] = 1.0f; } } - if ((_user_flags & UF_film_height) == 0) { - if ((_user_flags & (UF_vfov | UF_focal_length)) == (UF_vfov | UF_focal_length)) { - _film_size[1] = fov_to_film(_fov[1], _focal_length, false); + if ((cdata->_user_flags & UF_film_height) == 0) { + if ((cdata->_user_flags & (UF_vfov | UF_focal_length)) == (UF_vfov | UF_focal_length)) { + cdata->_film_size[1] = fov_to_film(cdata->_fov[1], cdata->_focal_length, false); - } else if ((_user_flags & (UF_hfov | UF_vfov)) == (UF_hfov | UF_vfov)) { + } else if ((cdata->_user_flags & (UF_hfov | UF_vfov)) == (UF_hfov | UF_vfov)) { // If we don't have a focal length, but we have an explicit vfov // and hfov, we can infer the focal length is whatever makes the // film width, above, be what it is. - if ((_comp_flags & CF_focal_length) == 0) { - _focal_length = fov_to_focal_length(_fov[0], _film_size[0], true); - adjust_comp_flags(0, CF_focal_length); + if ((cdata->_comp_flags & CF_focal_length) == 0) { + cdata->_focal_length = fov_to_focal_length(cdata->_fov[0], cdata->_film_size[0], true); + do_adjust_comp_flags(cdata, 0, CF_focal_length); } - _film_size[1] = fov_to_film(_fov[1], _focal_length, false); + cdata->_film_size[1] = fov_to_film(cdata->_fov[1], cdata->_focal_length, false); - } else if ((_user_flags & UF_aspect_ratio) != 0 || - (_comp_flags & CF_aspect_ratio) != 0) { - _film_size[1] = _film_size[0] / _aspect_ratio; + } else if ((cdata->_user_flags & UF_aspect_ratio) != 0 || + (cdata->_comp_flags & CF_aspect_ratio) != 0) { + cdata->_film_size[1] = cdata->_film_size[0] / cdata->_aspect_ratio; } else { // Default is an aspect ratio of 1. - _film_size[1] = _film_size[0]; + cdata->_film_size[1] = cdata->_film_size[0]; } } } - adjust_comp_flags(0, CF_film_size); + do_adjust_comp_flags(cdata, 0, CF_film_size); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_focal_length +// Function: Lens::do_compute_focal_length // Access: Protected, Virtual // Description: Computes the focal length of the lens, based on the // fov and film size. This is based on the horizontal // dimension. //////////////////////////////////////////////////////////////////// void Lens:: -compute_focal_length() { - if ((_user_flags & UF_focal_length) == 0) { - const LVecBase2 &film_size = get_film_size(); - const LVecBase2 &fov = get_fov(); - _focal_length = fov_to_focal_length(fov[0], film_size[0], true); +do_compute_focal_length(CData *cdata) { + if ((cdata->_user_flags & UF_focal_length) == 0) { + const LVecBase2 &film_size = do_get_film_size(cdata); + const LVecBase2 &fov = do_get_fov(cdata); + cdata->_focal_length = fov_to_focal_length(fov[0], film_size[0], true); } - adjust_comp_flags(0, CF_focal_length); + do_adjust_comp_flags(cdata, 0, CF_focal_length); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_fov +// Function: Lens::do_compute_fov // Access: Protected, Virtual // Description: Computes the field of view of the lens, based on the // film size and focal length. //////////////////////////////////////////////////////////////////// void Lens:: -compute_fov() { - const LVecBase2 &film_size = get_film_size(); +do_compute_fov(CData *cdata) { + const LVecBase2 &film_size = do_get_film_size(cdata); - bool got_hfov = ((_user_flags & UF_hfov) != 0); - bool got_vfov = ((_user_flags & UF_vfov) != 0); - bool got_min_fov = ((_user_flags & UF_min_fov) != 0); + bool got_hfov = ((cdata->_user_flags & UF_hfov) != 0); + bool got_vfov = ((cdata->_user_flags & UF_vfov) != 0); + bool got_min_fov = ((cdata->_user_flags & UF_min_fov) != 0); if (!got_hfov && !got_vfov && !got_min_fov) { // If the user hasn't specified any FOV, we have to compute it. - if ((_user_flags & UF_focal_length) != 0) { + if ((cdata->_user_flags & UF_focal_length) != 0) { // The FOV is determined from the film size and focal length. - _fov[0] = film_to_fov(film_size[0], _focal_length, true); - _fov[1] = film_to_fov(film_size[1], _focal_length, true); + cdata->_fov[0] = film_to_fov(film_size[0], cdata->_focal_length, true); + cdata->_fov[1] = film_to_fov(film_size[1], cdata->_focal_length, true); got_hfov = true; got_vfov = true; } else { // We can't compute the FOV; take the default. - _min_fov = default_fov; + cdata->_min_fov = default_fov; got_min_fov = true; } } @@ -1562,179 +1426,177 @@ compute_fov() { // If we have just a min_fov, use it to derive whichever fov is // smaller. if (film_size[0] < film_size[1]) { - _fov[0] = _min_fov; + cdata->_fov[0] = cdata->_min_fov; got_hfov = true; } else { - _fov[1] = _min_fov; + cdata->_fov[1] = cdata->_min_fov; got_vfov = true; } } // Now compute whichever fov is remaining. if (!got_hfov) { - if ((_user_flags & UF_focal_length) == 0 && - (_comp_flags & CF_focal_length) == 0) { + if ((cdata->_user_flags & UF_focal_length) == 0 && + (cdata->_comp_flags & CF_focal_length) == 0) { // If we don't have an explicit focal length, we can infer it // from the above. nassertv(got_vfov); - _focal_length = fov_to_focal_length(_fov[1], film_size[1], true); - adjust_comp_flags(0, CF_focal_length); + cdata->_focal_length = fov_to_focal_length(cdata->_fov[1], film_size[1], true); + do_adjust_comp_flags(cdata, 0, CF_focal_length); } - _fov[0] = film_to_fov(film_size[0], _focal_length, false); + cdata->_fov[0] = film_to_fov(film_size[0], cdata->_focal_length, false); got_hfov = true; } if (!got_vfov) { - if ((_user_flags & UF_focal_length) == 0 && - (_comp_flags & CF_focal_length) == 0) { + if ((cdata->_user_flags & UF_focal_length) == 0 && + (cdata->_comp_flags & CF_focal_length) == 0) { // If we don't have an explicit focal length, we can infer it // from the above. nassertv(got_hfov); - _focal_length = fov_to_focal_length(_fov[0], film_size[0], true); - adjust_comp_flags(0, CF_focal_length); + cdata->_focal_length = fov_to_focal_length(cdata->_fov[0], film_size[0], true); + do_adjust_comp_flags(cdata, 0, CF_focal_length); } - _fov[1] = film_to_fov(film_size[1], _focal_length, false); + cdata->_fov[1] = film_to_fov(film_size[1], cdata->_focal_length, false); got_vfov = true; } if (!got_min_fov) { - _min_fov = film_size[0] < film_size[1] ? _fov[0] : _fov[1]; + cdata->_min_fov = film_size[0] < film_size[1] ? cdata->_fov[0] : cdata->_fov[1]; got_min_fov = true; } nassertv(got_hfov && got_vfov && got_min_fov); - adjust_comp_flags(0, CF_fov); + do_adjust_comp_flags(cdata, 0, CF_fov); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_aspect_ratio +// Function: Lens::do_compute_aspect_ratio // Access: Protected, Virtual // Description: Computes the aspect ratio of the film rectangle, as a // ratio of width to height. //////////////////////////////////////////////////////////////////// void Lens:: -compute_aspect_ratio() { - if ((_user_flags & UF_aspect_ratio) == 0) { - const LVecBase2 &film_size = get_film_size(); +do_compute_aspect_ratio(CData *cdata) { + if ((cdata->_user_flags & UF_aspect_ratio) == 0) { + const LVecBase2 &film_size = do_get_film_size(cdata); if (film_size[1] == 0.0f) { - _aspect_ratio = 1.0f; + cdata->_aspect_ratio = 1.0f; } else { - _aspect_ratio = film_size[0] / film_size[1]; + cdata->_aspect_ratio = film_size[0] / film_size[1]; } } - adjust_comp_flags(0, CF_aspect_ratio); + do_adjust_comp_flags(cdata, 0, CF_aspect_ratio); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_view_hpr +// Function: Lens::do_compute_view_hpr // Access: Protected, Virtual // Description: Computes the Euler angles representing the lens' // rotation. //////////////////////////////////////////////////////////////////// void Lens:: -compute_view_hpr() { - if ((_user_flags & UF_view_hpr) == 0) { - const LMatrix4 &view_mat = get_view_mat(); +do_compute_view_hpr(CData *cdata) { + if ((cdata->_user_flags & UF_view_hpr) == 0) { + const LMatrix4 &view_mat = do_get_view_mat(cdata); LVecBase3 scale, shear, translate; - decompose_matrix(view_mat, scale, shear, _view_hpr, translate, _cs); + decompose_matrix(view_mat, scale, shear, cdata->_view_hpr, translate, cdata->_cs); } - adjust_comp_flags(0, CF_view_hpr); + do_adjust_comp_flags(cdata, 0, CF_view_hpr); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_view_vector +// Function: Lens::do_compute_view_vector // Access: Protected, Virtual // Description: Computes the view vector and up vector for the lens. //////////////////////////////////////////////////////////////////// void Lens:: -compute_view_vector() { - if ((_user_flags & UF_view_vector) == 0) { - const LMatrix4 &view_mat = get_view_mat(); - _view_vector = LVector3::forward(_cs) * view_mat; - _up_vector = LVector3::up(_cs) * view_mat; +do_compute_view_vector(CData *cdata) { + if ((cdata->_user_flags & UF_view_vector) == 0) { + const LMatrix4 &view_mat = do_get_view_mat(cdata); + cdata->_view_vector = LVector3::forward(cdata->_cs) * view_mat; + cdata->_up_vector = LVector3::up(cdata->_cs) * view_mat; } - adjust_comp_flags(0, CF_view_vector); + do_adjust_comp_flags(cdata, 0, CF_view_vector); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_projection_mat +// Function: Lens::do_compute_projection_mat // Access: Protected, Virtual // Description: Computes the complete transformation matrix from 3-d // point to 2-d point, if the lens is linear. //////////////////////////////////////////////////////////////////// void Lens:: -compute_projection_mat() { - _projection_mat = - _projection_mat_left = - _projection_mat_right = - _projection_mat_inv = - _projection_mat_left_inv = - _projection_mat_right_inv = +do_compute_projection_mat(CData *cdata) { + cdata->_projection_mat = + cdata->_projection_mat_left = + cdata->_projection_mat_right = + cdata->_projection_mat_inv = + cdata->_projection_mat_left_inv = + cdata->_projection_mat_right_inv = LMatrix4::ident_mat(); - adjust_comp_flags(0, CF_projection_mat | CF_projection_mat_inv | - CF_projection_mat_left_inv |CF_projection_mat_right_inv); + do_adjust_comp_flags(cdata, 0, CF_projection_mat | CF_projection_mat_inv | + CF_projection_mat_left_inv |CF_projection_mat_right_inv); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_film_mat +// Function: Lens::do_compute_film_mat // Access: Protected, Virtual // Description: Computes the matrix that transforms from a point // behind the lens to a point on the film. //////////////////////////////////////////////////////////////////// void Lens:: -compute_film_mat() { +do_compute_film_mat(CData *cdata) { // The lens will return a point in the range [-film_size/2, // film_size/2] in each dimension. Convert this to [-1, 1], and // also apply the offset. // We declare these two as local variables, instead of references, // to work around a VC7 compiler bug. - LVecBase2 film_size = get_film_size(); - LVector2 film_offset = get_film_offset(); + LVecBase2 film_size = do_get_film_size(cdata); + LVector2 film_offset = do_get_film_offset(cdata); PN_stdfloat scale_x = 2.0f / film_size[0]; PN_stdfloat scale_y = 2.0f / film_size[1]; - _film_mat.set(scale_x, 0.0f, 0.0f, 0.0f, + cdata->_film_mat.set(scale_x, 0.0f, 0.0f, 0.0f, 0.0f, scale_y, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -film_offset[0] * scale_x, -film_offset[1] * scale_y, 0.0f, 1.0f); - if ((_user_flags & UF_keystone) != 0) { - _film_mat = LMatrix4(1.0f, 0.0f, _keystone[0], _keystone[0], - 0.0f, 1.0f, _keystone[1], _keystone[1], + if ((cdata->_user_flags & UF_keystone) != 0) { + cdata->_film_mat = LMatrix4(1.0f, 0.0f, cdata->_keystone[0], cdata->_keystone[0], + 0.0f, 1.0f, cdata->_keystone[1], cdata->_keystone[1], 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f) * _film_mat; + 0.0f, 0.0f, 0.0f, 1.0f) * cdata->_film_mat; } - adjust_comp_flags(CF_film_mat_inv, - CF_film_mat); + do_adjust_comp_flags(cdata, CF_film_mat_inv, CF_film_mat); } //////////////////////////////////////////////////////////////////// -// Function: Lens::compute_lens_mat +// Function: Lens::do_compute_lens_mat // Access: Protected, Virtual // Description: Computes the matrix that transforms from a point // in front of the lens to a point in space. //////////////////////////////////////////////////////////////////// void Lens:: -compute_lens_mat() { - if ((_user_flags & UF_view_mat) == 0) { - if ((_user_flags & UF_view_hpr) != 0) { - compose_matrix(_lens_mat, +do_compute_lens_mat(CData *cdata) { + if ((cdata->_user_flags & UF_view_mat) == 0) { + if ((cdata->_user_flags & UF_view_hpr) != 0) { + compose_matrix(cdata->_lens_mat, LVecBase3(1.0f, 1.0f, 1.0f), LVecBase3(0.0f, 0.0f, 0.0f), - _view_hpr, - LVecBase3(0.0f, 0.0f, 0.0f), _cs); + cdata->_view_hpr, + LVecBase3(0.0f, 0.0f, 0.0f), cdata->_cs); - } else if ((_user_flags & UF_view_vector) != 0) { - look_at(_lens_mat, _view_vector, _up_vector, _cs); + } else if ((cdata->_user_flags & UF_view_vector) != 0) { + look_at(cdata->_lens_mat, cdata->_view_vector, cdata->_up_vector, cdata->_cs); } else { - _lens_mat = LMatrix4::ident_mat(); + cdata->_lens_mat = LMatrix4::ident_mat(); } } - adjust_comp_flags(CF_lens_mat_inv, - CF_lens_mat); + do_adjust_comp_flags(cdata, CF_lens_mat_inv, CF_lens_mat); } //////////////////////////////////////////////////////////////////// @@ -1780,7 +1642,7 @@ film_to_fov(PN_stdfloat, PN_stdfloat, bool) const { } //////////////////////////////////////////////////////////////////// -// Function: Lens::resequence_fov_triad +// Function: Lens::do_resequence_fov_triad // Access: Private // Description: Called whenever the user changes one of the three FOV // parameters: fov, focal length, or film size. This @@ -1794,7 +1656,7 @@ film_to_fov(PN_stdfloat, PN_stdfloat, bool) const { // this third value which should be discarded. //////////////////////////////////////////////////////////////////// void Lens:: -resequence_fov_triad(char &newest, char &older_a, char &older_b) const { +do_resequence_fov_triad(const CData *cdata, char &newest, char &older_a, char &older_b) const { nassertv(newest + older_a + older_b == 3); switch (newest) { case 0: @@ -1829,15 +1691,15 @@ resequence_fov_triad(char &newest, char &older_a, char &older_b) const { if (gobj_cat.is_debug()) { gobj_cat.debug() - << "Lens.resequence_fov_triad():"; + << "Lens.do_resequence_fov_triad():"; for (int i = 2; i >= 0; --i) { - if (_fov_seq == i) { + if (cdata->_fov_seq == i) { gobj_cat.debug(false) << " fov"; - } else if (_focal_length_seq == i) { + } else if (cdata->_focal_length_seq == i) { gobj_cat.debug(false) << " focal_length"; - } else if (_film_size_seq == i) { + } else if (cdata->_film_size_seq == i) { gobj_cat.debug(false) << " film_size"; } @@ -1848,7 +1710,7 @@ resequence_fov_triad(char &newest, char &older_a, char &older_b) const { } //////////////////////////////////////////////////////////////////// -// Function: Lens::define_geom_data +// Function: Lens::do_define_geom_data // Access: Private // Description: Adjusts (or defines for the first time) all the // vertices in the _geom_data to match the properties of @@ -1858,19 +1720,19 @@ resequence_fov_triad(char &newest, char &older_a, char &older_b) const { // edge. //////////////////////////////////////////////////////////////////// int Lens:: -define_geom_data() { +do_define_geom_data(CData *cdata) { int num_segments = 1; if (!is_linear()) { num_segments = 10; } - if (_geom_data == (GeomVertexData *)NULL) { - _geom_data = new GeomVertexData + if (cdata->_geom_data == (GeomVertexData *)NULL) { + cdata->_geom_data = new GeomVertexData ("lens", GeomVertexFormat::get_v3(), Geom::UH_dynamic); } - GeomVertexWriter vertex(_geom_data, InternalName::get_vertex()); + GeomVertexWriter vertex(cdata->_geom_data, InternalName::get_vertex()); LPoint3 near_point, far_point; for (int si = 0; si < num_segments; si++) { PN_stdfloat t = 2.0f * (PN_stdfloat)si / (PN_stdfloat)num_segments; @@ -1913,9 +1775,9 @@ define_geom_data() { } // Finally, add one more pair for the viewing axis. - LPoint3 near_axis = LPoint3::origin(_cs) + LVector3::forward(_cs) * _near_distance; - LPoint3 far_axis = LPoint3::origin(_cs) + LVector3::forward(_cs) * _far_distance; - const LMatrix4 &lens_mat = get_lens_mat(); + LPoint3 near_axis = LPoint3::origin(cdata->_cs) + LVector3::forward(cdata->_cs) * cdata->_near_distance; + LPoint3 far_axis = LPoint3::origin(cdata->_cs) + LVector3::forward(cdata->_cs) * cdata->_far_distance; + const LMatrix4 &lens_mat = do_get_lens_mat(cdata); near_axis = near_axis * lens_mat; far_axis = far_axis * lens_mat; vertex.add_data3(near_axis); @@ -2106,7 +1968,83 @@ sqr_dist_to_line(const LPoint3 &point, const LPoint3 &origin, void Lens:: write_datagram(BamWriter *manager, Datagram &dg) { TypedWritable::write_datagram(manager, dg); + manager->write_cdata(dg, _cycler); +} +//////////////////////////////////////////////////////////////////// +// Function: Lens::fillin +// Access: Protected +// Description: This internal function is called by make_from_bam to +// read in all of the relevant data from the BamFile for +// the new Lens. +//////////////////////////////////////////////////////////////////// +void Lens:: +fillin(DatagramIterator &scan, BamReader *manager) { + TypedWritable::fillin(scan, manager); + manager->read_cdata(scan, _cycler); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::CData::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +Lens::CData:: +CData() { + clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::CData::Copy Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +Lens::CData:: +CData(const Lens::CData ©) { + _change_event = copy._change_event; + _cs = copy._cs; + _film_size = copy._film_size; + _film_offset = copy._film_offset; + _focal_length = copy._focal_length; + _fov = copy._fov; + _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; + + _focal_length_seq = copy._focal_length_seq; + _fov_seq = copy._fov_seq; + _film_size_seq = copy._film_size_seq; + + _geom_data = copy._geom_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::CData::make_copy +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CycleData *Lens::CData:: +make_copy() const { + return new CData(*this); +} + +//////////////////////////////////////////////////////////////////// +// Function: Lens::CData::write_datagram +// Access: Public, Virtual +// Description: Writes the contents of this object to the datagram +// for shipping out to a Bam file. +//////////////////////////////////////////////////////////////////// +void Lens::CData:: +write_datagram(BamWriter *manager, Datagram &dg) const { dg.add_string(_change_event); dg.add_uint8((int)_cs); _film_size.write_datagram(dg); @@ -2120,16 +2058,14 @@ write_datagram(BamWriter *manager, Datagram &dg) { } //////////////////////////////////////////////////////////////////// -// Function: Lens::fillin -// Access: Protected +// Function: Lens::CData::fillin +// Access: Public, Virtual // Description: This internal function is called by make_from_bam to // read in all of the relevant data from the BamFile for -// the new Lens. +// the new Geom. //////////////////////////////////////////////////////////////////// -void Lens:: +void Lens::CData:: fillin(DatagramIterator &scan, BamReader *manager) { - TypedWritable::fillin(scan, manager); - _change_event = scan.get_string(); _cs = (CoordinateSystem)scan.get_uint8(); _film_size.read_datagram(scan); @@ -2143,3 +2079,41 @@ fillin(DatagramIterator &scan, BamReader *manager) { _comp_flags = 0; } + +//////////////////////////////////////////////////////////////////// +// Function: Lens::CData::clear +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void Lens::CData:: +clear() { + _change_event = ""; + _cs = CS_default; + _film_size.set(1.0f, 1.0f); + _film_offset.set(0.0f, 0.0f); + _focal_length = 1.0f; + _fov.set(default_fov, default_fov); + _aspect_ratio = 1.0f; + _near_distance = default_near; + _far_distance = default_far; + _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); + _keystone.set(0.0f, 0.0f); + + _user_flags = 0; + _comp_flags = CF_fov; + + _interocular_distance = 0.0; + _convergence_distance = 0.0; + + if (default_keystone.has_value()) { + _keystone.set(default_keystone[0], default_keystone[1]); + _user_flags |= UF_keystone; + } + + // Assign an initial arbitrary sequence to these three. + _film_size_seq = 0; + _focal_length_seq = 1; + _fov_seq = 2; +} diff --git a/panda/src/gobj/lens.h b/panda/src/gobj/lens.h index 3c72cb02a9..9b84341bdd 100644 --- a/panda/src/gobj/lens.h +++ b/panda/src/gobj/lens.h @@ -23,6 +23,10 @@ #include "updateSeq.h" #include "geomVertexData.h" #include "pointerTo.h" +#include "cycleData.h" +#include "cycleDataReader.h" +#include "cycleDataWriter.h" +#include "pipelineCycler.h" class BoundingVolume; @@ -32,11 +36,11 @@ class BoundingVolume; // lenses, linear and otherwise. Presently, this // includes perspective and orthographic lenses. // -// A Lens object is the main part of a Camera node -// (defined in sgraph), which defines the fundamental -// interface to point-of-view for rendering. Lenses are -// also used in other contexts, however; for instance, a -// Spotlight is also defined using a lens. +// A Lens object is the main part of a Camera node, +// which defines the fundamental interface to +// point-of-view for rendering. Lenses are also used in +// other contexts, however; for instance, a Spotlight is +// also defined using a lens. //////////////////////////////////////////////////////////////////// class EXPCL_PANDA_GOBJ Lens : public TypedWritableReferenceCount { public: @@ -71,29 +75,29 @@ PUBLISHED: void clear(); - void set_film_size(PN_stdfloat width); + INLINE void set_film_size(PN_stdfloat width); INLINE void set_film_size(PN_stdfloat width, PN_stdfloat height); - void set_film_size(const LVecBase2 &film_size); - const LVecBase2 &get_film_size() const; + INLINE void set_film_size(const LVecBase2 &film_size); + INLINE const LVecBase2 &get_film_size() const; INLINE void set_film_offset(PN_stdfloat x, PN_stdfloat y); INLINE void set_film_offset(const LVecBase2 &film_offset); INLINE const LVector2 &get_film_offset() const; - void set_focal_length(PN_stdfloat focal_length); - PN_stdfloat get_focal_length() const; + INLINE void set_focal_length(PN_stdfloat focal_length); + INLINE PN_stdfloat get_focal_length() const; void set_min_fov(PN_stdfloat min_fov); - void set_fov(PN_stdfloat fov); + INLINE void set_fov(PN_stdfloat fov); INLINE void set_fov(PN_stdfloat hfov, PN_stdfloat vfov); - void set_fov(const LVecBase2 &fov); - const LVecBase2 &get_fov() const; + INLINE void set_fov(const LVecBase2 &fov); + INLINE const LVecBase2 &get_fov() const; INLINE PN_stdfloat get_hfov() const; INLINE PN_stdfloat get_vfov() const; PN_stdfloat get_min_fov() const; - void set_aspect_ratio(PN_stdfloat aspect_ratio); - PN_stdfloat get_aspect_ratio() const; + INLINE void set_aspect_ratio(PN_stdfloat aspect_ratio); + INLINE PN_stdfloat get_aspect_ratio() const; INLINE void set_near(PN_stdfloat near_distance); INLINE PN_stdfloat get_near() const; @@ -113,13 +117,13 @@ PUBLISHED: const LVector3 &get_up_vector() const; LPoint3 get_nodal_point() const; - void set_interocular_distance(PN_stdfloat interocular_distance); - PN_stdfloat get_interocular_distance() const; - void set_convergence_distance(PN_stdfloat convergence_distance); - PN_stdfloat get_convergence_distance() const; + INLINE void set_interocular_distance(PN_stdfloat interocular_distance); + INLINE PN_stdfloat get_interocular_distance() const; + INLINE void set_convergence_distance(PN_stdfloat convergence_distance); + INLINE PN_stdfloat get_convergence_distance() const; - void set_view_mat(const LMatrix4 &view_mat); - const LMatrix4 &get_view_mat() const; + INLINE void set_view_mat(const LMatrix4 &view_mat); + INLINE const LMatrix4 &get_view_mat() const; void clear_view_mat(); void set_keystone(const LVecBase2 &keystone); @@ -150,14 +154,14 @@ PUBLISHED: virtual PT(BoundingVolume) make_bounds() const; - const LMatrix4 &get_projection_mat(StereoChannel channel = SC_mono) const; - const LMatrix4 &get_projection_mat_inv(StereoChannel channel = SC_mono) const; + INLINE const LMatrix4 &get_projection_mat(StereoChannel channel = SC_mono) const; + INLINE const LMatrix4 &get_projection_mat_inv(StereoChannel channel = SC_mono) const; - const LMatrix4 &get_film_mat() const; - const LMatrix4 &get_film_mat_inv() const; + INLINE const LMatrix4 &get_film_mat() const; + INLINE const LMatrix4 &get_film_mat_inv() const; - const LMatrix4 &get_lens_mat() const; - const LMatrix4 &get_lens_mat_inv() const; + INLINE const LMatrix4 &get_lens_mat() const; + INLINE const LMatrix4 &get_lens_mat_inv() const; virtual void output(ostream &out) const; virtual void write(ostream &out, int indent_level = 0) const; @@ -166,64 +170,83 @@ public: INLINE const UpdateSeq &get_last_change() const; protected: - INLINE void adjust_user_flags(int clear_flags, int set_flags); - INLINE void adjust_comp_flags(int clear_flags, int set_flags); + class CData; - void throw_change_event(); + INLINE void do_adjust_user_flags(CData *cdata, int clear_flags, int set_flags); + INLINE void do_adjust_comp_flags(CData *cdata, int clear_flags, int set_flags); - virtual bool extrude_impl(const LPoint3 &point2d, - LPoint3 &near_point, LPoint3 &far_point) const; - virtual bool extrude_vec_impl(const LPoint3 &point2d, LVector3 &vec) const; - virtual bool project_impl(const LPoint3 &point3d, LPoint3 &point2d) const; + void do_set_film_size(CData *cdata, PN_stdfloat width); + void do_set_film_size(CData *cdata, const LVecBase2 &film_size); + const LVecBase2 &do_get_film_size(const CData *cdata) const; - virtual void compute_film_size(); - virtual void compute_focal_length(); - virtual void compute_fov(); - virtual void compute_aspect_ratio(); - virtual void compute_view_hpr(); - virtual void compute_view_vector(); - virtual void compute_projection_mat(); - virtual void compute_film_mat(); - virtual void compute_lens_mat(); + INLINE void do_set_film_offset(CData *cdata, const LVecBase2 &film_offset); + INLINE const LVector2 &do_get_film_offset(const CData *cdata) const; + + void do_set_focal_length(CData *cdata, PN_stdfloat focal_length); + PN_stdfloat do_get_focal_length(const CData *cdata) const; + + void do_set_fov(CData *cdata, PN_stdfloat fov); + void do_set_fov(CData *cdata, const LVecBase2 &fov); + const LVecBase2 &do_get_fov(const CData *cdata) const; + + void do_set_aspect_ratio(CData *cdata, PN_stdfloat aspect_ratio); + PN_stdfloat do_get_aspect_ratio(const CData *cdata) const; + + INLINE void do_set_near(CData *cdata, PN_stdfloat near_distance); + INLINE PN_stdfloat do_get_near(const CData *cdata) const; + INLINE void do_set_far(CData *cdata, PN_stdfloat far_distance); + INLINE PN_stdfloat do_get_far(const CData *cdata) const; + INLINE void do_set_near_far(CData *cdata, PN_stdfloat near_distance, PN_stdfloat far_distance); + + const LMatrix4 &do_get_projection_mat(const CData *cdata, StereoChannel channel = SC_mono) const; + const LMatrix4 &do_get_projection_mat_inv(const CData *cdata, StereoChannel channel = SC_mono) const; + + const LMatrix4 &do_get_film_mat(const CData *cdata) const; + const LMatrix4 &do_get_film_mat_inv(const CData *cdata) const; + + const LMatrix4 &do_get_lens_mat(const CData *cdata) const; + const LMatrix4 &do_get_lens_mat_inv(const CData *cdata) const; + + void do_set_interocular_distance(CData *cdata, PN_stdfloat interocular_distance); + void do_set_convergence_distance(CData *cdata, PN_stdfloat convergence_distance); + + void do_set_view_mat(CData *cdata, const LMatrix4 &view_mat); + const LMatrix4 &do_get_view_mat(const CData *cdata) const; + + void do_throw_change_event(CData *cdata); + + virtual bool do_extrude(const CData *cdata, const LPoint3 &point2d, + LPoint3 &near_point, LPoint3 &far_point) const; + virtual bool do_extrude_vec(const CData *cdata, + const LPoint3 &point2d, LVector3 &vec) const; + virtual bool do_project(const CData *cdata, + const LPoint3 &point3d, LPoint3 &point2d) const; + + virtual void do_compute_film_size(CData *cdata); + virtual void do_compute_focal_length(CData *cdata); + virtual void do_compute_fov(CData *cdata); + virtual void do_compute_aspect_ratio(CData *cdata); + virtual void do_compute_view_hpr(CData *cdata); + virtual void do_compute_view_vector(CData *cdata); + virtual void do_compute_projection_mat(CData *cdata); + virtual void do_compute_film_mat(CData *cdata); + virtual void do_compute_lens_mat(CData *cdata); virtual PN_stdfloat fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool horiz) const; virtual PN_stdfloat fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool horiz) const; virtual PN_stdfloat film_to_fov(PN_stdfloat film_size, PN_stdfloat focal_length, bool horiz) const; private: - void resequence_fov_triad(char &newest, char &older_a, char &older_b) const; - int define_geom_data(); + void do_resequence_fov_triad(const CData *cdata, + char &newest, char &older_a, char &older_b) const; + int do_define_geom_data(CData *cdata); static void build_shear_mat(LMatrix4 &shear_mat, const LPoint3 &cul, const LPoint3 &cur, const LPoint3 &cll, const LPoint3 &clr); static PN_stdfloat sqr_dist_to_line(const LPoint3 &point, const LPoint3 &origin, - const LVector3 &vec); + const LVector3 &vec); protected: - string _change_event; - UpdateSeq _last_change; - CoordinateSystem _cs; - - LVecBase2 _film_size; - LVector2 _film_offset; - PN_stdfloat _focal_length; - LVecBase2 _fov; - PN_stdfloat _min_fov; - PN_stdfloat _aspect_ratio; - PN_stdfloat _near_distance, _far_distance; - - LVecBase3 _view_hpr; - LVector3 _view_vector, _up_vector; - PN_stdfloat _interocular_distance; - PN_stdfloat _convergence_distance; - LVecBase2 _keystone; - - LMatrix4 _film_mat, _film_mat_inv; - LMatrix4 _lens_mat, _lens_mat_inv; - LMatrix4 _projection_mat, _projection_mat_inv; - LMatrix4 _projection_mat_left, _projection_mat_left_inv; - LMatrix4 _projection_mat_right, _projection_mat_right_inv; - enum UserFlags { // Parameters the user may have explicitly specified. UF_film_width = 0x0001, @@ -260,16 +283,72 @@ protected: CF_focal_length = 0x1000, CF_fov = 0x2000, }; - short _user_flags; - short _comp_flags; - // The user may only specify two of these three parameters. - // Specifying the third parameter wipes out the first one specified. - // We therefore need to remember the order in which the user has - // specified these three parameters. A bit of a mess. - char _focal_length_seq, _fov_seq, _film_size_seq; + // This is the data that must be cycled between pipeline stages. + class EXPCL_PANDA_GOBJ CData : public CycleData { + public: + CData(); + CData(const CData ©); + ALLOC_DELETED_CHAIN(CData); + virtual CycleData *make_copy() const; + virtual void write_datagram(BamWriter *manager, Datagram &dg) const; + virtual void fillin(DatagramIterator &scan, BamReader *manager); + virtual TypeHandle get_parent_type() const { + return Lens::get_class_type(); + } - PT(GeomVertexData) _geom_data; + void clear(); + + string _change_event; + UpdateSeq _last_change; + CoordinateSystem _cs; + + LVecBase2 _film_size; + LVector2 _film_offset; + PN_stdfloat _focal_length; + LVecBase2 _fov; + PN_stdfloat _min_fov; + PN_stdfloat _aspect_ratio; + PN_stdfloat _near_distance, _far_distance; + + LVecBase3 _view_hpr; + LVector3 _view_vector, _up_vector; + PN_stdfloat _interocular_distance; + PN_stdfloat _convergence_distance; + LVecBase2 _keystone; + + LMatrix4 _film_mat, _film_mat_inv; + LMatrix4 _lens_mat, _lens_mat_inv; + LMatrix4 _projection_mat, _projection_mat_inv; + LMatrix4 _projection_mat_left, _projection_mat_left_inv; + LMatrix4 _projection_mat_right, _projection_mat_right_inv; + + short _user_flags; + short _comp_flags; + + // The user may only specify two of these three parameters. + // Specifying the third parameter wipes out the first one specified. + // We therefore need to remember the order in which the user has + // specified these three parameters. A bit of a mess. + char _focal_length_seq, _fov_seq, _film_size_seq; + + PT(GeomVertexData) _geom_data; + + public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + register_type(_type_handle, "Lens::CData"); + } + + private: + static TypeHandle _type_handle; + }; + + PipelineCycler _cycler; + typedef CycleDataReader CDReader; + typedef CycleDataWriter CDWriter; public: virtual void write_datagram(BamWriter *manager, Datagram &dg); @@ -289,6 +368,7 @@ public: TypedWritableReferenceCount::init_type(); register_type(_type_handle, "Lens", TypedWritableReferenceCount::get_class_type()); + CData::init_type(); } private: diff --git a/panda/src/gobj/matrixLens.I b/panda/src/gobj/matrixLens.I index 00acbb0ab6..eef0806ad4 100644 --- a/panda/src/gobj/matrixLens.I +++ b/panda/src/gobj/matrixLens.I @@ -76,8 +76,9 @@ operator = (const MatrixLens ©) { //////////////////////////////////////////////////////////////////// INLINE void MatrixLens:: set_user_mat(const LMatrix4 &user_mat) { + Lens::CDWriter lens_cdata(Lens::_cycler, true); _user_mat = user_mat; - adjust_comp_flags(CF_mat, 0); + do_adjust_comp_flags(lens_cdata, CF_mat, 0); } //////////////////////////////////////////////////////////////////// @@ -108,9 +109,10 @@ get_user_mat() const { //////////////////////////////////////////////////////////////////// INLINE void MatrixLens:: set_left_eye_mat(const LMatrix4 &left_eye_mat) { + Lens::CDWriter lens_cdata(Lens::_cycler, true); _left_eye_mat = left_eye_mat; _ml_flags |= MF_has_left_eye; - adjust_comp_flags(CF_mat, 0); + do_adjust_comp_flags(lens_cdata, CF_mat, 0); } //////////////////////////////////////////////////////////////////// @@ -122,8 +124,9 @@ set_left_eye_mat(const LMatrix4 &left_eye_mat) { //////////////////////////////////////////////////////////////////// INLINE void MatrixLens:: clear_left_eye_mat() { + Lens::CDWriter lens_cdata(Lens::_cycler, true); _ml_flags &= ~MF_has_left_eye; - adjust_comp_flags(CF_mat, 0); + do_adjust_comp_flags(lens_cdata, CF_mat, 0); } //////////////////////////////////////////////////////////////////// @@ -170,9 +173,10 @@ get_left_eye_mat() const { //////////////////////////////////////////////////////////////////// INLINE void MatrixLens:: set_right_eye_mat(const LMatrix4 &right_eye_mat) { + Lens::CDWriter lens_cdata(Lens::_cycler, true); _right_eye_mat = right_eye_mat; _ml_flags |= MF_has_right_eye; - adjust_comp_flags(CF_mat, 0); + do_adjust_comp_flags(lens_cdata, CF_mat, 0); } //////////////////////////////////////////////////////////////////// @@ -184,8 +188,9 @@ set_right_eye_mat(const LMatrix4 &right_eye_mat) { //////////////////////////////////////////////////////////////////// INLINE void MatrixLens:: clear_right_eye_mat() { + Lens::CDWriter lens_cdata(Lens::_cycler, true); _ml_flags &= ~MF_has_right_eye; - adjust_comp_flags(CF_mat, 0); + do_adjust_comp_flags(lens_cdata, CF_mat, 0); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/matrixLens.cxx b/panda/src/gobj/matrixLens.cxx index ca702c8070..5d50a32501 100644 --- a/panda/src/gobj/matrixLens.cxx +++ b/panda/src/gobj/matrixLens.cxx @@ -54,29 +54,29 @@ write(ostream &out, int indent_level) const { } //////////////////////////////////////////////////////////////////// -// Function: MatrixLens::compute_projection_mat +// Function: MatrixLens::do_compute_projection_mat // Access: Protected, Virtual // Description: Computes the complete transformation matrix from 3-d // point to 2-d point, if the lens is linear. //////////////////////////////////////////////////////////////////// void MatrixLens:: -compute_projection_mat() { - _projection_mat = get_lens_mat_inv() * _user_mat * get_film_mat(); +do_compute_projection_mat(Lens::CData *lens_cdata) { + lens_cdata->_projection_mat = do_get_lens_mat_inv(lens_cdata) * _user_mat * do_get_film_mat(lens_cdata); if (_ml_flags & MF_has_left_eye) { - _projection_mat_left = get_lens_mat_inv() * _left_eye_mat * get_film_mat(); + lens_cdata->_projection_mat_left = do_get_lens_mat_inv(lens_cdata) * _left_eye_mat * do_get_film_mat(lens_cdata); } else { - _projection_mat_left = _projection_mat; + lens_cdata->_projection_mat_left = lens_cdata->_projection_mat; } if (_ml_flags & MF_has_right_eye) { - _projection_mat_right = get_lens_mat_inv() * _right_eye_mat * get_film_mat(); + lens_cdata->_projection_mat_right = do_get_lens_mat_inv(lens_cdata) * _right_eye_mat * do_get_film_mat(lens_cdata); } else { - _projection_mat_right = _projection_mat; + lens_cdata->_projection_mat_right = lens_cdata->_projection_mat; } - adjust_comp_flags(CF_projection_mat_inv, - CF_projection_mat); + do_adjust_comp_flags(lens_cdata, CF_projection_mat_inv, + CF_projection_mat); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/matrixLens.h b/panda/src/gobj/matrixLens.h index 1a1b7b992e..45f77a07ad 100644 --- a/panda/src/gobj/matrixLens.h +++ b/panda/src/gobj/matrixLens.h @@ -57,7 +57,7 @@ public: virtual void write(ostream &out, int indent_level = 0) const; protected: - virtual void compute_projection_mat(); + virtual void do_compute_projection_mat(Lens::CData *lens_cdata); private: LMatrix4 _user_mat; diff --git a/panda/src/gobj/orthographicLens.cxx b/panda/src/gobj/orthographicLens.cxx index 2a18e8840c..41d75613c9 100644 --- a/panda/src/gobj/orthographicLens.cxx +++ b/panda/src/gobj/orthographicLens.cxx @@ -65,20 +65,20 @@ write(ostream &out, int indent_level) const { } //////////////////////////////////////////////////////////////////// -// Function: OrthographicLens::compute_projection_mat +// Function: OrthographicLens::do_compute_projection_mat // Access: Protected, Virtual // Description: Computes the complete transformation matrix from 3-d // point to 2-d point, if the lens is linear. //////////////////////////////////////////////////////////////////// void OrthographicLens:: -compute_projection_mat() { - CoordinateSystem cs = _cs; +do_compute_projection_mat(Lens::CData *lens_cdata) { + CoordinateSystem cs = lens_cdata->_cs; if (cs == CS_default) { cs = get_default_coordinate_system(); } - PN_stdfloat a = 2.0f / (_far_distance - _near_distance); - PN_stdfloat b = -(_far_distance + _near_distance) / (_far_distance - _near_distance); + PN_stdfloat a = 2.0f / (lens_cdata->_far_distance - lens_cdata->_near_distance); + PN_stdfloat b = -(lens_cdata->_far_distance + lens_cdata->_near_distance) / (lens_cdata->_far_distance - lens_cdata->_near_distance); LMatrix4 canonical; switch (cs) { @@ -116,12 +116,12 @@ compute_projection_mat() { canonical = LMatrix4::ident_mat(); } - _projection_mat = get_lens_mat_inv() * canonical * get_film_mat(); - _projection_mat_left = _projection_mat_right = _projection_mat; + lens_cdata->_projection_mat = do_get_lens_mat_inv(lens_cdata) * canonical * do_get_film_mat(lens_cdata); + lens_cdata->_projection_mat_left = lens_cdata->_projection_mat_right = lens_cdata->_projection_mat; - adjust_comp_flags(CF_projection_mat_inv | CF_projection_mat_left_inv | - CF_projection_mat_right_inv, - CF_projection_mat); + do_adjust_comp_flags(lens_cdata, + CF_projection_mat_inv | CF_projection_mat_left_inv | CF_projection_mat_right_inv, + CF_projection_mat); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/orthographicLens.h b/panda/src/gobj/orthographicLens.h index 1a0fade64b..155b09424e 100644 --- a/panda/src/gobj/orthographicLens.h +++ b/panda/src/gobj/orthographicLens.h @@ -47,7 +47,7 @@ public: virtual void write(ostream &out, int indent_level = 0) const; protected: - virtual void compute_projection_mat(); + virtual void do_compute_projection_mat(Lens::CData *lens_cdata); public: static void register_with_read_factory(); diff --git a/panda/src/gobj/perspectiveLens.I b/panda/src/gobj/perspectiveLens.I index 1deb077c3c..8b3c08498f 100644 --- a/panda/src/gobj/perspectiveLens.I +++ b/panda/src/gobj/perspectiveLens.I @@ -28,7 +28,8 @@ PerspectiveLens() { //////////////////////////////////////////////////////////////////// INLINE PerspectiveLens:: PerspectiveLens(PN_stdfloat hfov, PN_stdfloat vfov) { - _fov.set(hfov, vfov); + Lens::CDWriter lens_cdata(Lens::_cycler, true); + lens_cdata->_fov.set(hfov, vfov); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/perspectiveLens.cxx b/panda/src/gobj/perspectiveLens.cxx index 5ef9b7dbcd..8a0d76bfef 100644 --- a/panda/src/gobj/perspectiveLens.cxx +++ b/panda/src/gobj/perspectiveLens.cxx @@ -54,21 +54,21 @@ is_perspective() const { } //////////////////////////////////////////////////////////////////// -// Function: PerspectiveLens::compute_projection_mat +// Function: PerspectiveLens::do_compute_projection_mat // Access: Protected, Virtual // Description: Computes the complete transformation matrix from 3-d // point to 2-d point, if the lens is linear. //////////////////////////////////////////////////////////////////// void PerspectiveLens:: -compute_projection_mat() { - CoordinateSystem cs = _cs; +do_compute_projection_mat(Lens::CData *lens_cdata) { + CoordinateSystem cs = lens_cdata->_cs; if (cs == CS_default) { cs = get_default_coordinate_system(); } - PN_stdfloat fl = get_focal_length(); - PN_stdfloat fFar = get_far(); - PN_stdfloat fNear = get_near(); + PN_stdfloat fl = do_get_focal_length(lens_cdata); + PN_stdfloat fFar = do_get_far(lens_cdata); + PN_stdfloat fNear = do_get_near(lens_cdata); PN_stdfloat far_minus_near = fFar-fNear; PN_stdfloat a = (fFar + fNear); PN_stdfloat b = -2.0f * fFar * fNear; @@ -112,30 +112,30 @@ compute_projection_mat() { canonical = LMatrix4::ident_mat(); } - _projection_mat = get_lens_mat_inv() * canonical * get_film_mat(); + lens_cdata->_projection_mat = do_get_lens_mat_inv(lens_cdata) * canonical * do_get_film_mat(lens_cdata); - if ((_user_flags & UF_interocular_distance) == 0) { - _projection_mat_left = _projection_mat_right = _projection_mat; + if ((lens_cdata->_user_flags & UF_interocular_distance) == 0) { + lens_cdata->_projection_mat_left = lens_cdata->_projection_mat_right = lens_cdata->_projection_mat; } else { // Compute the left and right projection matrices in case this // lens is assigned to a stereo DisplayRegion. - LVector3 iod = _interocular_distance * 0.5f * LVector3::left(_cs); - _projection_mat_left = get_lens_mat_inv() * LMatrix4::translate_mat(-iod) * canonical * get_film_mat(); - _projection_mat_right = get_lens_mat_inv() * LMatrix4::translate_mat(iod) * canonical * get_film_mat(); + LVector3 iod = lens_cdata->_interocular_distance * 0.5f * LVector3::left(lens_cdata->_cs); + lens_cdata->_projection_mat_left = do_get_lens_mat_inv(lens_cdata) * LMatrix4::translate_mat(-iod) * canonical * do_get_film_mat(lens_cdata); + lens_cdata->_projection_mat_right = do_get_lens_mat_inv(lens_cdata) * LMatrix4::translate_mat(iod) * canonical * do_get_film_mat(lens_cdata); - if (_user_flags & UF_convergence_distance) { - nassertv(_convergence_distance != 0.0f); - LVector3 cd = (0.25f / _convergence_distance) * LVector3::left(_cs); - _projection_mat_left *= LMatrix4::translate_mat(cd); - _projection_mat_right *= LMatrix4::translate_mat(-cd); + if (lens_cdata->_user_flags & UF_convergence_distance) { + nassertv(lens_cdata->_convergence_distance != 0.0f); + LVector3 cd = (0.25f / lens_cdata->_convergence_distance) * LVector3::left(lens_cdata->_cs); + lens_cdata->_projection_mat_left *= LMatrix4::translate_mat(cd); + lens_cdata->_projection_mat_right *= LMatrix4::translate_mat(-cd); } } - adjust_comp_flags(CF_projection_mat_inv | CF_projection_mat_left_inv | - CF_projection_mat_right_inv, - CF_projection_mat); + do_adjust_comp_flags(lens_cdata, + CF_projection_mat_inv | CF_projection_mat_left_inv | CF_projection_mat_right_inv, + CF_projection_mat); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/perspectiveLens.h b/panda/src/gobj/perspectiveLens.h index 9ccf615231..7540630167 100644 --- a/panda/src/gobj/perspectiveLens.h +++ b/panda/src/gobj/perspectiveLens.h @@ -39,7 +39,7 @@ public: virtual bool is_perspective() const; protected: - virtual void compute_projection_mat(); + virtual void do_compute_projection_mat(Lens::CData *lens_cdata); virtual PN_stdfloat fov_to_film(PN_stdfloat fov, PN_stdfloat focal_length, bool horiz) const; virtual PN_stdfloat fov_to_focal_length(PN_stdfloat fov, PN_stdfloat film_size, bool horiz) const; diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index f241a38af6..42d02a8326 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -823,7 +823,7 @@ protected: return _type_handle; } static void init_type() { - register_type(_type_handle, "Geom::CData"); + register_type(_type_handle, "Texture::CData"); } private: @@ -897,6 +897,7 @@ public: TypedWritableReferenceCount::init_type(); register_type(_type_handle, "Texture", TypedWritableReferenceCount::get_class_type()); + CData::init_type(); } virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/pipeline/cycleDataReader.I b/panda/src/pipeline/cycleDataReader.I index 8e4e96caeb..a3e295eceb 100644 --- a/panda/src/pipeline/cycleDataReader.I +++ b/panda/src/pipeline/cycleDataReader.I @@ -95,6 +95,18 @@ operator const CycleDataType * () const { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataReader::p (full) +// Access: Public +// Description: This allows the CycleDataReader to be passed to any +// function that expects a const CycleDataType pointer. +//////////////////////////////////////////////////////////////////// +template +INLINE const CycleDataType *CycleDataReader:: +p() const { + return _pointer; +} + //////////////////////////////////////////////////////////////////// // Function: CycleDataReader::get_current_thread (full) // Access: Public @@ -178,6 +190,18 @@ operator const CycleDataType * () const { return _pointer; } +//////////////////////////////////////////////////////////////////// +// Function: CycleDataReader::p (trivial) +// Access: Public +// Description: This allows the CycleDataReader to be passed to any +// function that expects a const CycleDataType pointer. +//////////////////////////////////////////////////////////////////// +template +INLINE const CycleDataType *CycleDataReader:: +p() const { + return _pointer; +} + //////////////////////////////////////////////////////////////////// // Function: CycleDataReader::get_current_thread (trivial) // Access: Public diff --git a/panda/src/pipeline/cycleDataReader.h b/panda/src/pipeline/cycleDataReader.h index bff69b22fe..668bac6585 100644 --- a/panda/src/pipeline/cycleDataReader.h +++ b/panda/src/pipeline/cycleDataReader.h @@ -52,6 +52,7 @@ public: INLINE const CycleDataType *operator -> () const; INLINE operator const CycleDataType * () const; + INLINE const CycleDataType *p() const; INLINE Thread *get_current_thread() const;