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  */
145 void PartBundleNode::
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  */
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 }
set_bundle
Changes the actual PartBundle embedded within the handle.
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:3589
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
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
get_num_nodes
Returns the number of PartBundleNodes that contain a pointer to this PartBundle.
Definition: partBundle.h:114
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void xform(const LMatrix4 &mat)
Applies the indicated transform to the root of the animated hierarchy.
Definition: partBundle.I:136
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:63
This is a trivial class returned by PartBundleNode::get_bundle().
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition: bamReader.I:83
get_bundle
Returns the actual PartBundle embedded within the handle.
void add_uint16(uint16_t value)
Adds an unsigned 16-bit integer to the datagram.
Definition: datagram.I:85
This class is used by the SceneGraphReducer to maintain and accumulate the set of attributes we have ...
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().
This is a node that contains a pointer to an PartBundle.
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...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void xform(const LMatrix4 &mat)
Transforms the contents of this PandaNode by the indicated matrix, if it means anything to do so.
virtual void write_datagram(BamWriter *manager, Datagram &me)
Writes the contents of this object to the datagram for shipping out to a Bam file.
uint16_t get_uint16()
Extracts an unsigned 16-bit integer.
This is the root of a MovingPart hierarchy.
Definition: partBundle.h:46
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 int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin().
PartGroup * copy_subgraph() const
Allocates and returns a new copy of this node and of all of its children.
Definition: partGroup.cxx:75
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
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
An object specifically designed to transform the vertices of a Geom without disturbing indexing or af...