Panda3D
|
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 ¶ms) { 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 ¤t_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.