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.