00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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;
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())
00180 {
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 {
00188 child->ComputeLayout();
00189 child->ratioXY = father->ratioXY*(child->scale.x/child->scale.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
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
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
00319
00320 FaceNode * nodeBase;
00321 nodeBase=AddFace(name,idControl,-1,FALSE);
00322 Face *child = nodeBase->elem;
00323
00324 Push();
00325 GoTo(nodeBase);
00326
00327
00328
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 }