Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pgraph/spotlight.cxx

Go to the documentation of this file.
00001 // Filename: spotlight.cxx
00002 // Created by:  mike (09Jan97)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "spotlight.h"
00020 #include "graphicsStateGuardianBase.h"
00021 #include "bamWriter.h"
00022 #include "bamReader.h"
00023 #include "datagram.h"
00024 #include "datagramIterator.h"
00025 #include "colorAttrib.h"
00026 #include "config_pgraph.h"
00027 
00028 TypeHandle Spotlight::_type_handle;
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: Spotlight::CData::make_copy
00032 //       Access: Public, Virtual
00033 //  Description:
00034 ////////////////////////////////////////////////////////////////////
00035 CycleData *Spotlight::CData::
00036 make_copy() const {
00037   return new CData(*this);
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: Spotlight::CData::write_datagram
00042 //       Access: Public, Virtual
00043 //  Description: Writes the contents of this object to the datagram
00044 //               for shipping out to a Bam file.
00045 ////////////////////////////////////////////////////////////////////
00046 void Spotlight::CData::
00047 write_datagram(BamWriter *, Datagram &dg) const {
00048   dg.add_float32(_exponent);
00049   _specular_color.write_datagram(dg);
00050   _attenuation.write_datagram(dg);
00051 }
00052 
00053 ////////////////////////////////////////////////////////////////////
00054 //     Function: Spotlight::CData::fillin
00055 //       Access: Public, Virtual
00056 //  Description: This internal function is called by make_from_bam to
00057 //               read in all of the relevant data from the BamFile for
00058 //               the new Light.
00059 ////////////////////////////////////////////////////////////////////
00060 void Spotlight::CData::
00061 fillin(DatagramIterator &scan, BamReader *) {
00062   _exponent = scan.get_float32();
00063   _specular_color.read_datagram(scan);
00064   _attenuation.read_datagram(scan);
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: Spotlight::Constructor
00069 //       Access: Published
00070 //  Description:
00071 ////////////////////////////////////////////////////////////////////
00072 Spotlight::
00073 Spotlight(const string &name) : 
00074   LightLensNode(name) 
00075 {
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: Spotlight::Copy Constructor
00080 //       Access: Protected
00081 //  Description: Do not call the copy constructor directly; instead,
00082 //               use make_copy() or copy_subgraph() to make a copy of
00083 //               a node.
00084 ////////////////////////////////////////////////////////////////////
00085 Spotlight::
00086 Spotlight(const Spotlight &copy) :
00087   LightLensNode(copy),
00088   _cycler(copy._cycler)
00089 {
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: Spotlight::make_copy
00094 //       Access: Public, Virtual
00095 //  Description: Returns a newly-allocated PandaNode that is a shallow
00096 //               copy of this one.  It will be a different pointer,
00097 //               but its internal data may or may not be shared with
00098 //               that of the original PandaNode.  No children will be
00099 //               copied.
00100 ////////////////////////////////////////////////////////////////////
00101 PandaNode *Spotlight::
00102 make_copy() const {
00103   return new Spotlight(*this);
00104 }
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: Spotlight::xform
00108 //       Access: Public, Virtual
00109 //  Description: Transforms the contents of this PandaNode by the
00110 //               indicated matrix, if it means anything to do so.  For
00111 //               most kinds of PandaNodes, this does nothing.
00112 ////////////////////////////////////////////////////////////////////
00113 void Spotlight::
00114 xform(const LMatrix4f &mat) {
00115   LightLensNode::xform(mat); 
00116   mark_viz_stale();
00117 }
00118 
00119 ////////////////////////////////////////////////////////////////////
00120 //     Function: Spotlight::write
00121 //       Access: Public, Virtual
00122 //  Description:
00123 ////////////////////////////////////////////////////////////////////
00124 void Spotlight::
00125 write(ostream &out, int indent_level) const {
00126   indent(out, indent_level) << *this << ":\n";
00127   indent(out, indent_level + 2)
00128     << "color " << get_color() << "\n";
00129   indent(out, indent_level + 2)
00130     << "specular color " << get_specular_color() << "\n";
00131   indent(out, indent_level + 2)
00132     << "attenuation " << get_attenuation() << "\n";
00133   indent(out, indent_level + 2)
00134     << "exponent " << get_exponent() << "\n";
00135 
00136   Lens *lens = get_lens();
00137   if (lens != (Lens *)NULL) {
00138     lens->write(out, indent_level + 2);
00139   }
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: Spotlight::bind
00144 //       Access: Public, Virtual
00145 //  Description:
00146 ////////////////////////////////////////////////////////////////////
00147 void Spotlight::
00148 bind(GraphicsStateGuardianBase *gsg, int light_id) {
00149   gsg->bind_light(this, light_id);
00150 }
00151 
00152 ////////////////////////////////////////////////////////////////////
00153 //     Function: Spotlight::make_image
00154 //       Access: Public
00155 //  Description: Generates an image into the indicated texture of a
00156 //               circle with a soft edge that corresponds to the
00157 //               falloff of the spotlight.  This is intended to be
00158 //               used to implement projected texture spotlights; the
00159 //               image can be applied to geometry with UV's computed
00160 //               appropriate to simulate the texture's region of
00161 //               influence.
00162 //
00163 //               Returns true if the image is successfully generated,
00164 //               false otherwise.
00165 ////////////////////////////////////////////////////////////////////
00166 bool Spotlight::
00167 make_image(Texture *texture, float radius) {
00168   if (texture == NULL) {
00169     pgraph_cat.error()
00170       << "Spotlight::make_image() - NULL texture" << endl;
00171     return false;
00172   }
00173   PixelBuffer *pb = texture->_pbuffer;
00174   int size = pb->get_xsize();
00175   if (size == 0) {
00176     pgraph_cat.error()
00177       << "Spotlight::make_image() - pixel buffer has size == 0" << endl;
00178     return false;
00179   }
00180 
00181   const Colorf &color = get_color();
00182 
00183   RGBColorf scaled_color;
00184   scaled_color[0] = (color[0] * 255.0f);
00185   scaled_color[1] = (color[1] * 255.0f);
00186   scaled_color[2] = (color[2] * 255.0f);
00187 
00188   int half_width = (size - 2) / 2;
00189   float dXY = 1 / (float)half_width;
00190   float Y = dXY + dXY;
00191   float X, YY, dist_from_center, intensity;
00192   uchar C[3];
00193   int tx, ty, tx2, ty2;
00194 
00195   for (int y = 0; y < half_width; y++, Y += dXY) {
00196     X = dXY * y + dXY;
00197     YY = Y * Y;
00198     ty = y + half_width;
00199 
00200     for (int x = y; x < half_width; x++, X += dXY) {
00201       dist_from_center = (float)sqrt(X * X + YY);
00202       float D = dist_from_center;
00203       if (D <= radius)
00204         intensity = 1.0f;
00205           else if (D < 1.0f)
00206         intensity = pow(cos((D-radius) /
00207                 (1.0f-radius) * (MathNumbers::pi_f*0.5f)), get_exponent());
00208       else
00209         intensity = 0;
00210 
00211       C[0] = (uchar)(intensity * scaled_color[0]);
00212       C[1] = (uchar)(intensity * scaled_color[1]);
00213       C[2] = (uchar)(intensity * scaled_color[2]);
00214 
00215       tx = x + half_width;
00216 
00217       pb->set_uchar_rgb_texel(C, tx, ty, size);
00218       pb->set_uchar_rgb_texel(C, tx, size - ty - 1, size);
00219       pb->set_uchar_rgb_texel(C, size - tx - 1, ty, size);
00220       pb->set_uchar_rgb_texel(C, size - tx - 1, size - ty - 1, size);
00221 
00222       tx2 = ty; ty2 = tx;
00223 
00224       pb->set_uchar_rgb_texel(C, tx2, ty2, size);
00225       pb->set_uchar_rgb_texel(C, tx2, size - ty2 - 1, size);
00226       pb->set_uchar_rgb_texel(C, size - tx2 - 1, ty2, size);
00227       pb->set_uchar_rgb_texel(C, size - tx2 - 1, size - ty2 - 1, size);
00228     }
00229   }
00230   texture->unprepare();
00231 
00232   return true;
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: Spotlight::fill_viz_geom
00237 //       Access: Protected, Virtual
00238 //  Description: Fills the indicated GeomNode up with Geoms suitable
00239 //               for rendering this light.
00240 ////////////////////////////////////////////////////////////////////
00241 void Spotlight::
00242 fill_viz_geom(GeomNode *viz_geom) {
00243   Lens *lens = get_lens();
00244   if (lens == (Lens *)NULL) {
00245     return;
00246   }
00247   
00248   PT(Geom) geom = lens->make_geometry();
00249   if (geom == (Geom *)NULL) {
00250     return;
00251   }
00252 
00253   viz_geom->add_geom(geom, get_viz_state());
00254 }
00255 
00256 ////////////////////////////////////////////////////////////////////
00257 //     Function: Spotlight::get_viz_state
00258 //       Access: Private
00259 //  Description: Returns a RenderState for rendering the spotlight
00260 //               visualization.
00261 ////////////////////////////////////////////////////////////////////
00262 CPT(RenderState) Spotlight::
00263 get_viz_state() {
00264   return RenderState::make
00265     (ColorAttrib::make_flat(get_color()));
00266 }
00267 
00268 ////////////////////////////////////////////////////////////////////
00269 //     Function: Spotlight::register_with_read_factory
00270 //       Access: Public, Static
00271 //  Description: Tells the BamReader how to create objects of type
00272 //               Spotlight.
00273 ////////////////////////////////////////////////////////////////////
00274 void Spotlight::
00275 register_with_read_factory() {
00276   BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00277 }
00278 
00279 ////////////////////////////////////////////////////////////////////
00280 //     Function: Spotlight::write_datagram
00281 //       Access: Public, Virtual
00282 //  Description: Writes the contents of this object to the datagram
00283 //               for shipping out to a Bam file.
00284 ////////////////////////////////////////////////////////////////////
00285 void Spotlight::
00286 write_datagram(BamWriter *manager, Datagram &dg) {
00287   LightLensNode::write_datagram(manager, dg);
00288   manager->write_cdata(dg, _cycler);
00289 }
00290 
00291 ////////////////////////////////////////////////////////////////////
00292 //     Function: Spotlight::make_from_bam
00293 //       Access: Protected, Static
00294 //  Description: This function is called by the BamReader's factory
00295 //               when a new object of type Spotlight is encountered
00296 //               in the Bam file.  It should create the Spotlight
00297 //               and extract its information from the file.
00298 ////////////////////////////////////////////////////////////////////
00299 TypedWritable *Spotlight::
00300 make_from_bam(const FactoryParams &params) {
00301   Spotlight *node = new Spotlight("");
00302   DatagramIterator scan;
00303   BamReader *manager;
00304 
00305   parse_params(params, scan, manager);
00306   node->fillin(scan, manager);
00307 
00308   return node;
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: Spotlight::fillin
00313 //       Access: Protected
00314 //  Description: This internal function is called by make_from_bam to
00315 //               read in all of the relevant data from the BamFile for
00316 //               the new Spotlight.
00317 ////////////////////////////////////////////////////////////////////
00318 void Spotlight::
00319 fillin(DatagramIterator &scan, BamReader *manager) {
00320   LightLensNode::fillin(scan, manager);
00321   manager->read_cdata(scan, _cycler);
00322 }

Generated on Fri May 2 00:42:24 2003 for Panda by doxygen1.3