00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "fadeLodNode.h"
00016 #include "fadeLodNodeData.h"
00017 #include "cullTraverserData.h"
00018 #include "cullTraverser.h"
00019 #include "clockObject.h"
00020 #include "colorScaleAttrib.h"
00021 #include "depthWriteAttrib.h"
00022 #include "transparencyAttrib.h"
00023 #include "cullBinAttrib.h"
00024 #include "depthOffsetAttrib.h"
00025
00026 TypeHandle FadeLODNode::_type_handle;
00027
00028
00029
00030
00031
00032
00033 FadeLODNode::
00034 FadeLODNode(const string &name) :
00035 LODNode(name)
00036 {
00037 set_cull_callback();
00038
00039 _fade_time = lod_fade_time;
00040 _fade_bin_name = lod_fade_bin_name;
00041 _fade_bin_draw_order = lod_fade_bin_draw_order;
00042 _fade_state_override = lod_fade_state_override;
00043 }
00044
00045
00046
00047
00048
00049
00050 FadeLODNode::
00051 FadeLODNode(const FadeLODNode ©) :
00052 LODNode(copy)
00053 {
00054 _fade_time = copy._fade_time;
00055 _fade_bin_name = copy._fade_bin_name;
00056 _fade_bin_draw_order = copy._fade_bin_draw_order;
00057 _fade_state_override = copy._fade_state_override;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 PandaNode *FadeLODNode::
00069 make_copy() const {
00070 return new FadeLODNode(*this);
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 bool FadeLODNode::
00099 cull_callback(CullTraverser *trav, CullTraverserData &data) {
00100 if (!support_fade_lod) {
00101 return LODNode::cull_callback(trav, data);
00102 }
00103
00104 if (is_any_shown()) {
00105 return show_switches_cull_callback(trav, data);
00106 }
00107
00108 consider_verify_lods(trav, data);
00109
00110 Camera *camera = trav->get_scene()->get_camera_node();
00111 NodePath this_np = data._node_path.get_node_path();
00112 FadeLODNodeData *ldata =
00113 DCAST(FadeLODNodeData, camera->get_aux_scene_data(this_np));
00114
00115 double now = ClockObject::get_global_clock()->get_frame_time();
00116
00117 if (ldata == (AuxSceneData *)NULL || now > ldata->get_expiration_time()) {
00118
00119
00120 ldata = new FadeLODNodeData;
00121 ldata->_fade_mode = FadeLODNodeData::FM_solid;
00122 ldata->_fade_out = -1;
00123 ldata->_fade_in = compute_child(trav, data);
00124 camera->set_aux_scene_data(this_np, ldata);
00125
00126 } else {
00127
00128
00129
00130 if (ldata->_fade_mode == FadeLODNodeData::FM_solid) {
00131
00132
00133 int index = compute_child(trav, data);
00134 if (index != ldata->_fade_in) {
00135
00136 if (index >= 0 && ldata->_fade_in >= 0 &&
00137 get_out(index) > get_out(ldata->_fade_in)) {
00138
00139
00140 ldata->_fade_mode = FadeLODNodeData::FM_less_detail;
00141 } else {
00142
00143
00144 ldata->_fade_mode = FadeLODNodeData::FM_more_detail;
00145 }
00146
00147
00148
00149
00150
00151 ldata->_fade_start = ldata->get_last_render_time();
00152 ldata->_fade_out = ldata->_fade_in;
00153 ldata->_fade_in = index;
00154 }
00155 }
00156
00157 if (ldata->_fade_mode != FadeLODNodeData::FM_solid) {
00158
00159
00160 PN_stdfloat elapsed = now - ldata->_fade_start;
00161
00162 if (elapsed >= _fade_time) {
00163
00164 ldata->_fade_mode = FadeLODNodeData::FM_solid;
00165
00166 } else {
00167 PN_stdfloat half_fade_time = _fade_time * 0.5f;
00168
00169 int in_child = ldata->_fade_in;
00170 int out_child = ldata->_fade_out;
00171
00172 if (ldata->_fade_mode == FadeLODNodeData::FM_less_detail) {
00173
00174
00175
00176 elapsed = _fade_time - elapsed;
00177 int t = in_child;
00178 in_child = out_child;
00179 out_child = t;
00180 }
00181
00182 nassertr(elapsed >= 0.0f && elapsed <= _fade_time, false);
00183
00184 if (elapsed < half_fade_time) {
00185
00186
00187
00188 if (out_child >= 0 && out_child < get_num_children()) {
00189 PandaNode *child = get_child(out_child);
00190 if (child != (PandaNode *)NULL) {
00191 CullTraverserData next_data_out(data, child);
00192 next_data_out._state =
00193 next_data_out._state->compose(get_fade_1_old_state());
00194 trav->traverse(next_data_out);
00195 }
00196 }
00197
00198 if (in_child >= 0 && in_child < get_num_children()) {
00199 PandaNode *child = get_child(in_child);
00200 if (child != (PandaNode *)NULL) {
00201 CullTraverserData next_data_in(data, child);
00202
00203 PN_stdfloat in_alpha = elapsed / half_fade_time;
00204 next_data_in._state =
00205 next_data_in._state->compose(get_fade_1_new_state(in_alpha));
00206 trav->traverse(next_data_in);
00207 }
00208 }
00209
00210 } else {
00211
00212
00213
00214 if (in_child >= 0 && in_child < get_num_children()) {
00215 PandaNode *child = get_child(in_child);
00216 if (child != (PandaNode *)NULL) {
00217 CullTraverserData next_data_in(data, child);
00218 next_data_in._state =
00219 next_data_in._state->compose(get_fade_2_new_state());
00220 trav->traverse(next_data_in);
00221 }
00222 }
00223
00224 if (out_child >= 0 && out_child < get_num_children()) {
00225 PandaNode *child = get_child(out_child);
00226 if (child != (PandaNode *)NULL) {
00227 CullTraverserData next_data_out(data, child);
00228
00229 PN_stdfloat out_alpha = 1.0f - (elapsed - half_fade_time) / half_fade_time;
00230 next_data_out._state =
00231 next_data_out._state->compose(get_fade_2_old_state(out_alpha));
00232 trav->traverse(next_data_out);
00233 }
00234 }
00235 }
00236 }
00237 }
00238 }
00239
00240 if (ldata->_fade_mode == FadeLODNodeData::FM_solid) {
00241
00242
00243 int index = ldata->_fade_in;
00244 if (index >= 0 && index < get_num_children()) {
00245 PandaNode *child = get_child(index);
00246 if (child != (PandaNode *)NULL) {
00247 CullTraverserData next_data(data, child);
00248 trav->traverse(next_data);
00249 }
00250 }
00251 }
00252
00253 ldata->set_last_render_time(now);
00254 ldata->set_duration(_fade_time);
00255
00256 return false;
00257 }
00258
00259
00260
00261
00262
00263
00264 void FadeLODNode::
00265 output(ostream &out) const {
00266 LODNode::output(out);
00267 out << " fade time: " << _fade_time;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277 void FadeLODNode::
00278 set_fade_bin(const string &name, int draw_order) {
00279 _fade_bin_name = name;
00280 _fade_bin_draw_order = draw_order;
00281 _fade_1_new_state.clear();
00282 _fade_2_old_state.clear();
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 void FadeLODNode::
00294 set_fade_state_override(int override) {
00295 _fade_state_override = override;
00296 _fade_1_old_state.clear();
00297 _fade_1_new_state.clear();
00298 _fade_2_old_state.clear();
00299 _fade_2_new_state.clear();
00300 }
00301
00302
00303
00304
00305
00306
00307
00308 CPT(RenderState) FadeLODNode::
00309 get_fade_1_old_state() {
00310 if (_fade_1_old_state == (const RenderState *)NULL) {
00311 _fade_1_old_state = RenderState::make_empty();
00312 }
00313
00314 return _fade_1_old_state;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323 CPT(RenderState) FadeLODNode::
00324 get_fade_1_new_state(PN_stdfloat in_alpha) {
00325 if (_fade_1_new_state == (const RenderState *)NULL) {
00326 _fade_1_new_state = RenderState::make
00327 (TransparencyAttrib::make(TransparencyAttrib::M_alpha),
00328 CullBinAttrib::make(_fade_bin_name, _fade_bin_draw_order),
00329 DepthOffsetAttrib::make(),
00330 _fade_state_override);
00331 }
00332
00333 LVecBase4 alpha_scale(1.0f, 1.0f, 1.0f, in_alpha);
00334 return _fade_1_new_state->compose
00335 (RenderState::make(ColorScaleAttrib::make(alpha_scale)));
00336 }
00337
00338
00339
00340
00341
00342
00343
00344 CPT(RenderState) FadeLODNode::
00345 get_fade_2_old_state(PN_stdfloat out_alpha) {
00346 if (_fade_2_old_state == (const RenderState *)NULL) {
00347 _fade_2_old_state = RenderState::make
00348 (TransparencyAttrib::make(TransparencyAttrib::M_alpha),
00349 DepthWriteAttrib::make(DepthWriteAttrib::M_off),
00350 CullBinAttrib::make(_fade_bin_name, _fade_bin_draw_order),
00351 _fade_state_override);
00352 }
00353
00354 LVecBase4 alpha_scale(1.0f, 1.0f, 1.0f, out_alpha);
00355 return _fade_2_old_state->compose
00356 (RenderState::make(ColorScaleAttrib::make(alpha_scale)));
00357 }
00358
00359
00360
00361
00362
00363
00364
00365 CPT(RenderState) FadeLODNode::
00366 get_fade_2_new_state() {
00367 if (_fade_2_new_state == (const RenderState *)NULL) {
00368 _fade_2_new_state = RenderState::make
00369 (DepthOffsetAttrib::make(),
00370 _fade_state_override);
00371 }
00372
00373 return _fade_2_new_state;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 void FadeLODNode::
00383 register_with_read_factory() {
00384 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 void FadeLODNode::
00394 write_datagram(BamWriter *manager, Datagram &dg) {
00395 LODNode::write_datagram(manager, dg);
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 TypedWritable *FadeLODNode::
00407 make_from_bam(const FactoryParams ¶ms) {
00408 FadeLODNode *node = new FadeLODNode("");
00409 DatagramIterator scan;
00410 BamReader *manager;
00411
00412 parse_params(params, scan, manager);
00413 node->fillin(scan, manager);
00414
00415 return node;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425 void FadeLODNode::
00426 fillin(DatagramIterator &scan, BamReader *manager) {
00427 LODNode::fillin(scan, manager);
00428 }