00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "compassEffect.h"
00020 #include "config_pgraph.h"
00021 #include "nodePath.h"
00022 #include "bamReader.h"
00023 #include "bamWriter.h"
00024 #include "datagram.h"
00025 #include "datagramIterator.h"
00026
00027 TypeHandle CompassEffect::_type_handle;
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 CPT(RenderEffect) CompassEffect::
00041 make(const NodePath &reference, int properties) {
00042 CompassEffect *effect = new CompassEffect;
00043 effect->_reference = reference;
00044 effect->_properties = (properties & P_all);
00045 return return_new(effect);
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055 bool CompassEffect::
00056 safe_to_transform() const {
00057 return false;
00058 }
00059
00060
00061
00062
00063
00064
00065 void CompassEffect::
00066 output(ostream &out) const {
00067 out << get_type() << ":";
00068 if (_properties == 0) {
00069 out << " none";
00070 }
00071 if ((_properties & P_pos) == P_pos) {
00072 out << " xyz";
00073 } else {
00074 if ((_properties & P_x) != 0) {
00075 out << " x";
00076 }
00077 if ((_properties & P_y) != 0) {
00078 out << " y";
00079 }
00080 if ((_properties & P_z) != 0) {
00081 out << " z";
00082 }
00083 }
00084 if ((_properties & P_rot) != 0) {
00085 out << " rot";
00086 }
00087 if ((_properties & P_scale) == P_scale) {
00088 out << " scale";
00089 } else {
00090 if ((_properties & P_sx) != 0) {
00091 out << " sx";
00092 }
00093 if ((_properties & P_sy) != 0) {
00094 out << " sy";
00095 }
00096 if ((_properties & P_sz) != 0) {
00097 out << " sz";
00098 }
00099 }
00100 if (!_reference.is_empty()) {
00101 out << " reference " << _reference;
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 CPT(TransformState) CompassEffect::
00113 do_compass(const TransformState *net_transform,
00114 const TransformState *node_transform) const {
00115 if (_properties == 0) {
00116
00117 return TransformState::make_identity();
00118 }
00119
00120
00121
00122 CPT(TransformState) ref_transform;
00123 if (_reference.is_empty()) {
00124 ref_transform = node_transform;
00125 } else {
00126 ref_transform = _reference.get_net_transform()->compose(node_transform);
00127 }
00128
00129
00130
00131
00132
00133 CPT(TransformState) want_transform;
00134 if (_properties == P_all) {
00135
00136 want_transform = ref_transform;
00137
00138 } else {
00139
00140
00141 LVecBase3f want_pos = net_transform->get_pos();
00142 const LVecBase3f &ref_pos = ref_transform->get_pos();
00143 if ((_properties & P_x) != 0) {
00144 want_pos[0] = ref_pos[0];
00145 }
00146 if ((_properties & P_y) != 0) {
00147 want_pos[1] = ref_pos[1];
00148 }
00149 if ((_properties & P_z) != 0) {
00150 want_pos[2] = ref_pos[2];
00151 }
00152
00153 if ((_properties & ~P_pos) == 0) {
00154
00155 want_transform = net_transform->set_pos(want_pos);
00156
00157 } else if ((_properties & (P_rot | P_scale)) == (P_rot | P_scale)) {
00158
00159 want_transform = ref_transform->set_pos(want_pos);
00160
00161 } else {
00162
00163
00164 if (!net_transform->has_components() ||
00165 !ref_transform->has_components()) {
00166
00167
00168 want_transform = ref_transform->set_pos(want_pos);
00169
00170 } else {
00171
00172 LQuaternionf want_quat = net_transform->get_quat();
00173 if ((_properties & P_rot) != 0) {
00174 want_quat = ref_transform->get_quat();
00175 }
00176
00177 LVecBase3f want_scale = net_transform->get_scale();
00178 const LVecBase3f &ref_scale = ref_transform->get_scale();
00179 if ((_properties & P_sx) != 0) {
00180 want_scale[0] = ref_scale[0];
00181 }
00182 if ((_properties & P_sy) != 0) {
00183 want_scale[1] = ref_scale[1];
00184 }
00185 if ((_properties & P_sz) != 0) {
00186 want_scale[2] = ref_scale[2];
00187 }
00188
00189 want_transform =
00190 TransformState::make_pos_quat_scale(want_pos, want_quat, want_scale);
00191 }
00192 }
00193 }
00194
00195
00196
00197 return net_transform->invert_compose(want_transform);
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 int CompassEffect::
00216 compare_to_impl(const RenderEffect *other) const {
00217 const CompassEffect *ta;
00218 DCAST_INTO_R(ta, other, 0);
00219
00220 if (_properties != ta->_properties) {
00221 return _properties - ta->_properties;
00222 }
00223 int compare = _reference.compare_to(ta->_reference);
00224 if (compare != 0) {
00225 return compare;
00226 }
00227 return 0;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236 void CompassEffect::
00237 register_with_read_factory() {
00238 BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247 void CompassEffect::
00248 write_datagram(BamWriter *manager, Datagram &dg) {
00249 RenderEffect::write_datagram(manager, dg);
00250 dg.add_uint16(_properties);
00251
00252
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 TypedWritable *CompassEffect::
00264 make_from_bam(const FactoryParams ¶ms) {
00265 CompassEffect *effect = new CompassEffect;
00266 DatagramIterator scan;
00267 BamReader *manager;
00268
00269 parse_params(params, scan, manager);
00270 effect->fillin(scan, manager);
00271
00272 return effect;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282 void CompassEffect::
00283 fillin(DatagramIterator &scan, BamReader *manager) {
00284 RenderEffect::fillin(scan, manager);
00285 _properties = scan.get_uint16();
00286 }