Panda3D
partBundleNode.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 partBundleNode.cxx
10  * @author drose
11  * @date 2002-03-06
12  */
13 
14 #include "partBundleNode.h"
15 #include "datagram.h"
16 #include "datagramIterator.h"
17 #include "bamReader.h"
18 #include "bamWriter.h"
19 #include "sceneGraphReducer.h"
20 
21 TypeHandle PartBundleNode::_type_handle;
22 
23 /**
24  *
25  */
26 PartBundleNode::
27 ~PartBundleNode() {
28  Bundles::iterator bi;
29  for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
30  (*bi)->get_bundle()->remove_node(this);
31  }
32 }
33 
34 /**
35  * Applies whatever attributes are specified in the AccumulatedAttribs object
36  * (and by the attrib_types bitmask) to the vertices on this node, if
37  * appropriate. If this node uses geom arrays like a GeomNode, the supplied
38  * GeomTransformer may be used to unify shared arrays across multiple
39  * different nodes.
40  *
41  * This is a generalization of xform().
42  */
44 apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
45  GeomTransformer &transformer) {
46  if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
47  Bundles::iterator bi;
48  for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
49  PT(PartBundleHandle) handle = (*bi);
50  PartBundle *bundle = handle->get_bundle();
51  PT(PartBundle) new_bundle = bundle->apply_transform(attribs._transform);
52  update_bundle(handle, new_bundle);
53  }
54 
55  // Make sure the Geom bounding volumes get recomputed due to this update.
56  r_mark_geom_bounds_stale(Thread::get_current_thread());
57  }
58 }
59 
60 /**
61  * Transforms the contents of this PandaNode by the indicated matrix, if it
62  * means anything to do so. For most kinds of PandaNodes, this does nothing.
63  */
65 xform(const LMatrix4 &mat) {
66  // With plain xform(), we can't attempt to share bundles across different
67  // nodes. Better to use apply_attribs_to_vertices(), instead.
68 
69  if (mat.almost_equal(LMatrix4::ident_mat())) {
70  // Don't bother.
71  return;
72  }
73 
74  Bundles::iterator bi;
75  for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
76  PT(PartBundleHandle) handle = (*bi);
77  PartBundle *bundle = handle->get_bundle();
78  if (bundle->get_num_nodes() > 1) {
79  PT(PartBundle) new_bundle = DCAST(PartBundle, bundle->copy_subgraph());
80  update_bundle(handle, new_bundle);
81  bundle = new_bundle;
82  }
83  bundle->xform(mat);
84  }
85 }
86 
87 /**
88  *
89  */
90 void PartBundleNode::
91 add_bundle(PartBundle *bundle) {
92  PT(PartBundleHandle) handle = new PartBundleHandle(bundle);
93  add_bundle_handle(handle);
94 }
95 
96 /**
97  *
98  */
99 void PartBundleNode::
100 add_bundle_handle(PartBundleHandle *handle) {
101  Bundles::iterator bi = find(_bundles.begin(), _bundles.end(), handle);
102  if (bi != _bundles.end()) {
103  // This handle is already within the node.
104  return;
105  }
106 
107  _bundles.push_back(handle);
108  handle->get_bundle()->add_node(this);
109 }
110 
111 /**
112  * Moves the PartBundles from the other node onto this one.
113  */
114 void PartBundleNode::
115 steal_bundles(PartBundleNode *other) {
116  if (other == this) {
117  return;
118  }
119 
120  Bundles::iterator bi;
121  for (bi = other->_bundles.begin(); bi != other->_bundles.end(); ++bi) {
122  PartBundleHandle *handle = (*bi);
123  handle->get_bundle()->remove_node(other);
124  add_bundle_handle(handle);
125  }
126  other->_bundles.clear();
127 }
128 
129 /**
130  * Replaces the contents of the indicated PartBundleHandle (presumably stored
131  * within this node) with new_bundle.
132  */
133 void PartBundleNode::
134 update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle) {
135  PartBundle *old_bundle = old_bundle_handle->get_bundle();
136  old_bundle->remove_node(this);
137  old_bundle_handle->set_bundle(new_bundle);
138  new_bundle->add_node(this);
139 }
140 
141 /**
142  * Writes the contents of this object to the datagram for shipping out to a
143  * Bam file.
144  */
146 write_datagram(BamWriter *manager, Datagram &dg) {
147  PandaNode::write_datagram(manager, dg);
148 
149  dg.add_uint16(_bundles.size());
150  Bundles::iterator bi;
151  for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
152  manager->write_pointer(dg, (*bi)->get_bundle());
153  }
154 }
155 
156 /**
157  * Receives an array of pointers, one for each time manager->read_pointer()
158  * was called in fillin(). Returns the number of pointers processed.
159  */
161 complete_pointers(TypedWritable **p_list, BamReader* manager) {
162  int pi = PandaNode::complete_pointers(p_list, manager);
163 
164  Bundles::iterator bi;
165  for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
166  PT(PartBundle) bundle = DCAST(PartBundle, p_list[pi++]);
167  bundle->add_node(this);
168  (*bi) = new PartBundleHandle(bundle);
169  }
170 
171  return pi;
172 }
173 
174 /**
175  * This internal function is called by make_from_bam to read in all of the
176  * relevant data from the BamFile for the new PandaNode.
177  */
178 void PartBundleNode::
179 fillin(DatagramIterator &scan, BamReader* manager) {
180  PandaNode::fillin(scan, manager);
181 
182  int num_bundles = 1;
183  if (manager->get_file_minor_ver() >= 5) {
184  num_bundles = scan.get_uint16();
185  }
186 
187  nassertv(num_bundles >= 1);
188 
189  // Bundle 0. We already have a slot for this one.
190  manager->read_pointer(scan);
191 
192  // Remaining bundles. Push a new slot for each one.
193  for (int i = 1; i < num_bundles; ++i) {
194  manager->read_pointer(scan);
195  _bundles.push_back(nullptr);
196  }
197 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
bool read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:610
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
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
A class to retrieve the individual data elements previously stored in a Datagram.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:85
An object specifically designed to transform the vertices of a Geom without disturbing indexing or af...
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: pandaNode.cxx:3583
This is a trivial class returned by PartBundleNode::get_bundle().
set_bundle
Changes the actual PartBundle embedded within the handle.
get_bundle
Returns the actual PartBundle embedded within the handle.
This is a node that contains a pointer to an PartBundle.
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so.
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 void apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types, GeomTransformer &transformer)
Applies whatever attributes are specified in the AccumulatedAttribs object (and by the attrib_types b...
virtual void write_datagram(BamWriter *manager, Datagram &me)
Writes the contents of this object to the datagram for shipping out to a Bam file.
This is the root of a MovingPart hierarchy.
Definition: partBundle.h:46
void xform(const LMatrix4 &mat)
Applies the indicated transform to the root of the animated hierarchy.
Definition: partBundle.I:136
get_num_nodes
Returns the number of PartBundleNodes that contain a pointer to this PartBundle.
Definition: partBundle.h:114
PartGroup * copy_subgraph() const
Allocates and returns a new copy of this node and of all of its children.
Definition: partGroup.cxx:75
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition: thread.h:109
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
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().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.