home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / graphtal / vwtrnsfr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-19  |  3.3 KB  |  123 lines

  1. /*
  2.  * ViewTransform.C - general view transformation.
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  */
  17.  
  18. #include "ViewTransform.h"
  19. #include "Error.h"
  20.  
  21. //___________________________________________________________ ViewTransform
  22.  
  23.  
  24. ViewTransform::ViewTransform(const Vector& Eye, const Vector& Lookat,
  25.                  const Vector& Up, real Fov, int ResX, int ResY)
  26. : eye(Eye), lookat(Lookat), up(Up), fov(Fov), resX(ResX), resY(ResY)
  27. {
  28.   buildView();
  29. }
  30.  
  31. ViewTransform::ViewTransform(const BoundingBox& b, const Vector& Up, real Fov, 
  32.                  int ResX, int ResY)
  33. : up(Up), fov(Fov), resX(ResX), resY(ResY)
  34. {
  35.   real widthX2 = 0.5*(b.xmax()-b.xmin());
  36.   real widthY2 = 0.5*(b.ymax()-b.ymin());
  37.   real height2 = 0.5*(b.zmax()-b.zmin());
  38.  
  39.   if (widthX2 > widthY2) {
  40.     // let's look to the xz-plane
  41.     if (widthX2 >= height2)
  42.       eye[1] = b.ymax() + widthX2/tan(dtor(fov/2));
  43.     else
  44.       eye[1] = b.ymax() + height2/tan(dtor(fov/2));
  45.     eye[0] = lookat[0] = b.xmin() + widthX2;
  46.     lookat[1] = b.ymax();
  47.   } 
  48.   else {
  49.     // let's look to the yz-plane
  50.     if (widthY2 >= height2)
  51.       eye[0] = b.xmax() + widthY2/tan(dtor(fov/2));
  52.     else
  53.       eye[0] = b.xmax() + height2/tan(dtor(fov/2));
  54.     eye[1] = lookat[1] = b.ymin() + widthY2;
  55.     lookat[0] = b.xmax();
  56.   }
  57.   eye[2] = lookat[2] = b.zmin()+height2; 
  58.   
  59.   buildView();
  60. }
  61.  
  62. Vector ViewTransform::transformWorld2Screen(const Vector& p)
  63. {
  64.   Vector vp = p*viewmat;
  65.  
  66.   if (equal(vp[2], 0)) 
  67.     return Vector(0,0,0);
  68.  
  69.   real scale = widthOfViewplane/vp[2];
  70.   vp[0] = resX*(0.5+vp[0]*scale);
  71.   vp[1] = resY*(0.5+vp[1]*scale);
  72.  
  73.   return vp;
  74. }
  75.  
  76. Vector ViewTransform::transformWorld2View(const Vector& p)
  77. {
  78.   return p*viewmat;
  79. }
  80.  
  81. Vector ViewTransform::transformView2Screen(const Vector& p)
  82. {
  83.   if (equal(p[2], 0)) 
  84.     return Vector(0,0,0);
  85.  
  86.   Vector vp = p;
  87.   real scale = widthOfViewplane/vp[2];
  88.   vp[0] = resX*(0.5+vp[0]*scale);
  89.   vp[1] = resY*(0.5+vp[1]*scale);
  90.  
  91.   return vp;
  92. }
  93.  
  94. // buildView assumes that eye, lookat, up, fov, resX, resY are already set!!!
  95. void ViewTransform::buildView()
  96. {
  97.   Vector n,v,u;
  98.  
  99.   n = lookat - eye; n.normalize();
  100.   v = up - (n^up)*n;
  101.   if (v.normalize() == 0) 
  102.     Error(ERR_PANIC, "The view and up directions are identical?");
  103.   u = n * v; 
  104.   widthOfViewplane = 0.5/(tan(dtor(fov)/2));
  105.  
  106.   viewmat(0,0) = u[0]; viewmat(1,0) = u[1]; viewmat(2,0) = u[2];
  107.   viewmat(0,1) = v[0]; viewmat(1,1) = v[1]; viewmat(2,1) = v[2];
  108.   viewmat(0,2) = n[0]; viewmat(1,2) = n[1]; viewmat(2,2) = n[2];
  109.   viewmat(3,0) = -eye[0]*u[0] - eye[1]*u[1] - eye[2]*u[2];
  110.   viewmat(3,1) = -eye[0]*v[0] - eye[1]*v[1] - eye[2]*v[2];
  111.   viewmat(3,2) = -eye[0]*n[0] - eye[1]*n[1] - eye[2]*n[2];
  112. }
  113.  
  114. ostream& operator<<(ostream& os, const ViewTransform& view)
  115. {
  116.   os << "Eye:    " << view.eye    << '\n'
  117.      << "Lookat: " << view.lookat << '\n'
  118.      << "Up:     " << view.up     << '\n'
  119.      << "Fov:    " << view.fov    << '\n';
  120.  
  121.   return os;
  122. }
  123.