Panda3D
 All Classes Functions Variables Enumerations
movingPartScalar.cxx
1 // Filename: movingPartScalar.cxx
2 // Created by: drose (23Feb99)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 #include "movingPartScalar.h"
17 #include "animChannelScalarDynamic.h"
18 #include "datagram.h"
19 #include "datagramIterator.h"
20 #include "bamReader.h"
21 #include "bamWriter.h"
22 #include "config_chan.h"
23 
24 // Tell GCC that we'll take care of the instantiation explicitly here.
25 #ifdef __GNUC__
26 #pragma implementation
27 #endif
28 
29 TypeHandle MovingPartScalar::_type_handle;
30 
31 ////////////////////////////////////////////////////////////////////
32 // Function: MovingPartScalar::Destructor
33 // Access: Public, Virtual
34 // Description:
35 ////////////////////////////////////////////////////////////////////
36 MovingPartScalar::
37 ~MovingPartScalar() {
38 }
39 
40 ////////////////////////////////////////////////////////////////////
41 // Function: MovingPartScalar::get_blend_value
42 // Access: Public
43 // Description: Attempts to blend the various scalar values
44 // indicated, and sets the _value member to the
45 // resulting scalar.
46 ////////////////////////////////////////////////////////////////////
49  // If a forced channel is set on this particular scalar, we always
50  // return that value instead of performing the blend. Furthermore,
51  // the frame number is always 0 for the forced channel.
52  if (_forced_channel != (AnimChannelBase *)NULL) {
53  ChannelType *channel = DCAST(ChannelType, _forced_channel);
54  channel->get_value(0, _value);
55  return;
56  }
57 
58  PartBundle::CDReader cdata(root->_cycler);
59 
60  if (cdata->_blend.empty()) {
61  // No channel is bound; supply the default value.
62  if (restore_initial_pose) {
63  _value = _default_value;
64  }
65 
66  } else if (_effective_control != (AnimControl *)NULL &&
67  !cdata->_frame_blend_flag) {
68  // A single value, the normal case.
69  ChannelType *channel = DCAST(ChannelType, _effective_channel);
70  channel->get_value(_effective_control->get_frame(), _value);
71 
72  } else {
73  // A blend of two or more values.
74  _value = 0.0f;
75  PN_stdfloat net = 0.0f;
76 
77  PartBundle::ChannelBlend::const_iterator cbi;
78  for (cbi = cdata->_blend.begin(); cbi != cdata->_blend.end(); ++cbi) {
79  AnimControl *control = (*cbi).first;
80  PN_stdfloat effect = (*cbi).second;
81  nassertv(effect != 0.0f);
82 
83  ChannelType *channel = NULL;
84  int channel_index = control->get_channel_index();
85  if (channel_index >= 0 && channel_index < (int)_channels.size()) {
86  channel = DCAST(ChannelType, _channels[channel_index]);
87  }
88  if (channel != NULL) {
89  ValueType v;
90  channel->get_value(control->get_frame(), v);
91 
92  if (!cdata->_frame_blend_flag) {
93  // Hold the current frame until the next one is ready.
94  _value += v * effect;
95  } else {
96  // Blend between successive frames.
97  PN_stdfloat frac = (PN_stdfloat)control->get_frac();
98  _value += v * (effect * (1.0f - frac));
99 
100  channel->get_value(control->get_next_frame(), v);
101  _value += v * (effect * frac);
102  }
103  net += effect;
104  }
105  }
106 
107  if (net == 0.0f) {
108  if (restore_initial_pose) {
109  _value = _default_value;
110  }
111 
112  } else {
113  _value /= net;
114  }
115  }
116 }
117 
118 ////////////////////////////////////////////////////////////////////
119 // Function: MovingPartScalar::apply_freeze_scalar
120 // Access: Public, Virtual
121 // Description: Freezes this particular joint so that it will always
122 // hold the specified transform. Returns true if this
123 // is a joint that can be so frozen, false otherwise.
124 // This is called internally by
125 // PartBundle::freeze_joint().
126 ////////////////////////////////////////////////////////////////////
128 apply_freeze_scalar(PN_stdfloat value) {
129  _forced_channel = new AnimChannelFixed<ACScalarSwitchType>(get_name(), value);
130  return true;
131 }
132 
133 ////////////////////////////////////////////////////////////////////
134 // Function: MovingPartScalar::apply_control
135 // Access: Public, Virtual
136 // Description: Specifies a node to influence this particular joint
137 // so that it will always hold the node's transform.
138 // Returns true if this is a joint that can be so
139 // controlled, false otherwise. This is called
140 // internally by PartBundle::control_joint().
141 ////////////////////////////////////////////////////////////////////
144  AnimChannelScalarDynamic *chan = new AnimChannelScalarDynamic(get_name());
145  chan->set_value_node(node);
146  _forced_channel = chan;
147  return true;
148 }
149 
150 ////////////////////////////////////////////////////////////////////
151 // Function: MovingPartScalar::make_MovingPartScalar
152 // Access: Protected
153 // Description: Factory method to generate a MovingPartScalar object
154 ////////////////////////////////////////////////////////////////////
158  DatagramIterator scan;
159  BamReader *manager;
160 
161  parse_params(params, scan, manager);
162  me->fillin(scan, manager);
163  return me;
164 }
165 
166 ////////////////////////////////////////////////////////////////////
167 // Function: MovingPartScalar::register_with_factory
168 // Access: Public, Static
169 // Description: Factory method to generate a MovingPartScalar object
170 ////////////////////////////////////////////////////////////////////
174 }
175 
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
static TypedWritable * make_MovingPartScalar(const FactoryParams &params)
Factory method to generate a MovingPartScalar object.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
double get_frac() const
Returns the fractional part of the current frame.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
static void register_with_read_factory()
Factory method to generate a MovingPartScalar object.
void set_value_node(PandaNode *node)
Specifies a node whose transform will be queried each frame to implicitly specify the transform of th...
This template class is the parent class for all kinds of AnimChannels that return different values...
Definition: animChannel.h:30
virtual bool apply_freeze_scalar(PN_stdfloat value)
Freezes this particular joint so that it will always hold the specified transform.
This template class calls PipelineCycler::read_unlocked(), and then provides a transparent read-only ...
int get_frame() const
Returns the current integer frame number.
Parent class for all animation channels.
virtual bool apply_control(PandaNode *node)
Specifies a node to influence this particular joint so that it will always hold the node&#39;s transform...
This template class is a special kind of AnimChannel that always returns just one fixed value...
int get_next_frame() const
Returns the current integer frame number + 1, constrained to the range 0 &lt;= f &lt; get_num_frames().
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
virtual void get_blend_value(const PartBundle *root)
Attempts to blend the various scalar values indicated, and sets the _value member to the resulting sc...
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
An animation channel that accepts a scalar each frame from some dynamic input provided by code...
This is a particular kind of MovingPart that accepts a scalar each frame.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
This is the root of a MovingPart hierarchy.
Definition: partBundle.h:49
Controls the timing of a character animation.
Definition: animControl.h:41
A class to retrieve the individual data elements previously stored in a Datagram. ...
int get_channel_index() const
Returns the particular channel index associated with this AnimControl.
Definition: animControl.I:67
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85