00001 // Filename: modelNode.cxx 00002 // Created by: drose (16Mar02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "modelNode.h" 00016 00017 #include "bamReader.h" 00018 #include "datagram.h" 00019 #include "datagramIterator.h" 00020 00021 TypeHandle ModelNode::_type_handle; 00022 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: ModelNode::make_copy 00026 // Access: Public, Virtual 00027 // Description: Returns a newly-allocated Node that is a shallow copy 00028 // of this one. It will be a different Node pointer, 00029 // but its internal data may or may not be shared with 00030 // that of the original Node. 00031 //////////////////////////////////////////////////////////////////// 00032 PandaNode *ModelNode:: 00033 make_copy() const { 00034 return new ModelNode(*this); 00035 } 00036 00037 //////////////////////////////////////////////////////////////////// 00038 // Function: ModelNode::combine_with 00039 // Access: Public, Virtual 00040 // Description: Collapses this PandaNode with the other PandaNode, if 00041 // possible, and returns a pointer to the combined 00042 // PandaNode, or NULL if the two PandaNodes cannot 00043 // safely be combined. 00044 // 00045 // The return value may be this, other, or a new 00046 // PandaNode altogether. 00047 // 00048 // This function is called from GraphReducer::flatten(), 00049 // and need not deal with children; its job is just to 00050 // decide whether to collapse the two PandaNodes and 00051 // what the collapsed PandaNode should look like. 00052 //////////////////////////////////////////////////////////////////// 00053 PandaNode *ModelNode:: 00054 combine_with(PandaNode *other) { 00055 if (_preserve_transform == PT_drop_node) { 00056 // If we have PT_drop_node set, we always yield to the other node. 00057 return other; 00058 } 00059 00060 return PandaNode::combine_with(other); 00061 } 00062 00063 //////////////////////////////////////////////////////////////////// 00064 // Function: ModelNode::safe_to_flatten 00065 // Access: Public, Virtual 00066 // Description: Returns true if it is generally safe to flatten out 00067 // this particular kind of Node by duplicating 00068 // instances, false otherwise (for instance, a Camera 00069 // cannot be safely flattened, because the Camera 00070 // pointer itself is meaningful). 00071 //////////////////////////////////////////////////////////////////// 00072 bool ModelNode:: 00073 safe_to_flatten() const { 00074 return _preserve_transform == PT_drop_node; 00075 } 00076 00077 //////////////////////////////////////////////////////////////////// 00078 // Function: ModelNode::safe_to_flatten_below 00079 // Access: Public, Virtual 00080 // Description: Returns true if a flatten operation may safely 00081 // continue past this node, or false if nodes below this 00082 // node may not be molested. 00083 //////////////////////////////////////////////////////////////////// 00084 bool ModelNode:: 00085 safe_to_flatten_below() const { 00086 return _preserve_transform != PT_no_touch; 00087 } 00088 00089 //////////////////////////////////////////////////////////////////// 00090 // Function: ModelNode::safe_to_transform 00091 // Access: Public, Virtual 00092 // Description: Returns true if it is generally safe to transform 00093 // this particular kind of Node by calling the xform() 00094 // method, false otherwise. For instance, it's usually 00095 // a bad idea to attempt to xform a Character. 00096 //////////////////////////////////////////////////////////////////// 00097 bool ModelNode:: 00098 safe_to_transform() const { 00099 return _preserve_transform == PT_none || _preserve_transform == PT_drop_node; 00100 } 00101 00102 //////////////////////////////////////////////////////////////////// 00103 // Function: ModelNode::safe_to_modify_transform 00104 // Access: Public, Virtual 00105 // Description: Returns true if it is safe to automatically adjust 00106 // the transform on this kind of node. Usually, this is 00107 // only a bad idea if the user expects to find a 00108 // particular transform on the node. 00109 // 00110 // ModelNodes with the preserve_transform flag set are 00111 // presently the only kinds of nodes that should not 00112 // have their transform even adjusted. 00113 //////////////////////////////////////////////////////////////////// 00114 bool ModelNode:: 00115 safe_to_modify_transform() const { 00116 return _preserve_transform != PT_local && _preserve_transform != PT_no_touch; 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: ModelNode::safe_to_combine 00121 // Access: Public, Virtual 00122 // Description: Returns true if it is generally safe to combine this 00123 // particular kind of PandaNode with other kinds of 00124 // PandaNodes of compatible type, adding children or 00125 // whatever. For instance, an LODNode should not be 00126 // combined with any other PandaNode, because its set of 00127 // children is meaningful. 00128 //////////////////////////////////////////////////////////////////// 00129 bool ModelNode:: 00130 safe_to_combine() const { 00131 return _preserve_transform == PT_drop_node; 00132 } 00133 00134 //////////////////////////////////////////////////////////////////// 00135 // Function: ModelNode::preserve_name 00136 // Access: Public, Virtual 00137 // Description: Returns true if the node's name has extrinsic meaning 00138 // and must be preserved across a flatten operation, 00139 // false otherwise. 00140 //////////////////////////////////////////////////////////////////// 00141 bool ModelNode:: 00142 preserve_name() const { 00143 return _preserve_transform != PT_drop_node && _preserve_transform != PT_no_touch; 00144 } 00145 00146 //////////////////////////////////////////////////////////////////// 00147 // Function: ModelNode::get_unsafe_to_apply_attribs 00148 // Access: Public, Virtual 00149 // Description: Returns the union of all attributes from 00150 // SceneGraphReducer::AttribTypes that may not safely be 00151 // applied to the vertices of this node. If this is 00152 // nonzero, these attributes must be dropped at this 00153 // node as a state change. 00154 // 00155 // This is a generalization of safe_to_transform(). 00156 //////////////////////////////////////////////////////////////////// 00157 int ModelNode:: 00158 get_unsafe_to_apply_attribs() const { 00159 return _preserve_attributes; 00160 } 00161 00162 //////////////////////////////////////////////////////////////////// 00163 // Function: ModelNode::register_with_read_factory 00164 // Access: Public, Static 00165 // Description: Tells the BamReader how to create objects of type 00166 // ModelNode. 00167 //////////////////////////////////////////////////////////////////// 00168 void ModelNode:: 00169 register_with_read_factory() { 00170 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); 00171 } 00172 00173 //////////////////////////////////////////////////////////////////// 00174 // Function : test_transform 00175 // Access : private 00176 // Description : this tests the transform to make sure it's within 00177 // the specified limits. It's done so we can assert 00178 // to see when an invalid transform is being applied. 00179 //////////////////////////////////////////////////////////////////// 00180 void ModelNode:: 00181 test_transform(const TransformState *ts) const { 00182 LPoint3 pos(ts->get_pos()); 00183 nassertv(pos[0] < _transform_limit); 00184 nassertv(pos[0] > -_transform_limit); 00185 nassertv(pos[1] < _transform_limit); 00186 nassertv(pos[1] > -_transform_limit); 00187 nassertv(pos[2] < _transform_limit); 00188 nassertv(pos[2] > -_transform_limit); 00189 } 00190 00191 //////////////////////////////////////////////////////////////////// 00192 // Function : transform_changed 00193 // Access : private, virtual 00194 // Description : node hook. This function handles outside 00195 // (non-physics) actions on the actor 00196 // and updates the internal representation of the node. 00197 // i.e. copy from PandaNode to PhysicsObject 00198 //////////////////////////////////////////////////////////////////// 00199 void ModelNode:: 00200 transform_changed() { 00201 PandaNode::transform_changed(); 00202 // get the transform 00203 CPT(TransformState) transform = get_transform(); 00204 00205 if (_transform_limit > 0.0) { 00206 test_transform(transform); 00207 } 00208 } 00209 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: ModelNode::write_datagram 00213 // Access: Public, Virtual 00214 // Description: Writes the contents of this object to the datagram 00215 // for shipping out to a Bam file. 00216 //////////////////////////////////////////////////////////////////// 00217 void ModelNode:: 00218 write_datagram(BamWriter *manager, Datagram &dg) { 00219 PandaNode::write_datagram(manager, dg); 00220 dg.add_uint8((int)_preserve_transform); 00221 dg.add_uint16(_preserve_attributes); 00222 } 00223 00224 //////////////////////////////////////////////////////////////////// 00225 // Function: ModelNode::make_from_bam 00226 // Access: Protected, Static 00227 // Description: This function is called by the BamReader's factory 00228 // when a new object of type ModelNode is encountered 00229 // in the Bam file. It should create the ModelNode 00230 // and extract its information from the file. 00231 //////////////////////////////////////////////////////////////////// 00232 TypedWritable *ModelNode:: 00233 make_from_bam(const FactoryParams ¶ms) { 00234 ModelNode *node = new ModelNode(""); 00235 DatagramIterator scan; 00236 BamReader *manager; 00237 00238 parse_params(params, scan, manager); 00239 node->fillin(scan, manager); 00240 00241 return node; 00242 } 00243 00244 //////////////////////////////////////////////////////////////////// 00245 // Function: ModelNode::fillin 00246 // Access: Protected 00247 // Description: This internal function is called by make_from_bam to 00248 // read in all of the relevant data from the BamFile for 00249 // the new ModelNode. 00250 //////////////////////////////////////////////////////////////////// 00251 void ModelNode:: 00252 fillin(DatagramIterator &scan, BamReader *manager) { 00253 PandaNode::fillin(scan, manager); 00254 00255 _preserve_transform = (PreserveTransform)scan.get_uint8(); 00256 _preserve_attributes = scan.get_uint16(); 00257 }