Panda3D

movingPartScalar.cxx

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 &params) {
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 
 All Classes Functions Variables Enumerations