00001 #ifndef SG_FRAME_H
00002 #define SG_FRAME_H
00003
00004 #include "SGObject.h"
00005
00006 namespace Spr {;
00007
00008 class SGBBox{
00009 Vec3f bboxCenter;
00010 Vec3f bboxExtent;
00011 public:
00012
00013 void SetBBoxCenterExtent(Vec3f c, Vec3f e){
00014 bboxCenter = c;
00015 bboxExtent = e;
00016 }
00017
00018 void SetBBoxMinMax(Vec3f bmin, Vec3f bmax){
00019 bboxCenter = (bmin+bmax)*0.5f;
00020 bboxExtent = (bmax-bmin)*0.5f;
00021 }
00022
00023 void AddBBox(Vec3f bmin, Vec3f bmax){
00024 Vec3f bboxMin = GetBBoxMin();
00025 Vec3f bboxMax = GetBBoxMax();
00026 bboxMin.element_min(bmin);
00027 bboxMax.element_max(bmax);
00028 SetBBoxMinMax(bboxMin, bboxMax);
00029 }
00030
00031 Vec3f GetBBoxCenter(){ return bboxCenter; }
00032
00033 Vec3f GetBBoxExtent(){ return bboxExtent; }
00034
00035 Vec3f GetBBoxMin(){ return bboxCenter-bboxExtent; }
00036
00037 Vec3f GetBBoxMax(){ return bboxCenter+bboxExtent; }
00038
00039 void GetSupport(const Vec3f& dir, float& minS, float& maxS){
00040 Vec3f ext0( bboxExtent.X(), bboxExtent.Y(), bboxExtent.Z());
00041 Vec3f ext1(-bboxExtent.X(), bboxExtent.Y(), bboxExtent.Z());
00042 Vec3f ext2( bboxExtent.X(), -bboxExtent.Y(), bboxExtent.Z());
00043 Vec3f ext3( bboxExtent.X(), bboxExtent.Y(), -bboxExtent.Z());
00044 float d = abs(dir*ext0);
00045 float d1 = abs(dir*ext1);
00046 if (d < d1) d = d1;
00047 float d2 = abs(dir*ext2);
00048 if (d < d2) d = d2;
00049 float d3 = abs(dir*ext3);
00050 if (d < d3) d = d3;
00051 float c = dir * bboxCenter;
00052 minS = c-d;
00053 maxS = c+d;
00054 }
00055 };
00056
00057 class SGFrame;
00058
00059 class SPR_DLL SGFrames:public std::vector< UTRef<SGFrame> >{
00060 public:
00061 };
00062
00063
00064
00065
00066 class SPR_DLL SGFrame: public SGObject, public UTTreeNode<SGFrame, SGFrames>{
00067 public:
00068 SGOBJECTDEF(SGFrame);
00069 typedef UTTreeNode<SGFrame, SGFrames> Tree;
00070 protected:
00071
00072 Affinef posture;
00073 public:
00074
00075 SGBBox bbox;
00076
00077 SGObjects contents;
00078
00079
00080
00081
00082 virtual size_t NChildObjects();
00083
00084 virtual SGObject* ChildObject(size_t i);
00085
00086 virtual bool AddChildObject(SGObject* o, SGScene* s);
00087
00088 virtual bool DelChildObject(SGObject* o, SGScene* s);
00089
00090 virtual SGFrame* FindFrame(UTString);
00091
00092
00093 virtual const UTTypeInfo** ChildCandidates();
00094 template <class T>
00095 void FindObject(T*& obj){
00096 for(unsigned i=0; i<NChildObjects(); ++i){
00097 obj = DCAST(T, ChildObject(i));
00098 if (obj) return;
00099 }
00100 }
00101 template <class T> void FindObject(UTRef<T>& obj){
00102 T* t = &*obj;
00103 FindObject(t);
00104 obj = t;
00105 }
00106
00107
00108
00109 void Clear();
00110
00111
00112 virtual void ReleaseDoc(){
00113 doc = NULL;
00114 ForEachChild(&SGFrame::ReleaseDoc);
00115 for(SGObjects::iterator it = contents.begin(); it != contents.end(); ++it){
00116 (*it)->ReleaseDoc();
00117 }
00118 }
00119
00120 void Print(std::ostream& os) const;
00121
00122
00123
00124
00125 const Vec3f& GetPosition(){ return posture.Pos(); }
00126 Matrix3f GetRotation(){ return posture.Rot(); }
00127 template<class T> void SetPosition(T p){ posture.Pos() = p; }
00128 template<class T> void SetRotation(T p){ posture.Rot() = p; }
00129
00130 const Affinef& GetPosture(){ return posture;}
00131
00132
00133
00134 void SetPosture(const Affinef& a){ posture = a; }
00135
00136 Affinef GetWorldPosture(){
00137 Affinef af;
00138 SGFrame* fr = this;
00139 while(fr){
00140 af = fr->posture * af;
00141 fr = fr->GetParent();
00142 }
00143 return af;
00144 }
00145
00146
00147
00148 void SetWorldPosture(const Affinef& a){
00149 if (GetParent()){
00150 posture = GetParent()->GetWorldPosture().inv() * a;
00151 }else{
00152 posture = a;
00153 }
00154 }
00155
00156 virtual void CalcBBox();
00157
00158 void GetBBoxSupport(const Vec3f& dir, float& minS, float& maxS){
00159 bbox.GetSupport(GetPosture().Rot().inv()*dir, minS, maxS);
00160 float c = GetPosture().Pos() * dir;
00161 minS += c;
00162 maxS += c;
00163 }
00164
00165
00166 void Loaded(SGScene* scene);
00167
00168
00169 void EnumContents(SGObjects& objs);
00170 void EnumContents(SGObjects& objs, SGFrames& frames);
00171 };
00172
00173 }
00174 #endif