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 #include "Teddy/Graphics/View.h"
00026 #include "Teddy/Materials/Light.h"
00027 #include "Teddy/Materials/Material.h"
00028 #include "Teddy/Models/Geometry.h"
00029 #include "Teddy/PhysicalComponents/Projection.h"
00030 #include "Teddy/Scenes/Camera.h"
00031 #include "Teddy/Scenes/PostElement.h"
00032 #include "Teddy/Scenes/Scene.h"
00033 #include "Teddy/SysSupport/Messages.h"
00034 #include "Teddy/SysSupport/StdMaths.h"
00035 #include "Teddy/SysSupport/StdIO.h"
00036 #ifndef SWIG
00037 #include <cstdlib>
00038 #include <algorithm>
00039 #endif
00040 using namespace Teddy::Graphics;
00041 using namespace Teddy::Materials;
00042 using namespace Teddy::Models;
00043 using namespace Teddy::PhysicalComponents;
00044 using namespace std;
00045
00046
00047 namespace Teddy {
00048 namespace Scenes {
00049
00050
00052 Scene::Scene( const std::string &name )
00053 :
00054 Named( name )
00055 {
00056 cull_count = 0;
00057 draw_count = 0;
00058 last_draw_count = 0;
00059 ambient_color = Color::GRAY_25;
00060 }
00061
00062
00063 int Scene::getDrawCount(){
00064 return last_draw_count;
00065 }
00066
00067
00069 void Scene::add( Light *l ){
00070 lights.push_back( l );
00071 }
00072
00073
00075 void Scene::add( PostElement *p ){
00076 post_elements.push_back( p );
00077 }
00078
00079
00081 void Scene::add( Model *m ){
00082 models.push_back( m );
00083 }
00084
00085
00086 void Scene::remove( Light *l ){
00087 lights.remove( l );
00088 }
00089
00090 void Scene::remove( PostElement *p ){
00091 post_elements.remove( p );
00092 }
00093
00094 void Scene::remove( Model *m ){
00095 models.remove( m );
00096 }
00097
00098
00103 void Scene::update( Projection *p ){
00104
00105
00106
00107
00108
00109
00110 }
00111
00112
00114 list<Model*> &Scene::getModels(){
00115 return models;
00116 }
00117
00118
00119 void Scene::setAmbientColor( Teddy::Graphics::Color ambient_color ){
00120 this->ambient_color = ambient_color;
00121 }
00122
00123
00125 void Scene::draw( Camera *c, Projection *p ){
00126 View *view = p->getView();
00127 list<Light *>::iterator l_it;
00128 list<PostElement*>::iterator p_it;
00129 list<Model *>::iterator m_it;
00130 cull_count = 0;
00131
00132
00133 glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient_color.rgba );
00134 switch( p->getMaster()->getLighting() ){
00135
00136 case 1:
00137
00138 break;
00139
00140 case 2:
00141
00142 break;
00143
00144 case 3:
00145
00146 l_it = lights.begin();
00147 if( l_it != lights.end() ){
00148 (*l_it)->applyLight( p );
00149 }
00150 break;
00151
00152 case 5:
00153
00154 case 4:
00155
00156 l_it = lights.begin();
00157 while( l_it != lights.end() ){
00158 (*l_it)->applyLight( p );
00159 l_it++;
00160 }
00161 break;
00162
00163
00164 default:
00165
00166 break;
00167 }
00168
00169
00170 m_it = models.begin();
00171 while( m_it != models.end() ){
00172 Model *m = *m_it;
00173 if( m != c ){
00174 m->draw( p );
00175 }
00176 m_it++;
00177 }
00178 last_draw_count = Geometry::draw_count;
00179
00180 drawPostElements( c, p );
00181 }
00182
00183
00184 int Scene::getCullCount(){
00185 return cull_count;
00186 }
00187
00188
00190 void Scene::drawPostElements( Camera *c, Projection *p ){
00191 View *view = p->getView();
00192 list<PostElement*>::iterator p_it;
00193
00194
00195 c->doProjection ( p, true );
00196
00197 view->enable ( View::BLEND );
00198 view->setShadeModel ( GL_SMOOTH );
00199 view->setPolygonMode( GL_FILL );
00200 view->setBlendFunc ( GL_ONE, GL_ONE );
00201 view->disable ( View::LIGHTING );
00202 view->disable ( View::DEPTH_TEST );
00203 view->disable ( View::CULL_FACE );
00204 view->disable ( View::POLYGON_OFFSET );
00205
00206
00207 view->setModelViewMatrix ( Matrix::IDENTITY );
00208
00209 p_it = post_elements.begin();
00210 while( p_it != post_elements.end() ){
00211 (*p_it)->draw( p );
00212 p_it++;
00213 }
00214 }
00215
00216
00218 Model *Scene::pick( Camera *c, Projection *p ){
00219 Model *m_lookup[1024];
00220 Model *pick = NULL;
00221 View *view;
00222 GLuint hits[1024];
00223 list<Model*>::iterator m_it;
00224
00225 glSelectBuffer( 1024, hits );
00226
00227 glRenderMode( GL_SELECT );
00228 view = p->getView();
00229 p->pickState( true );
00230
00231
00232
00233 glInitNames();
00234 glPushName( 0 );
00235
00236 int name = 1;
00237 int pick_drawn = 0;
00238 int pick_culled = 0;
00239 int pick_hidden = 0;
00240
00241 m_it = models.begin();
00242 while( m_it != models.end() ){
00243 Model *m = (*m_it);
00244 m_lookup[name] = m;
00245 glLoadName( name++ );
00246
00247
00248 if( m != c ){
00249
00250
00251
00252
00253
00254
00255 m->draw( p );
00256 pick_drawn++;
00257 }else{
00258 pick_hidden++;
00259 }
00260
00261 m_it++;
00262 }
00263 GLuint num_hits = glRenderMode( GL_RENDER );
00264 GLuint *ptr = hits;
00265 GLuint names;
00266 GLuint z_min;
00267 GLuint z_max;
00268 GLuint hit_name;
00269 GLuint nearest = 0xffffffff;
00270
00271 for( GLuint i=0; i<num_hits; i++ ){
00272 names = *ptr++;
00273 z_min = *ptr++;
00274 z_max = *ptr++;
00275 for( GLuint j=0; j<names; j++ ){
00276 hit_name = *ptr++;
00277 if( z_min<nearest ){
00278 nearest = z_min;
00279 pick = m_lookup[hit_name];
00280 }
00281 }
00282 }
00283 p->pickState( false );
00284
00285
00286
00287
00288
00289 return pick;
00290 }
00291
00292
00293
00294 float Scene::getMaxObSize(){
00295 float max_ob_size = 0.0f;
00296 list<Model*>::iterator m_it = models.begin();
00297 while( m_it != models.end() ){
00298 Model *model = *m_it;
00299 max_ob_size = MAX(
00300 max_ob_size,
00301 model->getClipRadius()
00302 );
00303 m_it++;
00304 }
00305 return max_ob_size;
00306 }
00307
00308
00309
00310 float Scene::getMaxObDistance(){
00311 float max_ob_dist = 0.0f;
00312 list<Model*>::iterator m_it = models.begin();
00313 while( m_it != models.end() ){
00314 Model *model = *m_it;
00315 DoubleVector ob_pos = model->getPosition();
00316 float ob_dist = (float)ob_pos.magnitude();
00317 max_ob_dist = MAX(
00318 max_ob_dist,
00319 ob_dist
00320 );
00321 m_it++;
00322 }
00323 return max_ob_dist;
00324 }
00325
00326
00327 };
00328 };
00329
00330