35 effect->_contribution_type = CT_proximal;
36 effect->_weight = 1.0;
37 effect->_effect_center = LPoint3(0.0,0.0,0.0);
38 return return_new(effect);
45 make(PN_stdfloat weight, ContribType contrib,
const LPoint3 &effect_center) {
47 effect->_contribution_type = contrib;
48 effect->_weight = weight;
49 effect->_effect_center = effect_center;
50 return return_new(effect);
57 make(PN_stdfloat weight, ContribType contrib,
const LPoint3 &effect_center,
58 const LightGroup &lights) {
60 effect->_contribution_type = contrib;
61 effect->_weight = weight;
62 effect->_effect_center = effect_center;
63 effect->_lightgroup = lights;
64 return return_new(effect);
74 return !_lightgroup.empty();
97 CPT(
RenderState) poly_light_state = RenderState::make(poly_light_attrib);
98 node_state = node_state->compose(poly_light_state);
112 PN_stdfloat min_dist;
114 PN_stdfloat light_scale;
115 PN_stdfloat weight_scale = 1.0f;
116 PN_stdfloat Rcollect, Gcollect, Bcollect;
124 Rcollect = Gcollect = Bcollect = 0.0;
128 if (polylight_info) {
129 pgraph_cat.debug() <<
"scene color scale = " << scene_color << endl;
133 LightGroup::const_iterator light_iter;
134 for (light_iter = _lightgroup.begin(); light_iter != _lightgroup.end(); light_iter++){
139 PN_stdfloat light_radius = light->
get_radius();
142 const NodePath lightnp = *light_iter;
143 LPoint3 relative_point = data->get_node_path().get_relative_point(lightnp, light->
get_pos());
145 if (_effect_center[2]) {
146 dist = (relative_point - _effect_center).length();
149 LVector2 xz(relative_point[0], relative_point[1]);
153 if (dist <= light_radius) {
156 LPoint3 light_position = light->
get_pos();
160 LPoint3 avatar_position = lightnp.
get_relative_point(data->get_node_path(), LPoint3(0,0,0));
161 LVector3 light_camera = camera_position - light_position;
162 LVector3 light_avatar = avatar_position - light_position;
163 light_camera.normalize();
164 light_avatar.normalize();
165 PN_stdfloat intensity = light_camera.dot(light_avatar);
167 if (polylight_info) {
168 pgraph_cat.debug() <<
"light position = " << light_position << endl;
169 pgraph_cat.debug() <<
"relative avatar position = " << avatar_position << endl;
170 pgraph_cat.debug() <<
"relative camera position = " << camera_position << endl;
171 pgraph_cat.debug() <<
"light->camera " << light_camera << endl;
172 pgraph_cat.debug() <<
"light->avatar " << light_avatar << endl;
173 pgraph_cat.debug() <<
"light->camera.light->avatar = " << intensity << endl;
174 pgraph_cat.debug() <<
"effect center = " << _effect_center << endl;
177 pgraph_cat.debug() <<
"dist = " << dist <<
";radius = " << light_radius << endl;
181 intensity = 1.0 - ((intensity + 1.0) * 0.5);
182 if (polylight_info) {
183 pgraph_cat.debug() <<
"remapped intensity = " << intensity << endl;
186 PolylightNode::Attenuation_Type light_attenuation = light->
get_attenuation();
189 light_color = light->
flicker();
195 PN_stdfloat ratio = dist/light_radius;
196 if (light_attenuation == PolylightNode::ALINEAR) {
197 light_scale = 1.0 - ratio;
198 }
else if (light_attenuation == PolylightNode::AQUADRATIC) {
217 light_scale = (ratio*ratio)*(3-2*ratio);
224 light_scale *= intensity;
226 if (min_dist > dist) {
231 weight_scale = _weight * (1.0 - light_scale);
234 if (polylight_info) {
235 pgraph_cat.debug() <<
"weight_scale = " << weight_scale
236 <<
"; light_scale " << light_scale << endl;
239 Rcollect += light_color[0] * light_scale;
240 Gcollect += light_color[1] * light_scale;
241 Bcollect += light_color[2] * light_scale;
259 if ( _contribution_type == CT_all) {
263 num_lights = _lightgroup.size();
270 pgraph_cat.debug() <<
"num lights = " << num_lights << endl;
278 pgraph_cat.debug() <<
"avg: r=" << r <<
"; g=" << g <<
"; b=" << b << endl;
281 r += scene_color[0] * weight_scale;
282 g += scene_color[1] * weight_scale;
283 b += scene_color[2] * weight_scale;
285 pgraph_cat.debug() <<
"weighed: r=" << r <<
"; g=" << g <<
"; b=" << b << endl;
300 r = (r > 1.0)? 1.0 : r;
301 g = (g > 1.0)? 1.0 : g;
302 b = (b > 1.0)? 1.0 : b;
305 pgraph_cat.debug() <<
"capped: r=" << r <<
"; g=" << g <<
"; b=" << b << endl;
310 if (scene_color[0] >= 0.01)
312 if (scene_color[1] >= 0.01)
314 if (scene_color[2] >= 0.01)
318 pgraph_cat.debug() <<
"final: r=" << r <<
"; g=" << g <<
"; b=" << b << endl;
332 return ColorScaleAttrib::make(LVecBase4(r, g, b, 1.0));
338 void PolylightEffect::
339 output(std::ostream &out)
const {
340 out << get_type() <<
":";
342 LightGroup::const_iterator li;
343 for (li = _lightgroup.begin(); li != _lightgroup.end(); ++li) {
347 out <<
" weight " << _weight <<
" contrib " << _contribution_type
348 <<
" center " << _effect_center;
364 int PolylightEffect::
367 DCAST_INTO_R(ta, other, 0);
369 if (_contribution_type != ta->_contribution_type) {
370 return _contribution_type < ta->_contribution_type ? -1 : 1;
373 if (_weight != ta->_weight) {
374 return _weight < ta->_weight ? -1 :1;
377 if (_lightgroup != ta->_lightgroup) {
378 return _lightgroup < ta->_lightgroup ? -1 : 1;
390 add_light(
const NodePath &newlight)
const {
392 effect->_lightgroup.push_back(newlight);
393 return return_new(effect);
401 remove_light(
const NodePath &newlight)
const {
403 LightGroup::iterator light_iter;
404 light_iter = find(effect->_lightgroup.begin(),effect->_lightgroup.end(), newlight);
405 if (light_iter == effect->_lightgroup.end()) {
407 <<
"Attempt to remove Polylight " << newlight <<
"; not found.\n";
410 effect->_lightgroup.erase(light_iter);
412 return return_new(effect);
423 set_weight(PN_stdfloat w)
const {
426 return return_new(effect);
436 set_contrib(ContribType ct)
const {
438 effect->_contribution_type = ct;
439 return return_new(effect);
449 set_effect_center(
const LPoint3 &ec)
const{
451 effect->_effect_center = ec;
452 return return_new(effect);
459 bool PolylightEffect::
460 has_light(
const NodePath &light)
const {
461 LightGroup::const_iterator li;
462 li = find(_lightgroup.begin(), _lightgroup.end(), light);
463 return (li != _lightgroup.end());
467 operator << (std::ostream &out, PolylightEffect::ContribType ct) {
469 case PolylightEffect::CT_proximal:
470 return out <<
"proximal";
472 case PolylightEffect::CT_all:
476 return out <<
"**Invalid ContribType(" << (int)ct <<
")**";
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for a number of render attributes (other than transform) that may be set on sc...
const LVecBase4 & get_color_scale() const
Returns the complete color scale vector that has been applied to this node via a previous call to set...
PN_stdfloat get_radius() const
Get radius of the spherical light volume.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This collects together the pieces of data that are accumulated for each node while walking the scene ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for a number of special render effects that may be set on scene graph nodes to...
Attenuation_Type get_attenuation() const
Get "linear" or "quadratic" attenuation type.
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined.
CPT(RenderEffect) PolylightEffect
Constructs a new PolylightEffect object.
bool is_enabled() const
Is this light is enabled/disabled?
A PolylightEffect can be used on a node to define a LightGroup for that node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void cull_callback(CullTraverser *trav, CullTraverserData &data, CPT(TransformState) &node_transform, CPT(RenderState) &node_state) const
If has_cull_callback() returns true, this function will be called during the cull traversal to perfor...
LPoint3 get_pos() const
Returns position as a LPoint3.
const NodePath & get_scene_root() const
Returns the root node of the scene.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_flickering() const
Check is this light is flickering.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
LColor flicker() const
If flickering is on, the do_poly_light function in PolylightNodeEffect will compute this light's colo...
const NodePath & get_cull_center() const
Returns the point from which the culling operations will be performed.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
SceneSetup * get_scene() const
Returns the SceneSetup object.
LPoint3 get_relative_point(const NodePath &other, const LVecBase3 &point) const
Given that the indicated point is in the coordinate system of the other node, returns the same point ...
TypeHandle is the identifier used to differentiate C++ class types.
This object holds the camera position, etc., and other general setup information for rendering a part...
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
LColor get_color() const
Returns the light's color as LColor.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.