00001 #include "stdafx.h"
00002 #include "raycaster.h"
00003
00004 #include "messages.h"
00005
00006
00007 Raycaster::Raycaster() {
00008 ready = false;
00009
00010 m_specular = 0.2f;
00011 m_highlight = 8;
00012 m_lightpos = VECTOR(300,300,300);
00013 m_light = false;
00014 m_image = NULL;
00015 m_ambient = 0.2f;
00016 m_diffuse = 0.2f;
00017 m_height = 0;
00018 m_width = 0;
00019 m_viewingplane = NULL;
00020 m_viewingtoworld = NULL;
00021 m_stepX = 1.0;
00022 m_stepY = 1.0;
00023 m_data = NULL;
00024 m_tf = NULL;
00025 m_xdir = VECTOR(1,0,0);
00026 m_ydir = VECTOR(0,1,0);
00027 m_treshold = 1500;
00028 m_rendermode = STANDARD;
00029 m_raytype = NN;
00030 m_precalc = false;
00031 m_zoom = 1.0;
00032
00033 m_dOwnType = RAYCASTER;
00034 }
00035
00036 Raycaster::~Raycaster() {
00037 if(m_image != NULL) delete m_image;
00038 if(m_viewingplane != NULL) delete m_viewingplane;
00039 if(m_viewingtoworld != NULL) delete m_viewingtoworld;
00040 m_image = NULL;
00041 m_viewingplane = NULL;
00042 m_viewingtoworld = NULL;
00043 }
00044
00045 bool
00046 Raycaster::SetViewingCondition(VECTOR lightpos, Color background, float ambient, float diffuse, float specular, int highlight) {
00047 m_ambient = ambient;
00048 m_diffuse = diffuse;
00049 m_background = background;
00050 m_specular = specular;
00051 m_highlight = highlight;
00052 m_lightpos = lightpos;
00053 return true;
00054 }
00055
00056
00057 bool
00058 Raycaster::Render(int width, int height) {
00059
00060 int m_x = width / 2 - m_width / 2;
00061 int m_y = height / 2 - m_height / 2;
00062
00063
00064 if (!ready)
00065 return false;
00066
00067 glRasterPos2i(m_x, m_y);
00068 glPixelStorei(GL_UNPACK_ALIGNMENT,1);
00069 glDrawPixels(m_width, m_height, GL_RGB, GL_UNSIGNED_BYTE, m_image);
00070 return true;
00071 }
00072
00073 bool
00074 Raycaster::Initialize(VECTOR viewingplanepos, int width, int height, float steplength, Data *data, Transfunc *tf) {
00075 m_data = data;
00076 m_tf = tf;
00077 m_width = width;
00078 m_height = height;
00079 m_steplength = steplength;
00080 int maxX = m_data->GetXDim()-1;
00081 int maxY = m_data->GetYDim()-1;
00082 int maxZ = m_data->GetZDim()-1;
00083 VECTOR viewingplanenormal = VECTOR(maxX/2,maxY/2,maxZ/2)-viewingplanepos;
00084 viewingplanenormal.normalize();
00085 m_viewingplane = new Plane(viewingplanenormal,viewingplanepos);
00086
00087
00088 Zoom(m_zoom);
00089
00090
00091 if(m_viewingplane == NULL) return false;
00092 if(m_data == NULL) return false;
00093 if(m_tf == NULL) return false;
00094 return true;
00095 }
00096
00097
00098 void Raycaster::SetViewingPlanePos(float x, float y, float z) {
00099 if (!m_data)
00100 return;
00101
00102 VECTOR viewingplanepos = VECTOR(x, y, z);
00103 int maxX = m_data->GetXDim()-1;
00104 int maxY = m_data->GetYDim()-1;
00105 int maxZ = m_data->GetZDim()-1;
00106 VECTOR viewingplanenormal = VECTOR(maxX/2,maxY/2,maxZ/2)-viewingplanepos;
00107 viewingplanenormal.normalize();
00108 m_viewingplane = new Plane(viewingplanenormal,viewingplanepos);
00109 }
00110
00111
00112
00113
00114 bool
00115 Raycaster::Raycast() {
00116
00117 CWnd* pFrame = AfxGetMainWnd();
00118
00119
00120 m_data->SetPreCalc(m_precalc);
00121 m_image = new rgb[m_width*m_height];
00122
00123 VECTOR pos = m_viewingplane->point-m_width/2*m_xdir-m_height/2*m_ydir;
00124 VECTOR backup = pos;
00125
00126 int loadSize = (m_height * m_width) / 100;
00127 int counter = loadSize / 100;
00128 int progPos = 0;
00129
00130
00131
00132 Ray *r;
00133
00134 switch (m_rendermode) {
00135 case STANDARD:
00136 if (m_raytype == NN)
00137 r = new Ray();
00138 else if (m_raytype == TRI)
00139 r = new Trilinear();
00140 break;
00141 case FH:
00142 if (m_raytype == NN) {
00143 r = new FirstHitNN();
00144 ((FirstHitNN *)r)->SetTreshold(m_treshold);
00145 }
00146 else if (m_raytype == TRI) {
00147 r = new FirstHitTRI();
00148 ((FirstHitTRI *)r)->SetTreshold(m_treshold);
00149 }
00150 break;
00151 case MI:
00152 if (m_raytype == NN)
00153 r = new MaxIntensityNN();
00154 else if (m_raytype == TRI)
00155 r = new MaxIntensityTRI();
00156 break;
00157 case XRAY:
00158 if (m_raytype == NN)
00159 r = new XRayNN();
00160 else if (m_raytype == TRI)
00161 r = new XRayTRI();
00162 break;
00163 }
00164
00165 r->SetViewingCondition(m_lightpos, m_ambient, m_diffuse, m_specular, m_highlight);
00166 r->Initialize(m_background,m_background,m_steplength,m_viewingplane,m_data,m_tf);
00167 r->SetLight(m_light);
00168
00169 for(int j = 0; j < m_height; j++) {
00170 for(int i = 0; i < m_width; i++) {
00171 r->Reset();
00172 r->SetPosDir(pos, m_viewingplane->normal);
00173 r->CastNext();
00174 m_image[j * m_width + i] = r->GetCurrentColor().toRGB();
00175
00176 pos += m_xdir;
00177
00178 if ((counter-- <= 0) && (progPos < 100)) {
00179 counter = loadSize;
00180 pFrame->SendMessage(MYWM_PROGRESS, progPos++);
00181 }
00182
00183
00184 }
00185 pos = backup;
00186 pos += j*m_ydir;
00187
00188 pFrame->SendMessage(MYWM_PROGRESS, 0);
00189
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 if (r)
00319 delete r;
00320
00321 ready = true;
00322 return true;
00323 }
00324
00325
00326 bool
00327 Raycaster::Zoom(float zoom) {
00328 int maxX = m_data->GetXDim()-1;
00329 int maxY = m_data->GetYDim()-1;
00330 int maxZ = m_data->GetZDim()-1;
00331 m_zoom = zoom;
00332 float maxlength = sqrtf(powf((float)maxX,2.0)+powf((float)maxY,2.0)+powf((float)maxZ,2.0));
00333 m_stepX = (1/m_zoom)*maxlength/(m_width-1);
00334 m_stepY = (1/m_zoom)*maxlength/(m_height-1);
00335
00336 SetViewingMatrix();
00337 return true;
00338 }
00339
00340
00341 bool
00342 Raycaster::SetViewingMatrix() {
00343 VECTOR zaxis = VECTOR(0,0,1);
00344 if(m_viewingtoworld == NULL) m_viewingtoworld = new Matrix4x4();
00345 m_viewingtoworld->rotation(zaxis,m_viewingplane->normal);
00346
00347 m_xdir = VECTOR(1,0,0);
00348 m_ydir = VECTOR(0,1,0);
00349
00350 m_xdir = *m_viewingtoworld*m_xdir;
00351 m_ydir = *m_viewingtoworld*m_ydir;
00352 m_xdir.normalize();
00353 m_ydir.normalize();
00354 m_xdir = m_stepX * m_xdir;
00355 m_ydir = m_stepY * m_ydir;
00356
00357 return true;
00358 }
00359
00360 bool
00361 Raycaster::RotateX(float alpha) {
00362 Matrix4x4 rotmat;
00363 rotmat.rotateX(-alpha);
00364 m_viewingplane->point = rotmat*m_viewingplane->point;
00365 int maxX = m_data->GetXDim()-1;
00366 int maxY = m_data->GetYDim()-1;
00367 int maxZ = m_data->GetZDim()-1;
00368 m_viewingplane->normal = VECTOR(maxX/2,maxY/2,maxZ/2)-m_viewingplane->point;
00369 m_viewingplane->normal.normalize();
00370 SetViewingMatrix();
00371 return true;
00372 }
00373
00374 bool
00375 Raycaster::RotateY(float alpha) {
00376 Matrix4x4 rotmat;
00377 rotmat.rotateY(-alpha);
00378 m_viewingplane->point = rotmat*m_viewingplane->point;
00379 int maxX = m_data->GetXDim()-1;
00380 int maxY = m_data->GetYDim()-1;
00381 int maxZ = m_data->GetZDim()-1;
00382 m_viewingplane->normal = VECTOR(maxX/2,maxY/2,maxZ/2)-m_viewingplane->point;
00383 m_viewingplane->normal.normalize();
00384 SetViewingMatrix();
00385 return true;
00386 }
00387
00388 bool
00389 Raycaster::RotateZ(float alpha) {
00390 Matrix4x4 rotmat;
00391 rotmat.rotateZ(-alpha);
00392 m_viewingplane->point = rotmat*m_viewingplane->point;
00393 int maxX = m_data->GetXDim()-1;
00394 int maxY = m_data->GetYDim()-1;
00395 int maxZ = m_data->GetZDim()-1;
00396 m_viewingplane->normal = VECTOR(maxX/2,maxY/2,maxZ/2)-m_viewingplane->point;
00397 m_viewingplane->normal.normalize();
00398 SetViewingMatrix();
00399 return true;
00400 }
00401
00402
00403 Perspective::Perspective() {
00404 m_eye = VECTOR(0,0,-10);
00405 m_dist = 0;
00406
00407 m_dOwnType = PERSPECTIVE;
00408 }
00409
00410 Perspective::~Perspective() {}
00411
00412 bool
00413 Perspective::Initialize(VECTOR eye, float dist, int width, int height,float steplength,Data *data,Transfunc *tf) {
00414 m_eye = eye;
00415 m_data = data;
00416 m_tf = tf;
00417 m_width = width;
00418 m_height = height;
00419 m_steplength = steplength;
00420 m_dist = dist;
00421 int maxX = m_data->GetXDim()-1;
00422 int maxY = m_data->GetYDim()-1;
00423 int maxZ = m_data->GetZDim()-1;
00424 VECTOR viewingplanenormal = VECTOR(maxX/2,maxY/2,maxZ/2)-m_eye;
00425 viewingplanenormal.normalize();
00426
00427 VECTOR viewingplanepos = m_eye + m_dist * viewingplanenormal;
00428 m_viewingplane = new Plane(viewingplanenormal,viewingplanepos);
00429
00430 Zoom(m_zoom);
00431
00432 if(m_viewingplane == NULL) return false;
00433 if(m_data == NULL) return false;
00434 if(m_tf == NULL) return false;
00435 return true;
00436 }
00437
00438
00439 bool
00440 Perspective::Raycast() {
00441
00442 CWnd* pFrame = AfxGetMainWnd();
00443
00444
00445 m_data->SetPreCalc(m_precalc);
00446 m_image = new rgb[m_width*m_height];
00447
00448 VECTOR pos = m_viewingplane->point-m_width/2*m_xdir-m_height/2*m_ydir;
00449 VECTOR backup = pos;
00450
00451 VECTOR direction;
00452
00453 int loadSize = (m_height * m_width) / 100;
00454 int counter = loadSize / 100;
00455 int progPos = 0;
00456
00457
00458
00459 Ray *r;
00460
00461 switch (m_rendermode) {
00462 case STANDARD:
00463 if (m_raytype == NN)
00464 r = new Ray();
00465 else if (m_raytype == TRI)
00466 r = new Trilinear();
00467 break;
00468 case FH:
00469 if (m_raytype == NN) {
00470 r = new FirstHitNN();
00471 ((FirstHitNN *)r)->SetTreshold(m_treshold);
00472 }
00473 else if (m_raytype == TRI) {
00474 r = new FirstHitTRI();
00475 ((FirstHitTRI *)r)->SetTreshold(m_treshold);
00476 }
00477 break;
00478 case MI:
00479 if (m_raytype == NN)
00480 r = new MaxIntensityNN();
00481 else if (m_raytype == TRI)
00482 r = new MaxIntensityTRI();
00483 break;
00484 case XRAY:
00485 if (m_raytype == NN)
00486 r = new XRayNN();
00487 else if (m_raytype == TRI)
00488 r = new XRayTRI();
00489 break;
00490 }
00491
00492 r->SetViewingCondition(m_lightpos, m_ambient, m_diffuse, m_specular, m_highlight);
00493 r->Initialize(m_background,m_background,m_steplength,m_viewingplane,m_data,m_tf);
00494 r->SetLight(m_light);
00495
00496 for(int j = 0; j < m_height; j++) {
00497 for(int i = 0; i < m_width; i++) {
00498 r->Reset();
00499 direction = pos-m_eye;
00500 r->SetPosDir(m_eye,direction);
00501 r->CastNext();
00502 m_image[j*m_width+i] = r->GetCurrentColor().toRGB();
00503
00504
00505 pos += m_xdir;
00506
00507 if ((counter-- <= 0) && (progPos < 100)) {
00508 counter = loadSize;
00509 pFrame->SendMessage(MYWM_PROGRESS, progPos++);
00510 }
00511
00512
00513 }
00514 pos = backup;
00515 pos += j*m_ydir;
00516
00517 pFrame->SendMessage(MYWM_PROGRESS, 0);
00518
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 if (r)
00660 delete r;
00661
00662 ready = true;
00663 return true;
00664 }
00665
00666
00667 bool
00668 Perspective::RotateX(float alpha) {
00669 int maxX = m_data->GetXDim()-1;
00670 int maxY = m_data->GetYDim()-1;
00671 int maxZ = m_data->GetZDim()-1;
00672 Matrix4x4 rotmat;
00673 rotmat.rotateX(-alpha);
00674 m_eye = rotmat*m_eye;
00675 m_viewingplane->normal = VECTOR(maxX/2,maxY/2,maxZ/2)-m_eye;
00676 m_viewingplane->normal.normalize();
00677 m_viewingplane->point = m_eye + m_dist*m_viewingplane->normal;
00678
00679 SetViewingMatrix();
00680 return true;
00681 }
00682
00683 bool
00684 Perspective::RotateY(float alpha) {
00685 int maxX = m_data->GetXDim()-1;
00686 int maxY = m_data->GetYDim()-1;
00687 int maxZ = m_data->GetZDim()-1;
00688 Matrix4x4 rotmat;
00689 rotmat.rotateY(-alpha);
00690 m_eye = rotmat*m_eye;
00691 m_viewingplane->normal = VECTOR(maxX/2,maxY/2,maxZ/2)-m_eye;
00692 m_viewingplane->normal.normalize();
00693 m_viewingplane->point = m_eye + m_dist*m_viewingplane->normal;
00694
00695 SetViewingMatrix();
00696 return true;
00697 }
00698
00699 bool
00700 Perspective::RotateZ(float alpha) {
00701 int maxX = m_data->GetXDim()-1;
00702 int maxY = m_data->GetYDim()-1;
00703 int maxZ = m_data->GetZDim()-1;
00704 Matrix4x4 rotmat;
00705 rotmat.rotateZ(-alpha);
00706 m_eye = rotmat*m_eye;
00707 m_viewingplane->normal = VECTOR(maxX/2,maxY/2,maxZ/2)-m_eye;
00708 m_viewingplane->normal.normalize();
00709 m_viewingplane->point = m_eye + m_dist*m_viewingplane->normal;
00710
00711 SetViewingMatrix();
00712 return true;
00713 }