Panda3D
Loading...
Searching...
No Matches
animControl.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 animControl.cxx
10 * @author drose
11 * @date 1999-02-19
12 */
13
14#include "animControl.h"
15#include "animChannelBase.h"
16#include "partBundle.h"
17#include "config_chan.h"
18#include "dcast.h"
19#include "mutexHolder.h"
20#include "throw_event.h"
21
22TypeHandle AnimControl::_type_handle;
23
24/**
25 * This constructor is used to create a temporarily uninitialized AnimControl
26 * that will serve as a placeholder for an animation while the animation is
27 * being loaded during an asynchronous load-and-bind operation.
28 */
30AnimControl(const std::string &name, PartBundle *part,
31 double frame_rate, int num_frames) :
32 Namable(name),
33 _pending_lock(name),
34 _pending_cvar(_pending_lock),
35 _bound_joints(BitArray::all_on()),
36 _part(part)
37{
38#ifdef DO_MEMORY_USAGE
39 MemoryUsage::update_type(this, get_class_type());
40#endif
41
42 _pending = true;
43 _anim = nullptr;
44 _channel_index = -1;
45 set_frame_rate(frame_rate);
46 set_num_frames(num_frames);
47
48 _marked_frame = -1;
49}
50
51/**
52 * This can only be called once for a given AnimControl. It is used to supply
53 * the AnimBundle and related information.
54 */
56setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
57 const BitArray &bound_joints) {
58 MutexHolder holder(_pending_lock);
59 nassertv(_pending && part == _part);
60 nassertv(_anim == nullptr);
61 _anim = anim;
62 _channel_index = channel_index;
63 _bound_joints = bound_joints;
64 set_frame_rate(_anim->get_base_frame_rate());
65 set_num_frames(_anim->get_num_frames());
66
67 // Now the AnimControl is fully set up.
68 _marked_frame = -1;
69 _pending = false;
70 _pending_cvar.notify_all();
71 if (!_pending_done_event.empty()) {
72 throw_event(_pending_done_event);
73 }
74}
75
76/**
77 * Called to initialize the AnimControl with its array of bound_joints, before
78 * setup_anim() has completed.
79 */
81set_bound_joints(const BitArray &bound_joints) {
82 MutexHolder holder(_pending_lock);
83 _bound_joints = bound_joints;
84}
85
86/**
87 * This can only be called once for a given AnimControl. It indicates the
88 * attempt to bind it asynchronously has failed.
89 */
91fail_anim(PartBundle *part) {
92 MutexHolder holder(_pending_lock);
93 nassertv(_pending && part == _part);
94 _pending = false;
95 _pending_cvar.notify_all();
96 if (!_pending_done_event.empty()) {
97 throw_event(_pending_done_event);
98 }
99}
100
101/**
102 *
103 */
104AnimControl::
105~AnimControl() {
106 get_part()->control_removed(this);
107}
108
109/**
110 * Blocks the current thread until the AnimControl has finished loading and is
111 * fully bound.
112 */
114wait_pending() {
115 MutexHolder holder(_pending_lock);
116 if (_pending) {
117 // TODO: we should elevate the priority of the associated BindAnimRequest
118 // while we're waiting for it, so it will jump to the front of the queue.
119 chan_cat.info()
120 << "Blocking " << *Thread::get_current_thread()
121 << " until " << get_name() << " is bound\n";
122 while (_pending) {
123 _pending_cvar.wait();
124 }
125 }
126}
127
128/**
129 * Specifies an event name that will be thrown when the AnimControl is
130 * finished binding asynchronously. If the AnimControl has already finished
131 * binding, the event will be thrown immediately.
132 */
134set_pending_done_event(const std::string &done_event) {
135 MutexHolder holder(_pending_lock);
136 _pending_done_event = done_event;
137 if (!_pending) {
138 throw_event(_pending_done_event);
139 }
140}
141
142/**
143 * Returns the event name that will be thrown when the AnimControl is finished
144 * binding asynchronously.
145 */
146std::string AnimControl::
148 MutexHolder holder(_pending_lock);
149 return _pending_done_event;
150}
151
152/**
153 * Returns the PartBundle bound in with this AnimControl.
154 */
156get_part() const {
157 return DCAST(PartBundle, _part);
158}
159
160/**
161 *
162 */
163void AnimControl::
164output(std::ostream &out) const {
165 out << "AnimControl(" << get_name() << ", " << get_part()->get_name()
166 << ": ";
167 AnimInterface::output(out);
168 out << ")";
169
170 if (is_pending()) {
171 out << " (pending bind)";
172 } else if (!has_anim()) {
173 out << " (failed bind)";
174 }
175}
176
177/**
178 * Returns true if the indicated channel value has changed since the last call
179 * to mark_channels().
180 */
182channel_has_changed(AnimChannelBase *channel, bool frame_blend_flag) const {
183 if (_marked_frame < 0) {
184 return true;
185 }
186
187 int this_frame = get_frame();
188 double this_frac = 0.0;
189 if (frame_blend_flag) {
190 this_frac = get_frac();
191 }
192 return channel->has_changed(_marked_frame, _marked_frac,
193 this_frame, this_frac);
194}
195
196/**
197 * Marks this point as the point of reference for the next call to
198 * channel_has_changed().
199 */
201mark_channels(bool frame_blend_flag) {
202 _marked_frame = get_frame();
203 _marked_frac = 0.0;
204 if (frame_blend_flag) {
205 _marked_frac = get_frac();
206 }
207}
208
209/**
210 * This is provided as a callback method for when the user calls one of the
211 * play/loop/pose type methods to start the animation playing.
212 */
213void AnimControl::
214animation_activated() {
216}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the root of an AnimChannel hierarchy.
Definition animBundle.h:29
Parent class for all animation channels.
virtual bool has_changed(int last_frame, double last_frac, int this_frame, double this_frac)
Returns true if the value has changed since the last call to has_changed().
AnimControl(const std::string &name, PartBundle *part, double frame_rate, int num_frames)
This constructor is used to create a temporarily uninitialized AnimControl that will serve as a place...
void set_bound_joints(const BitArray &bound_joints)
Called to initialize the AnimControl with its array of bound_joints, before setup_anim() has complete...
void mark_channels(bool frame_blend_flag)
Marks this point as the point of reference for the next call to channel_has_changed().
void fail_anim(PartBundle *part)
This can only be called once for a given AnimControl.
bool is_pending() const
Returns true if the AnimControl is being bound asynchronously, and has not yet finished.
Definition animControl.I:21
void wait_pending()
Blocks the current thread until the AnimControl has finished loading and is fully bound.
void setup_anim(PartBundle *part, AnimBundle *anim, int channel_index, const BitArray &bound_joints)
This can only be called once for a given AnimControl.
std::string get_pending_done_event() const
Returns the event name that will be thrown when the AnimControl is finished binding asynchronously.
void set_pending_done_event(const std::string &done_event)
Specifies an event name that will be thrown when the AnimControl is finished binding asynchronously.
bool channel_has_changed(AnimChannelBase *channel, bool frame_blend_flag) const
Returns true if the indicated channel value has changed since the last call to mark_channels().
bool has_anim() const
Returns true if the AnimControl was successfully loaded, or false if there was a problem.
Definition animControl.I:30
PartBundle * get_part() const
Returns the PartBundle bound in with this AnimControl.
get_frame
Returns the current integer frame number.
get_frac
Returns the fractional part of the current frame.
A dynamic array with an unlimited number of bits.
Definition bitArray.h:40
void notify_all()
Informs all of the other threads who are currently blocked on wait() that the relevant condition has ...
void wait()
Waits on the condition.
static void update_type(ReferenceCount *ptr, TypeHandle type)
Associates the indicated type with the given pointer.
Definition memoryUsage.I:55
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition mutexHolder.h:25
A base class for all things which can have a name.
Definition namable.h:26
This is the root of a MovingPart hierarchy.
Definition partBundle.h:46
virtual void control_activated(AnimControl *control)
Called by the AnimControl whenever it starts an animation.
void control_removed(AnimControl *control)
Called by the AnimControl when it destructs.
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition thread.h:109
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.