43#include "SkeletalAnimationPlugin.hh"
46#include <ObjectTypes/Skeleton/SkeletonObjectData.hh>
47#include <ObjectTypes/Skeleton/SkinT.hh>
49#include <QInputDialog>
52#include "dialogs/AnimationToolbox.hh"
53#include "dialogs/AddAnimationDialog.hh"
82 return "SkeletalAnimation";
92 return "Plugin to control skeletal animations";
105 QSize size(300, 300);
117 connect(
pToolbox_->sbFPS, SIGNAL(valueChanged (
int )),
this, SLOT(
changeFPS(
int) ) );
124 pToolbox_->pbAddAnimation->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"addAnimation.png") );
125 pToolbox_->pbDeleteAnimation->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"deleteAnimation.png") );
126 pToolbox_->pbEditAnimation->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"editAnimation.png") );
128 pToolbox_->cbMethod->addItem(
"Linear Blend Skinning");
129 pToolbox_->cbMethod->addItem(
"Dual Quaternion Blend Skinning");
135 toolIcon_ =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"skeletalAnimation.png");
245 std::cerr <<
"SkeletalAnimationPlugin::checkObjectSelection : unable to get object! " << std::endl;
274 if(
pToolbox_->cbAnimation->currentText() ==
"Reference Pose") {
276 QMessageBox::warning(0,
"Not editable!",
"You cannot change the reference pose's name!");
280 QString newName = QInputDialog::getText(0, tr(
"Change Animation's Name"), tr(
"New Name:"),
281 QLineEdit::Normal,
pToolbox_->cbAnimation->currentText());
290 if ( baseObject == 0 )
294 if(!skeletonObject)
continue;
296 if(!skeleton)
continue;
299 if(skeleton != 0 && h.
isValid()) {
300 skeleton->
animation(h)->setName(newName.toStdString());
324 if ( baseObject == 0 )
385 for (
unsigned int i=0; i < skeletonData->
skinCount(); i++){
388 int meshId = skeletonData->
skin(i);
397 emit log(
LOGERR, tr(
"Error: Attached skin mesh has no skin-object-data."));
401 BaseSkin* skin =
dynamic_cast< BaseSkin*
> (
object->objectData(OBJECTDATA_SKIN) );
402 skin->deformSkin(_hAni,
method_ );
433 pToolbox_->cbAnimation->setCurrentIndex( 0 );
467 if ( skelObject == 0 )
475 pToolbox_->hsFrame->setRange( 0, pAnimation->frameCount() - 1 );
513 if ( skelObject == 0 )
565 pToolbox_->hsFrame->setSliderPosition(0);
611 setFrame(currentFrame % frameCount);
626 if(_state == Qt::Checked)
664 if ( baseObject == 0 )
707 if ( baseObject == 0 )
715 if(skeletonObj->
objectData(OBJECTDATA_SKELETON) == 0)
717 pToolbox_->pbAttachSkin->setEnabled(
true);
718 pToolbox_->pbClearSkins->setEnabled(
false);
719 pToolbox_->skinningBox->setTitle(tr(
"Attached Skins"));
721 pToolbox_->pbAttachSkin->setEnabled(
true);
722 pToolbox_->pbClearSkins->setEnabled(
true);
725 pToolbox_->skinningBox->setTitle(tr(
"Attached Skins (Currently: %1)").arg(skelData->
skinCount()) );
731 pToolbox_->pbAddAnimation->setEnabled(
true);
732 pToolbox_->cbAnimation->setEnabled(
true);
736 pToolbox_->cbAnimation->addItem(
"Reference Pose");
740 while ( animations ) {
757 pToolbox_->pbAddAnimation->setEnabled(
false);
758 pToolbox_->cbAnimation->setEnabled(
false);
764 pToolbox_->pbAttachSkin->setEnabled(
false);
765 pToolbox_->pbClearSkins->setEnabled(
false);
766 pToolbox_->skinningBox->setTitle(tr(
"Attached Skins"));
779 emit log(
LOGERR, tr(
"Cannot bind mesh. Please select only one skeleton."));
792 emit log(
LOGERR, tr(
"Cannot bind mesh. Please select at least one mesh as target."));
806 emit log(
LOGERR, tr(
"Cannot bind mesh as skin. Mesh is already a skin."));
825 bool hasSkinWeights =
true;
835 baseSkin->attachSkin();
843 _skeletonObj->
target(
true);
844 _skeletonObj->
source(
false);
846 if( !hasSkinWeights ){
849 emit pluginExists(
"skinningplugin", canCompute);
853 msgBox.setText(
"The mesh is not equipped with skin weights.");
854 msgBox.setInformativeText(
"Do you want to compute them automatically?");
855 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
856 msgBox.setDefaultButton(QMessageBox::Yes);
857 int ret = msgBox.exec();
859 if (ret == QMessageBox::Yes)
890 for (
int i=skelData->
skinCount()-1; i >= 0; i--){
892 int meshId = skelData->
skin(i);
912 emit log(
LOGERR, tr(
"Cannot detach skin. Skeleton has no object data."));
926 baseSkin->releaseSkin();
953 emit log(
LOGERR, tr(
"Cannot add animation. Please select only one skeleton."));
958 dialog.animationName->selectAll();
959 dialog.animationName->setFocus();
961 if ( dialog.exec() == QDialog::Accepted ){
962 if ( dialog.animationName->text() ==
"" ){
963 emit log(
LOGERR, tr(
"Cannot add animation with empty name"));
972 emit log(
LOGERR, tr(
"Unable to get object"));
978 if (skeletonObj == 0){
979 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
985 std::string stdName = dialog.animationName->text().toStdString();
987 if ( skeleton->
animation(stdName) != 0 ){
988 emit log(
LOGERR, tr(
"Animation with this name already exists"));
996 for (
unsigned int i=0; i < skeleton->
animation(handle)->frameCount(); i++){
1000 for (
unsigned int j=0; j < skeleton->
jointCount(); j++)
1015 int iAnimation =
pToolbox_->cbAnimation->currentIndex();
1016 unsigned int animationIndex =
pToolbox_->cbAnimation->itemData(iAnimation).toUInt();
1018 if ( iAnimation == 0 ) {
1019 emit log(
LOGERR,
"Reference pose could never be removed!");
1021 pToolbox_->cbAnimation->removeItem(iAnimation);
1045 int iAnimation =
pToolbox_->cbAnimation->currentIndex();
1046 unsigned int animationId =
pToolbox_->cbAnimation->itemData(iAnimation).toUInt();
1050 else if(iAnimation > 0)
1063 for (
int i = 0 ; i <
pToolbox_->cbAnimation->count(); ++i ) {
1064 unsigned int animationId =
pToolbox_->cbAnimation->itemData(i).toUInt();
1066 if ( animationId == _animationIndex ) {
1067 pToolbox_->cbAnimation->setCurrentIndex(i);
#define DATA_TRIANGLE_MESH
A handle used to refer to an animation or to a specific frame in an animation.
bool isValid() const
Returns true if the handle is valid.
size_t frame() const
Returns the selected frame (zero based)
void setFrame(size_t _iFrame)
Sets the current animation frame (not failsafe)
size_t animationIndex() const
Returns the animation index (zero based)
Stores a single animation.
void setObjectData(QString _dataName, PerObjectData *_data)
PerObjectData * objectData(QString _dataName)
Returns the object data pointer.
bool dataType(DataType _type) const
bool hasObjectData(QString _dataName)
Checks if object data with given name is available.
void clearObjectData(QString _dataName)
Clear the object data pointer ( this will not delete the object!! )
Abstract base class for the skin template, wrapping all template versions of the skin.
int skeletonId()
Holds the associated skeleton.
Helper Class for UpdateUI. assigns a bool value and set it to "true". after leaving the scope,...
A general pose, used to store the frames of the animation.
const Matrix & globalMatrix(unsigned int _joint) const
Returns the global matrix for the given joint.
void setGlobalMatrix(unsigned int _joint, const Matrix &_global, bool _keepGlobalChildPositions=true)
Sets the global coordinate system.
void exit()
Plugin gets closed.
bool bGuiUpdating_
Used to drop a few messages while the gui is being updated.
void slotAddAnimation()
Returns the number of frames in the currently active animation.
void playAnimation()
Called by the ui and starts an automatic animation.
int getFrame()
Gets the current frame number.
int animationOffset_
This frame was selected as the animation was started.
std::vector< int > activeSkeletons_
A pointer to the toolbox widget.
void slotObjectUpdated(int _id, const UpdateType &_type)
Check activePose if a skeleton was updated.
QString name()
returns the plugin name
void stopAnimation()
Called by the ui and stops the current animation.
void setFrame(int _iFrame)
Displays the given frame from the current animation and updates the view.
void pauseAnimation()
Called by the ui and stops the current animation.
void addedEmptyObject(int _id)
Update ui when the object is added.
QElapsedTimer animationTime_
Time since the animation was started, used to meet the given fps.
void slotAttachSkin()
Called by Qt as the user is trying to connect a mesh to a skeleton.
void slotSkipFramesChanged(int _state)
Called as the skip frames check box changes state.
void initializePlugin()
initialize the plugin
bool clearSkins(int skeletonId)
Returns the number of frames in the currently active animation.
void UpdateUI()
Called when the active object changes and the interface needs to be updated.
void pluginsInitialized()
final initializations
void slotAnimationNameChanged()
Returns the number of frames in the currently active animation.
void setDescriptions()
Returns the number of frames in the currently active animation.
void slotMethodChanged(int _index)
Called as the skin deformation method changed.
void slotDeleteAnimation()
Returns the number of frames in the currently active animation.
void slotAllCleared()
clear all occurred
void slotObjectSelectionChanged(int _id)
Update ui when the object selection changes.
void UpdateSkins(BaseObjectData *_pSkeletonObject, AnimationHandle &_hAni)
Changes the mesh's pose to represent the frame given by the animation handle.
void setComboBoxPosition(unsigned int _animationIndex)
Sets the animations combo box to the right entry.
void checkObjectSelection(const int _objectId)
Check source/target selection of objects.
void slotClearSkins()
Called by Qt as the user is trying to unbind a mesh from as a skeleton.
void prevFrame()
Called by the ui and goes to previous frame of the current animation.
~SkeletalAnimationPlugin()
Returns the number of frames in the currently active animation.
SkeletalAnimationPlugin()
Constructor.
Blending::Method method_
The current blending method for the skin.
void changeFPS(int _fps)
Change the frames per second (FPS)
void fileOpened(int _id)
Update ui when the object is loaded.
void animate()
Iterates the animation.
AnimationHandle currentAnimationHandle()
Returns a handle describing the current frame in the active animation.
void objectDeleted(int _id)
Update ui when the object is deleted.
bool detachSkin(int skeletonId, int skinId)
Returns the number of frames in the currently active animation.
bool attachSkin(int skeletonId, int skinId)
Returns the number of frames in the currently active animation.
QTimer animationTimer_
Timer used to control animations.
QString description()
returns a plugin description
AnimationToolboxWidget * pToolbox_
A pointer to the toolbox widget.
void nextFrame()
Called by the ui and goes to next frame of the current animation.
void slotAnimationIndexChanged(int)
Called by the framework when the animation index changed.
void slotFrameChanged(int)
Called by the framework when a different frame was selected.
QIcon * toolIcon_
A pointer to the toolbox widget.
int getNumberOfFrames()
Returns the number of frames in the currently active animation.
Data object attached to the skeleton.
unsigned int skinCount()
Get the number of associated skins.
void removeSkin(int _objectId)
Remove a skin from the skeleton.
int skin(unsigned int _index)
Get the skin with given index (0 <= _index < skinCount())
void addSkin(int _objectId)
Add a skin to the skeleton.
AnimationHandle activePose()
Returns true if the picked node given by _node_idx is this objects scenegraph node.
ACG::SceneGraph::SkeletonNodeT< Skeleton > * skeletonNode()
Returns the skeleton scenegraph node.
void setActivePose(const AnimationHandle &_hAni)
Call this to set the active pose.
Iterator class for the animations attached to a skeleton.
Pose * referencePose()
Returns a pointer to the reference pose.
size_t jointCount()
Returns the number of joints.
AnimationHandle addAnimation(std::string _name, Animation *_animation)
Adds a new animation to the list.
AnimationHandle animationHandle(std::string _name)
Get an AnimationHandle to the animation with the given name.
Animation * animation(std::string _name)
Returns a pointer to the animation to the given name.
void replaceAnimationName(const std::string &_strOld, const std::string &_strNew)
Returns a pointer to the pose with the given animation handle.
void removeAnimation(std::string _name)
Removes an animation from the list.
Pose * pose(const AnimationHandle &_hAni)
Returns a pointer to the pose with the given animation handle.
const std::string & animationName(size_t _index)
Returns the name of the animation with the given index.
AnimationIterator animationsBegin()
Iterator over the animations.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
SkeletonObject * skeletonObject(BaseObjectData *_object)
Cast an BaseObject to a SkeletonObject if possible.
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
Skeleton * skeleton(BaseObjectData *_object)
Get a skeleton from an object.
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
const QStringList TARGET_OBJECTS("target")
Iterable object range.
const QStringList ALL_OBJECTS
Iterable object range.
void callFunction(QString _plugin, QString _functionName)
call a function in another plugin