Panda3D
pointLight.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file pointLight.cxx
10  * @author mike
11  * @date 1997-01-09
12  */
13 
14 #include "pointLight.h"
16 #include "bamWriter.h"
17 #include "bamReader.h"
18 #include "datagram.h"
19 #include "datagramIterator.h"
20 #include "config_pgraphnodes.h"
21 
22 TypeHandle PointLight::_type_handle;
23 
24 /**
25  *
26  */
27 CycleData *PointLight::CData::
28 make_copy() const {
29  return new CData(*this);
30 }
31 
32 /**
33  * Writes the contents of this object to the datagram for shipping out to a
34  * Bam file.
35  */
36 void PointLight::CData::
37 write_datagram(BamWriter *manager, Datagram &dg) const {
38  _specular_color.write_datagram(dg);
39  _attenuation.write_datagram(dg);
40  if (manager->get_file_minor_ver() >= 41) {
41  dg.add_stdfloat(_max_distance);
42  }
43  _point.write_datagram(dg);
44 }
45 
46 /**
47  * This internal function is called by make_from_bam to read in all of the
48  * relevant data from the BamFile for the new Light.
49  */
50 void PointLight::CData::
51 fillin(DatagramIterator &scan, BamReader *manager) {
52  _specular_color.read_datagram(scan);
53  _attenuation.read_datagram(scan);
54  if (manager->get_file_minor_ver() >= 41) {
55  _max_distance = scan.get_stdfloat();
56  }
57  _point.read_datagram(scan);
58 }
59 
60 /**
61  *
62  */
63 PointLight::
64 PointLight(const std::string &name) :
65  LightLensNode(name) {
66  PT(Lens) lens;
67  lens = new PerspectiveLens(90, 90);
68  lens->set_interocular_distance(0);
69  lens->set_view_vector(1, 0, 0, 0, -1, 0);
70  set_lens(0, lens);
71  lens = new PerspectiveLens(90, 90);
72  lens->set_interocular_distance(0);
73  lens->set_view_vector(-1, 0, 0, 0, -1, 0);
74  set_lens(1, lens);
75  lens = new PerspectiveLens(90, 90);
76  lens->set_interocular_distance(0);
77  lens->set_view_vector(0, 1, 0, 0, 0, 1);
78  set_lens(2, lens);
79  lens = new PerspectiveLens(90, 90);
80  lens->set_interocular_distance(0);
81  lens->set_view_vector(0, -1, 0, 0, 0, -1);
82  set_lens(3, lens);
83  lens = new PerspectiveLens(90, 90);
84  lens->set_interocular_distance(0);
85  lens->set_view_vector(0, 0, 1, 0, -1, 0);
86  set_lens(4, lens);
87  lens = new PerspectiveLens(90, 90);
88  lens->set_interocular_distance(0);
89  lens->set_view_vector(0, 0, -1, 0, -1, 0);
90  set_lens(5, lens);
91 }
92 
93 /**
94  * Do not call the copy constructor directly; instead, use make_copy() or
95  * copy_subgraph() to make a copy of a node.
96  */
97 PointLight::
98 PointLight(const PointLight &copy) :
99  LightLensNode(copy),
100  _cycler(copy._cycler)
101 {
102 }
103 
104 /**
105  * Returns a newly-allocated PandaNode that is a shallow copy of this one. It
106  * will be a different pointer, but its internal data may or may not be shared
107  * with that of the original PandaNode. No children will be copied.
108  */
110 make_copy() const {
111  return new PointLight(*this);
112 }
113 
114 /**
115  * Transforms the contents of this PandaNode by the indicated matrix, if it
116  * means anything to do so. For most kinds of PandaNodes, this does nothing.
117  */
118 void PointLight::
119 xform(const LMatrix4 &mat) {
121  CDWriter cdata(_cycler);
122  cdata->_point = cdata->_point * mat;
123  mark_viz_stale();
124 }
125 
126 /**
127  *
128  */
129 void PointLight::
130 write(std::ostream &out, int indent_level) const {
131  indent(out, indent_level) << *this << ":\n";
132  indent(out, indent_level + 2)
133  << "color " << get_color() << "\n";
134  if (_has_specular_color) {
135  indent(out, indent_level + 2)
136  << "specular color " << get_specular_color() << "\n";
137  }
138  indent(out, indent_level + 2)
139  << "attenuation " << get_attenuation() << "\n";
140 
141  if (!cinf(get_max_distance())) {
142  indent(out, indent_level + 2)
143  << "max distance " << get_max_distance() << "\n";
144  }
145 }
146 
147 /**
148  * Computes the vector from a particular vertex to this light. The exact
149  * vector depends on the type of light (e.g. point lights return a different
150  * result than directional lights).
151  *
152  * The input parameters are the vertex position in question, expressed in
153  * object space, and the matrix which converts from light space to object
154  * space. The result is expressed in object space.
155  *
156  * The return value is true if the result is successful, or false if it cannot
157  * be computed (e.g. for an ambient light).
158  */
159 bool PointLight::
160 get_vector_to_light(LVector3 &result, const LPoint3 &from_object_point,
161  const LMatrix4 &to_object_space) {
162  CDReader cdata(_cycler);
163  LPoint3 point = cdata->_point * to_object_space;
164 
165  result = point - from_object_point;
166  return true;
167 }
168 
169 /**
170  * Returns the relative priority associated with all lights of this class.
171  * This priority is used to order lights whose instance priority
172  * (get_priority()) is the same--the idea is that other things being equal,
173  * AmbientLights (for instance) are less important than DirectionalLights.
174  */
175 int PointLight::
177  return (int)CP_point_priority;
178 }
179 
180 /**
181  *
182  */
183 void PointLight::
184 bind(GraphicsStateGuardianBase *gsg, const NodePath &light, int light_id) {
185  gsg->bind_light(this, light, light_id);
186 }
187 
188 /**
189  * Creates the shadow map texture. Can be overridden.
190  */
191 void PointLight::
192 setup_shadow_map() {
193  if (_shadow_map != nullptr && _shadow_map->get_x_size() == _sb_size[0]) {
194  // Nothing to do.
195  return;
196  }
197 
198  if (_sb_size[0] != _sb_size[1]) {
199  pgraphnodes_cat.error()
200  << "PointLight shadow buffers must have an equal width and height!\n";
201  }
202 
203  if (_shadow_map == nullptr) {
204  _shadow_map = new Texture(get_name());
205  }
206 
207  _shadow_map->setup_cube_map(_sb_size[0], Texture::T_unsigned_byte, Texture::F_depth_component);
208  _shadow_map->set_clear_color(LColor(1));
209  _shadow_map->set_wrap_u(SamplerState::WM_clamp);
210  _shadow_map->set_wrap_v(SamplerState::WM_clamp);
211 
212  // Note: cube map shadow filtering doesn't seem to work in Cg.
213  _shadow_map->set_minfilter(SamplerState::FT_linear);
214  _shadow_map->set_magfilter(SamplerState::FT_linear);
215 }
216 
217 /**
218  * Tells the BamReader how to create objects of type PointLight.
219  */
220 void PointLight::
222  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
223 }
224 
225 /**
226  * Writes the contents of this object to the datagram for shipping out to a
227  * Bam file.
228  */
229 void PointLight::
231  LightLensNode::write_datagram(manager, dg);
232  if (manager->get_file_minor_ver() >= 39) {
233  dg.add_bool(_has_specular_color);
234  }
235  manager->write_cdata(dg, _cycler);
236 }
237 
238 /**
239  * This function is called by the BamReader's factory when a new object of
240  * type PointLight is encountered in the Bam file. It should create the
241  * PointLight and extract its information from the file.
242  */
243 TypedWritable *PointLight::
244 make_from_bam(const FactoryParams &params) {
245  PointLight *node = new PointLight("");
246  DatagramIterator scan;
247  BamReader *manager;
248 
249  parse_params(params, scan, manager);
250  node->fillin(scan, manager);
251 
252  return node;
253 }
254 
255 /**
256  * This internal function is called by make_from_bam to read in all of the
257  * relevant data from the BamFile for the new PointLight.
258  */
259 void PointLight::
260 fillin(DatagramIterator &scan, BamReader *manager) {
261  LightLensNode::fillin(scan, manager);
262 
263  if (manager->get_file_minor_ver() >= 39) {
264  _has_specular_color = scan.get_bool();
265  } else {
266  _has_specular_color = true;
267  }
268 
269  manager->read_cdata(scan, _cycler);
270 }
virtual bool get_vector_to_light(LVector3 &result, const LPoint3 &from_object_point, const LMatrix4 &to_object_space)
Computes the vector from a particular vertex to this light.
Definition: pointLight.cxx:160
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so.
Definition: pointLight.cxx:119
bool get_bool()
Extracts a boolean value.
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
A base class for any number of different kinds of lenses, linear and otherwise.
Definition: lens.h:41
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
Definition: pointLight.cxx:230
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
Definition: bamReader.cxx:695
const LColor & get_specular_color() const final
Returns the color of specular highlights generated by the light.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A single page of data maintained by a PipelineCycler.
Definition: cycleData.h:47
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
Definition: texture.h:71
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
void write_cdata(Datagram &packet, const PipelineCyclerBase &cycler)
Writes out the indicated CycleData object.
Definition: bamWriter.cxx:425
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual PandaNode * make_copy() const
Returns a newly-allocated PandaNode that is a shallow copy of this one.
Definition: pointLight.cxx:110
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being written.
Definition: bamWriter.I:59
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:133
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:34
const LVecBase3 & get_attenuation() const final
Returns the terms of the attenuation equation for the light.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
A perspective-type lens: a normal camera.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
static void register_with_read_factory()
Tells the BamReader how to create objects of type PointLight.
Definition: pointLight.cxx:221
This template class calls PipelineCycler::write() in the constructor and PipelineCycler::release_writ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_max_distance
Returns the maximum distance at which the light has any effect, as previously specified by set_max_di...
Definition: pointLight.h:53
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so.
Definition: lensNode.cxx:53
virtual int get_class_priority() const
Returns the relative priority associated with all lights of this class.
Definition: pointLight.cxx:176
A derivative of Light and of Camera.
Definition: lightLensNode.h:33
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
A class to retrieve the individual data elements previously stored in a Datagram.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
Definition: nodePath.h:161
A light originating from a single point in space, and shining in all directions.
Definition: pointLight.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.