forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcamera.cxx
More file actions
329 lines (289 loc) · 8.29 KB
/
camera.cxx
File metadata and controls
329 lines (289 loc) · 8.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file camera.cxx
* @author drose
* @date 2002-02-26
*/
#include "pandabase.h"
#include "camera.h"
#include "lens.h"
#include "throw_event.h"
using std::string;
TypeHandle Camera::_type_handle;
/**
*
*/
Camera::
Camera(const string &name, Lens *lens) :
LensNode(name, lens),
_active(true),
_camera_mask(~PandaNode::get_overall_bit()),
_initial_state(RenderState::make_empty()),
_lod_scale(1)
{
}
/**
*
*/
Camera::
Camera(const Camera ©) :
LensNode(copy),
_active(copy._active),
_scene(copy._scene),
_camera_mask(copy._camera_mask),
_initial_state(copy._initial_state),
_lod_scale(copy._lod_scale),
_tag_state_key(copy._tag_state_key),
_tag_states(copy._tag_states)
{
}
/**
*
*/
Camera::
~Camera() {
// We don't have to destroy the display region(s) associated with the
// camera; they're responsible for themselves. However, they should have
// removed themselves before we destruct, or something went wrong.
nassertv(_display_regions.empty());
}
/**
* 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 *Camera::
make_copy() const {
return new Camera(*this);
}
/**
* Returns true if it is generally safe to flatten out this particular kind of
* Node by duplicating instances, false otherwise (for instance, a Camera
* cannot be safely flattened, because the Camera pointer itself is
* meaningful).
*/
bool Camera::
safe_to_flatten() const {
return false;
}
/**
* Returns true if it is generally safe to transform this particular kind of
* Node by calling the xform() method, false otherwise. For instance, it's
* usually a bad idea to attempt to xform a Character.
*/
bool Camera::
safe_to_transform() const {
return false;
}
/**
* Associates a particular state transition with the indicated tag value.
* When a node is encountered during traversal with the tag key specified by
* set_tag_state_key(), if the value of that tag matches tag_state, then the
* indicated state is applied to this node--but only when it is rendered by
* this camera.
*
* This can be used to apply special effects to nodes when they are rendered
* by certain cameras. It is particularly useful for multipass rendering, in
* which specialty cameras might be needed to render the scene with a
* particular set of effects.
*/
void Camera::
set_tag_state(const string &tag_state, const RenderState *state) {
_tag_states[tag_state] = state;
}
/**
* Removes the association established by a previous call to set_tag_state().
*/
void Camera::
clear_tag_state(const string &tag_state) {
_tag_states.erase(tag_state);
}
/**
* Removes all associations established by previous calls to set_tag_state().
*/
void Camera::
clear_tag_states() {
_tag_states.clear();
}
/**
* Returns true if set_tag_state() has previously been called with the
* indicated tag state, false otherwise.
*/
bool Camera::
has_tag_state(const string &tag_state) const {
TagStates::const_iterator tsi;
tsi = _tag_states.find(tag_state);
return (tsi != _tag_states.end());
}
/**
* Returns the state associated with the indicated tag state by a previous
* call to set_tag_state(), or the empty state if nothing has been associated.
*/
CPT(RenderState) Camera::
get_tag_state(const string &tag_state) const {
TagStates::const_iterator tsi;
tsi = _tag_states.find(tag_state);
if (tsi != _tag_states.end()) {
return (*tsi).second;
}
return RenderState::make_empty();
}
/**
* Associates the indicated AuxSceneData object with the given NodePath,
* possibly replacing a previous data defined for the same NodePath, if any.
*/
void Camera::
set_aux_scene_data(const NodePath &node_path, AuxSceneData *data) {
if (data == nullptr) {
clear_aux_scene_data(node_path);
} else {
_aux_data[node_path] = data;
}
}
/**
* Removes the AuxSceneData associated with the indicated NodePath. Returns
* true if it is removed successfully, false if it was already gone.
*/
bool Camera::
clear_aux_scene_data(const NodePath &node_path) {
AuxData::iterator ai;
ai = _aux_data.find(node_path);
if (ai != _aux_data.end()) {
_aux_data.erase(ai);
return true;
}
return false;
}
/**
* Returns the AuxSceneData associated with the indicated NodePath, or NULL if
* nothing is associated.
*/
AuxSceneData *Camera::
get_aux_scene_data(const NodePath &node_path) const {
AuxData::const_iterator ai;
ai = _aux_data.find(node_path);
if (ai != _aux_data.end()) {
return (*ai).second;
}
return nullptr;
}
/**
* Outputs all of the NodePaths and AuxSceneDatas in use.
*/
void Camera::
list_aux_scene_data(std::ostream &out) const {
out << _aux_data.size() << " data objects held:\n";
AuxData::const_iterator ai;
for (ai = _aux_data.begin(); ai != _aux_data.end(); ++ai) {
out << (*ai).first << " " << *(*ai).second << "\n";
}
}
/**
* Walks through the list of currently-assigned AuxSceneData objects and
* releases any that are past their expiration times. Returns the number of
* elements released.
*/
int Camera::
cleanup_aux_scene_data(Thread *current_thread) {
int num_deleted = 0;
double now = ClockObject::get_global_clock()->get_frame_time(current_thread);
AuxData::iterator ai;
ai = _aux_data.begin();
while (ai != _aux_data.end()) {
AuxData::iterator anext = ai;
++anext;
if (now > (*ai).second->get_expiration_time()) {
_aux_data.erase(ai);
num_deleted++;
}
ai = anext;
}
return num_deleted;
}
/**
* Adds the indicated DisplayRegion to the set of DisplayRegions shared by the
* camera. This is only intended to be called from the DisplayRegion.
*/
void Camera::
add_display_region(DisplayRegion *display_region) {
_display_regions.push_back(display_region);
}
/**
* Removes the indicated DisplayRegion from the set of DisplayRegions shared
* by the camera. This is only intended to be called from the DisplayRegion.
*/
void Camera::
remove_display_region(DisplayRegion *display_region) {
DisplayRegions::iterator dri =
find(_display_regions.begin(), _display_regions.end(), display_region);
if (dri != _display_regions.end()) {
_display_regions.erase(dri);
}
}
/**
* Tells the BamReader how to create objects of type Camera.
*/
void Camera::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
/**
* Writes the contents of this object to the datagram for shipping out to a
* Bam file.
*/
void Camera::
write_datagram(BamWriter *manager, Datagram &dg) {
LensNode::write_datagram(manager, dg);
dg.add_bool(_active);
dg.add_uint32(_camera_mask.get_word());
if (manager->get_file_minor_ver() >= 41) {
manager->write_pointer(dg, _initial_state);
dg.add_stdfloat(_lod_scale);
}
}
/**
* Receives an array of pointers, one for each time manager->read_pointer()
* was called in fillin(). Returns the number of pointers processed.
*/
int Camera::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = LensNode::complete_pointers(p_list, manager);
if (manager->get_file_minor_ver() >= 41) {
_initial_state = DCAST(RenderState, p_list[pi++]);
}
return pi;
}
/**
* This function is called by the BamReader's factory when a new object of
* type Camera is encountered in the Bam file. It should create the Camera
* and extract its information from the file.
*/
TypedWritable *Camera::
make_from_bam(const FactoryParams ¶ms) {
Camera *node = new Camera("");
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
node->fillin(scan, manager);
return node;
}
/**
* This internal function is called by make_from_bam to read in all of the
* relevant data from the BamFile for the new Camera.
*/
void Camera::
fillin(DatagramIterator &scan, BamReader *manager) {
LensNode::fillin(scan, manager);
_active = scan.get_bool();
_camera_mask.set_word(scan.get_uint32());
if (manager->get_file_minor_ver() >= 41) {
manager->read_pointer(scan);
_lod_scale = scan.get_stdfloat();
}
}