00001 #include "BboxUpdaterGroupingVisitor.h"
00002 #include "StaticGroup.h"
00003 #include "X3DGroupingNode.h"
00004 #include "Group.h"
00005 #include "Transform.h"
00006 #include "Bbox.h"
00007
00008 #include <iostream>
00009
00010 using namespace std;
00011 using namespace X3DTK;
00012
00013 BboxUpdaterGroupingVisitor::BboxUpdaterGroupingVisitor()
00014 : GroupingVisitor()
00015 {
00016
00017 defineNewWalkOnFunction<BboxUpdaterGroupingVisitor, StaticGroup>(&BboxUpdaterGroupingVisitor::walkOnStaticGroup);
00018 defineNewWalkOnFunction<BboxUpdaterGroupingVisitor, X3DGroupingNode>(&BboxUpdaterGroupingVisitor::walkOnX3DGroupingNode);
00019
00020
00021 defineNewLeaveFunction<BboxUpdaterGroupingVisitor, StaticGroup>(&BboxUpdaterGroupingVisitor::leaveStaticGroup);
00022 defineNewLeaveFunction<BboxUpdaterGroupingVisitor, Group>(&BboxUpdaterGroupingVisitor::leaveGroup);
00023 defineNewLeaveFunction<BboxUpdaterGroupingVisitor, Transform>(&BboxUpdaterGroupingVisitor::leaveTransform);
00024
00025
00026 globalVariables = GVManager::getInstanceOf<BboxUpdaterGlobalVariables>();
00027 }
00028
00029 BboxUpdaterGroupingVisitor::~BboxUpdaterGroupingVisitor()
00030 {
00031 }
00032
00033 bool BboxUpdaterGroupingVisitor::walkOnStaticGroup(StaticGroup *S, SFNode Child) const
00034 {
00035 return true;
00036 }
00037
00038 bool BboxUpdaterGroupingVisitor::walkOnX3DGroupingNode(X3DGroupingNode *N, SFNode Child) const
00039 {
00040 return true;
00041 }
00042
00043 void BboxUpdaterGroupingVisitor::leaveStaticGroup(StaticGroup *S) const
00044 {
00045 Bbox *BB = globalVariables->getBbox(S);
00046 if (BB == 0)
00047 {
00048 if (!globalVariables->getStaticProcessing())
00049 {
00050 BB = new Bbox(S->getBboxCenter(), S->getBboxSize());
00051 globalVariables->addBbox(S, BB);
00052 }
00053 else
00054 {
00055
00056 MFNode children = S->getChildren();
00057 for (MFNode::iterator it = children.begin(); it != children.end(); ++it)
00058 {
00059 X3DBoundedObject *BO = dynamic_cast<X3DBoundedObject *>(*it);
00060 if (BO != 0)
00061 globalVariables->addBboxToMergeList(Bbox(BO->getBboxCenter(), BO->getBboxSize()));
00062 }
00063
00064 BB = new Bbox(globalVariables->mergeBbox());
00065 globalVariables->addBbox(S, BB);
00066
00067
00068 S->setBboxCenter(BB->getCenter());
00069 S->setBboxSize(BB->getSize());
00070 }
00071 }
00072 }
00073
00074 void BboxUpdaterGroupingVisitor::leaveGroup(Group *G) const
00075 {
00076 Bbox *BB = globalVariables->getBbox(G);
00077 if (BB == 0)
00078 {
00079 MFNode children = G->getChildren();
00080 for (MFNode::iterator it = children.begin(); it != children.end(); ++it)
00081 {
00082 X3DBoundedObject *BO = dynamic_cast<X3DBoundedObject *>(*it);
00083 if (BO != 0)
00084 globalVariables->addBboxToMergeList(Bbox(BO->getBboxCenter(), BO->getBboxSize()));
00085 }
00086
00087 BB = new Bbox(globalVariables->mergeBbox());
00088 globalVariables->addBbox(G, BB);
00089
00090
00091 G->setBboxCenter(BB->getCenter());
00092 G->setBboxSize(BB->getSize());
00093 }
00094 }
00095
00096 void BboxUpdaterGroupingVisitor::leaveTransform(Transform *T) const
00097 {
00098 Bbox *BB = globalVariables->getBbox(T);
00099 if (BB == 0)
00100 {
00101 MFNode children = T->getChildren();
00102 for (MFNode::iterator it = children.begin(); it != children.end(); ++it)
00103 {
00104 X3DBoundedObject *BO = dynamic_cast<X3DBoundedObject *>(*it);
00105 if (BO != 0)
00106 globalVariables->addBboxToMergeList(Bbox(BO->getBboxCenter(), BO->getBboxSize()));
00107 }
00108
00109 BB = new Bbox(globalVariables->mergeBbox());
00110
00111
00112 SFMatrix34f Tr = translation(T->getTranslation());
00113 SFMatrix34f C = translation(T->getCenter());
00114 SFVec3f v(T->getRotation().x, T->getRotation().y, T->getRotation().z);
00115 SFMatrix34f R = rotation(T->getRotation().angle, v);
00116 SFVec3f vs(T->getScaleOrientation().x, T->getScaleOrientation().y, T->getScaleOrientation().z);
00117 SFMatrix34f SR = rotation(T->getScaleOrientation().angle, vs);
00118 SFMatrix34f S = scale34(T->getScale().x, T->getScale().y, T->getScale().z);
00119 SFMatrix34f iSR = rotation(-T->getScaleOrientation().angle, vs);
00120 SFMatrix34f iC = translation(-1.0f*T->getCenter());
00121
00122 SFMatrix34f transform = Tr*C*R*SR*S*iSR*iC;
00123
00124
00125 SFPoint3f Corner[8];
00126 Corner[0] = transform*SFPoint3f(BB->getCenter().x - 0.5f*BB->getSize().x, BB->getCenter().y - 0.5f*BB->getSize().y, BB->getCenter().z - 0.5f*BB->getSize().z);
00127 Corner[1] = transform*SFPoint3f(BB->getCenter().x - 0.5f*BB->getSize().x, BB->getCenter().y - 0.5f*BB->getSize().y, BB->getCenter().z + 0.5f*BB->getSize().z);
00128 Corner[2] = transform*SFPoint3f(BB->getCenter().x - 0.5f*BB->getSize().x, BB->getCenter().y + 0.5f*BB->getSize().y, BB->getCenter().z - 0.5f*BB->getSize().z);
00129 Corner[3] = transform*SFPoint3f(BB->getCenter().x - 0.5f*BB->getSize().x, BB->getCenter().y + 0.5f*BB->getSize().y, BB->getCenter().z + 0.5f*BB->getSize().z);
00130 Corner[4] = transform*SFPoint3f(BB->getCenter().x + 0.5f*BB->getSize().x, BB->getCenter().y - 0.5f*BB->getSize().y, BB->getCenter().z - 0.5f*BB->getSize().z);
00131 Corner[5] = transform*SFPoint3f(BB->getCenter().x + 0.5f*BB->getSize().x, BB->getCenter().y - 0.5f*BB->getSize().y, BB->getCenter().z + 0.5f*BB->getSize().z);
00132 Corner[6] = transform*SFPoint3f(BB->getCenter().x + 0.5f*BB->getSize().x, BB->getCenter().y + 0.5f*BB->getSize().y, BB->getCenter().z - 0.5f*BB->getSize().z);
00133 Corner[7] = transform*SFPoint3f(BB->getCenter().x + 0.5f*BB->getSize().x, BB->getCenter().y + 0.5f*BB->getSize().y, BB->getCenter().z + 0.5f*BB->getSize().z);
00134
00135 SFPoint3f min = Corner[0];
00136 SFPoint3f max = Corner[0];
00137
00138 for (unsigned int i = 0; i < 8; ++i)
00139 {
00140 if (Corner[i].x < min.x)
00141 min.x = Corner[i].x;
00142 if (Corner[i].y < min.y)
00143 min.y = Corner[i].y;
00144 if (Corner[i].z < min.z)
00145 min.z = Corner[i].z;
00146
00147 if (Corner[i].x > max.x)
00148 max.x = Corner[i].x;
00149 if (Corner[i].y > max.y)
00150 max.y = Corner[i].y;
00151 if (Corner[i].z > max.z)
00152 max.z = Corner[i].z;
00153 }
00154
00155 SFVec3f mid = max - min;
00156 SFPoint3f center = min + 0.5f*mid;
00157 SFVec3f size = 2.0f*(max - center);
00158
00159 BB->setCenter(SFVec3f(center));
00160 BB->setSize(size);
00161
00162 globalVariables->addBbox(T, BB);
00163
00164
00165 T ->setBboxCenter(BB->getCenter());
00166 T->setBboxSize(BB->getSize());
00167 }
00168 }