Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

ScenePane.cc

Go to the documentation of this file.
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

Generated at Sat Aug 5 00:17:03 2000 for Graphics Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000