fixed multmatrix when a scaling factor is present

This commit is contained in:
Paolo Cignoni 2011-05-03 15:19:04 +00:00
parent 49a15ebd82
commit 2c15159659
1 changed files with 138 additions and 136 deletions

View File

@ -129,127 +129,129 @@ namespace vcg{
template <class S, class RotationType = Matrix44<S> >
class Shot {
public:
typedef Camera<S> CameraType;
typedef S ScalarType;
typedef Camera<S> CameraType;
typedef S ScalarType;
template <class ScalarType, class RotoType >
class ReferenceFrame {
friend class Shot<ScalarType, RotoType>;
RotoType rot; // rotation
Point3<S> tra; // viewpoint
public:
void SetIdentity(){ rot.SetIdentity(); tra = Point3<S>(0.0,0.0,0.0);}
void SetTra(const Point3<S> & tr) {tra = tr;}
void SetRot(const RotoType & rt) {rot = rt;}
Point3<ScalarType> Tra() const { return tra;}
RotoType Rot() const { return rot;}
};
template <class ScalarType, class RotoType >
class ReferenceFrame {
friend class Shot<ScalarType, RotoType>;
RotoType rot; // rotation
Point3<S> tra; // viewpoint
public:
void SetIdentity(){ rot.SetIdentity(); tra = Point3<S>(0.0,0.0,0.0);}
void SetTra(const Point3<S> & tr) {tra = tr;}
void SetRot(const RotoType & rt) {rot = rt;}
Point3<ScalarType> Tra() const { return tra;}
RotoType Rot() const { return rot;}
};
Camera<S> Intrinsics; // the camera that made the shot
ReferenceFrame<S,RotationType> Extrinsics; // the position and orientation of the camera
Camera<S> Intrinsics; // the camera that made the shot
ReferenceFrame<S,RotationType> Extrinsics; // the position and orientation of the camera
Shot(Camera<S> c)
{
Intrinsics = c;
Extrinsics.SetIdentity();
}
Shot(Camera<S> c)
{
Intrinsics = c;
Extrinsics.SetIdentity();
}
Shot()
{
Extrinsics.SetIdentity();
}
Shot()
{
Extrinsics.SetIdentity();
}
/// GET the i-th axis of the coordinate system of the camera
vcg::Point3<S> Axis(const int & i)const;
/// GET the i-th axis of the coordinate system of the camera
vcg::Point3<S> Axis(const int & i)const;
/// GET the viewdir
const vcg::Point3<S> GetViewDir()const;
/// GET the viewpoint
const vcg::Point3<S> GetViewPoint()const;
/// SET the viewpoint
void SetViewPoint(const vcg::Point3<S> & viewpoint);
void SetViewPoint(const vcg::Point3<S> & viewpoint);
/// GET fov from focal
float GetFovFromFocal();
/// GET fov from focal
float GetFovFromFocal();
/// look at (point+up)
void LookAt(const vcg::Point3<S> & point,const vcg::Point3<S> & up);
/// look at (point+up)
void LookAt(const vcg::Point3<S> & point,const vcg::Point3<S> & up);
/// look at (opengl-like)
void 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);
/// look at (opengl-like)
void 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);
/// look towards (dir+up)
void LookTowards(const vcg::Point3<S> & z_dir,const vcg::Point3<S> & up);
/// look towards (dir+up)
void LookTowards(const vcg::Point3<S> & z_dir,const vcg::Point3<S> & up);
/// convert a 3d point from world to camera coordinates
vcg::Point3<S> ConvertWorldToCameraCoordinates(const vcg::Point3<S> & p) const;
/// convert a 3d point from world to camera coordinates
vcg::Point3<S> ConvertWorldToCameraCoordinates(const vcg::Point3<S> & p) const;
/// convert a 3d point from camera to world coordinates
vcg::Point3<S> ConvertCameraToWorldCoordinates(const vcg::Point3<S> & p) const;
/// convert a 3d point from camera to world coordinates
vcg::Point3<S> ConvertCameraToWorldCoordinates(const vcg::Point3<S> & p) const;
/// convert a 3d point from camera to world coordinates, uses inverse instead of trranspose
/// for non-exactly-rigid rotation matrices (such as calculated by tsai and garcia)
vcg::Point3<S> ConvertCameraToWorldCoordinates_Substitute(const vcg::Point3<S> & p) const;
/// convert a 3d point from camera to world coordinates, uses inverse instead of trranspose
/// for non-exactly-rigid rotation matrices (such as calculated by tsai and garcia)
vcg::Point3<S> ConvertCameraToWorldCoordinates_Substitute(const vcg::Point3<S> & p) const;
/// project a 3d point from world coordinates to 2d camera viewport (pixel)
vcg::Point2<S> Project(const vcg::Point3<S> & p) const;
/// project a 3d point from world coordinates to 2d camera viewport (pixel)
vcg::Point2<S> Project(const vcg::Point3<S> & p) const;
/// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates
vcg::Point3<S> UnProject(const vcg::Point2<S> & p, const S & d) const;
/// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates
vcg::Point3<S> UnProject(const vcg::Point2<S> & p, const S & d) const;
/// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates, uses inverse instead of trranspose
/// for non-exactly-rigid rotation matrices (such as calculated by tsai and garcia)
vcg::Point3<S> UnProject_Substitute(const vcg::Point2<S> & p, const S & d) const;
/// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates, uses inverse instead of trranspose
/// for non-exactly-rigid rotation matrices (such as calculated by tsai and garcia)
vcg::Point3<S> UnProject_Substitute(const vcg::Point2<S> & p, const S & d) const;
/// returns distance of point p from camera plane (z depth), used for unprojection
S Depth(const vcg::Point3<S> & p)const;
/// returns distance of point p from camera plane (z depth), used for unprojection
S Depth(const vcg::Point3<S> & p)const;
// accessors
public:
/* Returns the matrix M such that
3dpoint_in_world_coordinates = M * 3dpoint_in_local_coordinates
*/
Matrix44<S> GetExtrinsicsToWorldMatrix() const {
Matrix44<S> rotM ;
Extrinsics.rot.ToMatrix(rotM);
return Matrix44<S>().SetTranslate(Extrinsics.tra) * rotM.transpose();
}
/* Returns the matrix M such that
3dpoint_in_world_coordinates = M * 3dpoint_in_local_coordinates
*/
Matrix44<S> GetExtrinsicsToWorldMatrix() const {
Matrix44<S> rotM ;
Extrinsics.rot.ToMatrix(rotM);
return Matrix44<S>().SetTranslate(Extrinsics.tra) * rotM.transpose();
}
/* Returns the matrix M such that
3dpoint_in_local_coordinates = M * 3dpoint_in_world_coordinates
*/
Matrix44<S> GetWorldToExtrinsicsMatrix() const {
Matrix44<S> rotM ;
Extrinsics.rot.ToMatrix(rotM);
return rotM * Matrix44<S>().SetTranslate(-Extrinsics.tra) ;
}
/* Returns the matrix M such that
3dpoint_in_local_coordinates = M * 3dpoint_in_world_coordinates
*/
Matrix44<S> GetWorldToExtrinsicsMatrix() const {
Matrix44<S> rotM ;
Extrinsics.rot.ToMatrix(rotM);
return rotM * Matrix44<S>().SetTranslate(-Extrinsics.tra) ;
}
/* 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
*/
/* 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
the matrix can have a scaling component, but is assumed uniform over the rows
*/
void MultMatrix( vcg::Matrix44<S> m44)
{
Extrinsics.tra = m44 * Extrinsics.tra;
m44[0][3] = m44[1][3] = m44[2][3] = 0.0; //set no translation
const S k = m44.GetRow3(0).Norm(); //compute scaling (assumed uniform)
Extrinsics.rot = Extrinsics.rot * m44.transpose() * (1/k);
Extrinsics.rot.ElementAt(3,3)=S(1.0); //fix back after scaling
}
/* 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> & s){ MultMatrix(s.Matrix());}
bool IsValid() const
{
return Intrinsics.PixelSizeMm[0]>0 && Intrinsics.PixelSizeMm[1]>0;
}
/* 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> & s){ MultMatrix(s.Matrix());}
bool IsValid() const
{
return Intrinsics.PixelSizeMm[0]>0 && Intrinsics.PixelSizeMm[1]>0;
}
}; // end class definition
@ -268,13 +270,13 @@ const vcg::Point3<S> Shot<S,RotationType>::GetViewDir() const
template <class S, class RotationType>
const vcg::Point3<S> Shot<S,RotationType>::GetViewPoint() const
{
return Extrinsics.tra;
return Extrinsics.tra;
}
/// SET the viewpoint
template <class S, class RotationType>
void Shot<S,RotationType>::SetViewPoint(const vcg::Point3<S> & viewpoint)
{
Extrinsics.SetTra( viewpoint );
Extrinsics.SetTra( viewpoint );
}
//---
@ -282,8 +284,8 @@ void Shot<S,RotationType>::SetViewPoint(const vcg::Point3<S> & viewpoint)
template <class S, class RotationType>
float Shot<S,RotationType>::GetFovFromFocal()
{
double viewportYMm= Intrinsics.PixelSizeMm[1]* Intrinsics.ViewportPx[1];
return 2*(vcg::math::ToDeg(atanf(viewportYMm/(2*Intrinsics.FocalMm))));
double viewportYMm= Intrinsics.PixelSizeMm[1]* Intrinsics.ViewportPx[1];
return 2*(vcg::math::ToDeg(atanf(viewportYMm/(2*Intrinsics.FocalMm))));
}
//---
@ -292,43 +294,43 @@ float Shot<S,RotationType>::GetFovFromFocal()
template <class S, class RotationType>
vcg::Point3<S> Shot<S,RotationType>::Axis(const int & i) const
{
vcg::Matrix44<S> m;
Extrinsics.rot.ToMatrix(m);
vcg::Point3<S> aa = m.GetRow3(i);
return aa;
vcg::Matrix44<S> m;
Extrinsics.rot.ToMatrix(m);
vcg::Point3<S> aa = m.GetRow3(i);
return aa;
}
/// look at (point+up)
template <class S, class RotationType>
void Shot<S,RotationType>::LookAt(const vcg::Point3<S> & z_dir,const vcg::Point3<S> & up)
{
LookTowards(z_dir-GetViewPoint(),up);
LookTowards(z_dir-GetViewPoint(),up);
}
/// look at (opengl-like)
template <class S, class RotationType>
void Shot<S,RotationType>::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)
const S & at_x, const S & at_y, const S & at_z,
const S & up_x,const S & up_y,const S & up_z)
{
SetViewPoint(Point3<S>(eye_x,eye_y,eye_z));
LookAt(Point3<S>(at_x,at_y,at_z),Point3<S>(up_x,up_y,up_z));
SetViewPoint(Point3<S>(eye_x,eye_y,eye_z));
LookAt(Point3<S>(at_x,at_y,at_z),Point3<S>(up_x,up_y,up_z));
}
/// look towards
template <class S, class RotationType>
void Shot<S,RotationType>::LookTowards(const vcg::Point3<S> & z_dir,const vcg::Point3<S> & up)
{
vcg::Point3<S> x_dir = up ^-z_dir;
vcg::Point3<S> y_dir = -z_dir ^x_dir;
vcg::Point3<S> x_dir = up ^-z_dir;
vcg::Point3<S> y_dir = -z_dir ^x_dir;
Matrix44<S> m;
m.SetIdentity();
*(vcg::Point3<S> *)&m[0][0] = x_dir/x_dir.Norm();
*(vcg::Point3<S> *)&m[1][0] = y_dir/y_dir.Norm();
*(vcg::Point3<S> *)&m[2][0] = -z_dir/z_dir.Norm();
Matrix44<S> m;
m.SetIdentity();
*(vcg::Point3<S> *)&m[0][0] = x_dir/x_dir.Norm();
*(vcg::Point3<S> *)&m[1][0] = y_dir/y_dir.Norm();
*(vcg::Point3<S> *)&m[2][0] = -z_dir/z_dir.Norm();
Extrinsics.rot.FromMatrix(m);
Extrinsics.rot.FromMatrix(m);
}
//--- Space transformation methods
@ -337,74 +339,74 @@ void Shot<S,RotationType>::LookTowards(const vcg::Point3<S> & z_dir,const vcg::P
template <class S, class RotationType>
vcg::Point3<S> Shot<S,RotationType>::ConvertWorldToCameraCoordinates(const vcg::Point3<S> & p) const
{
Matrix44<S> rotM;
Extrinsics.rot.ToMatrix(rotM);
vcg::Point3<S> cp = rotM * (p - GetViewPoint() );
cp[2]=-cp[2]; // note: camera reference system is right handed
return cp;
}
Matrix44<S> rotM;
Extrinsics.rot.ToMatrix(rotM);
vcg::Point3<S> cp = rotM * (p - GetViewPoint() );
cp[2]=-cp[2]; // note: camera reference system is right handed
return cp;
}
/// convert a 3d point from camera to world coordinates
template <class S, class RotationType>
vcg::Point3<S> Shot<S,RotationType>::ConvertCameraToWorldCoordinates(const vcg::Point3<S> & p) const
{
Matrix44<S> rotM;
vcg::Point3<S> cp = p;
cp[2]=-cp[2]; // note: World reference system is left handed
Extrinsics.rot.ToMatrix(rotM);
cp = rotM.transpose() * cp + GetViewPoint();
return cp;
Matrix44<S> rotM;
vcg::Point3<S> cp = p;
cp[2]=-cp[2]; // note: World reference system is left handed
Extrinsics.rot.ToMatrix(rotM);
cp = rotM.transpose() * cp + GetViewPoint();
return cp;
}
/// convert a 3d point from camera to world coordinates, uses inverse instead of trranspose
/// convert a 3d point from camera to world coordinates, uses inverse instead of trranspose
/// for non-exactly-rigid rotation matrices (such as calculated by tsai and garcia)
template <class S, class RotationType>
vcg::Point3<S> Shot<S,RotationType>::ConvertCameraToWorldCoordinates_Substitute(const vcg::Point3<S> & p) const
{
Matrix44<S> rotM;
vcg::Point3<S> cp = p;
cp[2]=-cp[2]; // note: World reference system is left handed
Extrinsics.rot.ToMatrix(rotM);
cp = Inverse(rotM) * cp + GetViewPoint(); // use invert istead of transpose to dela with non-rigid cases
return cp;
Matrix44<S> rotM;
vcg::Point3<S> cp = p;
cp[2]=-cp[2]; // note: World reference system is left handed
Extrinsics.rot.ToMatrix(rotM);
cp = Inverse(rotM) * cp + GetViewPoint(); // use invert istead of transpose to dela with non-rigid cases
return cp;
}
/// project a 3d point from world coordinates to 2d camera viewport (pixel)
template <class S, class RotationType>
vcg::Point2<S> Shot<S,RotationType>::Project(const vcg::Point3<S> & p) const
{
Point3<S> cp = ConvertWorldToCameraCoordinates(p);
Point2<S> pp = Intrinsics.Project(cp);
Point2<S> vp = Intrinsics.LocalToViewportPx(pp);
return vp;
Point3<S> cp = ConvertWorldToCameraCoordinates(p);
Point2<S> pp = Intrinsics.Project(cp);
Point2<S> vp = Intrinsics.LocalToViewportPx(pp);
return vp;
}
/// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates
template <class S, class RotationType>
vcg::Point3<S> Shot<S,RotationType>::UnProject(const vcg::Point2<S> & p, const S & d) const
{
Point2<S> lp = Intrinsics.ViewportPxToLocal(p);
Point3<S> cp = Intrinsics.UnProject(lp,d);
Point3<S> wp = ConvertCameraToWorldCoordinates(cp);
return wp;
Point2<S> lp = Intrinsics.ViewportPxToLocal(p);
Point3<S> cp = Intrinsics.UnProject(lp,d);
Point3<S> wp = ConvertCameraToWorldCoordinates(cp);
return wp;
}
/// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates, uses inverse instead of trranspose
/// inverse projection from 2d camera viewport (pixel) + Zdepth to 3d world coordinates, uses inverse instead of trranspose
/// for non-exactly-rigid rotation matrices (such as calculated by tsai and garcia)
template <class S, class RotationType>
vcg::Point3<S> Shot<S,RotationType>::UnProject_Substitute(const vcg::Point2<S> & p, const S & d) const
{
Point2<S> lp = Intrinsics.ViewportPxToLocal(p);
Point3<S> cp = Intrinsics.UnProject(lp,d);
Point3<S> wp = ConvertCameraToWorldCoordinates_Substitute(cp);
return wp;
Point2<S> lp = Intrinsics.ViewportPxToLocal(p);
Point3<S> cp = Intrinsics.UnProject(lp,d);
Point3<S> wp = ConvertCameraToWorldCoordinates_Substitute(cp);
return wp;
}
/// returns distance of point p from camera plane (z depth), used for unprojection
template <class S, class RotationType>
S Shot<S,RotationType>::Depth(const vcg::Point3<S> & p)const
{
return ConvertWorldToCameraCoordinates(p).Z();
return ConvertWorldToCameraCoordinates(p).Z();
}