mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
asynchronous animation binding
This commit is contained in:
parent
0f83ba7fe1
commit
6d953de53a
@ -20,7 +20,10 @@
|
||||
animChannelScalarTable.I animChannelScalarTable.h \
|
||||
animControl.I animControl.N \
|
||||
animControl.h animControlCollection.I \
|
||||
animControlCollection.h animGroup.I animGroup.h auto_bind.h \
|
||||
animControlCollection.h animGroup.I animGroup.h \
|
||||
animPreloadTable.I animPreloadTable.h \
|
||||
auto_bind.h \
|
||||
bindAnimRequest.I bindAnimRequest.h \
|
||||
config_chan.h \
|
||||
movingPart.I movingPart.h \
|
||||
movingPartBase.I movingPartBase.h \
|
||||
@ -43,7 +46,10 @@
|
||||
animChannelScalarDynamic.cxx \
|
||||
animChannelScalarTable.cxx \
|
||||
animControl.cxx \
|
||||
animControlCollection.cxx animGroup.cxx auto_bind.cxx \
|
||||
animControlCollection.cxx animGroup.cxx \
|
||||
animPreloadTable.cxx \
|
||||
auto_bind.cxx \
|
||||
bindAnimRequest.cxx \
|
||||
config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx \
|
||||
movingPartScalar.cxx partBundle.cxx \
|
||||
partBundleHandle.cxx \
|
||||
@ -64,7 +70,11 @@
|
||||
animChannelScalarTable.I animChannelScalarTable.h \
|
||||
animControl.I animControl.h \
|
||||
animControlCollection.I animControlCollection.h animGroup.I \
|
||||
animGroup.h auto_bind.h config_chan.h \
|
||||
animGroup.h \
|
||||
animPreloadTable.I animPreloadTable.h \
|
||||
auto_bind.h \
|
||||
bindAnimRequest.I bindAnimRequest.h \
|
||||
config_chan.h \
|
||||
movingPart.I movingPart.h movingPartBase.I \
|
||||
movingPartBase.h movingPartMatrix.I movingPartMatrix.h \
|
||||
movingPartScalar.I movingPartScalar.h partBundle.I partBundle.h \
|
||||
|
@ -45,6 +45,38 @@ safe_to_flatten() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimBundleNode::find_anim_bundle
|
||||
// Access: Published, Static
|
||||
// Description: Recursively walks the scene graph beginning at the
|
||||
// indicated node (which need not be an AnimBundleNode),
|
||||
// and returns the first AnimBundle found. Returns NULL
|
||||
// if no AnimBundle can be found.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimBundle *AnimBundleNode::
|
||||
find_anim_bundle(PandaNode *root) {
|
||||
nassertr(root != (PandaNode *)NULL, NULL);
|
||||
|
||||
if (root->is_of_type(AnimBundleNode::get_class_type())) {
|
||||
AnimBundleNode *anode = DCAST(AnimBundleNode, root);
|
||||
AnimBundle *anim = anode->get_bundle();
|
||||
if (anim != (AnimBundle *)NULL) {
|
||||
return anim;
|
||||
}
|
||||
}
|
||||
|
||||
Children cr = root->get_children();
|
||||
int num_children = cr.get_num_children();
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
AnimBundle *anim = find_anim_bundle(cr.get_child(i));
|
||||
if (anim != (AnimBundle *)NULL) {
|
||||
return anim;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimBundleNode::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
@ -42,6 +42,8 @@ public:
|
||||
|
||||
PUBLISHED:
|
||||
INLINE AnimBundle *get_bundle() const;
|
||||
|
||||
static AnimBundle *find_anim_bundle(PandaNode *root);
|
||||
|
||||
private:
|
||||
PT(AnimBundle) _bundle;
|
||||
|
@ -13,6 +13,33 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::is_pending
|
||||
// Access: Published
|
||||
// Description: Returns true if the AnimControl is being bound
|
||||
// asynchronously, and has not yet finished. If this is
|
||||
// true, the AnimControl's interface is still available
|
||||
// and will be perfectly useful (though get_anim() might
|
||||
// return NULL), but nothing visible will happen
|
||||
// immediately.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AnimControl::
|
||||
is_pending() const {
|
||||
return _pending;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::has_anim
|
||||
// Access: Published
|
||||
// Description: Returns true if the AnimControl was successfully
|
||||
// loaded, or false if there was a problem. This may
|
||||
// return false while is_pending() is true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AnimControl::
|
||||
has_anim() const {
|
||||
return (_anim != (AnimBundle *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_anim
|
||||
// Access: Published
|
||||
@ -56,3 +83,41 @@ INLINE const BitArray &AnimControl::
|
||||
get_bound_joints() const {
|
||||
return _bound_joints;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::set_anim_model
|
||||
// Access: Published
|
||||
// Description: Associates the indicated PandaNode with the
|
||||
// AnimControl. By convention, this node represents the
|
||||
// root node of the model file that corresponds to this
|
||||
// AnimControl's animation file, though nothing in this
|
||||
// code makes this assumption or indeed does anything
|
||||
// with this node.
|
||||
//
|
||||
// The purpose of this is simply to allow the
|
||||
// AnimControl to keep a reference count on the
|
||||
// ModelRoot node that generated it, so that the model
|
||||
// will not disappear from the model pool until it is no
|
||||
// longer referenced.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimControl::
|
||||
set_anim_model(PandaNode *model) {
|
||||
_anim_model = model;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_anim_model
|
||||
// Access: Published
|
||||
// Description: Retrieves the pointer set via set_anim_model(). See
|
||||
// set_anim_model().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *AnimControl::
|
||||
get_anim_model() const {
|
||||
return _anim_model;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const AnimControl &control) {
|
||||
control.output(out);
|
||||
return out;
|
||||
}
|
||||
|
@ -17,29 +17,81 @@
|
||||
#include "partBundle.h"
|
||||
#include "config_chan.h"
|
||||
#include "dcast.h"
|
||||
#include "mutexHolder.h"
|
||||
#include "throw_event.h"
|
||||
|
||||
TypeHandle AnimControl::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: This constructor is used to create a temporarily
|
||||
// uninitialized AnimControl that will serve as a
|
||||
// placeholder for an animation while the animation is
|
||||
// being loaded during an asynchronous load-and-bind
|
||||
// operation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimControl::
|
||||
AnimControl(PartBundle *part, AnimBundle *anim, int channel_index,
|
||||
const BitArray &bound_joints) {
|
||||
AnimControl(const string &name, PartBundle *part,
|
||||
double frame_rate, int num_frames) :
|
||||
Namable(name)
|
||||
{
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
MemoryUsage::update_type(this, get_class_type());
|
||||
#endif
|
||||
|
||||
_pending = true;
|
||||
_part = part;
|
||||
_anim = NULL;
|
||||
_channel_index = -1;
|
||||
set_frame_rate(frame_rate);
|
||||
set_num_frames(num_frames);
|
||||
|
||||
_marked_frame = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::setup_anim
|
||||
// Access: Public
|
||||
// Description: This can only be called once for a given AnimControl.
|
||||
// It is used to supply the AnimBundle and related
|
||||
// information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
|
||||
const BitArray &bound_joints) {
|
||||
MutexHolder holder(_pending_lock);
|
||||
nassertv(_pending && part == _part);
|
||||
nassertv(_anim == (AnimBundle *)NULL);
|
||||
_anim = anim;
|
||||
_channel_index = channel_index;
|
||||
_bound_joints = bound_joints;
|
||||
set_frame_rate(_anim->get_base_frame_rate());
|
||||
set_num_frames(_anim->get_num_frames());
|
||||
|
||||
// Now the AnimControl is fully set up.
|
||||
_marked_frame = -1;
|
||||
_pending = false;
|
||||
if (!_pending_done_event.empty()) {
|
||||
throw_event(_pending_done_event);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::fail_anim
|
||||
// Access: Public
|
||||
// Description: This can only be called once for a given AnimControl.
|
||||
// It indicates the attempt to bind it asynchronously
|
||||
// has failed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
fail_anim(PartBundle *part) {
|
||||
MutexHolder holder(_pending_lock);
|
||||
nassertv(_pending && part == _part);
|
||||
_pending = false;
|
||||
if (!_pending_done_event.empty()) {
|
||||
throw_event(_pending_done_event);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -52,6 +104,35 @@ AnimControl::
|
||||
get_part()->set_control_effect(this, 0.0f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::set_pending_done_event
|
||||
// Access: Published
|
||||
// Description: Specifies an event name that will be thrown when the
|
||||
// AnimControl is finished binding asynchronously. If
|
||||
// the AnimControl has already finished binding, the
|
||||
// event will be thrown immediately.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
set_pending_done_event(const string &done_event) {
|
||||
MutexHolder holder(_pending_lock);
|
||||
_pending_done_event = done_event;
|
||||
if (!_pending) {
|
||||
throw_event(_pending_done_event);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_pending_done_event
|
||||
// Access: Published
|
||||
// Description: Returns the event name that will be thrown when the
|
||||
// AnimControl is finished binding asynchronously.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string AnimControl::
|
||||
get_pending_done_event() const {
|
||||
MutexHolder holder(_pending_lock);
|
||||
return _pending_done_event;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimControl::get_part
|
||||
// Access: Published
|
||||
@ -70,10 +151,16 @@ get_part() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimControl::
|
||||
output(ostream &out) const {
|
||||
out << "AnimControl(" << get_part()->get_name()
|
||||
<< ", " << get_anim()->get_name() << ": ";
|
||||
out << "AnimControl(" << get_name() << ", " << get_part()->get_name()
|
||||
<< ": ";
|
||||
AnimInterface::output(out);
|
||||
out << ")";
|
||||
|
||||
if (is_pending()) {
|
||||
out << " (pending bind)";
|
||||
} else if (!has_anim()) {
|
||||
out << " (failed bind)";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -21,8 +21,10 @@
|
||||
#include "animBundle.h"
|
||||
#include "partGroup.h"
|
||||
#include "bitArray.h"
|
||||
|
||||
#include "referenceCount.h"
|
||||
#include "pandaNode.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "namable.h"
|
||||
#include "pmutex.h"
|
||||
|
||||
class PartBundle;
|
||||
class AnimChannelBase;
|
||||
@ -35,19 +37,30 @@ class AnimChannelBase;
|
||||
// animation: whether started, stopped, or looping, and
|
||||
// the current frame number and play rate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_CHAN AnimControl : public ReferenceCount, public AnimInterface {
|
||||
class EXPCL_PANDA_CHAN AnimControl : public TypedReferenceCount, public AnimInterface, public Namable {
|
||||
public:
|
||||
AnimControl(PartBundle *part, AnimBundle *anim, int channel_index,
|
||||
const BitArray &bound_joints);
|
||||
AnimControl(const string &name, PartBundle *part,
|
||||
double frame_rate, int num_frames);
|
||||
void setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
|
||||
const BitArray &bound_joints);
|
||||
void fail_anim(PartBundle *part);
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~AnimControl();
|
||||
|
||||
INLINE bool is_pending() const;
|
||||
INLINE bool has_anim() const;
|
||||
void set_pending_done_event(const string &done_event);
|
||||
string get_pending_done_event() const;
|
||||
|
||||
PartBundle *get_part() const;
|
||||
INLINE AnimBundle *get_anim() const;
|
||||
INLINE int get_channel_index() const;
|
||||
INLINE const BitArray &get_bound_joints() const;
|
||||
|
||||
INLINE void set_anim_model(PandaNode *model);
|
||||
INLINE PandaNode *get_anim_model() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
public:
|
||||
@ -65,6 +78,10 @@ private:
|
||||
// This is a PT(PartGroup) instead of a PT(PartBundle), just because
|
||||
// we can't include partBundle.h for circular reasons. But it
|
||||
// actually keeps a pointer to a PartBundle.
|
||||
bool _pending;
|
||||
string _pending_done_event;
|
||||
Mutex _pending_lock; // protects the above two.
|
||||
|
||||
PT(PartGroup) _part;
|
||||
PT(AnimBundle) _anim;
|
||||
int _channel_index;
|
||||
@ -80,15 +97,22 @@ private:
|
||||
// get_bound_joints().
|
||||
BitArray _bound_joints;
|
||||
|
||||
PT(PandaNode) _anim_model;
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
ReferenceCount::init_type();
|
||||
TypedReferenceCount::init_type();
|
||||
AnimInterface::init_type();
|
||||
register_type(_type_handle, "AnimControl",
|
||||
ReferenceCount::get_class_type(),
|
||||
TypedReferenceCount::get_class_type(),
|
||||
AnimInterface::get_class_type());
|
||||
}
|
||||
|
||||
@ -96,6 +120,8 @@ private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const AnimControl &control);
|
||||
|
||||
#include "animControl.I"
|
||||
|
||||
#endif
|
||||
|
86
panda/src/chan/animPreloadTable.I
Normal file
86
panda/src/chan/animPreloadTable.I
Normal file
@ -0,0 +1,86 @@
|
||||
// Filename: animPreloadTable.I
|
||||
// Created by: drose (05Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::AnimRecord::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE AnimPreloadTable::AnimRecord::
|
||||
AnimRecord() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::AnimRecord::operator <
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool AnimPreloadTable::AnimRecord::
|
||||
operator < (const AnimRecord &other) const {
|
||||
return _basename < other._basename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::get_basename
|
||||
// Access: Published
|
||||
// Description: Returns the basename stored for the nth animation
|
||||
// record. See find_anim().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE string AnimPreloadTable::
|
||||
get_basename(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_anims.size(), string());
|
||||
consider_sort();
|
||||
return _anims[n]._basename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::get_base_frame_rate
|
||||
// Access: Published
|
||||
// Description: Returns the frame rate stored for the nth animation
|
||||
// record.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float AnimPreloadTable::
|
||||
get_base_frame_rate(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_anims.size(), 0.0f);
|
||||
consider_sort();
|
||||
return _anims[n]._base_frame_rate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::get_num_frames
|
||||
// Access: Published
|
||||
// Description: Returns the number of frames stored for the nth
|
||||
// animation record.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int AnimPreloadTable::
|
||||
get_num_frames(int n) const {
|
||||
nassertr(n >= 0 && n < (int)_anims.size(), 0);
|
||||
consider_sort();
|
||||
return _anims[n]._num_frames;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::consider_sort
|
||||
// Access: Private
|
||||
// Description: Ensures the table is kept in alphabetical order by
|
||||
// basename.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void AnimPreloadTable::
|
||||
consider_sort() const {
|
||||
if (_needs_sort) {
|
||||
((AnimPreloadTable *)this)->_anims.sort();
|
||||
((AnimPreloadTable *)this)->_needs_sort = false;
|
||||
}
|
||||
}
|
240
panda/src/chan/animPreloadTable.cxx
Normal file
240
panda/src/chan/animPreloadTable.cxx
Normal file
@ -0,0 +1,240 @@
|
||||
// Filename: animPreloadTable.cxx
|
||||
// Created by: drose (05Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "animPreloadTable.h"
|
||||
|
||||
#include "indent.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
|
||||
TypeHandle AnimPreloadTable::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::make_cow_copy
|
||||
// Access: Protected, Virtual
|
||||
// Description: Required to implement CopyOnWriteObject.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(CopyOnWriteObject) AnimPreloadTable::
|
||||
make_cow_copy() {
|
||||
return new AnimPreloadTable(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimPreloadTable::
|
||||
AnimPreloadTable() {
|
||||
_needs_sort = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AnimPreloadTable::
|
||||
~AnimPreloadTable() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::get_num_anims
|
||||
// Access: Published
|
||||
// Description: Returns the number of animation records in the table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int AnimPreloadTable::
|
||||
get_num_anims() const {
|
||||
return (int)_anims.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::find_anim
|
||||
// Access: Published
|
||||
// Description: Returns the index number in the table of the
|
||||
// animation record with the indicated name, or -1 if
|
||||
// the name is not present. By convention, the basename
|
||||
// is the filename of the egg or bam file, without the
|
||||
// directory part and without the extension. That is,
|
||||
// it is Filename::get_basename_wo_extension().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int AnimPreloadTable::
|
||||
find_anim(const string &basename) const {
|
||||
consider_sort();
|
||||
AnimRecord record;
|
||||
record._basename = basename;
|
||||
Anims::const_iterator ai = _anims.find(record);
|
||||
if (ai != _anims.end()) {
|
||||
return int(ai - _anims.begin());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::clear_anims
|
||||
// Access: Published
|
||||
// Description: Removes all animation records from the table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
clear_anims() {
|
||||
_anims.clear();
|
||||
_needs_sort = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::remove_anim
|
||||
// Access: Published
|
||||
// Description: Removes the nth animation records from the table.
|
||||
// This renumbers indexes for following animations.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
remove_anim(int n) {
|
||||
nassertv(n >= 0 && n < (int)_anims.size());
|
||||
_anims.erase(_anims.begin() + n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::add_anim
|
||||
// Access: Published
|
||||
// Description: Adds a new animation record to the table. If there
|
||||
// is already a record of this name, no operation is
|
||||
// performed (the original record is unchanged). See
|
||||
// find_anim(). This will invalidate existing index
|
||||
// numbers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
add_anim(const string &basename, float base_frame_rate, int num_frames) {
|
||||
AnimRecord record;
|
||||
record._basename = basename;
|
||||
record._base_frame_rate = base_frame_rate;
|
||||
record._num_frames = num_frames;
|
||||
|
||||
_anims.push_back(record);
|
||||
_needs_sort = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::add_anims_from
|
||||
// Access: Published
|
||||
// Description: Copies the animation records from the other table
|
||||
// into this one. If a given record name exists in both
|
||||
// tables, the record in this one supercedes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
add_anims_from(const AnimPreloadTable *other) {
|
||||
_anims.reserve(_anims.size() + other->_anims.size());
|
||||
Anims::const_iterator ai;
|
||||
for (ai = other->_anims.begin(); ai != other->_anims.end(); ++ai) {
|
||||
_anims.push_back(*ai);
|
||||
}
|
||||
_needs_sort = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
output(ostream &out) const {
|
||||
out << "AnimPreloadTable, " << _anims.size() << " animation records.";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< "AnimPreloadTable, " << _anims.size() << " animation records:\n";
|
||||
consider_sort();
|
||||
Anims::const_iterator ai;
|
||||
for (ai = _anims.begin(); ai != _anims.end(); ++ai) {
|
||||
const AnimRecord &record = (*ai);
|
||||
indent(out, indent_level + 2)
|
||||
<< record._basename << ": " << record._num_frames << " frames at "
|
||||
<< record._base_frame_rate << " fps\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Factory method to generate an AnimPreloadTable object
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::write_datagram
|
||||
// Access: Public
|
||||
// Description: Function to write the important information in
|
||||
// the particular object to a Datagram
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
consider_sort();
|
||||
|
||||
dg.add_uint16(_anims.size());
|
||||
Anims::const_iterator ai;
|
||||
for (ai = _anims.begin(); ai != _anims.end(); ++ai) {
|
||||
const AnimRecord &record = (*ai);
|
||||
dg.add_string(record._basename);
|
||||
dg.add_float32(record._base_frame_rate);
|
||||
dg.add_int32(record._num_frames);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::make_from_bam
|
||||
// Access: Protected
|
||||
// Description: Factory method to generate an AnimPreloadTable object
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *AnimPreloadTable::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
AnimPreloadTable *me = new AnimPreloadTable;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
me->fillin(scan, manager);
|
||||
return me;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AnimPreloadTable::fillin
|
||||
// Access: Protected
|
||||
// Description: Function that reads out of the datagram (or asks
|
||||
// manager to read) all of the data that is needed to
|
||||
// re-create this object and stores it in the appropiate
|
||||
// place
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AnimPreloadTable::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
int num_anims = scan.get_uint16();
|
||||
_anims.reserve(num_anims);
|
||||
for (int i = 0; i < num_anims; ++i) {
|
||||
AnimRecord record;
|
||||
record._basename = scan.get_string();
|
||||
record._base_frame_rate = scan.get_float32();
|
||||
record._num_frames = scan.get_int32();
|
||||
_anims.push_back(record);
|
||||
}
|
||||
}
|
117
panda/src/chan/animPreloadTable.h
Normal file
117
panda/src/chan/animPreloadTable.h
Normal file
@ -0,0 +1,117 @@
|
||||
// Filename: animPreloadTable.h
|
||||
// Created by: drose (05Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ANIMPRELOADTABLE_H
|
||||
#define ANIMPRELOADTABLE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "copyOnWriteObject.h"
|
||||
|
||||
class BamWriter;
|
||||
class BamReader;
|
||||
class Datagram;
|
||||
class DatagramIterator;
|
||||
class FactoryParams;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : AnimPreloadTable
|
||||
// Description : This table records data about a list of animations
|
||||
// for a particular model, such as number of frames and
|
||||
// frame rate. It's used for implementating
|
||||
// asynchronous binding.
|
||||
//
|
||||
// This table is normally built by an offline tool, such
|
||||
// as egg-optchar.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_CHAN AnimPreloadTable : public CopyOnWriteObject {
|
||||
public:
|
||||
class AnimRecord {
|
||||
public:
|
||||
INLINE AnimRecord();
|
||||
INLINE bool operator < (const AnimRecord &other) const;
|
||||
|
||||
string _basename;
|
||||
float _base_frame_rate;
|
||||
int _num_frames;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual PT(CopyOnWriteObject) make_cow_copy();
|
||||
|
||||
PUBLISHED:
|
||||
AnimPreloadTable();
|
||||
virtual ~AnimPreloadTable();
|
||||
|
||||
int get_num_anims() const;
|
||||
int find_anim(const string &basename) const;
|
||||
|
||||
INLINE string get_basename(int n) const;
|
||||
INLINE float get_base_frame_rate(int n) const;
|
||||
INLINE int get_num_frames(int n) const;
|
||||
|
||||
void clear_anims();
|
||||
void remove_anim(int n);
|
||||
void add_anim(const string &basename, float base_frame_rate, int num_frames);
|
||||
void add_anims_from(const AnimPreloadTable *other);
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
INLINE void consider_sort() const;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
||||
protected:
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
private:
|
||||
typedef ov_set<AnimRecord> Anims;
|
||||
Anims _anims;
|
||||
bool _needs_sort;
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
CopyOnWriteObject::init_type();
|
||||
register_type(_type_handle, "AnimPreloadTable",
|
||||
CopyOnWriteObject::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
inline ostream &operator << (ostream &out, const AnimPreloadTable &anim) {
|
||||
anim.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "animPreloadTable.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
32
panda/src/chan/bindAnimRequest.I
Normal file
32
panda/src/chan/bindAnimRequest.I
Normal file
@ -0,0 +1,32 @@
|
||||
// Filename: bindAnimRequest.I
|
||||
// Created by: drose (05Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BindAnimRequest::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BindAnimRequest::
|
||||
BindAnimRequest(const Filename &filename, const LoaderOptions &options,
|
||||
AnimControl *control, int hierarchy_match_flags,
|
||||
const PartSubset &subset) :
|
||||
ModelLoadRequest(filename, options),
|
||||
_control(control),
|
||||
_hierarchy_match_flags(hierarchy_match_flags),
|
||||
_subset(subset)
|
||||
{
|
||||
}
|
||||
|
||||
|
63
panda/src/chan/bindAnimRequest.cxx
Normal file
63
panda/src/chan/bindAnimRequest.cxx
Normal file
@ -0,0 +1,63 @@
|
||||
// Filename: bindAnimRequest.cxx
|
||||
// Created by: drose (05Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "bindAnimRequest.h"
|
||||
#include "animBundleNode.h"
|
||||
#include "animControl.h"
|
||||
#include "partBundle.h"
|
||||
|
||||
TypeHandle BindAnimRequest::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BindAnimRequest::do_task
|
||||
// Access: Protected, Virtual
|
||||
// Description: Performs the task: that is, loads and binds the
|
||||
// animation.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BindAnimRequest::
|
||||
do_task() {
|
||||
ModelLoadRequest::do_task();
|
||||
|
||||
PartBundle *part = _control->get_part();
|
||||
|
||||
if (_control->get_ref_count() == 1) {
|
||||
// We're holding the only remaining reference to this AnimControl.
|
||||
// Therefore, forget the bind attempt; no one cares anyway.
|
||||
_control->fail_anim(part);
|
||||
return false;
|
||||
}
|
||||
|
||||
PT(PandaNode) model = get_model();
|
||||
if (model == (PandaNode *)NULL) {
|
||||
// Couldn't load the file.
|
||||
_control->fail_anim(part);
|
||||
return false;
|
||||
}
|
||||
_control->set_anim_model(model);
|
||||
|
||||
AnimBundle *anim = AnimBundleNode::find_anim_bundle(model);
|
||||
if (anim == (AnimBundle *)NULL) {
|
||||
// No anim bundle.
|
||||
_control->fail_anim(part);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!part->do_bind_anim(_control, anim, _hierarchy_match_flags, _subset)) {
|
||||
// Couldn't bind.
|
||||
_control->fail_anim(part);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
70
panda/src/chan/bindAnimRequest.h
Normal file
70
panda/src/chan/bindAnimRequest.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Filename: bindAnimRequest.h
|
||||
// Created by: drose (05Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BINDANIMREQUEST
|
||||
#define BINDANIMREQUEST
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "modelLoadRequest.h"
|
||||
#include "partSubset.h"
|
||||
|
||||
class AnimControl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BindAnimRequest
|
||||
// Description : This class object manages an asynchronous
|
||||
// load-and-bind animation request, as issued through
|
||||
// PartBundle::load_bind_anim().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_PGRAPH BindAnimRequest : public ModelLoadRequest {
|
||||
public:
|
||||
ALLOC_DELETED_CHAIN(BindAnimRequest);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE BindAnimRequest(const Filename &filename,
|
||||
const LoaderOptions &options,
|
||||
AnimControl *control,
|
||||
int hierarchy_match_flags,
|
||||
const PartSubset &subset);
|
||||
|
||||
protected:
|
||||
virtual bool do_task();
|
||||
|
||||
private:
|
||||
PT(AnimControl) _control;
|
||||
int _hierarchy_match_flags;
|
||||
PartSubset _subset;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
ModelLoadRequest::init_type();
|
||||
register_type(_type_handle, "BindAnimRequest",
|
||||
ModelLoadRequest::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "bindAnimRequest.I"
|
||||
|
||||
#endif
|
@ -1,3 +1,5 @@
|
||||
#include "animPreloadTable.cxx"
|
||||
#include "bindAnimRequest.cxx"
|
||||
#include "config_chan.cxx"
|
||||
#include "movingPartBase.cxx"
|
||||
#include "movingPartMatrix.cxx"
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include "animChannelScalarDynamic.h"
|
||||
#include "animControl.h"
|
||||
#include "animGroup.h"
|
||||
#include "animPreloadTable.h"
|
||||
#include "bindAnimRequest.h"
|
||||
#include "movingPartBase.h"
|
||||
#include "movingPartMatrix.h"
|
||||
#include "movingPartScalar.h"
|
||||
@ -86,6 +88,13 @@ PRC_DESC("Set this true to interpolate character animations between frames, "
|
||||
"also be changed on a per-character basis with "
|
||||
"PartBundle::set_frame_blend_flag()."));
|
||||
|
||||
ConfigVariableBool restore_initial_pose
|
||||
("restore-initial-pose", true,
|
||||
PRC_DESC("When this is true, stopping all animations on an Actor causes it "
|
||||
"to return to its initial, unanimated pose. When false, it retains "
|
||||
"whatever its last-computed pose was (which may or may not be "
|
||||
"the unanimated pose)."));
|
||||
|
||||
|
||||
ConfigureFn(config_chan) {
|
||||
AnimBundle::init_type();
|
||||
@ -98,6 +107,8 @@ ConfigureFn(config_chan) {
|
||||
AnimChannelScalarDynamic::init_type();
|
||||
AnimControl::init_type();
|
||||
AnimGroup::init_type();
|
||||
AnimPreloadTable::init_type();
|
||||
BindAnimRequest::init_type();
|
||||
MovingPartBase::init_type();
|
||||
MovingPartMatrix::init_type();
|
||||
MovingPartScalar::init_type();
|
||||
@ -125,6 +136,7 @@ ConfigureFn(config_chan) {
|
||||
AnimChannelMatrixDynamic::register_with_read_factory();
|
||||
AnimChannelScalarTable::register_with_read_factory();
|
||||
AnimChannelScalarDynamic::register_with_read_factory();
|
||||
AnimPreloadTable::register_with_read_factory();
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,5 +27,6 @@ EXPCL_PANDA_CHAN extern ConfigVariableBool compress_channels;
|
||||
EXPCL_PANDA_CHAN extern ConfigVariableInt compress_chan_quality;
|
||||
EXPCL_PANDA_CHAN extern ConfigVariableBool read_compressed_channels;
|
||||
EXPCL_PANDA_CHAN extern ConfigVariableBool interpolate_frames;
|
||||
EXPCL_PANDA_CHAN extern ConfigVariableBool restore_initial_pose;
|
||||
|
||||
#endif
|
||||
|
@ -116,8 +116,7 @@ output_value(ostream &out) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class SwitchType>
|
||||
void MovingPart<SwitchType>::
|
||||
write_datagram(BamWriter *manager, Datagram &me)
|
||||
{
|
||||
write_datagram(BamWriter *manager, Datagram &me) {
|
||||
MovingPartBase::write_datagram(manager, me);
|
||||
SwitchType::write_datagram(me, _value);
|
||||
SwitchType::write_datagram(me, _initial_value);
|
||||
@ -133,8 +132,7 @@ write_datagram(BamWriter *manager, Datagram &me)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class SwitchType>
|
||||
void MovingPart<SwitchType>::
|
||||
fillin(DatagramIterator& scan, BamReader* manager)
|
||||
{
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
MovingPartBase::fillin(scan, manager);
|
||||
SwitchType::read_datagram(scan, _value);
|
||||
SwitchType::read_datagram(scan, _initial_value);
|
||||
|
@ -143,9 +143,12 @@ do_update(PartBundle *root, const CycleData *root_cdata, PartGroup *parent,
|
||||
!needs_update && bci != cdata->_blend.end();
|
||||
++bci) {
|
||||
AnimControl *control = (*bci).first;
|
||||
|
||||
AnimChannelBase *channel = NULL;
|
||||
int channel_index = control->get_channel_index();
|
||||
nassertr(channel_index >= 0 && channel_index < (int)_channels.size(), false);
|
||||
AnimChannelBase *channel = _channels[channel_index];
|
||||
if (channel_index >= 0 && channel_index < (int)_channels.size()) {
|
||||
channel = _channels[channel_index];
|
||||
}
|
||||
if (channel != (AnimChannelBase*)NULL) {
|
||||
needs_update = control->channel_has_changed(channel, cdata->_frame_blend_flag);
|
||||
}
|
||||
|
@ -73,18 +73,24 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
if (cdata->_blend.empty()) {
|
||||
// No channel is bound; supply the default value.
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else if (cdata->_blend.size() == 1 && !cdata->_frame_blend_flag) {
|
||||
// A single value, the normal case.
|
||||
AnimControl *control = (*cdata->_blend.begin()).first;
|
||||
|
||||
ChannelType *channel = NULL;
|
||||
int channel_index = control->get_channel_index();
|
||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
if (channel_index >= 0 && channel_index < (int)_channels.size()) {
|
||||
channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
}
|
||||
if (channel == (ChannelType *)NULL) {
|
||||
// Nothing is actually bound here.
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
channel->get_value(control->get_frame(), _value);
|
||||
@ -131,7 +137,9 @@ get_blend_value(const PartBundle *root) {
|
||||
}
|
||||
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
} else {
|
||||
_value /= net;
|
||||
}
|
||||
@ -157,9 +165,11 @@ get_blend_value(const PartBundle *root) {
|
||||
float effect = (*cbi).second;
|
||||
nassertv(effect != 0.0f);
|
||||
|
||||
ChannelType *channel = NULL;
|
||||
int channel_index = control->get_channel_index();
|
||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
if (channel_index >= 0 && channel_index < (int)_channels.size()) {
|
||||
channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
}
|
||||
if (channel != (ChannelType *)NULL) {
|
||||
int frame = control->get_frame();
|
||||
ValueType v;
|
||||
@ -195,7 +205,9 @@ get_blend_value(const PartBundle *root) {
|
||||
}
|
||||
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
_value /= net;
|
||||
@ -226,9 +238,11 @@ get_blend_value(const PartBundle *root) {
|
||||
float effect = (*cbi).second;
|
||||
nassertv(effect != 0.0f);
|
||||
|
||||
ChannelType *channel = NULL;
|
||||
int channel_index = control->get_channel_index();
|
||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
if (channel_index >= 0 && channel_index < (int)_channels.size()) {
|
||||
channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
}
|
||||
if (channel != (ChannelType *)NULL) {
|
||||
int frame = control->get_frame();
|
||||
LVecBase3f iscale, ihpr, ipos, ishear;
|
||||
@ -270,7 +284,9 @@ get_blend_value(const PartBundle *root) {
|
||||
}
|
||||
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
scale /= net;
|
||||
@ -299,9 +315,11 @@ get_blend_value(const PartBundle *root) {
|
||||
float effect = (*cbi).second;
|
||||
nassertv(effect != 0.0f);
|
||||
|
||||
ChannelType *channel = NULL;
|
||||
int channel_index = control->get_channel_index();
|
||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
if (channel_index >= 0 && channel_index < (int)_channels.size()) {
|
||||
channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
}
|
||||
if (channel != (ChannelType *)NULL) {
|
||||
int frame = control->get_frame();
|
||||
LVecBase3f iscale, ipos, ishear;
|
||||
@ -345,7 +363,9 @@ get_blend_value(const PartBundle *root) {
|
||||
}
|
||||
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
scale /= net;
|
||||
|
@ -58,18 +58,24 @@ get_blend_value(const PartBundle *root) {
|
||||
|
||||
if (cdata->_blend.empty()) {
|
||||
// No channel is bound; supply the default value.
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else if (cdata->_blend.size() == 1 && !cdata->_frame_blend_flag) {
|
||||
// A single value, the normal case.
|
||||
AnimControl *control = (*cdata->_blend.begin()).first;
|
||||
|
||||
ChannelType *channel = NULL;
|
||||
int channel_index = control->get_channel_index();
|
||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
if (channel_index >= 0 && channel_index < (int)_channels.size()) {
|
||||
channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
}
|
||||
if (channel == NULL) {
|
||||
// Nothing is actually bound here.
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
channel->get_value(control->get_frame(), _value);
|
||||
@ -86,9 +92,11 @@ get_blend_value(const PartBundle *root) {
|
||||
float effect = (*cbi).second;
|
||||
nassertv(effect != 0.0f);
|
||||
|
||||
ChannelType *channel = NULL;
|
||||
int channel_index = control->get_channel_index();
|
||||
nassertv(channel_index >= 0 && channel_index < (int)_channels.size());
|
||||
ChannelType *channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
if (channel_index >= 0 && channel_index < (int)_channels.size()) {
|
||||
channel = DCAST(ChannelType, _channels[channel_index]);
|
||||
}
|
||||
if (channel != NULL) {
|
||||
ValueType v;
|
||||
channel->get_value(control->get_frame(), v);
|
||||
@ -109,7 +117,9 @@ get_blend_value(const PartBundle *root) {
|
||||
}
|
||||
|
||||
if (net == 0.0f) {
|
||||
_value = _initial_value;
|
||||
if (restore_initial_pose) {
|
||||
_value = _initial_value;
|
||||
}
|
||||
|
||||
} else {
|
||||
_value /= net;
|
||||
|
@ -13,6 +13,52 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::get_anim_preload
|
||||
// Access: Published
|
||||
// Description: Returns the AnimPreloadTable associated with
|
||||
// the PartBundle. This table, if present, can be used
|
||||
// for the benefit of load_bind_anim() to allow
|
||||
// asynchronous binding.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(AnimPreloadTable) PartBundle::
|
||||
get_anim_preload() const {
|
||||
return _anim_preload.get_read_pointer();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::modify_anim_preload
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the AnimPreloadTable
|
||||
// associated with the PartBundle, if any.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(AnimPreloadTable) PartBundle::
|
||||
modify_anim_preload() {
|
||||
return _anim_preload.get_write_pointer();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::set_anim_preload
|
||||
// Access: Published
|
||||
// Description: Replaces the AnimPreloadTable associated with
|
||||
// the PartBundle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PartBundle::
|
||||
set_anim_preload(AnimPreloadTable *anim_preload) {
|
||||
_anim_preload = anim_preload;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::clear_anim_preload
|
||||
// Access: Published
|
||||
// Description: Removes any AnimPreloadTable associated with
|
||||
// the PartBundle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PartBundle::
|
||||
clear_anim_preload() {
|
||||
_anim_preload = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::set_blend_type
|
||||
// Access: Published
|
||||
|
@ -15,7 +15,10 @@
|
||||
|
||||
#include "partBundle.h"
|
||||
#include "animBundle.h"
|
||||
#include "animBundleNode.h"
|
||||
#include "animControl.h"
|
||||
#include "loader.h"
|
||||
#include "animPreloadTable.h"
|
||||
#include "config_chan.h"
|
||||
#include "bitArray.h"
|
||||
#include "string_utils.h"
|
||||
@ -25,6 +28,7 @@
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "configVariableEnum.h"
|
||||
#include "loaderOptions.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -49,6 +53,8 @@ PartBundle::
|
||||
PartBundle(const PartBundle ©) :
|
||||
PartGroup(copy)
|
||||
{
|
||||
_anim_preload = copy._anim_preload;
|
||||
|
||||
CDWriter cdata(_cycler, true);
|
||||
CDReader cdata_from(copy._cycler);
|
||||
cdata->_blend_type = cdata_from->_blend_type;
|
||||
@ -81,6 +87,30 @@ make_copy() const {
|
||||
return new PartBundle(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::merge_anim_preloads
|
||||
// Access: Published
|
||||
// Description: Copies the contents of the other PartBundle's preload
|
||||
// table into this one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PartBundle::
|
||||
merge_anim_preloads(const PartBundle *other) {
|
||||
if (other->_anim_preload == (AnimPreloadTable *)NULL ||
|
||||
_anim_preload == other->_anim_preload) {
|
||||
// No-op.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_anim_preload == (AnimPreloadTable *)NULL) {
|
||||
// Trivial case.
|
||||
_anim_preload = other->_anim_preload;
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy-on-write.
|
||||
PT(AnimPreloadTable) anim_preload = _anim_preload.get_write_pointer();
|
||||
anim_preload->add_anims_from(other->_anim_preload.get_read_pointer());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::set_anim_blend_flag
|
||||
@ -239,45 +269,95 @@ write(ostream &out, int indent_level) const {
|
||||
PT(AnimControl) PartBundle::
|
||||
bind_anim(AnimBundle *anim, int hierarchy_match_flags,
|
||||
const PartSubset &subset) {
|
||||
nassertr(Thread::get_current_pipeline_stage() == 0, NULL);
|
||||
PT(AnimControl) control = new AnimControl(anim->get_name(), this, 1.0f, 0);
|
||||
if (do_bind_anim(control, anim, hierarchy_match_flags, subset)) {
|
||||
return control;
|
||||
}
|
||||
|
||||
// Make sure this pointer doesn't destruct during the lifetime of this
|
||||
// method.
|
||||
PT(AnimBundle) ptanim = anim;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((hierarchy_match_flags & HMF_ok_wrong_root_name) == 0) {
|
||||
// Make sure the root names match.
|
||||
if (get_name() != ptanim->get_name()) {
|
||||
if (chan_cat.is_error()) {
|
||||
chan_cat.error()
|
||||
<< "Root name of part (" << get_name()
|
||||
<< ") does not match that of anim (" << ptanim->get_name()
|
||||
<< ")\n";
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::load_bind_anim
|
||||
// Access: Published
|
||||
// Description: Binds an animation to the bundle. The animation is
|
||||
// loaded from the disk via the indicated Loader object.
|
||||
// In other respects, this behaves similarly to
|
||||
// bind_anim(), with the addition of asynchronous
|
||||
// support.
|
||||
//
|
||||
// If allow_aysnc is true, the load will be asynchronous
|
||||
// if possible. This requires that the animation
|
||||
// basename can be found in the PartBundle's preload
|
||||
// table (see get_anim_preload()).
|
||||
//
|
||||
// In an asynchronous load, the animation file will be
|
||||
// loaded and bound in a sub-thread. This means that
|
||||
// the animation will not necessarily be available at
|
||||
// the time this method returns. You may still use the
|
||||
// returned AnimControl immediately, though, but no
|
||||
// visible effect will occur until the animation
|
||||
// eventually becomes available.
|
||||
//
|
||||
// You can test AnimControl::is_pending() to see if the
|
||||
// animation has been loaded yet. You can also set an
|
||||
// event to be triggered when the animation finishes
|
||||
// loading with AnimControl::set_pending_done_event().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(AnimControl) PartBundle::
|
||||
load_bind_anim(Loader *loader, const Filename &filename,
|
||||
int hierarchy_match_flags, const PartSubset &subset,
|
||||
bool allow_async) {
|
||||
nassertr(loader != (Loader *)NULL, NULL);
|
||||
|
||||
LoaderOptions anim_options(LoaderOptions::LF_search |
|
||||
LoaderOptions::LF_report_errors |
|
||||
LoaderOptions::LF_convert_anim);
|
||||
string basename = filename.get_basename_wo_extension();
|
||||
|
||||
int anim_index = -1;
|
||||
CPT(AnimPreloadTable) anim_preload = _anim_preload.get_read_pointer();
|
||||
if (anim_preload != (AnimPreloadTable *)NULL) {
|
||||
anim_index = anim_preload->find_anim(basename);
|
||||
}
|
||||
|
||||
if (anim_index < 0 || !allow_async) {
|
||||
// The animation is not present in the table, or allow_async is
|
||||
// false. Therefore, perform an ordinary synchronous
|
||||
// load-and-bind.
|
||||
|
||||
PT(PandaNode) model = loader->load_sync(filename, anim_options);
|
||||
if (model == (PandaNode *)NULL) {
|
||||
// Couldn't load the file.
|
||||
return NULL;
|
||||
}
|
||||
AnimBundle *anim = AnimBundleNode::find_anim_bundle(model);
|
||||
if (anim == (AnimBundle *)NULL) {
|
||||
// No anim bundle.
|
||||
return NULL;
|
||||
}
|
||||
PT(AnimControl) control = bind_anim(anim, hierarchy_match_flags, subset);
|
||||
if (control == (AnimControl *)NULL) {
|
||||
// Couldn't bind.
|
||||
return NULL;
|
||||
}
|
||||
control->set_anim_model(model);
|
||||
return control;
|
||||
}
|
||||
|
||||
if (!check_hierarchy(anim, NULL, hierarchy_match_flags)) {
|
||||
return NULL;
|
||||
}
|
||||
// The animation is present in the table, so we can perform an
|
||||
// asynchronous load-and-bind.
|
||||
float frame_rate = anim_preload->get_base_frame_rate(anim_index);
|
||||
int num_frames = anim_preload->get_num_frames(anim_index);
|
||||
PT(AnimControl) control =
|
||||
new AnimControl(basename, this, frame_rate, num_frames);
|
||||
|
||||
plist<int> holes;
|
||||
int channel_index = 0;
|
||||
pick_channel_index(holes, channel_index);
|
||||
PT(BindAnimRequest) request =
|
||||
new BindAnimRequest(filename, anim_options, control,
|
||||
hierarchy_match_flags, subset);
|
||||
loader->load_async(request);
|
||||
|
||||
if (!holes.empty()) {
|
||||
channel_index = holes.front();
|
||||
}
|
||||
|
||||
int joint_index = 0;
|
||||
BitArray bound_joints;
|
||||
if (subset.is_include_empty()) {
|
||||
bound_joints = BitArray::all_on();
|
||||
}
|
||||
bind_hierarchy(ptanim, channel_index, joint_index,
|
||||
subset.is_include_empty(), bound_joints, subset);
|
||||
return new AnimControl(this, anim, channel_index, bound_joints);
|
||||
return control;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -440,6 +520,59 @@ control_activated(AnimControl *control) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::do_bind_anim
|
||||
// Access: Public
|
||||
// Description: The internal implementation of bind_anim(), this
|
||||
// receives a pointer to an uninitialized AnimControl
|
||||
// and fills it in if the bind is successful. Returns
|
||||
// true if successful, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PartBundle::
|
||||
do_bind_anim(AnimControl *control, AnimBundle *anim,
|
||||
int hierarchy_match_flags, const PartSubset &subset) {
|
||||
nassertr(Thread::get_current_pipeline_stage() == 0, false);
|
||||
|
||||
// Make sure this pointer doesn't destruct during the lifetime of this
|
||||
// method.
|
||||
PT(AnimBundle) ptanim = anim;
|
||||
|
||||
if ((hierarchy_match_flags & HMF_ok_wrong_root_name) == 0) {
|
||||
// Make sure the root names match.
|
||||
if (get_name() != ptanim->get_name()) {
|
||||
if (chan_cat.is_error()) {
|
||||
chan_cat.error()
|
||||
<< "Root name of part (" << get_name()
|
||||
<< ") does not match that of anim (" << ptanim->get_name()
|
||||
<< ")\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check_hierarchy(anim, NULL, hierarchy_match_flags)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
plist<int> holes;
|
||||
int channel_index = 0;
|
||||
pick_channel_index(holes, channel_index);
|
||||
|
||||
if (!holes.empty()) {
|
||||
channel_index = holes.front();
|
||||
}
|
||||
|
||||
int joint_index = 0;
|
||||
BitArray bound_joints;
|
||||
if (subset.is_include_empty()) {
|
||||
bound_joints = BitArray::all_on();
|
||||
}
|
||||
bind_hierarchy(ptanim, channel_index, joint_index,
|
||||
subset.is_include_empty(), bound_joints, subset);
|
||||
control->setup_anim(this, anim, channel_index, bound_joints);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::add_node
|
||||
// Access: Protected, Virtual
|
||||
@ -604,9 +737,26 @@ finalize(BamReader *) {
|
||||
void PartBundle::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
PartGroup::write_datagram(manager, dg);
|
||||
manager->write_pointer(dg, _anim_preload.get_read_pointer());
|
||||
manager->write_cdata(dg, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::complete_pointers
|
||||
// Access: Public
|
||||
// Description: Takes in a vector of pointers to TypedWritable
|
||||
// objects that correspond to all the requests for
|
||||
// pointers that this object made to BamReader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PartBundle::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = PartGroup::complete_pointers(p_list, manager);
|
||||
|
||||
_anim_preload = DCAST(AnimPreloadTable, p_list[pi++]);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PartBundle::make_from_bam
|
||||
// Access: Protected
|
||||
@ -634,7 +784,9 @@ make_from_bam(const FactoryParams ¶ms) {
|
||||
void PartBundle::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
PartGroup::fillin(scan, manager);
|
||||
|
||||
if (manager->get_file_minor_ver() >= 16) {
|
||||
manager->read_pointer(scan); // _anim_preload
|
||||
}
|
||||
if (manager->get_file_minor_ver() >= 10) {
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "partGroup.h"
|
||||
#include "animControl.h"
|
||||
#include "partSubset.h"
|
||||
#include "animPreloadTable.h"
|
||||
#include "pointerTo.h"
|
||||
#include "thread.h"
|
||||
#include "cycleData.h"
|
||||
@ -30,11 +31,14 @@
|
||||
#include "pvector.h"
|
||||
#include "transformState.h"
|
||||
#include "weakPointerTo.h"
|
||||
#include "copyOnWritePointer.h"
|
||||
|
||||
class Loader;
|
||||
class AnimBundle;
|
||||
class PartBundleNode;
|
||||
class PartBundleNode;
|
||||
class TransformState;
|
||||
class AnimPreloadTable;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PartBundle
|
||||
@ -58,6 +62,11 @@ public:
|
||||
virtual PartGroup *make_copy() const;
|
||||
|
||||
PUBLISHED:
|
||||
INLINE CPT(AnimPreloadTable) get_anim_preload() const;
|
||||
INLINE PT(AnimPreloadTable) modify_anim_preload();
|
||||
INLINE void set_anim_preload(AnimPreloadTable *table);
|
||||
INLINE void clear_anim_preload();
|
||||
void merge_anim_preloads(const PartBundle *other);
|
||||
|
||||
// This is the parameter to set_blend_type() and specifies the kind
|
||||
// of blending operation to be performed when multiple controls are
|
||||
@ -119,6 +128,11 @@ PUBLISHED:
|
||||
PT(AnimControl) bind_anim(AnimBundle *anim,
|
||||
int hierarchy_match_flags = 0,
|
||||
const PartSubset &subset = PartSubset());
|
||||
PT(AnimControl) load_bind_anim(Loader *loader,
|
||||
const Filename &filename,
|
||||
int hierarchy_match_flags,
|
||||
const PartSubset &subset,
|
||||
bool allow_async);
|
||||
|
||||
bool freeze_joint(const string &joint_name, const TransformState *transform);
|
||||
bool control_joint(const string &joint_name, PandaNode *node);
|
||||
@ -133,6 +147,9 @@ public:
|
||||
// bunch of friends.
|
||||
virtual void control_activated(AnimControl *control);
|
||||
|
||||
bool do_bind_anim(AnimControl *control, AnimBundle *anim,
|
||||
int hierarchy_match_flags, const PartSubset &subset);
|
||||
|
||||
protected:
|
||||
virtual void add_node(PartBundleNode *node);
|
||||
virtual void remove_node(PartBundleNode *node);
|
||||
@ -145,6 +162,8 @@ private:
|
||||
void recompute_net_blend(CData *cdata);
|
||||
void clear_and_stop_intersecting(AnimControl *control, CData *cdata);
|
||||
|
||||
COWPT(AnimPreloadTable) _anim_preload;
|
||||
|
||||
typedef pvector<PartBundleNode *> Nodes;
|
||||
Nodes _nodes;
|
||||
|
||||
@ -183,6 +202,8 @@ public:
|
||||
static void register_with_read_factory();
|
||||
virtual void finalize(BamReader *manager);
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **p_list,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
@ -253,6 +253,7 @@ sort_descendants() {
|
||||
bool PartGroup::
|
||||
check_hierarchy(const AnimGroup *anim, const PartGroup *,
|
||||
int hierarchy_match_flags) const {
|
||||
Thread::consider_yield();
|
||||
if (anim->get_value_type() != get_value_type()) {
|
||||
if (chan_cat.is_error()) {
|
||||
chan_cat.error()
|
||||
@ -507,6 +508,7 @@ void PartGroup::
|
||||
bind_hierarchy(AnimGroup *anim, int channel_index, int &joint_index,
|
||||
bool is_included, BitArray &bound_joints,
|
||||
const PartSubset &subset) {
|
||||
Thread::consider_yield();
|
||||
if (subset.matches_include(get_name())) {
|
||||
is_included = true;
|
||||
} else if (subset.matches_exclude(get_name())) {
|
||||
|
@ -281,7 +281,11 @@ merge_bundles(PartBundle *old_bundle, PartBundle *new_bundle) {
|
||||
void Character::
|
||||
merge_bundles(PartBundleHandle *old_bundle_handle,
|
||||
PartBundleHandle *new_bundle_handle) {
|
||||
update_bundle(old_bundle_handle, new_bundle_handle->get_bundle());
|
||||
PartBundle *old_bundle = old_bundle_handle->get_bundle();
|
||||
PartBundle *new_bundle = new_bundle_handle->get_bundle();
|
||||
new_bundle->merge_anim_preloads(old_bundle);
|
||||
|
||||
update_bundle(old_bundle_handle, new_bundle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -12,7 +12,9 @@
|
||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||
|
||||
#define SOURCES \
|
||||
config_egg.h eggAnimData.I eggAnimData.h eggAttributes.I \
|
||||
config_egg.h eggAnimData.I eggAnimData.h \
|
||||
eggAnimPreload.I eggAnimPreload.h \
|
||||
eggAttributes.I \
|
||||
eggAttributes.h eggBin.h eggBinMaker.h eggComment.I \
|
||||
eggComment.h \
|
||||
eggCompositePrimitive.I eggCompositePrimitive.h \
|
||||
@ -54,7 +56,9 @@
|
||||
vector_PT_EggTexture.h pt_EggVertex.h vector_PT_EggVertex.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_egg.cxx eggAnimData.cxx eggAttributes.cxx eggBin.cxx \
|
||||
config_egg.cxx eggAnimData.cxx \
|
||||
eggAnimPreload.cxx \
|
||||
eggAttributes.cxx eggBin.cxx \
|
||||
eggBinMaker.cxx eggComment.cxx \
|
||||
eggCompositePrimitive.cxx \
|
||||
eggCoordinateSystem.cxx \
|
||||
@ -85,6 +89,7 @@
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
eggAnimData.I eggAnimData.h \
|
||||
eggAnimPreload.I eggAnimPreload.h \
|
||||
eggAttributes.I eggAttributes.h eggBin.h eggBinMaker.h eggComment.I \
|
||||
eggComment.h \
|
||||
eggCompositePrimitive.I eggCompositePrimitive.h \
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "config_egg.h"
|
||||
#include "eggRenderMode.h"
|
||||
#include "eggAnimData.h"
|
||||
#include "eggAnimPreload.h"
|
||||
#include "eggAttributes.h"
|
||||
#include "eggBin.h"
|
||||
#include "eggBinMaker.h"
|
||||
@ -166,6 +167,7 @@ init_libegg() {
|
||||
|
||||
EggRenderMode::init_type();
|
||||
EggAnimData::init_type();
|
||||
EggAnimPreload::init_type();
|
||||
EggAttributes::init_type();
|
||||
EggBin::init_type();
|
||||
EggBinMaker::init_type();
|
||||
|
145
panda/src/egg/eggAnimPreload.I
Normal file
145
panda/src/egg/eggAnimPreload.I
Normal file
@ -0,0 +1,145 @@
|
||||
// Filename: eggAnimPreload.I
|
||||
// Created by: drose (06Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggAnimPreload::
|
||||
EggAnimPreload(const string &name) : EggNode(name) {
|
||||
_has_fps = false;
|
||||
_has_num_frames = false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::Copy constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggAnimPreload::
|
||||
EggAnimPreload(const EggAnimPreload ©) :
|
||||
EggNode(copy),
|
||||
_fps(copy._fps),
|
||||
_has_fps(copy._has_fps),
|
||||
_num_frames(copy._num_frames),
|
||||
_has_num_frames(copy._has_num_frames)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::Copy assignment operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggAnimPreload &EggAnimPreload::
|
||||
operator = (const EggAnimPreload ©) {
|
||||
EggNode::operator = (copy);
|
||||
_fps = copy._fps;
|
||||
_has_fps = copy._has_fps;
|
||||
_num_frames = copy._num_frames;
|
||||
_has_num_frames = copy._has_num_frames;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::set_fps
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAnimPreload::
|
||||
set_fps(double fps) {
|
||||
_fps = fps;
|
||||
_has_fps = true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::clear_fps
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAnimPreload::
|
||||
clear_fps() {
|
||||
_has_fps = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::has_fps
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggAnimPreload::
|
||||
has_fps() const {
|
||||
return _has_fps;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::get_fps
|
||||
// Access: Public
|
||||
// Description: This is only valid if has_fps() returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double EggAnimPreload::
|
||||
get_fps() const {
|
||||
nassertr(has_fps(), 0.0);
|
||||
return _fps;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::set_num_frames
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAnimPreload::
|
||||
set_num_frames(int num_frames) {
|
||||
_num_frames = num_frames;
|
||||
_has_num_frames = true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::clear_num_frames
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAnimPreload::
|
||||
clear_num_frames() {
|
||||
_has_num_frames = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::has_num_frames
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggAnimPreload::
|
||||
has_num_frames() const {
|
||||
return _has_num_frames;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::get_num_frames
|
||||
// Access: Public
|
||||
// Description: This is only valid if has_num_frames() returns true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int EggAnimPreload::
|
||||
get_num_frames() const {
|
||||
nassertr(has_num_frames(), 0);
|
||||
return _num_frames;
|
||||
}
|
45
panda/src/egg/eggAnimPreload.cxx
Normal file
45
panda/src/egg/eggAnimPreload.cxx
Normal file
@ -0,0 +1,45 @@
|
||||
// Filename: eggAnimPreload.cxx
|
||||
// Created by: drose (06Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggAnimPreload.h"
|
||||
|
||||
#include "string_utils.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle EggAnimPreload::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAnimPreload::write
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the table and all of its children to the
|
||||
// indicated output stream in Egg format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggAnimPreload::
|
||||
write(ostream &out, int indent_level) const {
|
||||
test_under_integrity();
|
||||
|
||||
write_header(out, indent_level, "<AnimPreload>");
|
||||
|
||||
if (has_fps()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> fps { " << get_fps() << " }\n";
|
||||
}
|
||||
|
||||
if (has_num_frames()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> frames { " << get_num_frames() << " }\n";
|
||||
}
|
||||
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
71
panda/src/egg/eggAnimPreload.h
Normal file
71
panda/src/egg/eggAnimPreload.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Filename: eggAnimPreload.h
|
||||
// Created by: drose (06Aug08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGANIMPRELOAD_H
|
||||
#define EGGANIMPRELOAD_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eggNode.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggAnimPreload
|
||||
// Description : This corresponds to an <AnimPreload> entry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG EggAnimPreload : public EggNode {
|
||||
PUBLISHED:
|
||||
INLINE EggAnimPreload(const string &name = "");
|
||||
INLINE EggAnimPreload(const EggAnimPreload ©);
|
||||
INLINE EggAnimPreload &operator = (const EggAnimPreload ©);
|
||||
|
||||
INLINE void set_fps(double fps);
|
||||
INLINE void clear_fps();
|
||||
INLINE bool has_fps() const;
|
||||
INLINE double get_fps() const;
|
||||
|
||||
INLINE void set_num_frames(int num_frames);
|
||||
INLINE void clear_num_frames();
|
||||
INLINE bool has_num_frames() const;
|
||||
INLINE int get_num_frames() const;
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
double _fps;
|
||||
bool _has_fps;
|
||||
int _num_frames;
|
||||
bool _has_num_frames;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
EggNode::init_type();
|
||||
register_type(_type_handle, "EggAnimPreload",
|
||||
EggNode::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "eggAnimPreload.I"
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "config_egg.cxx"
|
||||
#include "eggAnimData.cxx"
|
||||
#include "eggAnimPreload.cxx"
|
||||
#include "eggAttributes.cxx"
|
||||
#include "eggBin.cxx"
|
||||
#include "eggBinMaker.cxx"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -339,6 +339,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
||||
|
||||
|
||||
|
||||
"<ANIMPRELOAD>" {
|
||||
accept();
|
||||
return ANIMPRELOAD;
|
||||
}
|
||||
"<BEZIERCURVE>" {
|
||||
accept();
|
||||
return BEZIERCURVE;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,233 +1,92 @@
|
||||
/* A Bison parser, made by GNU Bison 2.3. */
|
||||
#define EGG_NUMBER 257
|
||||
#define EGG_ULONG 258
|
||||
#define EGG_STRING 259
|
||||
#define ANIMPRELOAD 260
|
||||
#define BEZIERCURVE 261
|
||||
#define BFACE 262
|
||||
#define BILLBOARD 263
|
||||
#define BILLBOARDCENTER 264
|
||||
#define BINORMAL 265
|
||||
#define BUNDLE 266
|
||||
#define CLOSED 267
|
||||
#define COLLIDE 268
|
||||
#define COMMENT 269
|
||||
#define COMPONENT 270
|
||||
#define COORDSYSTEM 271
|
||||
#define CV 272
|
||||
#define DART 273
|
||||
#define DNORMAL 274
|
||||
#define DRGBA 275
|
||||
#define DUV 276
|
||||
#define DXYZ 277
|
||||
#define DCS 278
|
||||
#define DISTANCE 279
|
||||
#define DTREF 280
|
||||
#define DYNAMICVERTEXPOOL 281
|
||||
#define EXTERNAL_FILE 282
|
||||
#define FLIGHT 283
|
||||
#define GROUP 284
|
||||
#define HIP 285
|
||||
#define INTANGENT 286
|
||||
#define JOINT 287
|
||||
#define KNOTS 288
|
||||
#define INCLUDE 289
|
||||
#define INSTANCE 290
|
||||
#define LINE 291
|
||||
#define LOOP 292
|
||||
#define MATERIAL 293
|
||||
#define MATRIX3 294
|
||||
#define MATRIX4 295
|
||||
#define MODEL 296
|
||||
#define MREF 297
|
||||
#define NORMAL 298
|
||||
#define NURBSCURVE 299
|
||||
#define NURBSSURFACE 300
|
||||
#define OBJECTTYPE 301
|
||||
#define ORDER 302
|
||||
#define OUTTANGENT 303
|
||||
#define POINTLIGHT 304
|
||||
#define POLYGON 305
|
||||
#define REF 306
|
||||
#define RGBA 307
|
||||
#define ROTATE 308
|
||||
#define ROTX 309
|
||||
#define ROTY 310
|
||||
#define ROTZ 311
|
||||
#define SANIM 312
|
||||
#define SCALAR 313
|
||||
#define SCALE 314
|
||||
#define SEQUENCE 315
|
||||
#define SHADING 316
|
||||
#define SWITCH 317
|
||||
#define SWITCHCONDITION 318
|
||||
#define TABLE 319
|
||||
#define TABLE_V 320
|
||||
#define TAG 321
|
||||
#define TANGENT 322
|
||||
#define TEXLIST 323
|
||||
#define TEXTURE 324
|
||||
#define TLENGTHS 325
|
||||
#define TRANSFORM 326
|
||||
#define TRANSLATE 327
|
||||
#define TREF 328
|
||||
#define TRIANGLEFAN 329
|
||||
#define TRIANGLESTRIP 330
|
||||
#define TRIM 331
|
||||
#define TXT 332
|
||||
#define UKNOTS 333
|
||||
#define UV 334
|
||||
#define VKNOTS 335
|
||||
#define VERTEX 336
|
||||
#define VERTEXANIM 337
|
||||
#define VERTEXPOOL 338
|
||||
#define VERTEXREF 339
|
||||
#define XFMANIM 340
|
||||
#define XFMSANIM 341
|
||||
#define START_EGG 342
|
||||
#define START_GROUP_BODY 343
|
||||
#define START_TEXTURE_BODY 344
|
||||
#define START_PRIMITIVE_BODY 345
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
EGG_NUMBER = 258,
|
||||
EGG_ULONG = 259,
|
||||
EGG_STRING = 260,
|
||||
BEZIERCURVE = 261,
|
||||
BFACE = 262,
|
||||
BILLBOARD = 263,
|
||||
BILLBOARDCENTER = 264,
|
||||
BINORMAL = 265,
|
||||
BUNDLE = 266,
|
||||
CLOSED = 267,
|
||||
COLLIDE = 268,
|
||||
COMMENT = 269,
|
||||
COMPONENT = 270,
|
||||
COORDSYSTEM = 271,
|
||||
CV = 272,
|
||||
DART = 273,
|
||||
DNORMAL = 274,
|
||||
DRGBA = 275,
|
||||
DUV = 276,
|
||||
DXYZ = 277,
|
||||
DCS = 278,
|
||||
DISTANCE = 279,
|
||||
DTREF = 280,
|
||||
DYNAMICVERTEXPOOL = 281,
|
||||
EXTERNAL_FILE = 282,
|
||||
FLIGHT = 283,
|
||||
GROUP = 284,
|
||||
HIP = 285,
|
||||
INTANGENT = 286,
|
||||
JOINT = 287,
|
||||
KNOTS = 288,
|
||||
INCLUDE = 289,
|
||||
INSTANCE = 290,
|
||||
LINE = 291,
|
||||
LOOP = 292,
|
||||
MATERIAL = 293,
|
||||
MATRIX3 = 294,
|
||||
MATRIX4 = 295,
|
||||
MODEL = 296,
|
||||
MREF = 297,
|
||||
NORMAL = 298,
|
||||
NURBSCURVE = 299,
|
||||
NURBSSURFACE = 300,
|
||||
OBJECTTYPE = 301,
|
||||
ORDER = 302,
|
||||
OUTTANGENT = 303,
|
||||
POINTLIGHT = 304,
|
||||
POLYGON = 305,
|
||||
REF = 306,
|
||||
RGBA = 307,
|
||||
ROTATE = 308,
|
||||
ROTX = 309,
|
||||
ROTY = 310,
|
||||
ROTZ = 311,
|
||||
SANIM = 312,
|
||||
SCALAR = 313,
|
||||
SCALE = 314,
|
||||
SEQUENCE = 315,
|
||||
SHADING = 316,
|
||||
SWITCH = 317,
|
||||
SWITCHCONDITION = 318,
|
||||
TABLE = 319,
|
||||
TABLE_V = 320,
|
||||
TAG = 321,
|
||||
TANGENT = 322,
|
||||
TEXLIST = 323,
|
||||
TEXTURE = 324,
|
||||
TLENGTHS = 325,
|
||||
TRANSFORM = 326,
|
||||
TRANSLATE = 327,
|
||||
TREF = 328,
|
||||
TRIANGLEFAN = 329,
|
||||
TRIANGLESTRIP = 330,
|
||||
TRIM = 331,
|
||||
TXT = 332,
|
||||
UKNOTS = 333,
|
||||
UV = 334,
|
||||
VKNOTS = 335,
|
||||
VERTEX = 336,
|
||||
VERTEXANIM = 337,
|
||||
VERTEXPOOL = 338,
|
||||
VERTEXREF = 339,
|
||||
XFMANIM = 340,
|
||||
XFMSANIM = 341,
|
||||
START_EGG = 342,
|
||||
START_GROUP_BODY = 343,
|
||||
START_TEXTURE_BODY = 344,
|
||||
START_PRIMITIVE_BODY = 345
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define EGG_NUMBER 258
|
||||
#define EGG_ULONG 259
|
||||
#define EGG_STRING 260
|
||||
#define BEZIERCURVE 261
|
||||
#define BFACE 262
|
||||
#define BILLBOARD 263
|
||||
#define BILLBOARDCENTER 264
|
||||
#define BINORMAL 265
|
||||
#define BUNDLE 266
|
||||
#define CLOSED 267
|
||||
#define COLLIDE 268
|
||||
#define COMMENT 269
|
||||
#define COMPONENT 270
|
||||
#define COORDSYSTEM 271
|
||||
#define CV 272
|
||||
#define DART 273
|
||||
#define DNORMAL 274
|
||||
#define DRGBA 275
|
||||
#define DUV 276
|
||||
#define DXYZ 277
|
||||
#define DCS 278
|
||||
#define DISTANCE 279
|
||||
#define DTREF 280
|
||||
#define DYNAMICVERTEXPOOL 281
|
||||
#define EXTERNAL_FILE 282
|
||||
#define FLIGHT 283
|
||||
#define GROUP 284
|
||||
#define HIP 285
|
||||
#define INTANGENT 286
|
||||
#define JOINT 287
|
||||
#define KNOTS 288
|
||||
#define INCLUDE 289
|
||||
#define INSTANCE 290
|
||||
#define LINE 291
|
||||
#define LOOP 292
|
||||
#define MATERIAL 293
|
||||
#define MATRIX3 294
|
||||
#define MATRIX4 295
|
||||
#define MODEL 296
|
||||
#define MREF 297
|
||||
#define NORMAL 298
|
||||
#define NURBSCURVE 299
|
||||
#define NURBSSURFACE 300
|
||||
#define OBJECTTYPE 301
|
||||
#define ORDER 302
|
||||
#define OUTTANGENT 303
|
||||
#define POINTLIGHT 304
|
||||
#define POLYGON 305
|
||||
#define REF 306
|
||||
#define RGBA 307
|
||||
#define ROTATE 308
|
||||
#define ROTX 309
|
||||
#define ROTY 310
|
||||
#define ROTZ 311
|
||||
#define SANIM 312
|
||||
#define SCALAR 313
|
||||
#define SCALE 314
|
||||
#define SEQUENCE 315
|
||||
#define SHADING 316
|
||||
#define SWITCH 317
|
||||
#define SWITCHCONDITION 318
|
||||
#define TABLE 319
|
||||
#define TABLE_V 320
|
||||
#define TAG 321
|
||||
#define TANGENT 322
|
||||
#define TEXLIST 323
|
||||
#define TEXTURE 324
|
||||
#define TLENGTHS 325
|
||||
#define TRANSFORM 326
|
||||
#define TRANSLATE 327
|
||||
#define TREF 328
|
||||
#define TRIANGLEFAN 329
|
||||
#define TRIANGLESTRIP 330
|
||||
#define TRIM 331
|
||||
#define TXT 332
|
||||
#define UKNOTS 333
|
||||
#define UV 334
|
||||
#define VKNOTS 335
|
||||
#define VERTEX 336
|
||||
#define VERTEXANIM 337
|
||||
#define VERTEXPOOL 338
|
||||
#define VERTEXREF 339
|
||||
#define XFMANIM 340
|
||||
#define XFMSANIM 341
|
||||
#define START_EGG 342
|
||||
#define START_GROUP_BODY 343
|
||||
#define START_TEXTURE_BODY 344
|
||||
#define START_PRIMITIVE_BODY 345
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef int YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE eggyylval;
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "eggCoordinateSystem.h"
|
||||
#include "eggExternalReference.h"
|
||||
#include "eggData.h"
|
||||
#include "eggAnimPreload.h"
|
||||
#include "pt_EggTexture.h"
|
||||
#include "pt_EggMaterial.h"
|
||||
|
||||
@ -146,6 +147,7 @@ egg_cleanup_parser() {
|
||||
%token <_ulong> EGG_ULONG
|
||||
%token <_string> EGG_STRING
|
||||
|
||||
%token ANIMPRELOAD
|
||||
%token BEZIERCURVE BFACE BILLBOARD BILLBOARDCENTER BINORMAL BUNDLE CLOSED
|
||||
%token COLLIDE COMMENT COMPONENT
|
||||
%token COORDSYSTEM CV DART
|
||||
@ -190,6 +192,7 @@ egg_cleanup_parser() {
|
||||
%type <_egg> nurbs_curve
|
||||
%type <_egg> table
|
||||
%type <_egg> bundle
|
||||
%type <_egg> anim_preload
|
||||
%type <_egg> sanim
|
||||
%type <_egg> xfmanim
|
||||
%type <_egg> xfm_s_anim
|
||||
@ -261,6 +264,7 @@ node:
|
||||
| nurbs_surface
|
||||
| nurbs_curve
|
||||
| table
|
||||
| anim_preload
|
||||
;
|
||||
|
||||
/*
|
||||
@ -2484,7 +2488,6 @@ bundle:
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/*
|
||||
* table_body
|
||||
*
|
||||
@ -2670,6 +2673,52 @@ xfm_s_anim_body:
|
||||
;
|
||||
|
||||
|
||||
/*
|
||||
* anim_preload
|
||||
*
|
||||
* enter:
|
||||
* exit: returns a new EggAnimPreload object.
|
||||
*
|
||||
*/
|
||||
anim_preload:
|
||||
ANIMPRELOAD optional_name
|
||||
{
|
||||
EggAnimPreload *anim_preload = new EggAnimPreload($2);
|
||||
egg_stack.push_back(anim_preload);
|
||||
}
|
||||
'{' anim_preload_body '}'
|
||||
{
|
||||
$$ = egg_stack.back();
|
||||
egg_stack.pop_back();
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/*
|
||||
* anim_preload_body
|
||||
*
|
||||
* enter: TOS is EggAnimPreload.
|
||||
* exit: anim_preload contents have been filled.
|
||||
*
|
||||
*/
|
||||
anim_preload_body:
|
||||
empty
|
||||
| anim_preload_body SCALAR required_name '{' real_or_string '}'
|
||||
{
|
||||
EggAnimPreload *anim_preload = DCAST(EggAnimPreload, egg_stack.back());
|
||||
string name = $3;
|
||||
double value = $<_number>5;
|
||||
|
||||
if (cmp_nocase_uh(name, "fps") == 0) {
|
||||
anim_preload->set_fps(value);
|
||||
} else if (cmp_nocase_uh(name, "frames") == 0) {
|
||||
anim_preload->set_num_frames((int)value);
|
||||
} else {
|
||||
eggyywarning("Unsupported AnimPreload scalar: " + name);
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* integer_list
|
||||
*
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include "characterVertexSlider.h"
|
||||
#include "jointVertexTransform.h"
|
||||
#include "userVertexTransform.h"
|
||||
#include "eggAnimPreload.h"
|
||||
#include "animPreloadTable.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CharacterMaker::Construtor
|
||||
@ -238,6 +240,28 @@ make_bundle() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CharacterMaker::
|
||||
build_joint_hierarchy(EggNode *egg_node, PartGroup *part, int index) {
|
||||
if (egg_node->is_of_type(EggAnimPreload::get_class_type())) {
|
||||
EggAnimPreload *egg_anim_preload = DCAST(EggAnimPreload, egg_node);
|
||||
|
||||
double fps = 24.0;
|
||||
if (egg_anim_preload->has_fps()) {
|
||||
fps = egg_anim_preload->get_fps();
|
||||
}
|
||||
|
||||
int num_frames = 1;
|
||||
if (egg_anim_preload->has_num_frames()) {
|
||||
num_frames = egg_anim_preload->get_num_frames();
|
||||
}
|
||||
|
||||
PT(AnimPreloadTable) anim_preload = _bundle->modify_anim_preload();
|
||||
if (anim_preload == (AnimPreloadTable *)NULL) {
|
||||
anim_preload = new AnimPreloadTable;
|
||||
_bundle->set_anim_preload(anim_preload);
|
||||
}
|
||||
anim_preload->add_anim(egg_node->get_name(), fps, num_frames);
|
||||
return;
|
||||
}
|
||||
|
||||
if (egg_node->is_of_type(EggGroup::get_class_type())) {
|
||||
EggGroup *egg_group = DCAST(EggGroup, egg_node);
|
||||
|
||||
|
@ -45,6 +45,11 @@ EventQueue::
|
||||
void EventQueue::
|
||||
queue_event(CPT_Event event) {
|
||||
nassertv(!event.is_null());
|
||||
if (event->get_name().empty()) {
|
||||
// Never mind.
|
||||
return;
|
||||
}
|
||||
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
_queue.push_back(event);
|
||||
|
@ -53,6 +53,20 @@ throw_event(const string &event_name,
|
||||
EventQueue::get_global_event_queue()->queue_event(event);
|
||||
}
|
||||
|
||||
INLINE void
|
||||
throw_event(const string &event_name,
|
||||
const EventParameter &p1,
|
||||
const EventParameter &p2,
|
||||
const EventParameter &p3,
|
||||
const EventParameter &p4) {
|
||||
Event *event = new Event(event_name);
|
||||
event->add_parameter(p1);
|
||||
event->add_parameter(p2);
|
||||
event->add_parameter(p3);
|
||||
event->add_parameter(p4);
|
||||
EventQueue::get_global_event_queue()->queue_event(event);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
INLINE void
|
||||
|
@ -33,6 +33,11 @@ INLINE void throw_event(const string &event_name,
|
||||
const EventParameter &p1,
|
||||
const EventParameter &p2,
|
||||
const EventParameter &p3);
|
||||
INLINE void throw_event(const string &event_name,
|
||||
const EventParameter &p1,
|
||||
const EventParameter &p2,
|
||||
const EventParameter &p3,
|
||||
const EventParameter &p4);
|
||||
|
||||
#include "eventHandler.h"
|
||||
|
||||
|
@ -278,6 +278,11 @@ compute_billboard(CPT(TransformState) &node_transform,
|
||||
|
||||
CPT(TransformState) rel_transform =
|
||||
net_transform->compose(translate)->invert_compose(camera_transform);
|
||||
if (!rel_transform->has_mat()) {
|
||||
// Never mind.
|
||||
return;
|
||||
}
|
||||
|
||||
const LMatrix4f &rel_mat = rel_transform->get_mat();
|
||||
|
||||
// Determine the look_at point in the camera space.
|
||||
|
@ -49,6 +49,7 @@ static const unsigned short _bam_minor_ver = 16;
|
||||
// Bumped to minor version 14 on 12/19/07 to change default ColorAttrib.
|
||||
// Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort.
|
||||
// Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level.
|
||||
// Bumped to minor version 17 on 8/6/08 to add PartBundle::_anim_preload.
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -540,6 +540,8 @@ read_handle(DatagramIterator &scan) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BamReader::
|
||||
read_pointer(DatagramIterator &scan) {
|
||||
Thread::consider_yield();
|
||||
|
||||
nassertv(_now_creating != _created_objs.end());
|
||||
int requestor_id = (*_now_creating).first;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user