Panda3D
|
00001 // Filename: PolylightNode.cxx 00002 // Created by: sshodhan (02Jun04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "polylightNode.h" 00016 #include "config_pgraph.h" 00017 #include "nodePath.h" 00018 #include "clockObject.h" 00019 #include "bamReader.h" 00020 #include "bamWriter.h" 00021 #include "datagram.h" 00022 #include "datagramIterator.h" 00023 00024 #include <time.h> 00025 #include <math.h> 00026 00027 TypeHandle PolylightNode::_type_handle; 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: PolylightNode::Constructor 00031 // Access: Published 00032 // Description: Use PolylightNode() to construct a new 00033 // PolylightNode object. 00034 //////////////////////////////////////////////////////////////////// 00035 PolylightNode:: 00036 PolylightNode(const string &name) : 00037 PandaNode(name) 00038 { 00039 _enabled = true; 00040 set_pos(0,0,0); 00041 set_color(1,1,1); 00042 _radius = 50; 00043 set_attenuation(ALINEAR); 00044 _a0 = 1.0; 00045 _a1 = 0.1; 00046 _a2 = 0.01; 00047 _flickering = true; 00048 set_flicker_type(FRANDOM); 00049 _offset = -0.5; 00050 _scale = 0.1; 00051 _step_size = 0.1; 00052 _sin_freq = 2.0; 00053 } 00054 00055 //////////////////////////////////////////////////////////////////// 00056 // Function: PolylightNode::make_copy 00057 // Access: Public, Virtual 00058 // Description: Returns a newly-allocated Node that is a shallow copy 00059 // of this one. It will be a different Node pointer, 00060 // but its internal data may or may not be shared with 00061 // that of the original Node. 00062 //////////////////////////////////////////////////////////////////// 00063 PandaNode *PolylightNode:: 00064 make_copy() const { 00065 return new PolylightNode(*this); 00066 } 00067 00068 //////////////////////////////////////////////////////////////////// 00069 // Function: PolylightNode::Constructor 00070 // Access: Public 00071 // Description: If flickering is on, the do_poly_light function 00072 // in PolylightNodeEffect will compute this light's color 00073 // based on the variations applied in this function 00074 // Variation can be sin or random 00075 // Use offset, scale and step_size to tweak 00076 // Future addition: custom function variations to flicker 00077 //////////////////////////////////////////////////////////////////// 00078 LColor PolylightNode::flicker() const { 00079 PN_stdfloat r,g,b; 00080 00081 PN_stdfloat variation= 0.0; 00082 LColor color = get_color(); //color = get_color_scenegraph(); 00083 00084 r = color[0]; 00085 g = color[1]; 00086 b = color[2]; 00087 00088 if (_flicker_type == FRANDOM) { 00089 //srand((int)ClockObject::get_global_clock()->get_frame_time()); 00090 variation = (rand()%100); // a value between 0-99 00091 variation /= 100.0; 00092 if (polylight_info) 00093 pgraph_cat.info() << "Random Variation: " << variation << endl; 00094 } else if (_flicker_type == FSIN) { 00095 double now = ClockObject::get_global_clock()->get_frame_time(); 00096 variation = sinf(now*_sin_freq); 00097 if (polylight_info) 00098 pgraph_cat.info() << "Variation: " << variation << endl; 00099 // can't use negative variation, so make it positive 00100 if (variation < 0.0) 00101 variation *= -1.0; 00102 } else if (_flicker_type == FCUSTOM) { 00103 // fixed point list of variation values coming soon... 00104 //double index = (ClockObject::get_global_clock()->get_frame_time() % len(fixed_points)) * ClockObject::get_global_clock()->get_dt(); 00105 //index *= _speed; 00106 /*if (!(int)index > len(fixed_points) { 00107 variation = _fixed_points[(int)index]; 00108 variation += _offset; 00109 variation *= _scale; 00110 }*/ 00111 } 00112 00113 //variation += _offset; 00114 //variation *= _scale; 00115 00116 //printf("Variation: %f\n",variation); 00117 r += r * variation; 00118 g += g * variation; 00119 b += b * variation; 00120 00121 /* CLAMPING 00122 if (fabs(r - color[0]) > 0.5 || fabs(g - color[1]) > 0.5 || fabs(b - color[2]) > 0.5) { 00123 r = color[0]; 00124 g = color[1]; 00125 b = color[2]; 00126 } 00127 */ 00128 pgraph_cat.debug() << "Color R:" << r << "; G:" << g << "; B:" << b << endl; 00129 return LColor(r,g,b,1.0); 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: PolylightNode::compare_to 00134 // Access: Published 00135 // Description: Returns a number less than zero if this PolylightNode 00136 // sorts before the other one, greater than zero if it 00137 // sorts after, or zero if they are equivalent. 00138 // 00139 // Two PolylightNodes are considered equivalent if they 00140 // consist of exactly the same properties 00141 // Otherwise, they are different; different 00142 // PolylightNodes will be ranked in a consistent but 00143 // undefined ordering; the ordering is useful only for 00144 // placing the PolylightNodes in a sorted container like an 00145 // STL set. 00146 //////////////////////////////////////////////////////////////////// 00147 int PolylightNode:: 00148 compare_to(const PolylightNode &other) const { 00149 00150 if (_enabled != other._enabled) { 00151 return _enabled ? 1 :-1; 00152 } 00153 00154 if (_radius != other._radius) { 00155 return _radius < other._radius ? -1 :1; 00156 } 00157 LVecBase3 position = get_pos(); 00158 LVecBase3 other_position = other.get_pos(); 00159 if (position != other_position) { 00160 return position < other_position ? -1 :1; 00161 } 00162 00163 LColor color = get_color(); 00164 LColor other_color = other.get_color(); 00165 if (color != other_color) { 00166 return color < other_color ? -1 :1; 00167 } 00168 00169 if (_attenuation_type != other._attenuation_type) { 00170 return _attenuation_type < other._attenuation_type ? -1 :1; 00171 } 00172 00173 if (_a0 != other._a0) { 00174 return _a0 < other._a0 ? -1 :1; 00175 } 00176 00177 if (_a1 != other._a1) { 00178 return _a1 < other._a1 ? -1 :1; 00179 } 00180 00181 if (_a2 != other._a2) { 00182 return _a2 < other._a2 ? -1 :1; 00183 } 00184 00185 if (_flickering != other._flickering) { 00186 return _flickering ? 1 :-1; 00187 } 00188 00189 if (_flicker_type != other._flicker_type) { 00190 return _flicker_type < other._flicker_type ? -1 :1; 00191 } 00192 00193 if (_offset != other._offset) { 00194 return _offset < other._offset ? -1 :1; 00195 } 00196 00197 if (_scale != other._scale) { 00198 return _scale < other._scale ? -1 :1; 00199 } 00200 00201 if (_step_size != other._step_size) { 00202 return _step_size < other._step_size ? -1 :1; 00203 } 00204 00205 if (_sin_freq != other._sin_freq) { 00206 return _sin_freq < other._sin_freq ? -1 :1; 00207 } 00208 00209 00210 return 0; 00211 } 00212 00213 00214 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: PolylightNode::register_with_read_factory 00218 // Access: Public, Static 00219 // Description: Tells the BamReader how to create objects of type 00220 // PolylightNode 00221 //////////////////////////////////////////////////////////////////// 00222 void PolylightNode:: 00223 register_with_read_factory() { 00224 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00225 } 00226 00227 //////////////////////////////////////////////////////////////////// 00228 // Function: PolylightNode::write_datagram 00229 // Access: Public, Virtual 00230 // Description: Writes the contents of this object to the datagram 00231 // for shipping out to a Bam file. 00232 //////////////////////////////////////////////////////////////////// 00233 void PolylightNode:: 00234 write_datagram(BamWriter *manager, Datagram &dg) { 00235 PandaNode::write_datagram(manager, dg); 00236 _position.write_datagram(dg); 00237 LRGBColor color; 00238 color.set(_color[0], _color[1], _color[2]); 00239 color.write_datagram(dg); 00240 dg.add_stdfloat(_radius); 00241 } 00242 00243 //////////////////////////////////////////////////////////////////// 00244 // Function: PolylightNode::make_from_bam 00245 // Access: Protected, Static 00246 // Description: This function is called by the BamReader's factory 00247 // when a new object of type CompassEffect is encountered 00248 // in the Bam file. It should create the CompassEffect 00249 // and extract its information from the file. 00250 //////////////////////////////////////////////////////////////////// 00251 TypedWritable *PolylightNode:: 00252 make_from_bam(const FactoryParams ¶ms) { 00253 PolylightNode *light = new PolylightNode(""); 00254 DatagramIterator scan; 00255 BamReader *manager; 00256 00257 parse_params(params, scan, manager); 00258 light->fillin(scan, manager); 00259 00260 return light; 00261 } 00262 00263 //////////////////////////////////////////////////////////////////// 00264 // Function: PolylightNode::fillin 00265 // Access: Protected 00266 // Description: This internal function is called by make_from_bam to 00267 // read in all of the relevant data from the BamFile for 00268 // the new CompassEffect. 00269 //////////////////////////////////////////////////////////////////// 00270 void PolylightNode:: 00271 fillin(DatagramIterator &scan, BamReader *manager) { 00272 PandaNode::fillin(scan, manager); 00273 _position.read_datagram(scan); 00274 LRGBColor color; 00275 color.read_datagram(scan); 00276 set_color(color[0], color[1], color[2]); 00277 _radius = scan.get_stdfloat(); 00278 } 00279 00280 00281 00282 //////////////////////////////////////////////////////////////////// 00283 // Function: PolylightNode::output 00284 // Access: Public, Virtual 00285 // Description: 00286 //////////////////////////////////////////////////////////////////// 00287 void PolylightNode:: 00288 output(ostream &out) const { 00289 out << get_type() << ":"; 00290 //out << "Position: " << get_x() << " " << get_y() << " " << get_z() << "\n"; 00291 //out << "Color: " << get_r() << " " << get_g() << " " << get_b() << "\n"; 00292 out << "Radius: " << get_radius() << "\n"; 00293 } 00294