diff --git a/vcg/math/shot.h b/vcg/math/shot.h index 6bb75e09..1c9e20b7 100644 --- a/vcg/math/shot.h +++ b/vcg/math/shot.h @@ -104,14 +104,27 @@ creation namespace vcg{ -template +template > class Shot { public: typedef Camera CameraType; typedef S ScalarType; - Camera Intrinsics; // the camera that made the shot - Similarity > Extrinsics; // the position and orientation of the camera + template + class ReferenceFrame { + friend class Shot; + RotoType rot; // rotation + Point3 tra; // viewpoint + public: + void SetIdentity(){ rot.SetIdentity(); tra = Point3(0.0,0.0,0.0);} + void SetTra(const Point3 & tr) {tra = tr;} + void SetRot(const RotoType & rt) {rot = rt;} + Point3 Tra() const { return tra;} + RotoType Rot() const { return rot;} + }; + + Camera Intrinsics; // the camera that made the shot + ReferenceFrame Extrinsics; // the position and orientation of the camera Shot(Camera c) @@ -164,36 +177,51 @@ public: // accessors public: - vcg::Similarity > * GetExtrinsics(){return &Extrinsics;} - void SetExtrinsics(vcg::Similarity > &m44) + /* returns a matrix which contains the reference frame of the shot + On the first three rows the axes (x,y,z) and on the 4th colum the viewpoint */ + Matrix44 GetExtrinsics() const { + Matrix44 rotM ; + Extrinsics.rot.ToMatrix(rotM); + return Matrix44().SetTranslate(Extrinsics.tra) * rotM; + } + + /* multiply the current reference frame for the matrix passed + note: it is up to the caller to check the the matrix passed is a pure rototraslation + */ + void MultMatrix( vcg::Matrix44 m44) { - Extrinsics.tra = m44.tra; - Extrinsics.rot.FromMatrix(m44.rot); - Extrinsics.sca = m44.sca; + Extrinsics.tra = m44 * Extrinsics.tra; + m44[0][3] = m44[1][3] = m44[2][3] = 0.0; + Extrinsics.rot = m44 * Extrinsics.rot ; } + /* multiply the current reference frame for the similarity passed + note: it is up to the caller to check the the matrix passed is a pure rototraslation + */ + void MultSimilarity( const Similarity & s){ MultMatrix(s.Matrix());} + }; // end class definition //--- /// GET the viewpoint -template -const vcg::Point3 Shot::GetViewPoint() const +template +const vcg::Point3 Shot::GetViewPoint() const { - return -Extrinsics.tra; + return Extrinsics.tra; } /// SET the viewpoint -template -void Shot::SetViewPoint(const vcg::Point3 & viewpoint) +template +void Shot::SetViewPoint(const vcg::Point3 & viewpoint) { - Extrinsics.tra = -viewpoint; + Extrinsics.tra = viewpoint; } //--- /// GET the i-th axis of the coordinate system of the camera -template -vcg::Point3 Shot::Axis(const int & i) const +template +vcg::Point3 Shot::Axis(const int & i) const { vcg::Matrix44 m; Extrinsics.rot.ToMatrix(m); @@ -202,15 +230,15 @@ vcg::Point3 Shot::Axis(const int & i) const } /// look at (dir+up) -template -void Shot::LookAt(const vcg::Point3 & z_dir,const vcg::Point3 & up) +template +void Shot::LookAt(const vcg::Point3 & z_dir,const vcg::Point3 & up) { LookTowards(z_dir-GetViewPoint(),up); } /// look at (opengl-like) -template -void Shot::LookAt(const S & eye_x, const S & eye_y, const S & eye_z, +template +void Shot::LookAt(const S & eye_x, const S & eye_y, const S & eye_z, const S & at_x, const S & at_y, const S & at_z, const S & up_x,const S & up_y,const S & up_z) { @@ -219,8 +247,8 @@ void Shot::LookAt(const S & eye_x, const S & eye_y, const S & eye_z, } /// look towards -template -void Shot::LookTowards(const vcg::Point3 & z_dir,const vcg::Point3 & up) +template +void Shot::LookTowards(const vcg::Point3 & z_dir,const vcg::Point3 & up) { vcg::Point3 x_dir = up ^-z_dir; vcg::Point3 y_dir = -z_dir ^x_dir; @@ -237,32 +265,32 @@ void Shot::LookTowards(const vcg::Point3 & z_dir,const vcg::Point3 & up //--- Space transformation methods /// convert a 3d point from world to camera coordinates -template -vcg::Point3 Shot::ConvertWorldToCameraCoordinates(const vcg::Point3 & p) const +template +vcg::Point3 Shot::ConvertWorldToCameraCoordinates(const vcg::Point3 & p) const { Matrix44 rotM; Extrinsics.rot.ToMatrix(rotM); - vcg::Point3 cp = rotM * (p + Extrinsics.tra); + vcg::Point3 cp = rotM * (p - Extrinsics.tra); cp[2]=-cp[2]; // note: camera reference system is right handed return cp; } /// convert a 3d point from camera to world coordinates -template -vcg::Point3 Shot::ConvertCameraToWorldCoordinates(const vcg::Point3 & p) const +template +vcg::Point3 Shot::ConvertCameraToWorldCoordinates(const vcg::Point3 & p) const { Matrix44 rotM; vcg::Point3 cp = p; cp[2]=-cp[2]; // note: World reference system is left handed Extrinsics.rot.ToMatrix(rotM); Invert(rotM); - cp = rotM * cp-Extrinsics.tra; + cp = rotM * cp+Extrinsics.tra; return cp; } /// project a 3d point from world coordinates to 2d camera viewport (pixel) -template -vcg::Point2 Shot::Project(const vcg::Point3 & p) const +template +vcg::Point2 Shot::Project(const vcg::Point3 & p) const { Point3 cp = ConvertWorldToCameraCoordinates(p); Point2 pp = Intrinsics.Project(cp); @@ -271,8 +299,8 @@ vcg::Point2 Shot::Project(const vcg::Point3 & p) const } /// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates -template -vcg::Point3 Shot::UnProject(const vcg::Point2 & p, const S & d) const +template +vcg::Point3 Shot::UnProject(const vcg::Point2 & p, const S & d) const { Point2 lp = Intrinsics.ViewportPxToLocal(p); Point3 cp = Intrinsics.UnProject(lp,d); @@ -281,8 +309,8 @@ vcg::Point3 Shot::UnProject(const vcg::Point2 & p, const S & d) const } /// returns distance of point p from camera plane (z depth), used for unprojection -template -S Shot::Depth(const vcg::Point3 & p)const +template +S Shot::Depth(const vcg::Point3 & p)const { return ConvertWorldToCameraCoordinates(p).Z(); }