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

primitive.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 "layout.h"
00021 #include "face.h"
00022 #include "primitive.h"
00023 #include "controlEngine.h"
00024 
00025 extern ControlEngine ce;
00026 
00027 Primitive::Primitive()
00028 {
00029         //layout.SetFull();
00030 }
00031 
00032 Primitive::~Primitive()
00033 {
00034         tree.SuprAll();
00035 }
00036 
00037 void Primitive::Push()
00038 {
00039         stack.Push(tree.GetCurrent());
00040 }
00041 
00042 void Primitive::Pop()
00043 {
00044         tree.GoTo(stack.Pop());
00045 }
00046 
00047 FaceNode * Primitive::GoTo(int childNumber)
00048 {
00049         return tree.GoToChild(childNumber);
00050 }
00051 
00052 FaceNode * Primitive::GoTo(FaceNode *node)
00053 {
00054         return tree.GoTo(node);
00055 }
00056 
00057 FaceNode * Primitive::GoToParent()
00058 {
00059         return tree.GoToParent();
00060 }
00061 
00062 FaceNode * Primitive::Peek()
00063 {
00064         if (!stack.GetNbElem()) return NULL;
00065         return stack.Peek();
00066 }
00067 
00071 void Primitive::ViewDebug(FaceNode *node)
00072 {
00073         if (!node) node= tree.GetRoot();
00074         static MyString message;
00075         static int level=0;
00076         for (int i=0;i<level;i++) message+="| ";
00077         level++;
00078         message<<node->elem->name<<"\n";
00079         for (node->childs.i=0;node->childs.i.More();node->childs.i++) 
00080                 ViewDebug(node->childs.i.GetElem());
00081         level--;
00082         if (!level) 
00083         {
00084                 MessageBox(NULL,message,"Debug of primitive",0);
00085                 message="";
00086         }
00087 }
00088 
00089 void Primitive::ComputeLayout(FaceNode *faceNode)
00090 {
00091         if (!faceNode) return;
00092         ComputeLayout(faceNode->parent);
00093         faceNode->elem->ComputeLayout();
00094 }
00095 
00096 void Primitive::ReOrderForBlending()
00097 {
00098         ReOrderForBlending(tree.GetRoot());
00099 }
00100 
00102 BOOL Primitive::ReOrderForBlending(FaceNode *faceNode)
00103 {
00104         if (!faceNode) return FALSE;
00105         FaceNode *curChild;
00106         MyListItem<FaceNode *> *item;
00107         item = faceNode->childs.first;
00108         BOOL contentBlending = FALSE;
00109         while (item)
00110         {
00111                 curChild = *item->elem;
00112                 item = item->after;
00113                 if (ReOrderForBlending(curChild)) contentBlending=TRUE;
00114         }
00115         if (faceNode->elem->blending||contentBlending) 
00116         {
00117                 faceNode->MoveToLastChild();
00118                 return TRUE;
00119         }
00120         return FALSE;
00121 
00122 }
00123 
00124 void Primitive::GetCorners(FaceNode *faceNode,Point3D<double> *points)
00125 {
00126         glMatrixMode(GL_MODELVIEW);
00127         glPushMatrix();
00128         glLoadIdentity();
00129         gluLookAt(0,0,ce.depth,0,0,0,0,1,0);
00130         ce.ApplyScaleView();
00131         GetCornersRecursive(faceNode,TRUE,points);
00132         glPopMatrix();
00133 }
00134 
00136 Point2D<double> Primitive::GetLocalPos(FaceNode *faceNode,Point2D<double> absolutePos)
00137 {
00138         Point3D<double> corners[4];
00139         GetCorners(faceNode,corners);
00140 
00141         Point2D<double> a,b,c,d,p;
00142         a.Set(corners[0].x,corners[0].y);
00143         b.Set(corners[1].x,corners[1].y);
00144         c.Set(corners[2].x,corners[2].y);
00145         d.Set(corners[3].x,corners[3].y);
00146         double alphaX=0,alphaY=0;
00147         if (!absolutePos.GetRelativePtOnQuadrilatere(a,b,c,d,&alphaX,&alphaY)) return p; // erreur
00148         p.Set(faceNode->elem->computeSize.x*alphaX,faceNode->elem->computeSize.y*(1.0-alphaY));
00149         return p;
00150 }
00151 
00152 void Primitive::GetCornersRecursive(FaceNode *faceNode,BOOL isObjective,Point3D<double> *points)
00153 {
00154         if (!faceNode) return ;
00155         GetCornersRecursive(faceNode->parent,FALSE,points);
00156         Face *face = faceNode->elem;
00157         face->MovingInside();
00158         if (face->scale.x!=1||face->scale.y!=1||face->scale.z) face->scale.glScale();
00159         if (isObjective) face->GetCorners(points);
00160 }
00161 
00162 BOOL Primitive::Draw(BOOL isPicking) 
00163 { 
00164         if (isPicking) glLoadName(0);
00165         FaceNode *node = tree.GetRoot();
00166         if (!isPicking) node->elem->ComputeLayout();
00167         return Draw(node,isPicking); 
00168 }
00169 
00170 BOOL Primitive::Draw(FaceNode *faceNode,BOOL isPicking)
00171 {       
00172         if (!faceNode) return FALSE;
00173         FaceNode *childNode;
00174         Face *child;
00175         Face *father = faceNode->elem;
00176         glPushMatrix();
00177         father->MovingInside();
00178         father->Draw(isPicking);
00179         if (faceNode->childs.GetNbElem()) // contenueur ?
00180         {   // gestion des fils
00181                 for (faceNode->childs.i=0;faceNode->childs.i.More();faceNode->childs.i++)
00182                 {
00183                         childNode = faceNode->childs.i.GetElem();
00184                         child = childNode->elem;
00185 
00186                         if (!isPicking)
00187                         {       // calcul des dimentions et position suivant les layouts par rapport au pere
00188                                 child->ComputeLayout();
00189                                 child->ratioXY = father->ratioXY*(child->scale.x/child->scale.y); // donne le ratio entre X et Y
00190                         }
00191                         if (child->scale.x!=1||child->scale.y!=1) glScaled(child->scale.x,child->scale.y,1);
00192                         if (!Draw(childNode,isPicking)) return FALSE;
00193                 }
00194         }
00195         glPopMatrix();
00196         return TRUE;
00197 }
00198 
00199 /*
00200 
00201 BOOL Primitive::Draw(FaceNode *faceNode,BOOL isPicking)
00202 {       
00203         if (!faceNode) return FALSE;
00204         FaceNode *childNode;
00205         Face *child;
00206         Face *father = faceNode->elem;
00207         glPushMatrix();
00208         father->Draw(isPicking);
00209         if (faceNode->childs.GetNbElem()) // contenueur ?
00210         {   // gestion des fils
00211                 for (faceNode->childs=0;faceNode->childs.More();faceNode->childs++)
00212                 {
00213                         childNode = faceNode->childs.GetElem();
00214                         child = childNode->elem;
00215 
00216                         if (!isPicking)
00217                         {       // calcul des dimentions et position suivant les layouts par rapport au pere
00218                                 child->ComputeLayout();
00219                                 child->ratioXY = father->ratioXY*(child->scale.x/child->scale.y); // donne le ratio entre X et Y
00220                         }
00221                         if (child->scale.x!=1||child->scale.y!=1) glScaled(child->scale.x,child->scale.y,1);
00222                         if (!Draw(childNode,isPicking)) return FALSE;
00223                 }
00224         }
00225         glPopMatrix();
00226 #ifdef DEBUG_3D
00227         static BOOL isFirst = TRUE;
00228         if (!faceNode->parent&&isFirst) { isFirst = FALSE; ViewDebug();  }
00229 #endif
00230         return TRUE;
00231 }
00232 */
00233 FaceNode * Primitive::Find(int idControl,int idFace,FaceNode *node)
00234 {
00235         FaceNode *result;
00236         if (!node) node = tree.GetRoot();
00237         if (node->elem->idControl==idControl && node->elem->idFace==idFace) return node;
00238 
00239         for (node->childs.i=0;node->childs.i.More();node->childs.i++)
00240         {
00241                 result = Find(idControl,idFace,node->childs.i.GetElem());
00242                 if (result) return result;
00243         }               
00244         return NULL;
00245 }
00246 
00247 FaceNode * Primitive::AddFace (char *name,int idControl,int idFace,BOOL view)
00248 {
00249         Face face;
00250         face.Set(name,idControl,idFace,view);
00251         return tree.Add(face);
00252 }
00253 
00254 FaceNode * Primitive::AddFace (
00255         char *name,int idControl,int idFace,BOOL view,
00256         double xConstPosition,double xPercentPosition,
00257         double yConstPosition,double yPercentPosition,
00258         double zConstPosition,
00259         double xConstSize,double xPercentSize,
00260         double yConstSize,double yPercentSize)
00261 {
00262         FaceNode *nodeFace = AddFace(name,idControl,idFace,view);
00263         Face *face = nodeFace->elem;
00264         Face *father = nodeFace->parent?nodeFace->parent->elem:NULL;
00265         face->ConfigStaticLayout(xConstPosition,yConstPosition,zConstPosition,xConstSize,yConstSize);
00266         face->ConfigDynamicLayout(father,xPercentPosition,yPercentPosition,xPercentSize,yPercentSize);
00267         return nodeFace;
00268 }
00269 
00270 void Primitive::BeginContainer(
00271         int idControl,
00272         double xConstPosition,double xPercentPosition,
00273         double yConstPosition,double yPercentPosition,
00274         double xConstSize,double xPercentSize,
00275         double yConstSize,double yPercentSize)
00276 {
00277         AddFace("container",idControl,0,FALSE,
00278                 xConstPosition,xPercentPosition,
00279                 yConstPosition,yPercentPosition,
00280                 0,
00281                 xConstSize,xPercentSize,
00282                 yConstSize,yPercentSize);
00283         Push();
00284         GoTo(0);
00285 }
00286 
00287 void Primitive::EndContainer()
00288 {
00289         Pop();
00290 }
00291 
00292 
00305 FaceNode * Primitive::AddBox (char *name,int idControl,GLdouble depth,BOOL viewBack)
00306 {
00307         GLdouble depthTemp = depth;
00308         return AddBox(name,idControl,FALSE,&depthTemp,viewBack);
00309 }
00310 
00311 FaceNode * Primitive::AddBox (char *name,int idControl,GLdouble *depth,BOOL viewBack)
00312 {
00313         return AddBox(name,idControl,TRUE,depth,viewBack);
00314 }
00315 
00316 FaceNode * Primitive::AddBox (char *name,int idControl,BOOL isDynamic,GLdouble *depth,BOOL viewBack)
00317 {   
00318         // une boite est contenu dans une face non visible afin de pouvoir faire des
00319         // rotation et translation libre
00320         FaceNode * nodeBase;
00321         nodeBase=AddFace(name,idControl,-1,FALSE); // creation de la face container (jamais visisble: pure conteneur)
00322         Face *child = nodeBase->elem;
00323 
00324         Push();
00325         GoTo(nodeBase);
00326 
00327         // ajout des 6 faces
00328         // pour des pb de blending, l'ordre d'insertion doit etre du cachant au caché, sinon certaine facette ne sont pas affiché
00329         MyString nameCur;
00330 
00331         nameCur<<clear<<name<<" [back]";
00332         FaceNode *nodeFace;
00333         Face *childFace;
00334         nodeFace=AddFace(nameCur,idControl,FACE_BACK,viewBack);
00335         childFace=nodeFace->elem;
00336         childFace->angle.Set(180,0);
00337         childFace->size.x.Set(0,1,&child->computeSize.x);
00338         childFace->size.y.Set(0,1,&child->computeSize.y);
00339         childFace->view=viewBack;
00340 
00341         nameCur<<clear<<name<<" [bottom]";
00342         nodeFace=AddFace(nameCur,idControl,FACE_BOTTOM,TRUE);
00343         childFace=nodeFace->elem;
00344         childFace->angle.Set(90,0);
00345         childFace->position.y.Set(0,-0.5,&child->computeSize.y);
00346         if (isDynamic) 
00347         {
00348                 childFace->position.z.Set(0,0.5,depth);
00349                 childFace->size.y.Set(0,1,depth);
00350         }
00351         else 
00352         {
00353                 childFace->position.z.Set(*depth/2.0);
00354                 childFace->size.y.Set(*depth);
00355         }
00356         childFace->size.x.Set(0,1,&child->computeSize.x);
00357 
00358         nameCur<<clear<<name<<" [top]";
00359         nodeFace=AddFace(nameCur,idControl,FACE_TOP,TRUE);
00360         childFace=nodeFace->elem;
00361         childFace->angle.Set(-90,0);
00362         childFace->position.y.Set(0,0.5,&child->computeSize.y);
00363         if (isDynamic) 
00364         {
00365                 childFace->position.z.Set(0,0.5,depth);
00366                 childFace->size.y.Set(0,1,depth);
00367         }
00368         else 
00369         {
00370                 childFace->position.z.Set(*depth/2.0);
00371                 childFace->size.y.Set(*depth);
00372         }
00373         childFace->size.x.Set(0,1,&child->computeSize.x);
00374 
00375         nameCur<<clear<<name<<" [left]";
00376         nodeFace=AddFace(nameCur,idControl,FACE_LEFT,TRUE);
00377         childFace=nodeFace->elem;
00378         childFace->angle.Set(0,-90);
00379         childFace->position.x.Set(0,-0.5,&child->computeSize.x);
00380         if (isDynamic) 
00381         {
00382                 childFace->position.z.Set(0,0.5,depth);
00383                 childFace->size.x.Set(0,1,depth);
00384         }
00385         else 
00386         {
00387                 childFace->position.z.Set(*depth/2.0);
00388                 childFace->size.x.Set(*depth);
00389         }
00390         childFace->size.y.Set(0,1,&child->computeSize.y);
00391 
00392         nameCur<<clear<<name<<" [right]";
00393         nodeFace=AddFace(nameCur,idControl,FACE_RIGHT,TRUE);
00394         childFace=nodeFace->elem;
00395         childFace->angle.Set(0,90);
00396         childFace->position.x.Set(0,0.5,&child->computeSize.x);
00397         if (isDynamic) 
00398         {
00399                 childFace->position.z.Set(0,0.5,depth);
00400                 childFace->size.x.Set(0,1,depth);
00401         }
00402         else 
00403         {
00404                 childFace->position.z.Set(*depth/2.0);
00405                 childFace->size.x.Set(*depth);
00406         }
00407         childFace->size.y.Set(0,1,&child->computeSize.y);
00408 
00409         nameCur<<clear<<name<<" [front]";
00410         nodeFace=AddFace(nameCur,idControl,FACE_FRONT,TRUE);
00411         childFace=nodeFace->elem;
00412         childFace->angle.Set(0,0);
00413         if (isDynamic) childFace->position.z.Set(0,1,depth);
00414         else childFace->position.z.Set(*depth);
00415         childFace->size.x.Set(0,1,&child->computeSize.x);
00416         childFace->size.y.Set(0,1,&child->computeSize.y);
00417 
00418         Pop();
00419         return nodeBase;
00420 }

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