Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/effects/lensFlareNode.cxx

Go to the documentation of this file.
00001 // Filename: lensFlareNode.cxx
00002 // Created by:  jason (18Jul00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #if 0  // temporarily disabled until we can port to new scene graph.
00020 
00021 #include "lensFlareNode.h"
00022 #include "config_effects.h"
00023 
00024 #include "sequenceNode.h"
00025 #include "geomNode.h"
00026 #include "geomSprite.h"
00027 #include "textureTransition.h"
00028 #include "transformTransition.h"
00029 #include "billboardTransition.h"
00030 #include "transformTransition.h"
00031 #include "transparencyTransition.h"
00032 #include "renderTraverser.h"
00033 #include "lens.h"
00034 #include "get_rel_pos.h"
00035 #include "clockObject.h"
00036 #include "allTransitionsWrapper.h"
00037 #include "allTransitionsWrapper.h"
00038 #include "graphicsStateGuardian.h"
00039 #include "datagram.h"
00040 #include "datagramIterator.h"
00041 #include "bamReader.h"
00042 #include "bamWriter.h"
00043 #include "ioPtaDatagramFloat.h"
00044 #include "ioPtaDatagramLinMath.h"
00045 
00046 ////////////////////////////////////////////////////////////////////
00047 // Static variables
00048 ////////////////////////////////////////////////////////////////////
00049 TypeHandle LensFlareNode::_type_handle;
00050 
00051 ////////////////////////////////////////////////////////////////////
00052 //     Function: LensFlareNode::add_bloom
00053 //       Access: Public
00054 //  Description:
00055 ////////////////////////////////////////////////////////////////////
00056 void LensFlareNode::
00057 add_flare(PT(Texture) flare, PTA_float scales, PTA_float offsets,
00058           PTA_float angle_scales, PTA_Colorf colors)
00059 {
00060   nassertv(scales.size() == offsets.size());
00061   nassertv(colors.size() == offsets.size());
00062   nassertv(angle_scales.size() == offsets.size());
00063 
00064   _flare_scales.push_back(scales);
00065   _flare_offsets.push_back(offsets);
00066   _flare_colors.push_back(colors);
00067   _flare_angle_scales.push_back(angle_scales);
00068   _flares.push_back(flare);
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: LensFlareNode::add_blind
00073 //       Access: Public
00074 //  Description:
00075 ////////////////////////////////////////////////////////////////////
00076 void LensFlareNode::
00077 add_blind(PT(Texture) blind)
00078 {
00079   _blind = blind;
00080   GeomSprite *sprite = new GeomSprite();
00081   GeomNode *node = new GeomNode();
00082 
00083   //We don't want to set any geometry right now, as that will be
00084   //taken care of later (and on each subsequent render), but
00085   //Geoms requires a certain amount of info or else they crash,
00086   //so simply give it the minimum it needs not to crash
00087 
00088   //The lengths and number of prims will never change, so give
00089   //it valid values for those, but pass it an empty array of
00090   //vertices
00091   PTA_Vertexf coords=PTA_Vertexf::empty_array(0);
00092   PTA_float tex_scales=PTA_float::empty_array(0);
00093 
00094   tex_scales.push_back(_texel_scale);
00095 
00096   sprite->set_coords(coords);
00097   sprite->set_num_prims(1);
00098   sprite->set_texture(_blind);
00099 
00100   node->add_geom(sprite);
00101 
00102   _blind_arc = new RenderRelation(this, node);
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: LensFlareNode::set_geometry
00107 //       Access: Private
00108 //  Description:
00109 ////////////////////////////////////////////////////////////////////
00110 void LensFlareNode::
00111 set_geometry(GeomSprite *sprite, const PTA_float &geom_scales,
00112              const PTA_float &geom_offsets, const PTA_float &geom_angle_scales,
00113              const PTA_Colorf &geom_colors, const LVector3f &delta,
00114              const LPoint3f &light, const float &angle)
00115 {
00116 
00117   PTA_Vertexf coords=PTA_Vertexf::empty_array(0);
00118   PTA_float tex_scales=PTA_float::empty_array(0);
00119   PTA_Colorf colors=PTA_Colorf::empty_array(0);
00120 
00121   //Sanity check
00122   nassertv(geom_scales.size() == geom_offsets.size());
00123   nassertv(geom_colors.size() == geom_offsets.size());
00124 
00125   float world_scale = _texel_scale * _global_scale;
00126   for(int i = 0; i < (int)geom_scales.size(); i++)
00127   {
00128     LVector3f position = (delta * geom_offsets[i]) + light;
00129     float view_scale;
00130     //If this is true then we are supposed to invert the meaning of
00131     //the scale. I.E.  As the angle between the viewing direction and
00132     //the light direction increases we want the size of the thing to
00133     //get smaller and as it increases we want it to get bigger.  This
00134     //will actually be the normal use of angle scales
00135     if (geom_angle_scales[i] < 0)
00136     {
00137       view_scale = (1.0f-pow(angle, 15.0f)) * -geom_angle_scales[i];
00138     }
00139     else
00140     {
00141       view_scale = pow(angle, 15.0f) * geom_angle_scales[i];
00142     }
00143     float offset = (angle - 1.0f) / _flare_fall_off;
00144     offset = (offset < 0.0f) ? 0.0f : ((offset > 1.0f) ? 1.0f : offset);
00145     float r = geom_colors[i][0] - offset;
00146     float g = geom_colors[i][1] - offset;
00147     float b = geom_colors[i][2] - offset;
00148     r = (r < 0.0f) ? 0.0f : r;
00149     g = (g < 0.0f) ? 0.0f : g;
00150     b = (b < 0.0f) ? 0.0f : b;
00151 
00152     coords.push_back(position); tex_scales.push_back(geom_scales[i] * (world_scale + view_scale));
00153     colors.push_back(Colorf(r, g, b, 1));
00154   }
00155 
00156   sprite->set_coords(coords);
00157   sprite->set_x_texel_ratio(tex_scales, G_PER_PRIM);
00158   sprite->set_y_texel_ratio(tex_scales, G_PER_PRIM);
00159   sprite->set_colors(colors, G_PER_PRIM);
00160 }
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: LensFlareNode::prepare_flares
00164 //       Access: Private
00165 //  Description:
00166 ////////////////////////////////////////////////////////////////////
00167 void LensFlareNode::
00168 prepare_flares(const LVector3f &delta, const LPoint3f &light, const float &angle)
00169 {
00170   if (_flares.size() > 0)
00171   {
00172     if (_flares.size() > _flare_arcs.size())
00173     {
00174       for(int i = _flare_arcs.size(); i < (int)_flares.size(); i++)
00175       {
00176         //Sanity check
00177         nassertv(_flare_offsets[i].size() == _flare_scales[i].size());
00178 
00179         GeomSprite *sprite = new GeomSprite();
00180         GeomNode *node = new GeomNode();
00181 
00182         //We don't want to set any geometry right now, as that will be
00183         //taken care of later (and on each subsequent render), but
00184         //Geoms requires a certain amount of info or else they crash,
00185         //so simply give it the minimum it needs not to crash
00186 
00187         //The lengths and number of prims will never change, so give
00188         //it valid values for those, but pass it an empty array of
00189         //vertices
00190         PTA_Vertexf coords=PTA_Vertexf::empty_array(0);
00191 
00192         sprite->set_coords(coords);
00193         sprite->set_num_prims(_flare_offsets[i].size());
00194 
00195         node->add_geom(sprite);
00196 
00197         RenderRelation *arc = new RenderRelation(this, node);
00198         //arc->set_transition(new TransparencyTransition(TransparencyProperty::M_alpha));
00199         _flare_arcs.push_back(arc);
00200       }
00201     }
00202 
00203     for(int i = 0; i < (int)_flares.size(); i++)
00204     {
00205       GeomNode *node = DCAST(GeomNode, _flare_arcs[i]->get_child());
00206       GeomSprite *sprite = DCAST(GeomSprite, node->get_geom(0));
00207 
00208       set_geometry(sprite, _flare_scales[i], _flare_offsets[i],
00209                    _flare_angle_scales[i], _flare_colors[i],
00210                    delta, light, angle);
00211       sprite->set_texture(_flares[i]);
00212 
00213       //Tell them to recompute their bounding volumes
00214       sprite->mark_bound_stale();
00215       node->mark_bound_stale();
00216     }
00217   }
00218 }
00219 
00220 ////////////////////////////////////////////////////////////////////
00221 //     Function: LensFlareNode::prepare_blind
00222 //       Access: Private
00223 //  Description:
00224 ////////////////////////////////////////////////////////////////////
00225 void LensFlareNode::
00226 prepare_blind(const float &angle, const float &tnear)
00227 {
00228   if (_blind != (Texture*) NULL)
00229   {
00230     GeomNode *node = DCAST(GeomNode, _blind_arc->get_child());
00231     GeomSprite *sprite = DCAST(GeomSprite, node->get_geom(0));
00232 
00233     float offset = (angle - 1.0f) / _blind_fall_off;
00234     //Make sure that it always blends some
00235     offset = (offset < 0.3f) ? 0.3f : ((offset > 1.0f) ? 1.0f : offset);
00236 
00237     PTA_Vertexf coords=PTA_Vertexf::empty_array(0);
00238     PTA_Colorf colors=PTA_Colorf::empty_array(0);
00239     PTA_float x_tex_scales=PTA_float::empty_array(0);
00240     PTA_float y_tex_scales=PTA_float::empty_array(0);
00241 
00242     //The height and the width are set to two as sprites are always
00243     //drawn in a frustum of size 2.
00244     float width = sprite->get_frustum_right() - sprite->get_frustum_left();
00245     float height = sprite->get_frustum_top() - sprite->get_frustum_bottom();
00246     float x_offset_scale = width / _blind->_pbuffer->get_xsize();
00247     float y_offset_scale = height / _blind->_pbuffer->get_ysize();
00248 
00249     float inten = 1.0f - offset;
00250 
00251     coords.push_back(Vertexf(0.0f, 0.0f, -tnear ));
00252     colors.push_back(Colorf(inten,inten,inten,1.0f));
00253     x_tex_scales.push_back(x_offset_scale); y_tex_scales.push_back(y_offset_scale);
00254 
00255     sprite->set_x_texel_ratio(x_tex_scales, G_PER_PRIM);
00256     sprite->set_y_texel_ratio(y_tex_scales, G_PER_PRIM);
00257     sprite->set_coords(coords);
00258     sprite->set_colors(colors, G_PER_PRIM);
00259 
00260     //Tell it to recompute it's bounding volume
00261     sprite->mark_bound_stale();
00262     node->mark_bound_stale();
00263   }
00264 }
00265 ////////////////////////////////////////////////////////////////////
00266 //     Function: LensFlareNode::render_child
00267 //       Access: Pribate
00268 //  Description:
00269 ////////////////////////////////////////////////////////////////////
00270 void LensFlareNode::
00271 render_child(RenderRelation *arc, const AllTransitionsWrapper &trans,
00272              GraphicsStateGuardian *gsg)
00273 {
00274 
00275   AllTransitionsWrapper new_trans(trans);
00276   new_trans.clear_transition(TransformTransition::get_class_type());
00277 
00278   AllTransitionsWrapper arc_trans;
00279   arc_trans.extract_from(arc);
00280 
00281   new_trans.compose_in_place(arc_trans);
00282 
00283   // Now render everything from this node and below.
00284   gsg->render_subgraph(gsg->get_render_traverser(),
00285                        arc->get_child(), new_trans);
00286 }
00287 
00288 ////////////////////////////////////////////////////////////////////
00289 //     Function: LensFlareNode::render_children
00290 //       Access: Pribate
00291 //  Description:
00292 ////////////////////////////////////////////////////////////////////
00293 void LensFlareNode::
00294 render_children(const vector_relation &arcs, 
00295                 const AllTransitionsWrapper &trans,
00296                 GraphicsStateGuardian *gsg)
00297 {
00298   for(int i = 0; i < (int)arcs.size(); i++)
00299   {
00300     render_child(arcs[i], trans, gsg);
00301   }
00302 }
00303 
00304 ////////////////////////////////////////////////////////////////////
00305 //     Function: LensFlareNode::sub_render
00306 //       Access: Public, Virtual
00307 //  Description:
00308 ////////////////////////////////////////////////////////////////////
00309 bool LensFlareNode::
00310 sub_render(const AllTransitionsWrapper &input_trans,
00311            AllTransitionsWrapper &, RenderTraverser *trav) {
00312   GraphicsStateGuardian *gsg = trav->get_gsg();
00313 
00314   nassertr(_light_node != (Node*) NULL, false);
00315 
00316   //First we need the light position
00317   LensNode *camera_node = gsg->get_current_camera();
00318   Lens *lens = camera_node->get_lens();
00319 
00320   LPoint3f light_pos = get_rel_pos(_light_node, camera_node);
00321 
00322   LMatrix4f light_mat;
00323   get_rel_mat(_light_node, camera_node, light_mat);
00324 
00325   LMatrix4f modelview_mat;
00326 
00327   const TransformTransition *ta;
00328   if (!get_transition_into(ta, input_trans))
00329     modelview_mat = LMatrix4f::ident_mat();
00330   else
00331     modelview_mat = ta->get_matrix();
00332 
00333   LMatrix4f inv_light_mat = invert(light_mat);
00334   light_pos = light_pos * inv_light_mat * modelview_mat;
00335 
00336   //Now figure out where the center of the screen is.  Since we are
00337   //doing everything in camera space, this should merely be the
00338   //distance between the camera and the near clipping plane projected
00339   //along Y into the screen
00340   LPoint3f center = LPoint3f::origin() + LPoint3f::rfu(0,lens->get_near(),0);
00341   center = center * inv_light_mat * modelview_mat;
00342 
00343   //Now lets get the vector from the light to the center.
00344   LPoint3f delta = center - light_pos;
00345   delta.set_z(light_pos.get_z());
00346 
00347   //Now perform the angle caclulationss for increasing the brightness
00348   //as we look at the light dead on
00349   LPoint3f origin = LPoint3f::origin() * inv_light_mat * modelview_mat;
00350   LVector3f light_dir = light_pos - origin;
00351   light_dir.normalize();
00352   LVector3f view_dir = center - origin;
00353 
00354   float dot = view_dir.dot(light_dir);
00355   dot = (dot < 0.0f) ? -dot : dot;
00356 
00357   prepare_flares(delta, light_pos, dot);
00358   prepare_blind(dot, lens->get_near());
00359 
00360   render_children(_flare_arcs, input_trans, gsg);
00361   render_child(_blind_arc, input_trans, gsg);
00362 
00363   //Short circuit the rendering
00364   return false;
00365 }
00366 
00367 ////////////////////////////////////////////////////////////////////
00368 //     Function: LensFlareNode::has_sub_render
00369 //       Access: Public, Virtual
00370 //  Description: Should be redefined to return true if the function
00371 //               sub_render(), above, expects to be called during
00372 //               traversal.
00373 ////////////////////////////////////////////////////////////////////
00374 bool LensFlareNode::
00375 has_sub_render() const
00376 {
00377   return true;
00378 }
00379 
00380 ////////////////////////////////////////////////////////////////////
00381 //     Function: LensFlareNode::write_object
00382 //  Description: Writes the contents of this object to the datagram
00383 //               for shipping out to a Bam file.
00384 ////////////////////////////////////////////////////////////////////
00385 void LensFlareNode::
00386 write_datagram(BamWriter *manager, Datagram &me) {
00387   int i;
00388 
00389   Node::write_datagram(manager, me);
00390 
00391   me.add_uint16(_flares.size());
00392   for(i = 0; i < (int)_flares.size(); i++)
00393   {
00394     manager->write_pointer(me, _flares[i]);
00395   }
00396   manager->write_pointer(me, _blind);
00397 
00398   me.add_uint16(_flare_arcs.size());
00399   for(i = 0; i < (int)_flare_arcs.size(); i++)
00400   {
00401     manager->write_pointer(me, _flare_arcs[i]);
00402   }
00403 
00404   me.add_uint16(_flare_scales.size());
00405   for(i = 0; i < (int)_flare_scales.size(); i++)
00406   {
00407     WRITE_PTA(manager, me, IPD_float::write_datagram, _flare_scales[i])
00408   }
00409 
00410   me.add_uint16(_flare_angle_scales.size());
00411   for(i = 0; i < (int)_flare_angle_scales.size(); i++)
00412   {
00413     WRITE_PTA(manager, me, IPD_float::write_datagram, _flare_angle_scales[i])
00414   }
00415 
00416   me.add_uint16(_flare_offsets.size());
00417   for(i = 0; i < (int)_flare_offsets.size(); i++)
00418   {
00419     WRITE_PTA(manager, me, IPD_float::write_datagram, _flare_offsets[i])
00420   }
00421 
00422   me.add_uint16(_flare_colors.size());
00423   for(i = 0; i < (int)_flare_colors.size(); i++)
00424   {
00425     WRITE_PTA(manager, me, IPD_Colorf::write_datagram, _flare_colors[i])
00426   }
00427 
00428   me.add_float32(_global_scale);
00429   me.add_float32(_texel_scale);
00430   me.add_float32(_blind_fall_off);
00431   me.add_float32(_flare_fall_off);
00432 
00433   manager->write_pointer(me, _light_node);
00434 }
00435 
00436 ////////////////////////////////////////////////////////////////////
00437 //     Function: LensFlareNode::fillin
00438 //       Access: Protected
00439 //  Description: This internal function is called by make_LensFlareNode to
00440 //               read in all of the relevant data from the BamFile for
00441 //               the new LensFlareNode.
00442 ////////////////////////////////////////////////////////////////////
00443 void LensFlareNode::
00444 fillin(DatagramIterator &scan, BamReader *manager)
00445 {
00446   int i, size;
00447   Node::fillin(scan, manager);
00448 
00449   Node::fillin(scan, manager);
00450 
00451   _num_flares = scan.get_uint16();
00452   for(i = 0; i < _num_flares; i++)
00453   {
00454     manager->read_pointer(scan);
00455   }
00456   manager->read_pointer(scan);
00457 
00458   _num_arcs = scan.get_uint16();
00459   for(i = 0; i < _num_arcs; i++)
00460   {
00461     manager->read_pointer(scan);
00462   }
00463 
00464   size = scan.get_uint16();
00465   for(i = 0; i < size; i++)
00466   {
00467     PTA_float temp=PTA_float::empty_array(0);
00468     READ_PTA(manager, scan, IPD_float::read_datagram, temp)
00469     _flare_scales.push_back(temp);
00470   }
00471 
00472   size = scan.get_uint16();
00473   for(i = 0; i < size; i++)
00474   {
00475     PTA_float temp=PTA_float::empty_array(0);
00476     READ_PTA(manager, scan, IPD_float::read_datagram, temp)
00477     _flare_angle_scales.push_back(temp);
00478   }
00479 
00480   size = scan.get_uint16();
00481   for(i = 0; i < size; i++)
00482   {
00483     PTA_float temp=PTA_float::empty_array(0);
00484     READ_PTA(manager, scan, IPD_float::read_datagram, temp)
00485     _flare_offsets.push_back(temp);
00486   }
00487 
00488   size = scan.get_uint16();
00489   for(i = 0; i < size; i++)
00490   {
00491     PTA_Colorf temp=PTA_Colorf::empty_array(0);
00492     READ_PTA(manager, scan, IPD_Colorf::read_datagram, temp)
00493     _flare_colors.push_back(temp);
00494   }
00495 
00496   _global_scale = scan.get_float32();
00497   _texel_scale = scan.get_float32();
00498   _blind_fall_off = scan.get_float32();
00499   _flare_fall_off = scan.get_float32();
00500 
00501   manager->read_pointer(scan);
00502 }
00503 
00504 ////////////////////////////////////////////////////////////////////
00505 //     Function: LensFlareNode::complete_pointers
00506 //       Access: Public
00507 //  Description: Takes in a vector of pointes to TypedWritable
00508 //               objects that correspond to all the requests for
00509 //               pointers that this object made to BamReader.
00510 ////////////////////////////////////////////////////////////////////
00511 int LensFlareNode::
00512 complete_pointers(TypedWritable **p_list, BamReader *manager)
00513 {
00514   int i;
00515   int start = Node::complete_pointers(p_list, manager);
00516   int end = _num_flares + start;
00517 
00518   for(i = start; i < end; i++)
00519   {
00520     _flares.push_back(DCAST(Texture, p_list[i]));
00521   }
00522 
00523   _blind = DCAST(Texture, p_list[end]);
00524 
00525   end += 1 + _num_arcs;
00526   for(; i < end; i++)
00527   {
00528     _flare_arcs.push_back(DCAST(RenderRelation, p_list[i]));
00529   }
00530 
00531   _light_node = DCAST(Node, p_list[end]);
00532 
00533   return end+1;
00534 }
00535 
00536 ////////////////////////////////////////////////////////////////////
00537 //     Function: LensFlareNode::make_LensFlareNode
00538 //       Access: Protected
00539 //  Description: This function is called by the BamReader's factory
00540 //               when a new object of type LensFlareNode is encountered in
00541 //               the Bam file.  It should create the LensFlareNode and
00542 //               extract its information from the file.
00543 ////////////////////////////////////////////////////////////////////
00544 TypedWritable *LensFlareNode::
00545 make_LensFlareNode(const FactoryParams &params) {
00546   LensFlareNode *me = new LensFlareNode;
00547   DatagramIterator scan;
00548   BamReader *manager;
00549 
00550   parse_params(params, scan, manager);
00551   me->fillin(scan, manager);
00552   return me;
00553 }
00554 
00555 ////////////////////////////////////////////////////////////////////
00556 //     Function: LensFlareNode::register_with_read_factory
00557 //       Access: Public, Static
00558 //  Description: Tells the BamReader how to create objects of type
00559 //               LensFlareNode.
00560 ////////////////////////////////////////////////////////////////////
00561 void LensFlareNode::
00562 register_with_read_factory() {
00563   BamReader::get_factory()->register_factory(get_class_type(), make_LensFlareNode);
00564 }
00565 
00566 
00567 /***************
00568  OLD SPARKLE CODE
00569 
00570 ////////////////////////////////////////////////////////////////////
00571 //     Function: LensFlareNode::Constructor
00572 //       Access: Public
00573 //  Description:
00574 ////////////////////////////////////////////////////////////////////
00575 LensFlareNode::
00576 LensFlareNode(void) :
00577   _global_scale(1), _next_switch(-1), _sparkle_fps(0.2),
00578   _texel_scale(0.1), _inv_sparkle_fps(5), _exp_scale(15)
00579 {
00580   _global_clock = ClockObject::get_global_clock();
00581   _next_switch =  _global_clock->get_real_time() + _sparkle_fps;
00582 }
00583 
00584 ////////////////////////////////////////////////////////////////////
00585 //     Function: LensFlareNode::set_sparkle_fps
00586 //       Access: Public
00587 //  Description:
00588 ////////////////////////////////////////////////////////////////////
00589 void LensFlareNode::
00590 set_sparkle_fps(float fps)
00591 {
00592   nassertv(fps > 0);
00593   _next_switch = _next_switch - _sparkle_fps + fps;
00594   _sparkle_fps = fps;
00595   _inv_sparkle_fps = 1. / _sparkle_fps;
00596 }
00597 
00598 ////////////////////////////////////////////////////////////////////
00599 //     Function: LensFlareNode::compute_current
00600 //       Access: Private
00601 //  Description: Determines the current sparkle index
00602 ////////////////////////////////////////////////////////////////////
00603 int LensFlareNode::
00604 compute_current(int &current_sparkle, vector_texture sparkles)
00605 {
00606   double current_time = _global_clock->get_real_time();
00607   unsigned int increment = (unsigned int) ((current_time - _next_switch) * _inv_sparkle_fps);
00608 
00609   _next_switch += _sparkle_fps * increment;
00610   current_sparkle = (current_sparkle + increment) % sparkles.size();
00611 
00612   return current_sparkle;
00613 }
00614 
00615 ////////////////////////////////////////////////////////////////////
00616 //     Function: LensFlareNode::add_sparkle
00617 //       Access: Public
00618 //  Description:
00619 ////////////////////////////////////////////////////////////////////
00620 void LensFlareNode::
00621 add_sparkle(PT_Node source, PT(Texture) sparkle)
00622 {
00623   set_light(source);
00624   _sparkles.push_back(sparkle);
00625 }
00626 
00627 ////////////////////////////////////////////////////////////////////
00628 //     Function: LensFlareNode::set_sparkles_attributes
00629 //       Access: Public
00630 //  Description:
00631 ////////////////////////////////////////////////////////////////////
00632 void LensFlareNode::
00633 set_sparkles_attributes(PT_Node source, vector_float scales,
00634                         vector_float offsets, vector_Colorf colors)
00635 {
00636   nassertv(scales.size() == offsets.size());
00637 
00638   set_light(source);
00639 
00640   _sparkle_scales = scales;
00641   _sparkle_offsets = offsets;
00642   _sparkle_colors = colors;
00643 }
00644 
00645 ////////////////////////////////////////////////////////////////////
00646 //     Function: LensFlareNode::set_light
00647 //       Access: Private
00648 //  Description:
00649 ////////////////////////////////////////////////////////////////////
00650 void LensFlareNode::
00651 set_light(PT_Node light)
00652 {
00653  _lights.insert(light);
00654  if (_current_sparkles.find(light) == _current_sparkles.end())
00655  {
00656    _current_sparkles[light] = 0;
00657  }
00658 }
00659 
00660 ////////////////////////////////////////////////////////////////////
00661 //     Function: LensFlareNode::prepare_sparkles
00662 //       Access: Private
00663 //  Description:
00664 ////////////////////////////////////////////////////////////////////
00665 void LensFlareNode::
00666 prepare_sparkles(vector_relation &arcs, const vector_texture &sparkles,
00667                  const vector_float &scales, const vector_float &offsets,
00668                  const vector_Colorf &colors, const LVector3f &delta,
00669                  const LPoint3f &light, const BoundingVolume &bound, int &old_sparkle)
00670 {
00671   //Sanity check
00672   nassertv(scales.size() == offsets.size());
00673 
00674   if (scales.size() > 0)
00675   {
00676     if (arcs.size() == 0)
00677     {
00678       for(int i = 0; i < scales.size(); i++)
00679       {
00680         GeomSprite *sprite = new GeomSprite();
00681         GeomNode *node = new GeomNode();
00682 
00683         //We don't want to set any geometry right now, as that will be
00684         //taken care of later (and on each subsequent render), but
00685         //Geoms requires a certain amount of info or else they crash,
00686         //so simply give it the minimum it needs not to crash
00687 
00688         //The lengths and number of prims will never change, so give
00689         //it valid values for those, but pass it an empty array of
00690         //vertices
00691         PTA_Vertexf coords(0);
00692 
00693         sprite->set_coords(coords);
00694         sprite->set_num_prims(1);
00695 
00696         node->add_geom(sprite);
00697 
00698         arcs.push_back(new RenderRelation(this, node));
00699       }
00700     }
00701 
00702     //Unfortunately, we can't use set_geometry here because only a
00703     //certain number of sparkles are active at once, and set_geometry
00704     //knows nothing about switching between them
00705 
00706     for(int i = 0; i < scales.size(); i++)
00707     {
00708       int index = (compute_current(old_sparkle, sparkles)+i) % sparkles.size();
00709       LVector3f position = (delta * offsets[i]) + light;
00710 
00711       GeomNode *node = DCAST(GeomNode, arcs[i]->get_child());
00712       GeomSprite *sprite = DCAST(GeomSprite, node->get_geom(0));
00713 
00714       PTA_Vertexf coords(0);
00715       PTA_float tex_scales(0);
00716       PTA_Colorf sprite_colors(0);
00717 
00718       coords.push_back(position); tex_scales.push_back(scales[i] * _texel_scale * _global_scale);
00719 
00720       sprite_colors.push_back(colors[i]);
00721 
00722       sprite->set_coords(coords);
00723       sprite->set_x_texel_ratio(tex_scales, G_PER_PRIM);
00724       sprite->set_y_texel_ratio(tex_scales, G_PER_PRIM);
00725       sprite->set_colors(sprite_colors, G_PER_PRIM);
00726       sprite->set_texture(sparkles[index]);
00727 
00728       //Tell them to recompute their bounding volumes
00729       sprite->set_bound(bound);
00730       sprite->mark_bound_stale();
00731       node->mark_bound_stale();
00732     }
00733   }
00734 }
00735 
00736 ****************/
00737 
00738 #endif  // temporarily disabled until we can port to new scene graph.

Generated on Fri May 2 00:37:22 2003 for Panda by doxygen1.3