Panda3D
characterJointEffect.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 characterJointEffect.cxx
10  * @author drose
11  * @date 2006-07-26
12  */
13 
14 #include "characterJointEffect.h"
15 #include "cullTraverser.h"
16 #include "cullTraverserData.h"
17 #include "nodePath.h"
18 #include "look_at.h"
19 #include "bamReader.h"
20 #include "bamWriter.h"
21 #include "datagram.h"
22 #include "datagramIterator.h"
23 
24 TypeHandle CharacterJointEffect::_type_handle;
25 
26 /**
27  * Constructs a new CharacterJointEffect object that references the indicated
28  * character. When a relative get_transform() is called on the node that
29  * contains the CharacterJointEffect, it will implicitly call
30  * character->update() first.
31  */
32 CPT(RenderEffect) CharacterJointEffect::
33 make(Character *character) {
35  effect->_character = character;
36 
37  CPT(RenderEffect) new_effect_raw = return_new(effect);
38  const CharacterJointEffect *new_effect;
39  DCAST_INTO_R(new_effect, new_effect_raw, new_effect_raw);
40 
41  // It is possible that the CharacterJointEffect we have now is a different
42  // CharacterJointEffect to a different Character which has since been
43  // deleted, but which had the same memory address of our current character.
44  // If this happened, we have to force-update the CharacterJointEffect to
45  // tell its weak pointer that it is no longer invalid (and that it now
46  // points to this once-again-live Character object).
47 
48  // This is a little weird, because it means any nodes that used to be
49  // pointing to a deleted Character object (and knew they were pointing to a
50  // deleted Character object) will suddenly be pointing to a new, non-deleted
51  // Character object--and the wrong Character object, no less. But there's
52  // no other way to handle this, since we can't make the
53  // CharacterJointEffect's compare function base itself on whether its
54  // pointer is valid or not.
55 
56  if (!new_effect->_character.is_valid_pointer()) {
57  nassertr(new_effect->_character.get_orig() == character, new_effect_raw);
58  ((CharacterJointEffect *)new_effect)->_character = character;
59  }
60 
61  return new_effect_raw;
62 }
63 
64 /**
65  * Returns true if it is generally safe to transform this particular kind of
66  * RenderEffect by calling the xform() method, false otherwise.
67  */
70  // We now accept that it will be OK to transform the joint--we allow this on
71  // the assumption that anything that transforms the joint will also
72  // transform the Character node, above the joint.
73  return true;
74 }
75 
76 /**
77  * Returns true if this kind of effect can safely be combined with sibling
78  * nodes that share the exact same effect, or false if this is not a good
79  * idea.
80  */
82 safe_to_combine() const {
83  return false;
84 }
85 
86 /**
87  *
88  */
89 void CharacterJointEffect::
90 output(std::ostream &out) const {
91  out << get_type();
92  PT(Character) character = get_character();
93  if (character != nullptr) {
94  out << "(" << character->get_name() << ")";
95  } else {
96  out << "(**invalid**)";
97  }
98 }
99 
100 /**
101  * Should be overridden by derived classes to return true if cull_callback()
102  * has been defined. Otherwise, returns false to indicate cull_callback()
103  * does not need to be called for this effect during the cull traversal.
104  */
107  return true;
108 }
109 
110 /**
111  * If has_cull_callback() returns true, this function will be called during
112  * the cull traversal to perform any additional operations that should be
113  * performed at cull time. This may include additional manipulation of render
114  * state or additional visible/invisible decisions, or any other arbitrary
115  * operation.
116  *
117  * At the time this function is called, the current node's transform and state
118  * have not yet been applied to the net_transform and net_state. This
119  * callback may modify the node_transform and node_state to apply an effective
120  * change to the render state at this level.
121  */
124  CPT(TransformState) &node_transform,
125  CPT(RenderState) &) const {
126  if (auto character = _character.lock()) {
127  character->update();
128  }
129  node_transform = data.node()->get_transform();
130 }
131 
132 /**
133  * Should be overridden by derived classes to return true if
134  * adjust_transform() has been defined, and therefore the RenderEffect has
135  * some effect on the node's apparent local and net transforms.
136  */
139  return true;
140 }
141 
142 /**
143  * Performs some operation on the node's apparent net and/or local transforms.
144  * This will only be called if has_adjust_transform() is redefined to return
145  * true.
146  *
147  * Both parameters are in/out. The original transforms will be passed in, and
148  * they may (or may not) be modified in-place by the RenderEffect.
149  */
152  CPT(TransformState) &node_transform,
153  const PandaNode *node) const {
154  if (auto character = _character.lock()) {
155  character->update();
156  }
157  node_transform = node->get_transform();
158 }
159 
160 
161 /**
162  * Intended to be overridden by derived CharacterJointEffect types to return a
163  * unique number indicating whether this CharacterJointEffect is equivalent to
164  * the other one.
165  *
166  * This should return 0 if the two CharacterJointEffect objects are
167  * equivalent, a number less than zero if this one should be sorted before the
168  * other one, and a number greater than zero otherwise.
169  *
170  * This will only be called with two CharacterJointEffect objects whose
171  * get_type() functions return the same.
172  */
173 int CharacterJointEffect::
174 compare_to_impl(const RenderEffect *other) const {
175  const CharacterJointEffect *ta;
176  DCAST_INTO_R(ta, other, 0);
177 
178  if (_character.get_orig() != ta->_character.get_orig()) {
179  return _character.get_orig() < ta->_character.get_orig() ? -1 : 1;
180  }
181 
182  // As tempting as it is to include the sense of whether the character
183  // pointer is valid in this sorting, we can't, because that property might
184  // change without warning--which would invalidate the CharacterJointEffect's
185  // position in any maps if we used it to determine its sort.
186 
187  return 0;
188 }
189 
190 /**
191  * Tells the BamReader how to create objects of type CharacterJointEffect.
192  */
195  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
196 }
197 
198 /**
199  * Writes the contents of this object to the datagram for shipping out to a
200  * Bam file.
201  */
204  RenderEffect::write_datagram(manager, dg);
205 
206  PT(Character) character = get_character();
207  manager->write_pointer(dg, character);
208 }
209 
210 /**
211  * Receives an array of pointers, one for each time manager->read_pointer()
212  * was called in fillin(). Returns the number of pointers processed.
213  */
216  int pi = RenderEffect::complete_pointers(p_list, manager);
217 
218  _character = DCAST(Character, p_list[pi++]);
219 
220  return pi;
221 }
222 
223 /**
224  * This function is called by the BamReader's factory when a new object of
225  * type CharacterJointEffect is encountered in the Bam file. It should create
226  * the CharacterJointEffect and extract its information from the file.
227  */
228 TypedWritable *CharacterJointEffect::
229 make_from_bam(const FactoryParams &params) {
231  DatagramIterator scan;
232  BamReader *manager;
233 
234  parse_params(params, scan, manager);
235  effect->fillin(scan, manager);
236 
237  return effect;
238 }
239 
240 /**
241  * This internal function is called by make_from_bam to read in all of the
242  * relevant data from the BamFile for the new CharacterJointEffect.
243  */
244 void CharacterJointEffect::
245 fillin(DatagramIterator &scan, BamReader *manager) {
246  RenderEffect::fillin(scan, manager);
247 
248  manager->read_pointer(scan);
249 }
A basic node of the scene graph or data graph.
Definition: pandaNode.h:64
Indicates a coordinate-system transform on vertices.
CPT(RenderEffect) CharacterJointEffect
Constructs a new CharacterJointEffect object that references the indicated character.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
An animated character, with skeleton-morph animation and either soft- skinned or hard-skinned vertice...
Definition: character.h:38
virtual bool has_adjust_transform() const
Should be overridden by derived classes to return true if adjust_transform() has been defined,...
This effect will be added automatically to a node by CharacterJoint::add_net_transform() and Characte...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
This collects together the pieces of data that are accumulated for each node while walking the scene ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
This is the base class for a number of special render effects that may be set on scene graph nodes to...
Definition: renderEffect.h:48
virtual int complete_pointers(TypedWritable **plist, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
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
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...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
virtual bool safe_to_transform() const
Returns true if it is generally safe to transform this particular kind of RenderEffect by calling the...
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.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
Definition: renderState.h:47
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:177
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:610
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...
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:81
virtual void adjust_transform(CPT(TransformState) &net_transform, CPT(TransformState) &node_transform, const PandaNode *node) const
Performs some operation on the node's apparent net and/or local transforms.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
virtual bool has_cull_callback() const
Should be overridden by derived classes to return true if cull_callback() has been defined.
This object performs a depth-first traversal of the scene graph, with optional view-frustum culling,...
Definition: cullTraverser.h:45
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:317
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.