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));
338void PolylightEffect::
339output(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;
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;
390add_light(
const NodePath &newlight)
const {
392 effect->_lightgroup.push_back(newlight);
393 return return_new(effect);
401remove_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);
423set_weight(PN_stdfloat w)
const {
426 return return_new(effect);
436set_contrib(ContribType ct)
const {
438 effect->_contribution_type = ct;
439 return return_new(effect);
449set_effect_center(
const LPoint3 &ec)
const{
451 effect->_effect_center = ec;
452 return return_new(effect);
459bool PolylightEffect::
460has_light(
const NodePath &light)
const {
461 LightGroup::const_iterator li;
462 li = find(_lightgroup.begin(), _lightgroup.end(), light);
463 return (li != _lightgroup.end());
467operator << (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 <<
")**";