00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "vpscene.h"
00045 #include "vpgraphicobj.h"
00046 #include <cassert>
00047
00048 #ifdef VP_OGL
00049 #include <GL/gl.h>
00050 #endif
00051
00052 using namespace std;
00053
00054 VPScene::VPScene() {
00055 background = VPColor::BLACK();
00056 currentCamera = cameras.end();
00057 }
00058
00059 VPScene::~VPScene() {
00060 list<const VPSceneNode*>::const_iterator objItr;
00061 list<const VPLight*>::const_iterator lightItr;
00062
00063 for (objItr = objects.begin(); objItr != objects.end(); ++objItr)
00064 {
00065 (*objItr)->AutoDeleteChildren();
00066 if ((*objItr)->autoDelete)
00067 delete (*objItr);
00068 }
00069 for (lightItr = lights.begin(); lightItr != lights.end(); ++lightItr)
00070 {
00071 if ((*lightItr)->autoDelete)
00072 delete (*lightItr);
00073 }
00074 }
00075
00076 list<const VPLight*> VPScene::GetLights() {
00077 return lights;
00078 }
00079
00080 list<VPCamera*> VPScene::GetCameras() {
00081 return cameras;
00082 }
00083
00084 list<const VPSceneNode*> VPScene::GetObjects() {
00085 return objects;
00086 }
00087
00088 void VPScene::AddLight(VPLight* newLight) {
00089 lights.push_back(newLight);
00090 }
00091
00092 void VPScene::AddLight(const VPLight& newLight) {
00093 VPLight* lightPtr = new VPLight(newLight);
00094 lightPtr->autoDelete = true;
00095 lights.push_back(lightPtr);
00096 }
00097
00098 void VPScene::AddCamera(VPCamera* newCamera) {
00099 cameras.push_back( newCamera );
00100 if (currentCamera == cameras.end())
00101 currentCamera = cameras.begin();
00102 }
00103
00104 void VPScene::AddObject( VPSceneNode* newObjectPtr ) {
00105 objects.push_back( newObjectPtr );
00106 }
00107
00108 const VPLight* VPScene::GetLight(const string& lightName) {
00109 list<const VPLight*>::const_iterator iter;
00110 for (iter = lights.begin(); iter != lights.end(); ++iter) {
00111 if( (*iter)->GetDescription() == lightName ) {
00112 return (*iter);
00113 }
00114 }
00115 return NULL;
00116 }
00117
00118 const VPCamera* VPScene::GetCamera(const string& cameraName) {
00119 list<VPCamera*>::const_iterator iter;
00120 for (iter = cameras.begin(); iter != cameras.end(); ++iter) {
00121 if( (*iter)->GetDescription() == cameraName ) {
00122 return (*iter);
00123 }
00124 }
00125 return NULL;
00126 }
00127
00128 const VPSceneNode* VPScene::GetObject(const string& objectName) {
00129 list<const VPSceneNode*>::const_iterator iter;
00130 for (iter = objects.begin(); iter != objects.end(); ++iter) {
00131 if( (*iter)->GetDescription() == objectName ) {
00132 return (*iter);
00133 }
00134 }
00135 return NULL;
00136 }
00137
00138 VPColor VPScene::GetBackgroundColor() {
00139 return background;
00140 }
00141
00142 void VPScene::SetBackgroundColor(VPColor color) {
00143 background = color;
00144 }
00145
00146 bool VPScene::DrawOGL() const {
00147 #ifdef VP_OGL
00148 assert(*currentCamera);
00149 static float bgColor[4];
00150 background.GetScaled(1.0f, bgColor);
00151 glClearColor(bgColor[0], bgColor[1], bgColor[2], bgColor[3]);
00152 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00153
00154
00155 DrawLightsOGL();
00156
00157
00158 (*currentCamera)->DrawOGL();
00159
00160
00161 list<const VPSceneNode*>::const_iterator iter;
00162 for (iter = objects.begin(); iter != objects.end(); ++iter)
00163 {
00164 (*iter)->DrawOGL();
00165 }
00166 return true;
00167 #else
00168 return false;
00169 #endif
00170 }
00171
00172 bool VPScene::DrawLightsOGL() const {
00173 #ifdef VP_OGL
00174 unsigned int lightID = 0;
00175 list<const VPLight*>::const_iterator iter;
00176 for (iter = lights.begin(); iter != lights.end(); ++iter)
00177 {
00178 (*iter)->DrawOGL(lightID);
00179 ++lightID;
00180 }
00181 return true;
00182 #else
00183 return false;
00184 #endif
00185 }
00186
00187 VPCamera* VPScene::GetCurrentCamera() const {
00188 if (currentCamera == cameras.end())
00189 return NULL;
00190 else
00191 return *currentCamera;
00192 }
00193
00194 void VPScene::UseNextCamera() {
00195 ++currentCamera;
00196 if (currentCamera == cameras.end())
00197 currentCamera = cameras.begin();
00198 }
00199
00200 void VPScene::UsePreviousCamera() {
00201 --currentCamera;
00202 if (currentCamera == cameras.end())
00203 --currentCamera;
00204 }
00205
00206 void VPScene::SetAllCamerasAspectRatio(float newAspectRatio) {
00207 list<VPCamera*>::const_iterator iter;
00208 for (iter = cameras.begin(); iter != cameras.end(); ++iter) {
00209 (*iter)->SetAspectRatio(newAspectRatio);
00210 }
00211 }
00212
00213 void VPScene::ComputeBoundingBox() {
00214 list<const VPSceneNode*>::const_iterator iter = objects.begin();
00215 const VPGraphicObj* objPtr;
00216 bool notInitialized = true;
00217
00218
00219 for (; (iter != objects.end()) && notInitialized; ++iter) {
00220 objPtr = dynamic_cast<const VPGraphicObj*>(*iter);
00221 if (objPtr)
00222 {
00223 bbox = objPtr->GetRecursiveBoundingBox();
00224 notInitialized = false;
00225 }
00226 }
00227
00228
00229 for (; iter != objects.end(); ++iter) {
00230 objPtr = dynamic_cast<const VPGraphicObj*>(*iter);
00231 if (objPtr)
00232 bbox.MergeWith(objPtr->GetRecursiveBoundingBox());
00233 }
00234 }
00235
00236 void VPScene::MakeCameraViewAll()
00237 {
00238 assert(cameras.size() > 0);
00239 VPPoint4D bboxCenter;
00240 double distance, cameraDistance;
00241
00242 bbox.ProcessCenter();
00243 bboxCenter = bbox.GetCenter();
00244 (*currentCamera)->SetTarget(bboxCenter);
00245 cameraDistance = bbox.GetGreaterX()-bbox.GetSmallerX();
00246 distance = bbox.GetGreaterY()-bbox.GetSmallerY();
00247 if (distance > cameraDistance)
00248 cameraDistance = distance;
00249 distance = bbox.GetGreaterZ()-bbox.GetSmallerZ();
00250 if (distance > cameraDistance)
00251 cameraDistance = distance;
00252
00253 (*currentCamera)->SetLocation(bboxCenter+VPPoint4D(0,0,cameraDistance*1.2,0));
00254 (*currentCamera)->SetUp(VPPoint4D::Y());
00255
00256
00257 (*currentCamera)->SetFarPlaneDistance(cameraDistance*2.4);
00258 }