// ---------------------------------------------------------------------------- // - Open3D: www.open3d.org - // ---------------------------------------------------------------------------- // Copyright (c) 2018-2023 www.open3d.org // SPDX-License-Identifier: MIT // ---------------------------------------------------------------------------- #pragma once #include namespace open3d { namespace geometry { class AxisAlignedBoundingBox; } // namespace geometry namespace visualization { namespace rendering { class Camera { public: enum class FovType { Vertical, Horizontal }; enum class Projection { Perspective, Ortho }; using Transform = Eigen::Transform; using ProjectionMatrix = Eigen::Transform; virtual ~Camera() = default; virtual void SetProjection(double fov, double aspect, double near, double far, FovType fov_type) = 0; /** Sets the projection matrix from a frustum defined by six planes. * * @param projection type of #Projection to use. * * @param left distance in world units from the camera to the left * plane, at the near plane. * * @param right distance in world units from the camera to the right * plane, at the near plane. * * @param bottom distance in world units from the camera to the bottom * plane, at the near plane. * * @param top distance in world units from the camera to the top * plane, at the near plane. * * @param near distance in world units from the camera to the near * plane. The near plane's * * @param far distance in world units from the camera to the far * plane. The far plane's */ virtual void SetProjection(Projection projection, double left, double right, double bottom, double top, double near, double far) = 0; virtual void SetProjection(const Eigen::Matrix3d& intrinsics, double near, double far, double width, double height) = 0; virtual void LookAt(const Eigen::Vector3f& center, const Eigen::Vector3f& eye, const Eigen::Vector3f& up) = 0; virtual void FromExtrinsics(const Eigen::Matrix4d& extrinsics); virtual void SetModelMatrix(const Transform& view) = 0; virtual void SetModelMatrix(const Eigen::Vector3f& forward, const Eigen::Vector3f& left, const Eigen::Vector3f& up) = 0; virtual double GetNear() const = 0; virtual double GetFar() const = 0; /// only valid if fov was passed to SetProjection() virtual double GetFieldOfView() const = 0; /// only valid if fov was passed to SetProjection() virtual FovType GetFieldOfViewType() const = 0; virtual Eigen::Vector3f GetPosition() const = 0; virtual Eigen::Vector3f GetForwardVector() const = 0; virtual Eigen::Vector3f GetLeftVector() const = 0; virtual Eigen::Vector3f GetUpVector() const = 0; virtual Transform GetModelMatrix() const = 0; virtual Transform GetViewMatrix() const = 0; virtual ProjectionMatrix GetProjectionMatrix() const = 0; virtual Transform GetCullingProjectionMatrix() const = 0; /// Returns world space coordinates given an x,y position in screen /// coordinates relative to upper left, the screen dimensions, and z is the /// depth value (0.0 - 1.0) virtual Eigen::Vector3f Unproject(float x, float y, float z, float view_width, float view_height) const = 0; // Returns the normalized device coordinates (NDC) of the specified point // given the view and projection matrices of the camera. The returned point // is in the range [-1, 1] if the point is in view, or outside the range if // the point is out of view. virtual Eigen::Vector2f GetNDC(const Eigen::Vector3f& pt) const = 0; /// Returns the view space depth (i.e., distance from camera) for the given /// Z-buffer value virtual double GetViewZ(float z_buffer) const = 0; struct ProjectionInfo { bool is_ortho; bool is_intrinsic; union { struct { Projection projection; double left; double right; double bottom; double top; double near_plane; // Windows #defines "near" double far_plane; // Windows #defines "far" } ortho; struct { FovType fov_type; double fov; double aspect; double near_plane; double far_plane; } perspective; struct { double fx; double fy; double cx; double cy; double near_plane; double far_plane; double width; double height; } intrinsics; } proj; }; virtual const ProjectionInfo& GetProjection() const = 0; virtual void CopyFrom(const Camera* camera) = 0; /// Convenience function for configuring a camera as a pinhole camera. /// Configures the projection using the intrinsics and bounds, /// and the model matrix using the extrinsic matrix. Equivalent to calling /// SetProjection() and FromExtrinsics(). static void SetupCameraAsPinholeCamera( rendering::Camera& camera, const Eigen::Matrix3d& intrinsic, const Eigen::Matrix4d& extrinsic, int intrinsic_width_px, int intrinsic_height_px, const geometry::AxisAlignedBoundingBox& scene_bounds); /// Returns a good value for the near plane. static float CalcNearPlane(); /// Returns a value for the far plane that ensures that the entire bounds /// provided will not be clipped. static float CalcFarPlane( const rendering::Camera& camera, const geometry::AxisAlignedBoundingBox& scene_bounds); }; } // namespace rendering } // namespace visualization } // namespace open3d