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