00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "cullTraverserData.h"
00020 #include "cullTraverser.h"
00021 #include "config_pgraph.h"
00022 #include "pandaNode.h"
00023 #include "colorAttrib.h"
00024 #include "textureAttrib.h"
00025 #include "renderModeAttrib.h"
00026 #include "billboardEffect.h"
00027 #include "compassEffect.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036 void CullTraverserData::
00037 apply_transform_and_state(CullTraverser *trav,
00038 CPT(TransformState) node_transform,
00039 CPT(RenderState) node_state,
00040 CPT(RenderEffects) node_effects) {
00041
00042
00043 _net_transform = _net_transform->compose(node_transform);
00044
00045 const CompassEffect *compass = node_effects->get_compass();
00046 if (compass != (const CompassEffect *)NULL) {
00047 CPT(TransformState) compass_transform =
00048 compass->do_compass(_net_transform, node_transform);
00049 _net_transform = _net_transform->compose(compass_transform);
00050 node_transform = node_transform->compose(compass_transform);
00051 }
00052
00053 const BillboardEffect *billboard = node_effects->get_billboard();
00054 if (billboard != (const BillboardEffect *)NULL) {
00055 CPT(TransformState) billboard_transform =
00056 billboard->do_billboard(_net_transform, trav->get_camera_transform());
00057 _net_transform = _net_transform->compose(billboard_transform);
00058 node_transform = node_transform->compose(billboard_transform);
00059 }
00060
00061 if (!node_transform->is_identity()) {
00062 _render_transform = _render_transform->compose(node_transform);
00063
00064 if ((_view_frustum != (GeometricBoundingVolume *)NULL) ||
00065 (_guard_band != (GeometricBoundingVolume *)NULL)) {
00066
00067
00068 if (node_transform->is_singular()) {
00069
00070
00071
00072 _view_frustum = (GeometricBoundingVolume *)NULL;
00073 _guard_band = (GeometricBoundingVolume *)NULL;
00074
00075 } else {
00076 CPT(TransformState) inv_transform =
00077 node_transform->invert_compose(TransformState::make_identity());
00078
00079
00080
00081 if (_view_frustum != (GeometricBoundingVolume *)NULL) {
00082 _view_frustum = DCAST(GeometricBoundingVolume, _view_frustum->make_copy());
00083 _view_frustum->xform(inv_transform->get_mat());
00084 }
00085
00086 if (_guard_band != (GeometricBoundingVolume *)NULL) {
00087 _guard_band = DCAST(GeometricBoundingVolume, _guard_band->make_copy());
00088 _guard_band->xform(inv_transform->get_mat());
00089 }
00090 }
00091 }
00092 }
00093
00094 _state = _state->compose(node_state);
00095 }
00096
00097
00098
00099
00100
00101
00102 bool CullTraverserData::
00103 is_in_view_impl() {
00104
00105 nassertr(_view_frustum != (GeometricBoundingVolume *)NULL, true);
00106
00107 const BoundingVolume &node_volume = node()->get_bound();
00108 nassertr(node_volume.is_of_type(GeometricBoundingVolume::get_class_type()), false);
00109 const GeometricBoundingVolume *node_gbv =
00110 DCAST(GeometricBoundingVolume, &node_volume);
00111
00112 int result = _view_frustum->contains(node_gbv);
00113 if (result == BoundingVolume::IF_no_intersection) {
00114
00115 if (!fake_view_frustum_cull) {
00116 return false;
00117 }
00118
00119
00120
00121
00122 _view_frustum = (GeometricBoundingVolume *)NULL;
00123 CPT(RenderState) fake_state = get_fake_view_frustum_cull_state();
00124 _state = _state->compose(fake_state);
00125
00126 } else if ((result & BoundingVolume::IF_all) != 0) {
00127
00128
00129 _view_frustum = (GeometricBoundingVolume *)NULL;
00130
00131 } else {
00132 if (node()->is_final()) {
00133
00134
00135
00136
00137
00138
00139 _view_frustum = (GeometricBoundingVolume *)NULL;
00140 }
00141 }
00142
00143 return true;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 CPT(RenderState) CullTraverserData::
00155 get_fake_view_frustum_cull_state() {
00156
00157
00158 static CPT(RenderState) state = (const RenderState *)NULL;
00159 if (state == (const RenderState *)NULL) {
00160 state = RenderState::make
00161 (ColorAttrib::make_flat(Colorf(1.0f, 0.0f, 0.0f, 1.0f)),
00162 TextureAttrib::make_off(),
00163 RenderModeAttrib::make(RenderModeAttrib::M_wireframe),
00164 RenderState::get_max_priority());
00165 }
00166 return state;
00167 }
00168