00001 /* 00002 File: ScenePane.cc 00003 00004 Function: See header file 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2000, Andrew Willmott 00009 00010 Notes: May have to split some of this stuff out. 00011 To come: picking, quaternion rotation (mouseball) & 00012 mouse pole. 00013 */ 00014 00015 #include "gcl/GCLConfig.h" 00016 00017 #ifndef GCL_NO_GL 00018 00019 #include "gcl/ScenePane.h" 00020 #include "gcl/GCLConfig.h" 00021 #include "gcl/MRModel.h" 00022 #include "gcl/SceneLang.h" 00023 00024 #ifdef VL_ROW_ORIENT 00025 #error not_implemented 00026 #endif 00027 00028 00029 // --- Frame primitive --------------------------------------------------------- 00030 00031 // this is just for display -- don't add it to any model definitions. 00032 00033 class scFrame : public scPrimitive 00034 { 00035 public: 00036 scFrame() : 00037 scPrimitive(pExtension), 00038 divisions(10), 00039 gridOn(false), 00040 axesOn(false) 00041 {}; 00042 00043 Void Draw(Renderer &r, SLContext *); 00044 00045 Int divisions; 00046 Bool gridOn; 00047 Bool axesOn; 00048 }; 00049 00050 static Void DefineArrow(StrConst arrowName, GCLReal length, GCLReal width, GCLReal tipLength) 00051 { 00052 if (slObjectExists(arrowName)) return; 00053 00054 scScenePtr arrow; 00055 00056 arrow = slBeginObject(arrowName); 00057 00058 slBeginObject("shaft"); 00059 slColour(cWhite); 00060 slTransform(Scale(width, length - tipLength, width) * Shift(0.0, 0.5, 0.0)); 00061 slObject("cylinder"); 00062 slEndObject(); 00063 00064 slBeginObject("tip"); 00065 slTransform(Shift(0, length - tipLength, 0) * Scalef(tipLength)); 00066 slObject("cone"); 00067 slEndObject(); 00068 00069 slEndObject(); 00070 00071 slAddToLibrary(arrow); 00072 } 00073 00074 static Void DefineAxes() 00075 { 00076 scScenePtr axes; 00077 00078 DefineArrow("gridArrow", 0.5, 0.02, 0.1); 00079 00080 axes = slBeginObject("gridAxes"); 00081 slColour(cGreen); 00082 slObject("gridArrow"); 00083 slTransform(Rotation(vl_x, vl_halfPi)); 00084 slColour(cBlue); 00085 slObject("gridArrow"); 00086 slTransform(Rotation(vl_z, -vl_halfPi)); 00087 slColour(cRed); 00088 slObject("gridArrow"); 00089 slEndObject(); 00090 00091 slAddToLibrary(axes); 00092 } 00093 00094 Void scFrame::Draw(Renderer &r, SLContext *) 00095 { 00096 if (axesOn) 00097 { 00098 if (!slObjectExists("gridAxes")) 00099 DefineAxes(); 00100 00101 r.Draw(slGetLibrary()->Member("gridAxes")); 00102 } 00103 00104 if (gridOn) 00105 { 00106 Int i, j; 00107 GCLReal x, y, d; 00108 Point p1, p2, p3, p4; 00109 00110 d = 2.0 / divisions; 00111 00112 r.C(Colour4(cGreen, 0.5)); 00113 r.N(vl_y); 00114 p1 = p2 = p3 = p4 = vl_0; 00115 r.Begin(renLines); 00116 00117 for (i = 0; i <= divisions; i++) 00118 { 00119 y = -1.0 + i * d; 00120 r.P(Point(-1.0, 0.0, y)).P(Point(1.0, 0.0, y)); 00121 for (j = 0; j <= divisions; j++) 00122 { 00123 x = -1.0 + j * d; 00124 r.P(Point(x, 0.0, -1.0)).P(Point(x, 0.0, 1.0)); 00125 } 00126 } 00127 r.End(); 00128 00129 r.C(Colour4(cCyan, 0.3)); 00130 r.Begin(renPoly) 00131 .P(Point(-1.0, 0.0, -1.0)) 00132 .P(Point(-1.0, 0.0, 1.0)) 00133 .P(Point( 1.0, 0.0, 1.0)) 00134 .P(Point( 1.0, 0.0, -1.0)) 00135 .End(); 00136 } 00137 } 00138 00139 00140 // --- ScenePane class -------------------------------------------------------- 00141 00142 00143 ScenePane::ScenePane(Bool doubleBuf) : 00144 GLXPane(doubleBuf), 00145 itsScene(0), 00146 itsCamera(0), 00147 rot(vl_0), 00148 trans(vl_0), 00149 zoom(1.0), 00150 wire(false), 00151 gridShown(false), 00152 axesShown(false) 00153 { 00154 SetBgColour(cGrey50); 00155 } 00156 00157 Void ScenePane::SetScene(scScenePtr scene) 00158 { 00159 itsCamera = (scCamera *) scene->FindFirst(aCamera); 00160 00161 if (!itsCamera) 00162 itsCamera = new scCamera; 00163 else 00164 { 00165 itsCamera->GetModelCentricParams(); 00166 00167 trans = itsCamera->trans; 00168 rot = itsCamera->rot; 00169 } 00170 00171 itsScene = new scGroup; 00172 // add default colour 00173 itsScene->Add(new scColour(scPrimitive::sDefaultColour)); 00174 // scene & camera 00175 itsScene->Add(itsCamera); 00176 itsScene->Add(scene); 00177 // add frame 00178 frame = new scFrame; 00179 frame->gridOn = gridShown; 00180 frame->axesOn = axesShown; 00181 itsScene->Add(frame); 00182 00183 SetCameraParams(); 00184 00185 // make a list of mr models in the scene 00186 scene->ApplyAction(models); 00187 00188 Redraw(); 00189 00190 if (doubleBuffered) 00191 Redraw(); 00192 } 00193 00194 Void ScenePane::SetCameraParams() 00195 { 00196 itsCamera->SetAspect(GCLReal(width) / GCLReal(height)); 00197 itsCamera->SetModelCentric(rot, trans); 00198 } 00199 00200 Void ScenePane::Redraw() 00201 { 00202 Clear().Draw(itsScene).Show(); 00203 } 00204 00205 const GCLReal kElevLimit = 0.495; 00206 // To stop us reaching the singularity on the y axis. 00207 00208 00209 Void ScenePane::ViewFrom(Point &position, Vector &normal) 00210 { 00211 // BROKEN: view stack 00212 } 00213 00214 Void ScenePane::Restore() 00215 { 00216 // BROKEN 00217 } 00218 00219 // --- Scene dragging --------------------------------------------------------- 00220 00221 Void ScenePane::TrackMouse(Int sx, Int sy, Int modifiers) 00222 { 00223 Int x, y; 00224 Coord start((sx + 0.5) / width, 1.0 - (sy + 0.5) / height); 00225 Coord c = start; 00226 Int newModifiers; 00227 00228 StartDrag(start, modifiers); 00229 GetMouse(x, y, newModifiers); 00230 00231 while (newModifiers & wmButtons) 00232 { 00233 c = Coord((x + 0.5) / width, 1.0 - (y + 0.5) / height); 00234 Drag(c, modifiers); 00235 GetMouse(x, y, newModifiers); 00236 } 00237 00238 EndDrag(c, modifiers); 00239 } 00240 00241 Void ScenePane::StartDrag(Coord c, Int mod) 00242 { 00243 tRot = rot; 00244 tZoom = zoom; 00245 tTrans = trans; 00246 00247 dragStart = c; 00248 modifiersStart = mod; 00249 00250 baseErr = scMRModel::GetComplexity(); 00251 00252 if (mod & (wmButton1 | wmButton2)) 00253 if (baseErr > 0.5) 00254 scMRModel::SetComplexity(0.1); 00255 } 00256 00257 Void ScenePane::Drag(Coord c, Int) 00258 { 00259 // standard behaviour: button1 = rotation, button 2 = translation, 00260 // button 3 = adjust complexity. 00261 00262 offset = c - dragStart; 00263 if (modifiersStart & wmButton1) 00264 { 00265 if (modifiersStart & wmControl) 00266 SceneTransDrag(); 00267 else 00268 SceneRotDrag(); 00269 } 00270 else if (modifiersStart & wmButton2) 00271 SceneTransDrag(); 00272 else if (modifiersStart & wmButton3) 00273 ComplexityDrag(); 00274 } 00275 00276 Void ScenePane::EndDrag(Coord, Int) 00277 { 00278 rot = tRot; 00279 trans = tTrans; 00280 zoom = tZoom; 00281 00282 if (modifiersStart & (wmButton1 | wmButton2)) 00283 if (baseErr != scMRModel::GetComplexity()) 00284 { 00285 scMRModel::SetComplexity(baseErr); 00286 Redraw(); 00287 } 00288 } 00289 00290 Void ScenePane::ComplexityDrag() 00291 { 00292 scMRModel::SetComplexity(Clip(baseErr + offset[1], 00293 (GCLReal) 0.0, (GCLReal) 1.0)); 00294 00295 Redraw(); 00296 } 00297 00298 Void ScenePane::SceneRotDrag() 00299 { 00300 if (modifiersStart & wmShift) 00301 { 00302 tZoom = zoom - offset[1]; 00303 itsCamera->SetScale(tZoom); 00304 // itsCamera->SetFOV(30.0 / tZoom); 00305 } 00306 else 00307 { 00308 tRot[1] = rot[1] + offset[0]; // rotation 00309 tRot[0] = rot[0] - offset[1]; // elevation 00310 if (tRot[0] < -kElevLimit) 00311 tRot[0] = -kElevLimit; 00312 else if (tRot[0] > kElevLimit) 00313 tRot[0] = kElevLimit; 00314 00315 itsCamera->SetModelCentric(tRot, trans); 00316 } 00317 00318 Clear().Draw(itsScene).Show(); 00319 } 00320 00321 Void ScenePane::SceneTransDrag() 00322 { 00323 if (modifiersStart & wmShift) 00324 tTrans[2] = trans[2] - offset[1]; 00325 else 00326 { 00327 tTrans[0] = trans[0] + offset[0]; 00328 tTrans[1] = trans[1] + offset[1]; 00329 } 00330 itsCamera->SetModelCentric(rot, tTrans); 00331 00332 Clear().Draw(itsScene).Show(); 00333 } 00334 00335 Void ScenePane::HandleExpose() 00336 { 00337 Redraw(); 00338 } 00339 00340 Void ScenePane::HandleKey(Char c) 00341 { 00342 Int i; 00343 00344 switch (c) 00345 { 00346 case 'w': 00347 wire = !wire; 00348 if (wire) 00349 scPrimitive::sRenderStyle = renLineLoop; 00350 else 00351 scPrimitive::sRenderStyle = renPoly; 00352 Redraw(); 00353 break; 00354 00355 case 'G': 00356 SetGrid(!gridShown); 00357 Redraw(); 00358 break; 00359 00360 case 'A': 00361 SetAxes(!axesShown); 00362 Redraw(); 00363 break; 00364 00365 case 'S': 00366 for (i = 0; i < models.NumModels(); i++) 00367 models.Model(i)->SimplestModel(); 00368 scMRModel::SetComplexity(0.0); 00369 Redraw(); 00370 break; 00371 00372 case 'C': 00373 for (i = 0; i < models.NumModels(); i++) 00374 models.Model(i)->MostComplexModel(); 00375 scMRModel::SetComplexity(1.0); 00376 Redraw(); 00377 break; 00378 00379 case 'V': 00380 for (i = 0; i < models.NumModels(); i++) 00381 models.Model(i)->showMeta = !models.Model(i)->showMeta; 00382 Redraw(); 00383 break; 00384 00385 case 'F': 00386 for (i = 0; i < models.NumModels(); i++) 00387 models.Model(i)->showFaces = !models.Model(i)->showFaces; 00388 Redraw(); 00389 break; 00390 00391 case 'X': 00392 for (i = 0; i < models.NumModels(); i++) 00393 models.Model(i)->colourFaces = !models.Model(i)->colourFaces; 00394 Redraw(); 00395 break; 00396 00397 case 'N': 00398 for (i = 0; i < models.NumModels(); i++) 00399 models.Model(i)->CropClusters(models.Model(i)->currentClusters); 00400 Redraw(); 00401 break; 00402 00403 case '[': 00404 for (i = 0; i < models.NumModels(); i++) 00405 models.Model(i)->AdaptClusters(models.Model(i)->currentClusters - 1); 00406 Redraw(); 00407 break; 00408 case ']': 00409 for (i = 0; i < models.NumModels(); i++) 00410 models.Model(i)->AdaptClusters(models.Model(i)->currentClusters + 1); 00411 Redraw(); 00412 break; 00413 00414 case '0': 00415 SetHeadlight(false); 00416 Redraw(); 00417 break; 00418 00419 case '1': 00420 SetHeadlight(true); 00421 Redraw(); 00422 break; 00423 00424 case '!': 00425 SetDoubleSided(true); 00426 Redraw(); 00427 break; 00428 00429 case ')': 00430 SetDoubleSided(false); 00431 Redraw(); 00432 break; 00433 00434 default: 00435 XEventPane::HandleKey(c); 00436 } 00437 } 00438 00439 Void ScenePane::SetGrid(Bool on) 00440 { 00441 gridShown = on; 00442 frame->gridOn = on; 00443 } 00444 00445 Void ScenePane::SetAxes(Bool on) 00446 { 00447 axesShown = on; 00448 frame->axesOn = on; 00449 } 00450 00451 // --- ScenePane2D methods ---------------------------------------------------- 00452 00453 Void ScenePane2D::SetScene(scScenePtr scene) 00454 { 00455 ScenePane::SetScene(scene); 00456 itsCamera->SetFOV(RadsToDegs(atan(0.25))); 00457 } 00458 00459 Void ScenePane2D::Drag(Coord c, Int) 00460 { 00461 offset = c - dragStart; 00462 00463 if (modifiersStart & wmShift) 00464 { 00465 tTrans[2] = trans[2] + offset[1]; 00466 } 00467 else 00468 { 00469 tTrans[0] = trans[0] + offset[0] / zoom; 00470 tTrans[1] = trans[1] + offset[1] / zoom; 00471 } 00472 00473 itsCamera->SetModelCentric(rot, tTrans); 00474 00475 Clear().Draw(itsScene).Show(); 00476 } 00477 00478 #endif