panda3d/panda/src/pgraph/polylightNode.cxx

309 lines
9.7 KiB
C++
Executable File

// Filename: PolylightNode.cxx
// Created by: sshodhan (02Jun04)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "polylightNode.h"
#include "config_pgraph.h"
#include "nodePath.h"
#include "clockObject.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "datagram.h"
#include "datagramIterator.h"
#include <time.h>
#include <math.h>
TypeHandle PolylightNode::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::Constructor
// Access: Published
// Description: Use PolylightNode() to construct a new
// PolylightNode object.
////////////////////////////////////////////////////////////////////
PolylightNode::
PolylightNode(const string &name) :
PandaNode(name)
{
_enabled = true;
set_pos(0,0,0);
set_color(1,1,1);
_radius = 50;
set_attenuation(ALINEAR);
_a0 = 1.0;
_a1 = 0.1;
_a2 = 0.01;
_flickering = true;
set_flicker_type(FRANDOM);
_offset = -0.5;
_scale = 0.1;
_step_size = 0.1;
_sin_freq = 2.0;
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::make_copy
// Access: Public, Virtual
// Description: Returns a newly-allocated Node that is a shallow copy
// of this one. It will be a different Node pointer,
// but its internal data may or may not be shared with
// that of the original Node.
////////////////////////////////////////////////////////////////////
PandaNode *PolylightNode::
make_copy() const {
return new PolylightNode(*this);
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::Constructor
// Access: Public
// Description: If flickering is on, the do_poly_light function
// in PolylightNodeEffect will compute this light's color
// based on the variations applied in this function
// Variation can be sin or random
// Use offset, scale and step_size to tweak
// Future addition: custom function variations to flicker
////////////////////////////////////////////////////////////////////
Colorf PolylightNode::flicker() const {
float r,g,b;
float variation= 0.0;
Colorf color = get_color(); //color = get_color_scenegraph();
r = color[0];
g = color[1];
b = color[2];
if (_flicker_type == FRANDOM) {
//srand((int)ClockObject::get_global_clock()->get_frame_time());
variation = (rand()%100); // a value between 0-99
variation /= 100.0;
pgraph_cat.debug() << "Random Variation: " << variation << endl;
} else if (_flicker_type == FSIN) {
double now = ClockObject::get_global_clock()->get_frame_time();
variation = sinf(now*_sin_freq);
pgraph_cat.debug() << "Variation: " << variation << endl;
// can't use negative variation, so make it positive
if (variation < 0.0)
variation *= -1.0;
} else if (_flicker_type == FCUSTOM) {
// fixed point list of variation values coming soon...
//double index = (ClockObject::get_global_clock()->get_frame_time() % len(fixed_points)) * ClockObject::get_global_clock()->get_dt();
//index *= _speed;
/*if (!(int)index > len(fixed_points) {
variation = _fixed_points[(int)index];
variation += _offset;
variation *= _scale;
}*/
}
//variation += _offset;
variation *= _scale;
//printf("Variation: %f\n",variation);
r+=variation;
g+=variation;
b+=variation;
/* CLAMPING
if (fabs(r - color[0]) > 0.5 || fabs(g - color[1]) > 0.5 || fabs(b - color[2]) > 0.5) {
r = color[0];
g = color[1];
b = color[2];
}
*/
pgraph_cat.debug() << "Color R:" << r << "; G:" << g << "; B:" << b << endl;
return Colorf(r,g,b,1.0);
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::compare_to
// Access: Published
// Description: Returns a number less than zero if this PolylightNode
// sorts before the other one, greater than zero if it
// sorts after, or zero if they are equivalent.
//
// Two PolylightNodes are considered equivalent if they
// consist of exactly the same properties
// Otherwise, they are different; different
// PolylightNodes will be ranked in a consistent but
// undefined ordering; the ordering is useful only for
// placing the PolylightNodes in a sorted container like an
// STL set.
////////////////////////////////////////////////////////////////////
int PolylightNode::
compare_to(const PolylightNode &other) const {
if (_enabled != other._enabled) {
return _enabled ? 1 :-1;
}
if (_radius != other._radius) {
return _radius < other._radius ? -1 :1;
}
LVecBase3f position = get_pos();
LVecBase3f other_position = other.get_pos();
if (position != other_position) {
return position < other_position ? -1 :1;
}
Colorf color = get_color();
Colorf other_color = other.get_color();
if (color != other_color) {
return color < other_color ? -1 :1;
}
if (_attenuation_type != other._attenuation_type) {
return _attenuation_type < other._attenuation_type ? -1 :1;
}
if (_a0 != other._a0) {
return _a0 < other._a0 ? -1 :1;
}
if (_a1 != other._a1) {
return _a1 < other._a1 ? -1 :1;
}
if (_a2 != other._a2) {
return _a2 < other._a2 ? -1 :1;
}
if (_flickering != other._flickering) {
return _flickering ? 1 :-1;
}
if (_flicker_type != other._flicker_type) {
return _flicker_type < other._flicker_type ? -1 :1;
}
if (_offset != other._offset) {
return _offset < other._offset ? -1 :1;
}
if (_scale != other._scale) {
return _scale < other._scale ? -1 :1;
}
if (_step_size != other._step_size) {
return _step_size < other._step_size ? -1 :1;
}
if (_sin_freq != other._sin_freq) {
return _sin_freq < other._sin_freq ? -1 :1;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// PolylightNode
////////////////////////////////////////////////////////////////////
void PolylightNode::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void PolylightNode::
write_datagram(BamWriter *manager, Datagram &dg) {
PandaNode::write_datagram(manager, dg);
LVecBase3f position;
Colorf color;
position = get_pos();
color = get_color();
dg.add_float32(position[0]);
dg.add_float32(position[1]);
dg.add_float32(position[2]);
dg.add_float32(color[0]);
dg.add_float32(color[1]);
dg.add_float32(color[2]);
dg.add_float32(_radius);
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type CompassEffect is encountered
// in the Bam file. It should create the CompassEffect
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *PolylightNode::
make_from_bam(const FactoryParams &params) {
PolylightNode *light = new PolylightNode("");
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
light->fillin(scan, manager);
return light;
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new CompassEffect.
////////////////////////////////////////////////////////////////////
void PolylightNode::
fillin(DatagramIterator &scan, BamReader *manager) {
PandaNode::fillin(scan, manager);
LVecBase3f position;
Colorf color;
position[0] = scan.get_float32();
position[1] = scan.get_float32();
position[2] = scan.get_float32();
set_pos(position[0],position[1],position[2]);
color[0] = scan.get_float32();
color[1] = scan.get_float32();
color[2] = scan.get_float32();
set_color(color[0], color[1], color[2]);
_radius = scan.get_float32();
}
////////////////////////////////////////////////////////////////////
// Function: PolylightNode::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void PolylightNode::
output(ostream &out) const {
out << get_type() << ":";
//out << "Position: " << get_x() << " " << get_y() << " " << get_z() << "\n";
//out << "Color: " << get_r() << " " << get_g() << " " << get_b() << "\n";
out << "Radius: " << get_radius() << "\n";
}