Panda3D

lensFlareNode.cxx

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