00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00048
00049 TypeHandle LensFlareNode::_type_handle;
00050
00051
00052
00053
00054
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
00073
00074
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
00084
00085
00086
00087
00088
00089
00090
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
00107
00108
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
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
00131
00132
00133
00134
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
00164
00165
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
00177 nassertv(_flare_offsets[i].size() == _flare_scales[i].size());
00178
00179 GeomSprite *sprite = new GeomSprite();
00180 GeomNode *node = new GeomNode();
00181
00182
00183
00184
00185
00186
00187
00188
00189
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
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
00214 sprite->mark_bound_stale();
00215 node->mark_bound_stale();
00216 }
00217 }
00218 }
00219
00220
00221
00222
00223
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
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
00243
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
00261 sprite->mark_bound_stale();
00262 node->mark_bound_stale();
00263 }
00264 }
00265
00266
00267
00268
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
00284 gsg->render_subgraph(gsg->get_render_traverser(),
00285 arc->get_child(), new_trans);
00286 }
00287
00288
00289
00290
00291
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
00306
00307
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
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
00337
00338
00339
00340 LPoint3f center = LPoint3f::origin() + LPoint3f::rfu(0,lens->get_near(),0);
00341 center = center * inv_light_mat * modelview_mat;
00342
00343
00344 LPoint3f delta = center - light_pos;
00345 delta.set_z(light_pos.get_z());
00346
00347
00348
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
00364 return false;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374 bool LensFlareNode::
00375 has_sub_render() const
00376 {
00377 return true;
00378 }
00379
00380
00381
00382
00383
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
00438
00439
00440
00441
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
00506
00507
00508
00509
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
00538
00539
00540
00541
00542
00543
00544 TypedWritable *LensFlareNode::
00545 make_LensFlareNode(const FactoryParams ¶ms) {
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
00557
00558
00559
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
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 ¤t_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.