00001
00002
00003
00004
00005 #include "stdafx.h"
00006 #include "raycaster.h"
00007
00008 #include "messages.h"
00009
00010
00011 Raycaster::Raycaster() {
00012 ready = false;
00013
00014 m_specular = 0.2f;
00015 m_highlight = 8;
00016 m_lightpos = VECTOR(300,300,300);
00017 m_light = false;
00018 m_image = NULL;
00019 m_ambient = 0.2f;
00020 m_diffuse = 0.2f;
00021 m_height = 0;
00022 m_width = 0;
00023 m_viewingtoworld = NULL;
00024 m_stepX = 1.0;
00025 m_stepY = 1.0;
00026 m_data = NULL;
00027 m_tf = NULL;
00028 m_xdir = VECTOR(1,0,0);
00029 m_ydir = VECTOR(0,1,0);
00030 m_treshold = 1500;
00031 m_rendermode = STANDARD;
00032 m_raytype = NN;
00033 m_precalc = false;
00034 m_zoom = 1.0;
00035
00036 m_dOwnType = RAYCASTER;
00037
00038 m_dMaxDens = 4095;
00039 m_dMinDens = 0;
00040 }
00041
00042 Raycaster::~Raycaster() {
00043 if(m_image != NULL) delete m_image;
00044 if(m_viewingtoworld != NULL) delete m_viewingtoworld;
00045 m_image = NULL;
00046 m_viewingtoworld = NULL;
00047 }
00048
00049 bool
00050 Raycaster::SetViewingCondition(VECTOR lightpos, Color background, float ambient, float diffuse, float specular, int highlight) {
00051 m_ambient = ambient;
00052 m_diffuse = diffuse;
00053 m_background = background;
00054 m_specular = specular;
00055 m_highlight = highlight;
00056 m_lightpos = lightpos;
00057 return true;
00058 }
00059
00060
00061 bool
00062 Raycaster::Render(int width, int height) {
00063
00064 int m_x = width / 2 - m_width / 2;
00065 int m_y = height / 2 - m_height / 2;
00066
00067
00068 if (!ready)
00069 return false;
00070
00071 glRasterPos2i(m_x, m_y);
00072 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00073 glDrawPixels(m_width, m_height, GL_RGB, GL_UNSIGNED_BYTE, m_image);
00074 return true;
00075 }
00076
00077 bool
00078 Raycaster::Initialize(int width, int height, float steplength, Data *data, Transfunc *tf) {
00079 m_data = data;
00080 m_tf = tf;
00081 m_width = width;
00082 m_height = height;
00083 m_steplength = steplength;
00084 return true;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 bool
00105 Raycaster::Raycast() {
00106
00107 CWnd* pFrame = AfxGetMainWnd();
00108
00109
00110 m_data->SetPreCalc(m_precalc);
00111 m_image = new rgb[m_width*m_height];
00112
00113 int maxX = m_data->GetXDim();
00114 int maxY = m_data->GetYDim();
00115 int maxZ = m_data->GetZDim();
00116
00117 VECTOR pos = VECTOR(0,0,0);
00118 Matrix4x4 trans;
00119 trans.translate(VECTOR(-maxX/2,-maxY/2,-maxZ/2));
00120 pos = trans * pos;
00121 pos = *m_viewingtoworld_inv * pos;
00122 trans.translate(VECTOR(maxX/2,maxY/2,maxZ/2));
00123 pos = trans*pos;
00124 VECTOR backup = pos;
00125
00126 VECTOR normal = VECTOR(0,0,0)-pos;
00127 if(normal.x == 0 && normal.y == 0 && normal.z == 0)
00128 normal.z = 1.0;
00129
00130 Plane *viewingplane = new Plane(normal,pos);
00131 m_xdir = *m_viewingtoworld_inv * m_xdir;
00132 m_ydir = *m_viewingtoworld_inv * m_ydir;
00133
00134 int loadSize = (m_height * m_width) / 100;
00135 int counter = loadSize / 100;
00136 int progPos = 0;
00137
00138
00139
00140 Ray *r;
00141 switch (m_rendermode) {
00142 case STANDARD:
00143 if (m_raytype == NN)
00144 r = new Ray();
00145 else if (m_raytype == TRI)
00146 r = new Trilinear();
00147 break;
00148 case FH:
00149 if (m_raytype == NN) {
00150 r = new FirstHitNN();
00151 ((FirstHitNN *)r)->SetTreshold(m_treshold);
00152 }
00153 else if (m_raytype == TRI) {
00154 r = new FirstHitTRI();
00155 ((FirstHitTRI *)r)->SetTreshold(m_treshold);
00156 }
00157 break;
00158 case MI:
00159 if (m_raytype == NN)
00160 r = new MaxIntensityNN();
00161 else if (m_raytype == TRI)
00162 r = new MaxIntensityTRI();
00163 break;
00164 case XRAY:
00165 if (m_raytype == NN)
00166 r = new XRayNN();
00167 else if (m_raytype == TRI)
00168 r = new XRayTRI();
00169
00170 r->SetDensRange(m_dMinDens, m_dMaxDens);
00171 break;
00172 }
00173
00174 r->SetViewingCondition(m_lightpos, m_ambient, m_diffuse, m_specular, m_highlight);
00175 r->Initialize(m_background,m_background,m_steplength,viewingplane,m_data,m_tf);
00176 r->SetLight(m_light);
00177
00178 for(int j = 0; j < m_height; j++) {
00179 for(int i = 0; i < m_width; i++) {
00180 r->Reset();
00181 r->SetPosDir(pos, viewingplane->normal);
00182 r->CastNext();
00183 m_image[j * m_width + i] = r->GetCurrentColor().toRGB();
00184
00185 pos += m_xdir;
00186
00187 if ((counter-- <= 0) && (progPos < 100)) {
00188 counter = loadSize;
00189 pFrame->SendMessage(MYWM_PROGRESS, progPos++);
00190 }
00191
00192
00193 }
00194 pos = backup;
00195 pos += j*m_ydir;
00196
00197 pFrame->SendMessage(MYWM_PROGRESS, 0);
00198
00199 }
00200
00201
00202
00203 if (r)
00204 delete r;
00205
00206 ready = true;
00207 return true;
00208 }
00209
00210
00211 bool
00212 Raycaster::Zoom(float zoom) {
00213 int maxX = m_data->GetXDim()-1;
00214 int maxY = m_data->GetYDim()-1;
00215 int maxZ = m_data->GetZDim()-1;
00216 m_zoom = zoom;
00217 float maxlength = sqrtf(powf((float)maxX,2.0)+powf((float)maxY,2.0)+powf((float)maxZ,2.0));
00218 m_stepX = (1/m_zoom)*maxlength/(m_width-1);
00219 m_stepY = (1/m_zoom)*maxlength/(m_height-1);
00220
00221 SetViewingMatrix();
00222 return true;
00223 }
00224
00225
00226 bool
00227 Raycaster::SetViewingMatrix() {
00228 VECTOR zaxis = VECTOR(0,0,1);
00229 m_viewingtoworld = new Matrix4x4();
00230 m_viewingtoworld->identity();
00231 m_viewingtoworld_inv = new Matrix4x4();
00232 m_viewingtoworld_inv->identity();
00233 m_xdir = VECTOR(1,0,0);
00234 m_ydir = VECTOR(0,1,0);
00235
00236 m_xdir = m_stepX * m_xdir;
00237 m_ydir = m_stepY * m_ydir;
00238
00239 return true;
00240 }
00241
00242 bool
00243 Raycaster::RotateX(float alpha) {
00244 Matrix4x4 rotmat1;
00245 Matrix4x4 rotmat2;
00246 rotmat1.rotateX(alpha);
00247 rotmat2.rotateX(-alpha);
00248
00249 *m_viewingtoworld = m_viewingtoworld->mul(rotmat1);
00250 *m_viewingtoworld_inv = m_viewingtoworld_inv->mul(rotmat2);
00251 return true;
00252 }
00253
00254 bool
00255 Raycaster::RotateY(float alpha) {
00256 Matrix4x4 rotmat1;
00257 Matrix4x4 rotmat2;
00258 rotmat1.rotateY(alpha);
00259 rotmat2.rotateY(-alpha);
00260
00261 *m_viewingtoworld = m_viewingtoworld->mul(rotmat1);
00262 *m_viewingtoworld_inv = m_viewingtoworld_inv->mul(rotmat2);
00263 return true;
00264 }
00265
00266 bool
00267 Raycaster::RotateZ(float alpha) {
00268 Matrix4x4 rotmat1;
00269 Matrix4x4 rotmat2;
00270 rotmat1.rotateZ(alpha);
00271 rotmat2.rotateZ(-alpha);
00272
00273 *m_viewingtoworld = m_viewingtoworld->mul(rotmat1);
00274 *m_viewingtoworld_inv = m_viewingtoworld_inv->mul(rotmat2);
00275 return true;
00276 }
00277