00001
00002
00003
00004 #include "object.h"
00005 #include "objectarray.h"
00006 #include "facearray.h"
00007 #include "nodearray.h"
00008 #include "node.h"
00009 #include "face.h"
00010 #include "edgearray.h"
00011 #include "edge.h"
00012 #include "point3d.h"
00013 #include "cyberware.h"
00014
00015
00016
00017
00018 #include "screen.h"
00019
00020 #include <stdlib.h>
00021 #include <assert.h>
00022 #include <stdio.h>
00023
00024 #ifdef _WIN32
00025 #include <windows.h>
00026 #else
00027 #include <strings.h>
00028 #endif
00029
00030
00031 #ifndef __APPLE__
00032 #include <GL/gl.h>
00033 #include <GL/glu.h>
00034 #else
00035 #include <OpenGL/gl.h>
00036 #include <OpenGL/glu.h>
00037 #endif //__APPLE__
00038
00039 #define NumSources 4
00040
00041 int NP2(int num)
00042 {
00043 int res = 1;
00044 while (res < num) res *= 2;
00045 return res;
00046 }
00047
00048
00049
00050 int Screen::debug = 0;
00051 const char* Screen::rcsid = "@(#) $Id: screen.cpp,v 1.24 2006/05/30 18:48:02 craig Exp $ $Copyright: (c)2001 National Biocomputation Center, Stanford University $";
00052
00053 Screen::Screen() : Object()
00054 {
00055 if (debug) cerr << "Screen::constructor()\n";
00056 objectarray_p = NULL;
00057 type = nodes_only;
00058 dynamics = rest;
00059 behavior = none;
00060 nummethod = quasi_ordered;
00061 visible = 1;
00062 selected = 0;
00063 texture = NULL;
00064 nodearray.Init(&edgearray);
00065 strncpy(name, "UNINITIALIZED", NAME_LENGTH);
00066 sensor_p = NULL;
00067 linked_part = 0;
00068
00069 closest_node = NULL;
00070 being_grabbed = 0;
00071 sensor_offset = Point3D(0,0,0);
00072 uses_viagra = 1;
00073
00074
00075 collision_extent = no_collisions;
00076 collision_pairs.Init();
00077 boundingSphereRoot = NULL;
00078
00079
00080 dl_needs_refresh = 1;
00081 dl_id = -1;
00082
00083
00084 display_mode.mode = DisplayMode::smooth;
00085 display_mode.draw_subobjcolormode = 0;
00086 last_display_mode = display_mode;
00087
00088 Video = 0;
00089 View = 0;
00090 Source = 0;
00091 Dict = 0;
00092 Scan = 0;
00093 scan_index = 1;
00094 Dictation.x = -200.0;
00095 Dictation.y = 200.0;
00096 Dictation.z = 0.0;
00097
00098
00099 set_default_material_properties();
00100 }
00101
00102 Screen::~Screen()
00103 {
00104 if (debug) cerr << "Screen[" << name << "]::destructor()\n";
00105 strncpy(name, "DESTROYED", NAME_LENGTH);
00106 }
00107
00108 void Screen::Init(ObjectArray* objectarray_in, char* name_in)
00109 {
00110 objectarray_p = objectarray_in;
00111 if (!name_in) name_in = "UNNAMED";
00112 strncpy(name, name_in, NAME_LENGTH);
00113 nodearray.computeTextureCoords(Node::linear);
00114
00115 }
00116
00117
00118
00119
00120 void Screen::TVscreen(Point3D corner1, Point3D corner2,
00121 Point3D corner3, Point3D corner4)
00122 {
00123 type = faces_only;
00124 dynamics = rest;
00125 set_default_material_properties();
00126
00127
00128 nodearray.reset();
00129 edgearray.reset();
00130 facearray.reset();
00131 nodearray.allocateNodes(4);
00132 edgearray.allocateEdges(5);
00133 facearray.allocateFaces(2);
00134
00135
00136 int index1 = nodearray.addNode(corner1);
00137 int index2 = nodearray.addNode(corner2);
00138 int index3 = nodearray.addNode(corner3);
00139 int index4 = nodearray.addNode(corner4);
00140
00141
00142 facearray.addFace(index1, index2, index3);
00143 facearray.addFace(index3, index4, index1);
00144
00145
00146 nodearray.computeStats();
00147
00148
00149
00150
00151
00152 facearray.computeNormals();
00153
00154
00155 nodearray.interpolateNormals();
00156
00157
00158 nodearray.computeTextureCoords(Node::linear);
00159
00160
00161 }
00162
00163 int Screen::IsViewOn()
00164 {
00165 return (View);
00166 }
00167
00168 void Screen::SwitchOnView()
00169 {
00170 View = 1;
00171 }
00172
00173 void Screen::SwitchOffView()
00174 {
00175 View = 0;
00176 }
00177
00178
00179 int Screen::IsVideoOn()
00180 {
00181 return (Video);
00182 }
00183
00184 void Screen::SwitchOnVideo()
00185 {
00186 Video = 1;
00187 }
00188
00189 void Screen::SwitchOffVideo()
00190 {
00191 Video = 0;
00192 }
00193 int Screen::IsDictationOn()
00194 {
00195 return (Dict);
00196 }
00197
00198 void Screen::SwitchOnDictation()
00199 {
00200 Dict = 1;
00201 }
00202
00203 void Screen::SwitchOffDictation()
00204 {
00205 Dict = 0;
00206 }
00207
00208 int Screen::IsScanOn()
00209 {
00210 return (Scan);
00211 }
00212
00213 void Screen::SwitchOnScan()
00214 {
00215 Scan = 1;
00216 }
00217
00218 void Screen::SwitchOffScan()
00219 {
00220 Scan = 0;
00221 }
00222
00223 void Screen::ScanInit(int numscan, int scangrp)
00224 {
00225 scan_stopped = 1;
00226 scan_index = 1;
00227 scan_speed = 1;
00228 scan_count = numscan;
00229 scan_dir = 1;
00230 scan_group = scangrp;
00231 Scan = 1;
00232 }
00233
00234 void Screen::ScanFaster()
00235 {
00236 scan_stopped = 0;
00237 if (scan_speed < 50) scan_speed *=1.5;
00238 }
00239
00240 void Screen::ScanSlower()
00241 {
00242 scan_stopped = 0;
00243 if (scan_speed > 0.2) scan_speed /=1.5;
00244 }
00245
00246 void Screen::ScanRefresh()
00247 {
00248 if (!scan_stopped)
00249 {
00250 scan_index = ((int)floor(scan_index + scan_speed*scan_dir) % scan_count);
00251 if (scan_index < 0) scan_index += scan_count;
00252 }
00253 }
00254
00255 void Screen::ScanStop()
00256 {
00257 scan_stopped = 1;
00258 }
00259
00260 void Screen::ScanReverse()
00261 {
00262 scan_dir *= -1;
00263 }
00264
00265 int Screen::getScanIndex()
00266 {
00267 return scan_index;
00268 }
00269
00270 void Screen::showMarker(wall_pos dir)
00271 {
00272 double coeff;
00273 coeff = (scan_count) ? (double)scan_index/scan_count : 0;
00274 glColor4f((GLfloat)0.0, (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0.3);
00275 glBegin(GL_POLYGON);
00276 switch (dir) {
00277 case LEFT : {
00278 glVertex3d(min.x + coeff*(max.x - min.x), min.y, min.z);
00279 glVertex3d(min.x + coeff*(max.x - min.x), max.y, min.z);
00280 glVertex3d(min.x + coeff*(max.x - min.x), max.y, max.z);
00281 glVertex3d(min.x + coeff*(max.x - min.x), min.y, max.z);
00282 break;
00283 }
00284 case RIGHT : {
00285 glVertex3d(max.x - coeff*(max.x - min.x), min.y, min.z);
00286 glVertex3d(max.x - coeff*(max.x - min.x), max.y, min.z);
00287 glVertex3d(max.x - coeff*(max.x - min.x), max.y, max.z);
00288 glVertex3d(max.x - coeff*(max.x - min.x), min.y, max.z);
00289 break;
00290 }
00291 case UP : {
00292 glVertex3d(min.x,max.y - coeff*(max.y - min.y),min.z);
00293 glVertex3d(min.x,max.y - coeff*(max.y - min.y),max.z);
00294 glVertex3d(max.x,max.y - coeff*(max.y - min.y),max.z);
00295 glVertex3d(max.x,max.y - coeff*(max.y - min.y),min.z);
00296 break;
00297 }
00298 case DOWN : {
00299 glVertex3d(min.x,min.y + coeff*(max.y - min.y),min.z);
00300 glVertex3d(min.x,min.y + coeff*(max.y - min.y),max.z);
00301 glVertex3d(max.x,min.y + coeff*(max.y - min.y),max.z);
00302 glVertex3d(max.x,min.y + coeff*(max.y - min.y),min.z);
00303 break;
00304 }
00305 case BACK : {
00306 glVertex3d(min.x,min.y,min.z + coeff*(max.z - min.z));
00307 glVertex3d(max.x,min.y,min.z + coeff*(max.z - min.z));
00308 glVertex3d(max.x,max.y,min.z + coeff*(max.z - min.z));
00309 glVertex3d(min.x,max.y,min.z + coeff*(max.z - min.z));
00310 break;
00311 }
00312 case FRONT : {
00313 glVertex3d(min.x,min.y,max.z - coeff*(max.z - min.z));
00314 glVertex3d(max.x,min.y,max.z - coeff*(max.z - min.z));
00315 glVertex3d(max.x,max.y,max.z - coeff*(max.z - min.z));
00316 glVertex3d(min.x,max.y,max.z - coeff*(max.z - min.z));
00317 break;
00318 }
00319 }
00320 glEnd();
00321
00322 dl_needs_refresh = 1;
00323
00324 }
00325
00326 void Screen::newTexture(unsigned char* base)
00327 {
00328
00329
00330
00331 texture = base;
00332
00333
00334 dl_needs_refresh = 1;
00335
00336 }
00337
00338 void Screen::setGrayTexture(unsigned* my_texture)
00339 {
00340 int length = 512*512;
00341 texture = (unsigned char*)malloc(4*length*sizeof(unsigned char));
00342 for (int i = 0; i < length; i++)
00343 {
00344 texture[4*i] = my_texture[i];
00345 texture[4*i+1] = my_texture[i];
00346 texture[4*i+2] = my_texture[i];
00347 texture[4*i+3] = 0xff;
00348 }
00349 dl_needs_refresh = 1;
00350 }
00351
00352
00353
00354
00355
00356 void Screen::MakeTexture(int large, int haut)
00357 {
00358 glReadBuffer(GL_BACK);
00359 glReadPixels(0,0,large,haut,GL_RGBA,GL_UNSIGNED_BYTE, texture);
00360 }
00361
00362 void Screen::InitTexture(int large, int haut, int depth)
00363 {
00364 texture_size.x = large;
00365 texture_size.y = haut;
00366 texture_size.z = depth;
00367 }
00368
00369 void Screen::ScreenTranslate(wall_pos dir)
00370 {
00371 Point3D e1 = nodearray.getHorizontalVector();
00372 Point3D e2 = nodearray.getVerticalVector();
00373 Point3D e3;
00374 e3.x = e1.y*e2.z - e1.z*e2.y;
00375 e3.y = e1.z*e2.x - e1.x*e2.z;
00376 e3.z = e1.x*e2.y - e1.y*e2.x;
00377 float d = (float)0.04;
00378 float d2 = (float)0.0002;
00379
00380 switch (dir) {
00381 case RIGHT:
00382 {
00383 nodearray.translate(e1.x*d, e1.y*d, e1.z*d);
00384 dl_needs_refresh = 1;
00385 break;
00386 }
00387 case LEFT:
00388 {
00389 nodearray.translate(-e1.x*d, -e1.y*d, -e1.z*d);
00390 dl_needs_refresh = 1;
00391 break;
00392 }
00393 case UP:
00394 {
00395 nodearray.translate(e2.x*d, e2.y*d, e2.z*d);
00396 dl_needs_refresh = 1;
00397 break;
00398 }
00399 case DOWN:
00400 {
00401 nodearray.translate(-e2.x*d, -e2.y*d, -e2.z*d);
00402 dl_needs_refresh = 1;
00403 break;
00404 }
00405 case FRONT:
00406 {
00407 nodearray.translate(e3.x*d2, e3.y*d2, e3.z*d2);
00408 dl_needs_refresh = 1;
00409 break;
00410 }
00411 case BACK:
00412 {
00413 nodearray.translate(-e3.x*d2, -e3.y*d2, -e3.z*d2);
00414 dl_needs_refresh = 1;
00415 break;
00416 }
00417 }
00418 }
00419
00420
00421
00422 void Screen::ScreenRotate(wall_pos dir)
00423 {
00424 nodearray.pivote(dir);
00425 dl_needs_refresh = 1;
00426 }
00427
00428
00429 void Screen::ScreenStretch(wall_pos dir)
00430 {
00431 nodearray.stretch(dir);
00432 dl_needs_refresh = 1;
00433 }
00434
00435 int Screen::SwitchSource()
00436 {
00437 Source = (Source + 1) % NumSources;
00438 return (Source);
00439 }
00440
00441
00442 void Screen::ShowDictation(char* buf)
00443 {
00444
00445 }
00446
00447
00448
00449
00450 void Screen::Draw()
00451 {
00452 if (visible)
00453 DrawGeometry();
00454 if (selected)
00455 DrawBoundingBox();
00456 }
00457
00458
00459
00460
00461
00462 void Screen::DrawGeometry()
00463 {
00464 if (debug) cerr << "Object[" << name << "]::Draw(" << &display_mode << ")\n";
00465
00466
00467
00468 GLint rendermode;
00469 glGetIntegerv(GL_RENDER_MODE, &rendermode);
00470
00471
00472 extern int do_display_lists;
00473 if (do_display_lists && !dl_needs_refresh &&
00474 (display_mode == last_display_mode) && (rendermode == GL_RENDER)) {
00475 glCallList(dl_id);
00476 return;
00477 }
00478
00479
00480 if (dl_id == -1) dl_id = glGenLists(1);
00481 else glDeleteLists(dl_id, 1);
00482
00483
00484 glNewList(dl_id, GL_COMPILE_AND_EXECUTE);
00485 dl_needs_refresh = 0;
00486 last_display_mode = display_mode;
00487 if (debug) cerr << "Object[" << getName() << "- regen display-list\n";
00488
00489
00490
00491 nodearray.computeStats();
00492
00493
00494 if (rendermode == GL_SELECT)
00495 glPushName(objectarray_p->getIndex(this));
00496
00497
00498
00499 {
00500 glDisable(GL_LIGHTING);
00501 glShadeModel(GL_FLAT);
00502
00503
00504 if (display_mode.draw_nodenormals)
00505 { nodearray.drawnormals(); }
00506
00507
00508 if (display_mode.draw_facenormals)
00509 { facearray.drawnormals(); }
00510
00511
00512 if ((type == faces_only) && display_mode.draw_wireover)
00513 { glColor3d(0.0, 0.0, 0.0); edgearray.drawover(drawover_amount); }
00514
00515
00516 if (display_mode.draw_initial)
00517 { edgearray.drawinitial(); nodearray.drawinitial(); }
00518
00519
00520 if (display_mode.draw_nodelabels)
00521 { glColor3d(0.5, 1.0, 1.0); nodearray.drawlabels(label_offset); }
00522
00523
00524 if (display_mode.draw_edgelabels)
00525 { glColor3d(1.0, 1.0, 0.5); edgearray.drawlabels(label_offset); }
00526
00527
00528 if (display_mode.draw_facelabels)
00529 { glColor3d(0.5, 1.0, 0.5); facearray.drawlabels(label_offset); }
00530
00531
00532 if (display_mode.draw_objectlabels)
00533 { glColor3d(1.0, 0.0, 0.0); DrawLabel(); }
00534 }
00535
00536
00537 extern int do_textures;
00538 if (do_textures && texture && (type == faces_only) &&
00539 ((display_mode.mode == DisplayMode::flat) ||
00540 (display_mode.mode == DisplayMode::smooth))){
00541
00542 glEnable(GL_TEXTURE_2D);
00543
00544
00545 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00546
00547
00548
00549 if (texture_mode == Object::texture_env_mode(0))
00550 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00551 else if (texture_mode == texture_env_mode(1))
00552 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
00553 else if (texture_mode == Object::texture_env_mode(2))
00554 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
00555 else if (texture_mode == Object::texture_env_mode(3))
00556 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00557
00558 if (texture_wrap == Object::texture_wrap_st(0)) {
00559 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00560 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00561 }
00562 else {
00563 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00564 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00565 }
00566
00567 if (texture_filter == Object::texture_min_mag_filter(0)) {
00568 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00569 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00570 }
00571 else {
00572 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00573 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00574 }
00575
00576
00577 if (debug)
00578 cerr << "applying " << texture_size.x << "x" << texture_size.y
00579 << " texture...\n";
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 int crop_w = 1,crop_h = 1;
00593 int grab_w = 256,grab_h = 256;
00594 if ((texture_size.x == 256) || (texture_size.x == 512))
00595 {
00596 grab_w = texture_size.x;
00597 crop_w = 0;
00598 }
00599 if ((texture_size.y == 256) || (texture_size.y == 512))
00600 {
00601 grab_h = texture_size.y;
00602 crop_h = 0;
00603 }
00604
00605
00606 unsigned char*texture2 = NULL;
00607 int d = texture_size.z;
00608 if (crop_w*crop_h) {
00609
00610 if (!texture2)
00611 texture2 = (unsigned char*)malloc(grab_w*grab_h*d*sizeof(unsigned char));
00612
00613
00614
00615
00616
00617
00618 int texWidth = (grab_w > texture_size.x ? texture_size.x : grab_w);
00619 int texHeight = (grab_h > texture_size.y ? texture_size.y : grab_h);
00620
00621 for (int count = 0; count < texHeight; count++)
00622 memcpy((char *)texture2 + count*grab_w*d, (char *)texture + (count)*texture_size.x*d, texWidth*d);
00623 }
00624 else
00625 texture2 = (unsigned char*)texture;
00626
00627 switch (d) {
00628 case 1:
00629 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, grab_w,
00630 grab_h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texture2);
00631 break;
00632 case 3:
00633 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, grab_w,
00634 grab_h, 0, GL_RGB, GL_UNSIGNED_BYTE, texture2);
00635 break;
00636 case 4:
00637 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, grab_w,
00638 grab_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2);
00639 break;
00640 default:
00641 break;
00642 }
00643
00644
00645
00646
00647 }
00648
00649
00650
00651 switch (type) {
00652 case nodes_only: {
00653 glDisable(GL_LIGHTING);
00654 nodearray.DrawNodes();
00655 break;
00656 }
00657 case edges_only: {
00658 glDisable(GL_LIGHTING);
00659 edgearray.DrawEdges();
00660 if (display_mode.mode == DisplayMode::wireframe)
00661 nodearray.DrawNodes();
00662 break;
00663 }
00664 case faces_only: {
00665
00666 facearray.computeNormals();
00667
00668
00669 nodearray.interpolateNormals();
00670
00671
00672 if (display_mode.mode == DisplayMode::wireframe) {
00673 glDisable(GL_LIGHTING);
00674 edgearray.DrawEdges();
00675 nodearray.DrawNodes();
00676 }
00677
00678
00679 if ((display_mode.mode == DisplayMode::flat) ||
00680 (display_mode.mode == DisplayMode::smooth)) {
00681
00682 glEnable(GL_LIGHTING);
00683
00684
00685 if (display_mode.mode == DisplayMode::flat) glShadeModel(GL_FLAT);
00686 else glShadeModel(GL_SMOOTH);
00687
00688 {
00689 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
00690 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
00691 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
00692 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
00693
00694 glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
00695 glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
00696 glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
00697 glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
00698 }
00699
00700
00701 facearray.DrawFaces(int(do_textures && texture));
00702 }
00703 break;
00704 }
00705 }
00706
00707
00708 glDisable(GL_TEXTURE_2D);
00709
00710 {
00711
00712 if (display_mode.draw_tienodes) {
00713
00714 nodearray.drawtienodes();
00715
00716 }
00717
00718
00719 if (display_mode.draw_boundingspheres && boundingSphereRoot)
00720 boundingSphereRoot->drawSubtree();
00721
00722
00723 if (display_mode.draw_principalaxis){
00724 getNodeArray()->PrincipalAxes();
00725 DrawPrincipalAxes();
00726 }
00727 }
00728
00729
00730 if (rendermode == GL_SELECT)
00731 glPopName();
00732
00733
00734 glEndList();
00735 }