Panda3D
|
00001 // Filename: movingPartScalar.cxx 00002 // Created by: drose (23Feb99) 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 00016 #include "movingPartScalar.h" 00017 #include "animChannelScalarDynamic.h" 00018 #include "datagram.h" 00019 #include "datagramIterator.h" 00020 #include "bamReader.h" 00021 #include "bamWriter.h" 00022 00023 // Tell GCC that we'll take care of the instantiation explicitly here. 00024 #ifdef __GNUC__ 00025 #pragma implementation 00026 #endif 00027 00028 TypeHandle MovingPartScalar::_type_handle; 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Function: MovingPartScalar::Destructor 00032 // Access: Public, Virtual 00033 // Description: 00034 //////////////////////////////////////////////////////////////////// 00035 MovingPartScalar:: 00036 ~MovingPartScalar() { 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: MovingPartScalar::get_blend_value 00041 // Access: Public 00042 // Description: Attempts to blend the various scalar values 00043 // indicated, and sets the _value member to the 00044 // resulting scalar. 00045 //////////////////////////////////////////////////////////////////// 00046 void MovingPartScalar:: 00047 get_blend_value(const PartBundle *root) { 00048 // If a forced channel is set on this particular scalar, we always 00049 // return that value instead of performing the blend. Furthermore, 00050 // the frame number is always 0 for the forced channel. 00051 if (_forced_channel != (AnimChannelBase *)NULL) { 00052 ChannelType *channel = DCAST(ChannelType, _forced_channel); 00053 channel->get_value(0, _value); 00054 return; 00055 } 00056 00057 PartBundle::CDReader cdata(root->_cycler); 00058 00059 if (cdata->_blend.empty()) { 00060 // No channel is bound; supply the default value. 00061 if (restore_initial_pose) { 00062 _value = _default_value; 00063 } 00064 00065 } else if (_effective_control != (AnimControl *)NULL && 00066 !cdata->_frame_blend_flag) { 00067 // A single value, the normal case. 00068 ChannelType *channel = DCAST(ChannelType, _effective_channel); 00069 channel->get_value(_effective_control->get_frame(), _value); 00070 00071 } else { 00072 // A blend of two or more values. 00073 _value = 0.0f; 00074 PN_stdfloat net = 0.0f; 00075 00076 PartBundle::ChannelBlend::const_iterator cbi; 00077 for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) { 00078 AnimControl *control = (*cbi).first; 00079 PN_stdfloat effect = (*cbi).second; 00080 nassertv(effect != 0.0f); 00081 00082 ChannelType *channel = NULL; 00083 int channel_index = control->get_channel_index(); 00084 if (channel_index >= 0 && channel_index < (int)_channels.size()) { 00085 channel = DCAST(ChannelType, _channels[channel_index]); 00086 } 00087 if (channel != NULL) { 00088 ValueType v; 00089 channel->get_value(control->get_frame(), v); 00090 00091 if (!cdata->_frame_blend_flag) { 00092 // Hold the current frame until the next one is ready. 00093 _value += v * effect; 00094 } else { 00095 // Blend between successive frames. 00096 PN_stdfloat frac = (PN_stdfloat)control->get_frac(); 00097 _value += v * (effect * (1.0f - frac)); 00098 00099 channel->get_value(control->get_next_frame(), v); 00100 _value += v * (effect * frac); 00101 } 00102 net += effect; 00103 } 00104 } 00105 00106 if (net == 0.0f) { 00107 if (restore_initial_pose) { 00108 _value = _default_value; 00109 } 00110 00111 } else { 00112 _value /= net; 00113 } 00114 } 00115 } 00116 00117 //////////////////////////////////////////////////////////////////// 00118 // Function: MovingPartScalar::apply_freeze_scalar 00119 // Access: Public, Virtual 00120 // Description: Freezes this particular joint so that it will always 00121 // hold the specified transform. Returns true if this 00122 // is a joint that can be so frozen, false otherwise. 00123 // This is called internally by 00124 // PartBundle::freeze_joint(). 00125 //////////////////////////////////////////////////////////////////// 00126 bool MovingPartScalar:: 00127 apply_freeze_scalar(PN_stdfloat value) { 00128 _forced_channel = new AnimChannelFixed<ACScalarSwitchType>(get_name(), value); 00129 return true; 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: MovingPartScalar::apply_control 00134 // Access: Public, Virtual 00135 // Description: Specifies a node to influence this particular joint 00136 // so that it will always hold the node's transform. 00137 // Returns true if this is a joint that can be so 00138 // controlled, false otherwise. This is called 00139 // internally by PartBundle::control_joint(). 00140 //////////////////////////////////////////////////////////////////// 00141 bool MovingPartScalar:: 00142 apply_control(PandaNode *node) { 00143 AnimChannelScalarDynamic *chan = new AnimChannelScalarDynamic(get_name()); 00144 chan->set_value_node(node); 00145 _forced_channel = chan; 00146 return true; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: MovingPartScalar::make_MovingPartScalar 00151 // Access: Protected 00152 // Description: Factory method to generate a MovingPartScalar object 00153 //////////////////////////////////////////////////////////////////// 00154 TypedWritable* MovingPartScalar:: 00155 make_MovingPartScalar(const FactoryParams ¶ms) { 00156 MovingPartScalar *me = new MovingPartScalar; 00157 DatagramIterator scan; 00158 BamReader *manager; 00159 00160 parse_params(params, scan, manager); 00161 me->fillin(scan, manager); 00162 return me; 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: MovingPartScalar::register_with_factory 00167 // Access: Public, Static 00168 // Description: Factory method to generate a MovingPartScalar object 00169 //////////////////////////////////////////////////////////////////// 00170 void MovingPartScalar:: 00171 register_with_read_factory() { 00172 BamReader::get_factory()->register_factory(get_class_type(), make_MovingPartScalar); 00173 } 00174