Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

picking.cpp

Go to the documentation of this file.
00001 /* *************************************************************************************
00002         Writer:         Sebastien Bloc
00003         Copyright:      2003-2004
00004         eMail:          sebastien.bloc@free.fr
00005         URL:            http://mignonsoft.free.fr
00006 
00007         This program is free software; you can redistribute it and/or
00008         modify it under the terms of the GNU General Public License
00009         as published by the Free Software Foundation; either version 2
00010         of the License, or (at your option) any later version.
00011 
00012         This program is distributed in the hope that it will be useful,
00013         but WITHOUT ANY WARRANTY; without even the implied warranty of
00014         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015         GNU General Public License for more details.
00016         http://www.gnu.org/copyleft/gpl.html
00017 ************************************************************************************* */
00018 
00019 #include "3d.h"
00020 #include "control.h"
00021 #include "face.h"
00022 #include "controlEngine.h"
00023 #include "picking.h"
00024 #include "resource.h"
00025 
00026 extern ControlEngine ce;
00027 
00028 Picking::Picking()
00029 {
00030         ResetLast();
00031         ResetCurrent();
00032         isMoving=FALSE;
00033         zDist=0;
00034 }
00035 
00040 void Picking::ResetLast()
00041 {
00042         lastFaceHover=-1;
00043         lastFaceContainer=-1;
00044         lastControlHover=NULL;
00045         lastControlContainer=NULL;
00046 }
00047 
00048 void Picking::ResetCurrent()
00049 {
00050         faceHover=-1;
00051         faceContainer=-1;
00052         controlHover=NULL;
00053         controlContainer=NULL;
00054 }
00055 
00057 void Picking::UpdateLast()
00058 {
00059         lastFaceHover=faceHover;
00060         lastFaceContainer=faceContainer;
00061         lastControlHover=controlHover;
00062         lastControlContainer=controlContainer;
00063 }
00064 
00065 void Picking::operator=(Picking &src)
00066 {
00067         mouse=src.mouse;
00068         oldMouse=src.oldMouse;
00069         controlHover=src.controlHover;                  
00070         controlContainer=src.controlContainer;
00071         faceHover=src.faceHover;
00072         faceContainer=src.faceContainer;
00073         zDist=src.zDist;
00074         isMoving=src.isMoving;
00075 }
00076 
00077 void Picking::SetMousePos(int x,int y)
00078 {
00079         oldMouse = mouse;               
00080         mouse.pos.Set(x,y);
00081         isMoving = oldMouse.pos!=mouse.pos;
00082 }
00083 
00084 void Picking::SetDeltaWheel(int delta)
00085 {
00086         mouse.wheelDelta=delta;
00087         mouse.wheelVal+=delta;
00088 }
00089 
00090 
00091 void Picking::OnMouseMove(int x,int y)
00092 {
00093         SetMousePos(x,y);
00094         controlHover->OnMouseMove(&mouse,faceHover);
00096 }
00097 
00098 void Picking::OnMouseWheel(int delta)
00099 {
00100         SetDeltaWheel(delta);
00101         controlHover->OnMouseWheel(&mouse,faceHover);
00102 }
00103 
00104 void Picking::OnLButtonUp()
00105 {
00106         mouse.leftBtn=FALSE;
00107         controlHover->onControl.mouse.left.up(&mouse,faceHover);
00108 }
00109 
00110 void Picking::OnMButtonUp()
00111 {
00112         mouse.midBtn=FALSE;
00113         controlHover->onControl.mouse.mid.up(&mouse,faceHover);
00114 }
00115 
00116 void Picking::OnRButtonUp()
00117 {
00118         mouse.rightBtn=FALSE;
00119         controlHover->onControl.mouse.right.up(&mouse,faceHover);
00120 }
00121 
00122 
00123 GLuint bufferSelect[MAX_BUFFER_SELECT]; // buffer du picking
00124 
00129 void Picking::TestOvers()
00130 {
00131         TestOver(lastControlHover,lastFaceHover,controlHover,faceHover);
00132         if (lastControlHover!=lastControlContainer)
00133                 TestOver(lastControlContainer,lastFaceContainer,controlContainer,faceContainer);
00134 }
00135 
00137 
00138 void Picking::TestOver(Control *lastControl,int lastFace,Control *control,int face)
00139 {       
00140         if(!lastControl) lastControl=ce.univers;
00141         if (control!=lastControl)
00142         {
00143                 if (lastFace!=-1)
00144                 {
00145                         lastControl->OverOut(control,face);
00146                         lastControl->FaceOverOut(face); 
00147                 }
00148                 control->OverIn(lastControl,lastFace);
00149                 control->FaceOverIn(lastFace);
00150         } 
00151         else if (face!=lastFace)
00152         {
00153                 if (lastFace!=-1) lastControl->FaceOverOut(face);
00154                 control->FaceOverIn(lastFace);
00155         }
00156 }
00157 
00158 BOOL Picking::Test()
00159 {   
00160         ce.monitor.Begin("testPicking");
00161         // config du buffer de resultat du picking
00162         glSelectBuffer(MAX_BUFFER_SELECT,bufferSelect); // liste des noms en intersection
00163         glRenderMode(GL_SELECT);
00164 
00165         // inint des noms
00166         glInitNames();
00167         glPushName(-1);
00168 
00169         // on zoom sur la souris
00170         glMatrixMode(GL_PROJECTION);
00171         glPushMatrix();
00172         glLoadIdentity();
00173         gluPickMatrix(mouse.pos.x,(GLdouble)(ce.deltaYwin-mouse.pos.y),1,1,ce.viewPort);
00174         ce.SetPerspective(0,0);
00175 
00176         // on dessine la scene virtuelement
00177         glMatrixMode(GL_MODELVIEW); 
00178         ce.monitor.End("testPicking");
00179         ce.monitor.Begin("drawPicking");
00180         ce.DrawScene(TRUE);
00181         ce.monitor.End("drawPicking");
00182         ce.monitor.Begin("testPicking");
00183         // on ce replace comme avant le picking
00184         glMatrixMode(GL_PROJECTION);
00185         glPopMatrix();
00186 
00187         int idControl;
00188         int nbElem = glRenderMode(GL_RENDER);
00189         MyString fullText;
00190         MyString selectedText;
00191         MyString selectedTextTitle;
00192         static MyString oldFullText;
00193         fullText.Format("Find(%d): ",nbElem);
00194         UpdateLast();
00195         if (nbElem>0) 
00196         {
00197                 GLuint *ptr=bufferSelect;
00198                 float zMinMin;
00199                 for (int i=0;i<nbElem;i++)
00200                 {
00201                         int names = *ptr;
00202                         GLuint *ptr1= ++ptr;
00203                         GLuint *ptr2= ++ptr;
00204                         float zMin = (float)*ptr1/0x7fffffff;
00205                         float zMax = (float)*ptr2/0x7fffffff;
00206                         BOOL isMin;
00207 
00208                         // le quel est le plus pres de l'observeur
00209                         if (i==0) isMin=TRUE;
00210                         else 
00211                         {
00212                                 if (zMinMin>zMin) isMin = TRUE;
00213                                 else isMin = FALSE;
00214                         }
00215                         //temp.AddFormat("[%.1lf,%.1lf]",zMin,zMax);
00216                         ptr++;
00217                         fullText<<"{";
00218                         if (isMin) zMinMin=zMin;
00219                         for(int j=0;j<names;j++)
00220                         {
00221                                 if (isMin)
00222                                 {
00223                                         if (j==1) idControl = *ptr;
00224                                         if (j==2) faceHover = *ptr;
00225                                 }
00226                                 fullText.AddFormat("%d ",*ptr);
00227                                 ptr++;
00228                         }
00229                         fullText<<"} ";
00230                 }
00231                 controlHover = Control::Find(idControl);
00232                 if (!controlHover) 
00233                 {
00234                         controlHover =ce.univers;
00235                         faceHover=-1;
00236                 }
00237                 else 
00238                 {
00239                         Face *face;
00240                         if (controlHover->faceNode->childs.GetNbElem())
00241                                 face = controlHover->faceNode->childs.i[faceHover]->elem;
00242                         else 
00243                                 face = controlHover->faceNode->elem; // pour le cas d'un Tip par example
00244                         GLfloat zMouse;
00245                         glReadPixels(mouse.pos.x,(int)ce.dyWin-mouse.pos.y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&zMouse);
00246                         zDist=zMinMin;
00247 
00248                         selectedTextTitle.Format("%s / %s",(char *)controlHover->name,(char *)face->name);
00249                         selectedText.Format("d1:%f d2:%f",zMinMin,zMouse);
00250                 }
00251         }
00252         else 
00253         {
00254                 if (ce.enablePicking) selectedTextTitle="<Nothing>";
00255                 else selectedTextTitle="<Not tested>";
00256                 controlHover = ce.univers;
00257                 faceHover=-1;
00258         }       
00259         if (oldFullText!=fullText)
00260         {
00261                 // partie a optimise, car fait chutter un peut les performances
00262                 MyDebug::SendEvent("Picking",selectedTextTitle);
00263                 oldFullText=fullText;
00264                 if (ce.screenConfig.hWnd)
00265                 {
00266                         Edit_SetText(GetDlgItem(ce.screenConfig.hWnd,IDC_STATIC_PICKING_FULL),fullText);
00267                         Edit_SetText(GetDlgItem(ce.screenConfig.hWnd,IDC_STATIC_PICKING_SELECTED),selectedText);
00268                         Edit_SetText(GetDlgItem(ce.screenConfig.hWnd,IDC_STATIC_PICKING_SELECTED_TITLE),selectedTextTitle);
00269                 }
00270         }
00271         FindContainer();
00272         TestOvers();
00273         ce.monitor.End("testPicking");
00274         return TRUE;
00275 }
00276 
00283 BOOL Picking::FindContainer()
00284 {
00285         if (!controlHover) return FALSE;
00286 
00287         FaceNode *faceNode;
00288         if (faceHover==-1) faceNode = controlHover->faceNode;
00289         else faceNode = controlHover->faceNode->childs.i[faceHover];
00290         FaceNode *faceNodeOld = faceNode;
00291         while 
00292         (
00293                 (faceNode->parent!=ce.univers->faceNode)&&
00294                 (faceNode->parent!=ce.masterContainer->faceNode)
00295         ) 
00296         {
00297                 faceNodeOld=faceNode;
00298                 faceNode=faceNode->parent;
00299         }
00300         controlContainer=Control::Find(faceNodeOld->elem->idControl);
00301         faceContainer=faceNodeOld->elem->idFace;
00302 
00303         /*
00304         Control *control = controlHover;
00305         while (control->parent!=ce.univers) control=control->parent;
00306         controlContainer=control;
00307         */
00308         return TRUE;
00309 }

Generated on Fri Aug 20 19:19:48 2004 for 3d Controls by doxygen 1.3.6