Panda3D
 All Classes Functions Variables Enumerations
characterJointEffect.cxx
1 // Filename: characterJointEffect.cxx
2 // Created by: drose (26Jul06)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "characterJointEffect.h"
16 #include "cullTraverser.h"
17 #include "cullTraverserData.h"
18 #include "nodePath.h"
19 #include "look_at.h"
20 #include "bamReader.h"
21 #include "bamWriter.h"
22 #include "datagram.h"
23 #include "datagramIterator.h"
24 
25 TypeHandle CharacterJointEffect::_type_handle;
26 
27 ////////////////////////////////////////////////////////////////////
28 // Function: CharacterJointEffect::make
29 // Access: Published, Static
30 // Description: Constructs a new CharacterJointEffect object that
31 // references the indicated character. When a relative
32 // get_transform() is called on the node that contains
33 // the CharacterJointEffect, it will implicitly call
34 // character->update() first.
35 ////////////////////////////////////////////////////////////////////
37 make(Character *character) {
39  effect->_character = character;
40 
41  CPT(RenderEffect) new_effect_raw = return_new(effect);
42  const CharacterJointEffect *new_effect;
43  DCAST_INTO_R(new_effect, new_effect_raw, new_effect_raw);
44 
45  // It is possible that the CharacterJointEffect we have now is a
46  // different CharacterJointEffect to a different Character which has
47  // since been deleted, but which had the same memory address of our
48  // current character. If this happened, we have to force-update the
49  // CharacterJointEffect to tell its weak pointer that it is no
50  // longer invalid (and that it now points to this once-again-live
51  // Character object).
52 
53  // This is a little weird, because it means any nodes that used to
54  // be pointing to a deleted Character object (and knew they were
55  // pointing to a deleted Character object) will suddenly be pointing
56  // to a new, non-deleted Character object--and the wrong Character
57  // object, no less. But there's no other way to handle this, since
58  // we can't make the CharacterJointEffect's compare function base
59  // itself on whether its pointer is valid or not.
60 
61  if (!new_effect->_character.is_valid_pointer()) {
62  nassertr(new_effect->_character.get_orig() == character, new_effect_raw);
63  ((CharacterJointEffect *)new_effect)->_character = character;
64  }
65 
66  return new_effect_raw;
67 }
68 
69 ////////////////////////////////////////////////////////////////////
70 // Function: CharacterJointEffect::safe_to_transform
71 // Access: Public, Virtual
72 // Description: Returns true if it is generally safe to transform
73 // this particular kind of RenderEffect by calling the
74 // xform() method, false otherwise.
75 ////////////////////////////////////////////////////////////////////
78  // We now accept that it will be OK to transform the joint--we allow
79  // this on the assumption that anything that transforms the joint
80  // will also transform the Character node, above the joint.
81  return true;
82 }
83 
84 ////////////////////////////////////////////////////////////////////
85 // Function: CharacterJointEffect::safe_to_combine
86 // Access: Public, Virtual
87 // Description: Returns true if this kind of effect can safely be
88 // combined with sibling nodes that share the exact same
89 // effect, or false if this is not a good idea.
90 ////////////////////////////////////////////////////////////////////
92 safe_to_combine() const {
93  return false;
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function: CharacterJointEffect::output
98 // Access: Public, Virtual
99 // Description:
100 ////////////////////////////////////////////////////////////////////
101 void CharacterJointEffect::
102 output(ostream &out) const {
103  out << get_type();
104  if (_character.is_valid_pointer()) {
105  out << "(" << _character->get_name() << ")";
106  } else {
107  out << "(**invalid**)";
108  }
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: CharacterJointEffect::has_cull_callback
113 // Access: Public, Virtual
114 // Description: Should be overridden by derived classes to return
115 // true if cull_callback() has been defined. Otherwise,
116 // returns false to indicate cull_callback() does not
117 // need to be called for this effect during the cull
118 // traversal.
119 ////////////////////////////////////////////////////////////////////
122  return true;
123 }
124 
125 ////////////////////////////////////////////////////////////////////
126 // Function: CharacterJointEffect::cull_callback
127 // Access: Public, Virtual
128 // Description: If has_cull_callback() returns true, this function
129 // will be called during the cull traversal to perform
130 // any additional operations that should be performed at
131 // cull time. This may include additional manipulation
132 // of render state or additional visible/invisible
133 // decisions, or any other arbitrary operation.
134 //
135 // At the time this function is called, the current
136 // node's transform and state have not yet been applied
137 // to the net_transform and net_state. This callback
138 // may modify the node_transform and node_state to apply
139 // an effective change to the render state at this
140 // level.
141 ////////////////////////////////////////////////////////////////////
144  CPT(TransformState) &node_transform,
145  CPT(RenderState) &) const {
146  CPT(TransformState) dummy_transform = TransformState::make_identity();
147  adjust_transform(dummy_transform, node_transform, data.node());
148 }
149 
150 ////////////////////////////////////////////////////////////////////
151 // Function: CharacterJointEffect::has_adjust_transform
152 // Access: Public, Virtual
153 // Description: Should be overridden by derived classes to return
154 // true if adjust_transform() has been defined, and
155 // therefore the RenderEffect has some effect on the
156 // node's apparent local and net transforms.
157 ////////////////////////////////////////////////////////////////////
160  return true;
161 }
162 
163 ////////////////////////////////////////////////////////////////////
164 // Function: CharacterJointEffect::adjust_transform
165 // Access: Public, Virtual
166 // Description: Performs some operation on the node's apparent net
167 // and/or local transforms. This will only be called if
168 // has_adjust_transform() is redefined to return true.
169 //
170 // Both parameters are in/out. The original transforms
171 // will be passed in, and they may (or may not) be
172 // modified in-place by the RenderEffect.
173 ////////////////////////////////////////////////////////////////////
175 adjust_transform(CPT(TransformState) &net_transform,
176  CPT(TransformState) &node_transform,
177  PandaNode *node) const {
178  if (_character.is_valid_pointer()) {
179  _character->update();
180  }
181  node_transform = node->get_transform();
182 }
183 
184 
185 ////////////////////////////////////////////////////////////////////
186 // Function: CharacterJointEffect::compare_to_impl
187 // Access: Protected, Virtual
188 // Description: Intended to be overridden by derived CharacterJointEffect
189 // types to return a unique number indicating whether
190 // this CharacterJointEffect is equivalent to the other one.
191 //
192 // This should return 0 if the two CharacterJointEffect objects
193 // are equivalent, a number less than zero if this one
194 // should be sorted before the other one, and a number
195 // greater than zero otherwise.
196 //
197 // This will only be called with two CharacterJointEffect
198 // objects whose get_type() functions return the same.
199 ////////////////////////////////////////////////////////////////////
200 int CharacterJointEffect::
201 compare_to_impl(const RenderEffect *other) const {
202  const CharacterJointEffect *ta;
203  DCAST_INTO_R(ta, other, 0);
204 
205  if (_character.get_orig() != ta->_character.get_orig()) {
206  return _character.get_orig() < ta->_character.get_orig() ? -1 : 1;
207  }
208 
209  // As tempting as it is to include the sense of whether the
210  // character pointer is valid in this sorting, we can't, because
211  // that property might change without warning--which would
212  // invalidate the CharacterJointEffect's position in any maps if we
213  // used it to determine its sort.
214 
215  return 0;
216 }
217 
218 ////////////////////////////////////////////////////////////////////
219 // Function: CharacterJointEffect::register_with_read_factory
220 // Access: Public, Static
221 // Description: Tells the BamReader how to create objects of type
222 // CharacterJointEffect.
223 ////////////////////////////////////////////////////////////////////
226  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
227 }
228 
229 ////////////////////////////////////////////////////////////////////
230 // Function: CharacterJointEffect::write_datagram
231 // Access: Public, Virtual
232 // Description: Writes the contents of this object to the datagram
233 // for shipping out to a Bam file.
234 ////////////////////////////////////////////////////////////////////
237  RenderEffect::write_datagram(manager, dg);
238 
239  if (_character.is_valid_pointer()) {
240  manager->write_pointer(dg, _character);
241  } else {
242  manager->write_pointer(dg, NULL);
243  }
244 }
245 
246 ////////////////////////////////////////////////////////////////////
247 // Function: CharacterJointEffect::complete_pointers
248 // Access: Public, Virtual
249 // Description: Receives an array of pointers, one for each time
250 // manager->read_pointer() was called in fillin().
251 // Returns the number of pointers processed.
252 ////////////////////////////////////////////////////////////////////
255  int pi = RenderEffect::complete_pointers(p_list, manager);
256 
257  _character = DCAST(Character, p_list[pi++]);
258 
259  return pi;
260 }
261 
262 ////////////////////////////////////////////////////////////////////
263 // Function: CharacterJointEffect::make_from_bam
264 // Access: Protected, Static
265 // Description: This function is called by the BamReader's factory
266 // when a new object of type CharacterJointEffect is encountered
267 // in the Bam file. It should create the CharacterJointEffect
268 // and extract its information from the file.
269 ////////////////////////////////////////////////////////////////////
270 TypedWritable *CharacterJointEffect::
271 make_from_bam(const FactoryParams &params) {
273  DatagramIterator scan;
274  BamReader *manager;
275 
276  parse_params(params, scan, manager);
277  effect->fillin(scan, manager);
278 
279  return effect;
280 }
281 
282 ////////////////////////////////////////////////////////////////////
283 // Function: CharacterJointEffect::fillin
284 // Access: Protected
285 // Description: This internal function is called by make_from_bam to
286 // read in all of the relevant data from the BamFile for
287 // the new CharacterJointEffect.
288 ////////////////////////////////////////////////////////////////////
289 void CharacterJointEffect::
290 fillin(DatagramIterator &scan, BamReader *manager) {
291  RenderEffect::fillin(scan, manager);
292 
293  manager->read_pointer(scan);
294 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
An animated character, with skeleton-morph animation and either soft-skinned or hard-skinned vertices...
Definition: character.h:41
This effect will be added automatically to a node by CharacterJoint::add_net_transform() and Characte...
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
This collects together the pieces of data that are accumulated for each node while walking the scene ...
PandaNode * node() const
Returns the node traversed to so far.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
This is the base class for a number of special render effects that may be set on scene graph nodes to...
Definition: renderEffect.h:56
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager-&gt;read_pointer() was called in fillin()...
virtual void adjust_transform(CPT(TransformState)&net_transform, CPT(TransformState)&node_transform, PandaNode *node) const
Performs some operation on the node&#39;s apparent net and/or local transforms.
virtual bool safe_to_transform() const
Returns true if it is generally safe to transform this particular kind of RenderEffect by calling the...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager-&gt;read_pointer() was called in fillin()...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined...
virtual void cull_callback(CullTraverser *trav, CullTraverserData &data, CPT(TransformState)&node_transform, CPT(RenderState)&node_state) const
If has_cull_callback() returns true, this function will be called during the cull traversal to perfor...
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:53
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
virtual bool has_adjust_transform() const
Should be overridden by derived classes to return true if adjust_transform() has been defined...
A class to retrieve the individual data elements previously stored in a Datagram. ...
static void register_with_read_factory()
Tells the BamReader how to create objects of type CharacterJointEffect.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual bool safe_to_combine() const
Returns true if this kind of effect can safely be combined with sibling nodes that share the exact sa...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling...
Definition: cullTraverser.h:48
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:279
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:652
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.