00001 #include <cmath>
00002 #include <float.h>
00003 #include <animal/X3DTK/Qt/x3dTransformGUI/x3dTransformQt.h>
00004
00005 #include "frameNode.h"
00006
00007 namespace X3DTK
00008 {
00009 namespace X3D
00010 {
00011 FrameNode::FrameNode()
00012 : swollen(1.0)
00013 , x3dTransformNode(0)
00014 , size(1.0)
00015
00016 {
00017
00018
00019
00020 define(Recorder<FrameNode>::getTypeName("FrameNode"));
00021 }
00022
00023
00024 FrameNode::~FrameNode()
00025 {}
00026
00028
00029 void FrameNode::init()
00030 {
00031
00032 MFNode list = getParentList();
00033 MFNode::iterator i = list.begin();
00034 if (list.size()==1)
00035 {
00036 if ( Transform * T = dynamic_cast<Transform *>(*i))
00037 {
00038 x3dTransformNode = T;
00039 translation = x3dTransformNode->getTranslation();
00040 rotation = x3dTransformNode->getRotation();
00041 scale = x3dTransformNode->getScale();
00042 scaleOrientation = x3dTransformNode->getScaleOrientation();
00043 center = x3dTransformNode->getCenter();
00044 updateFrame();
00045
00046 animal::Engine::init();
00047 return;
00048 }
00049 }
00050 std::cerr<<std::endl<<"Warning FrameNode::init(): impossible to init a X3DTK::X3D::FrameNode."<<std::endl;
00051 std::cerr<<" It has to have only one X3DTK::X3D::Transform as parent."<<std::endl;
00052 }
00053
00054 void FrameNode::draw()
00055 {
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 }
00153
00154
00155 void FrameNode::updateBoundingBox()
00156 {
00157 float xmin, ymin, zmin, xmax, ymax, zmax;
00158 getBoundingBox(xmin, ymin, zmin, xmax, ymax, zmax);
00159 setBBoxCenter(SFVec3f((xmax+xmin)/2.0, (ymax+ymin)/2.0, (zmax+zmin)/2.0));
00160 setBBoxSize(SFVec3f(xmax-xmin, ymax-ymin, zmax-zmin));
00161
00162 }
00163
00164 void FrameNode::getBoundingBox( float & minX, float & minY, float & minZ,
00165 float & maxX, float & maxY, float & maxZ)
00166 {
00167
00170
00171 if (x3dTransformNode)
00172 {
00173
00174 bool boundedChild = false;
00175 if(x3dTransformNode->getChildList().size())
00176 {
00177 MFNode childList = x3dTransformNode->getChildList();
00178 for(MFNode::iterator it = childList.begin() ; it != childList.end() ; ++it)
00179 {
00180 X3DBoundedObject * BO = dynamic_cast<X3DBoundedObject *>(*it);
00181 if((*it)!= this && BO)
00182 {
00183 SFVec3f sizeBBox = BO->getBBoxSize();
00184 if (size < sizeBBox.x)
00185 size = sizeBBox.x;
00186 if (size < sizeBBox.y)
00187 size = sizeBBox.y;
00188 if (size < sizeBBox.z)
00189 size = sizeBBox.z;
00190 boundedChild = true;
00191 }
00192 }
00193 }
00194 if (boundedChild)
00195 size *= swollen*0.5;
00196 else
00197 size = swollen;
00198
00199
00200 qglviewer::Vec axis[3];
00201 axis[0] = qglviewer::Vec(size, 0.0, 0.0);
00202 axis[1] = qglviewer::Vec(0.0, size, 0.0);
00203 axis[2] = qglviewer::Vec(0.0, 0.0, size);
00204
00205 minX = maxX = minY = maxY = minZ = maxZ =0.0;
00206
00207 for (int i = 0; i<3; ++i)
00208 {
00209 if (minX > axis[i].x)
00210 minX = axis[i].x;
00211 if (maxX < axis[i].x)
00212 maxX = axis[i].x;
00213
00214 if (minY > axis[i].y)
00215 minY = axis[i].y;
00216 if (maxY < axis[i].y)
00217 maxY = axis[i].y;
00218
00219 if (minZ > axis[i].z)
00220 minZ = axis[i].z;
00221 if (maxZ < axis[i].z)
00222 maxZ = axis[i].z;
00223 }
00224
00225
00226 setBBoxCenter(SFVec3f((minX+maxX)/2.0, (minY+maxY)/2.0, (minZ+maxZ)/2.0));
00227 setBBoxSize(SFVec3f(maxX-minX, maxY-minY, maxZ-minZ));
00228 }
00229 }
00230
00231 void FrameNode::updateFrame()
00232 {
00233 if (x3dTransformNode)
00234 {
00235 SFVec3f pos = x3dTransformNode->getCenter();
00236 qglviewer::Frame::setPosition(pos.x, pos.y, pos.z);
00237 SFVec3f trans = x3dTransformNode->getTranslation();
00238 qglviewer::Frame::setTranslation(trans.x, trans.y, trans.z);
00239 SFRotation rot = x3dTransformNode->getRotation();
00240 qglviewer::Frame::setRotation(qglviewer::Quaternion(qglviewer::Vec(rot.x, rot.y, rot.z), rot.angle));
00241 }
00242 }
00243
00244 void FrameNode::updateTransform()
00245 {
00246 if (x3dTransformNode)
00247 {
00248 qglviewer::Vec pos = qglviewer::Frame::position();
00249 x3dTransformNode->setCenter(SFVec3f(pos[0], pos[1], pos[2]));
00250 qglviewer::Vec trans = qglviewer::Frame::translation();
00251 x3dTransformNode->setTranslation(SFVec3f(trans[0], trans[1], trans[2]));
00252 qglviewer::Vec axis = qglviewer::Frame::rotation().axis();
00253 float angle = qglviewer::Frame::rotation().angle();
00254 x3dTransformNode->setRotation(SFRotation(axis.x, axis.y, axis.z, angle));
00255 }
00256 }
00257
00259 void FrameNode::updateFrameNode()
00260 {
00261 if (x3dTransformNode)
00262 {
00263 x3dTransformNode->setTranslation (translation);
00264 x3dTransformNode->setRotation (rotation);
00265 x3dTransformNode->setScale (scale);
00266 x3dTransformNode->setScaleOrientation (scaleOrientation);
00267 x3dTransformNode->setCenter (center);
00268 updateFrame();
00269 }
00270 }
00271
00272 void FrameNode::drawCone(float radius, float height, int nbSub)
00273 {
00274 qglviewer::Vec pos(radius, 0.0, 0.0);
00275 qglviewer::Vec prevNormal(1.0, 0.0, radius/height);
00276 qglviewer::Vec normal, newNormal;
00277
00278 prevNormal.normalize();
00279
00280 glBegin(GL_TRIANGLES);
00281 for (unsigned short i=1; i<=nbSub; ++i)
00282 {
00283 glNormal3fv(prevNormal.address());
00284 glVertex3fv(pos.address());
00285
00286 normal.x = cos(2.0*M_PI*i/static_cast<float>(nbSub));
00287 normal.y = sin(2.0*M_PI*i/static_cast<float>(nbSub));
00288 normal.z = radius / height;
00289
00290 pos.x = radius * normal.x;
00291 pos.y = radius * normal.y;
00292
00293 normal.normalize();
00294
00295 prevNormal = normal;
00296 glNormal3fv(prevNormal.address());
00297 glVertex3fv(pos.address());
00298
00299 newNormal.x = prevNormal.x + normal.x;
00300 newNormal.y = prevNormal.y + normal.y;
00301 newNormal.z = 4.0*radius/height;
00302 newNormal.normalize();
00303
00304 glNormal3fv(newNormal.address());
00305 glVertex3f(0.0, 0.0, height);
00306 }
00307 glEnd();
00308 }
00309
00310 void FrameNode::drawCylinder(float radius, float length, int nbSub)
00311 {
00312 float prevX=radius, prevY=0.0f;
00313 float nx=1.0f, ny=0.0f;
00314
00315 glBegin(GL_QUAD_STRIP);
00316 for (unsigned short i=1; i<=nbSub; ++i)
00317 {
00318 glNormal3f(nx, ny, 0.0);
00319 glVertex3f(prevX , prevY , length);
00320 glNormal3f(nx, ny, 0.0);
00321 glVertex3f(prevX , prevY , 0.0);
00322
00323 nx = cos(2.0*M_PI*i/static_cast<float>(nbSub));
00324 ny = sin(2.0*M_PI*i/static_cast<float>(nbSub));
00325
00326 prevX = radius * nx;
00327 prevY = radius * ny;
00328
00329 glNormal3f(nx, ny, 0.0);
00330 glVertex3f(prevX , prevY , length);
00331 glNormal3f(nx, ny, 0.0);
00332 glVertex3f(prevX , prevY , 0.0);
00333 }
00334 glEnd();
00335 }
00336
00337 }
00338 }
00339
00340
00344 void X3DTK::X3D::FrameNode::declareOutputs( X3D_X3DNodeList& list)
00345 {
00346 list.push_back(x3dTransformNode);
00347 }