Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SkeletalAnimationPlugin.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50 #include <QInputDialog>
51 #include <QMessageBox>
52
53 #include "SkeletalAnimationPlugin.hh"
54 #include <ObjectTypes/Skeleton/SkeletonObjectData.hh>
55 #include <ObjectTypes/Skeleton/SkinT.hh>
56
57 #include "AddAnimationDialog.hh"
58
59 using namespace std;
60
61 //------------------------------------------------------------------------------
62
66 SkeletalAnimationPlugin::SkeletalAnimationPlugin() :
67 pToolbox_(0),
68 toolIcon_(0),
69 bGuiUpdating_(false),
70 animationOffset_(0)
71 {
72 }
73
74 //------------------------------------------------------------------------------
75
79 QString SkeletalAnimationPlugin::name()
80 {
81 return "SkeletalAnimation";
82 }
83
84 //------------------------------------------------------------------------------
85
89 QString SkeletalAnimationPlugin::description()
90 {
91 return "Plugin to control skeletal animations";
92 }
93
94 //------------------------------------------------------------------------------
95
99 void SkeletalAnimationPlugin::initializePlugin()
100 {
101 bGuiUpdating_ = false;
102
103 pToolbox_ = new AnimationToolboxWidget();
104 QSize size(300, 300);
105 pToolbox_->resize(size);
106
107 connect( pToolbox_->pbAttachSkin, SIGNAL(clicked()), this, SLOT(slotAttachSkin()) );
108 connect( pToolbox_->pbClearSkins, SIGNAL(clicked()), this, SLOT(slotClearSkins()) );
109
110 connect( pToolbox_->cbAnimation, SIGNAL(currentIndexChanged(int)), this, SLOT(slotAnimationIndexChanged(int)) );
111 connect( pToolbox_->hsFrame, SIGNAL(valueChanged(int)), this, SLOT(slotFrameChanged(int)) );
112 connect( pToolbox_->pbPlay, SIGNAL(clicked()), this, SLOT( playAnimation() ) );
113 connect( pToolbox_->pbStop, SIGNAL(clicked()), this, SLOT( stopAnimation() ) );
114 connect( pToolbox_->pbPrevFrame, SIGNAL(clicked()), this, SLOT( prevFrame() ) );
115 connect( pToolbox_->pbNextFrame, SIGNAL(clicked()), this, SLOT( nextFrame() ) );
116 connect( pToolbox_->sbFPS, SIGNAL(valueChanged ( int )), this, SLOT( changeFPS(int) ) );
117 connect( pToolbox_->cbSkipFrames, SIGNAL(stateChanged(int)), this, SLOT(slotSkipFramesChanged(int)) );
118 connect( pToolbox_->pbAddAnimation, SIGNAL(clicked()), this, SLOT(slotAddAnimation()) );
119 connect( pToolbox_->pbDeleteAnimation, SIGNAL(clicked()), this, SLOT(slotDeleteAnimation()) );
120
121 connect( pToolbox_->pbEditAnimation, SIGNAL(clicked()), this, SLOT(slotAnimationNameChanged()));
122
123 pToolbox_->pbAddAnimation->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"addAnimation.png") );
124 pToolbox_->pbDeleteAnimation->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"deleteAnimation.png") );
125 pToolbox_->pbEditAnimation->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"editAnimation.png") );
126
127 pToolbox_->cbMethod->addItem("Linear Blend Skinning");
128 pToolbox_->cbMethod->addItem("Dual Quaternion Blend Skinning");
129
130 pToolbox_->cbMethod->setCurrentIndex(0);
131 connect( pToolbox_->cbMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(slotMethodChanged(int)) );
132 method_ = BaseSkin::M_LBS;
133
134 toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"skeletalAnimation.png");
135 emit addToolbox( tr("Skeletal Animation") , pToolbox_, toolIcon_ );
136 }
137
138 //------------------------------------------------------------------------------
139
143 void SkeletalAnimationPlugin::pluginsInitialized()
144 {
145 emit setDescriptions();
146 }
147
148 //------------------------------------------------------------------------------
149
153 void SkeletalAnimationPlugin::exit()
154 {
155 }
156
157 //------------------------------------------------------------------------------
158
162 void SkeletalAnimationPlugin::slotAllCleared()
163 {
164 activeSkeletons_.clear();
165
166 slotAnimationIndexChanged(0);
167 }
168
169 //------------------------------------------------------------------------------
170
174 void SkeletalAnimationPlugin::slotObjectSelectionChanged(int _id)
175 {
176 checkObjectSelection(_id);
177 }
178
179 //------------------------------------------------------------------------------
180
184 void SkeletalAnimationPlugin::fileOpened( int _id) {
185 checkObjectSelection(_id);
186 }
187
188 //------------------------------------------------------------------------------
189
193 void SkeletalAnimationPlugin::addedEmptyObject(int _id) {
194
195 checkObjectSelection(_id);
196 }
197
198 //------------------------------------------------------------------------------
199
203 void SkeletalAnimationPlugin::objectDeleted(int _id) {
204
205 checkObjectSelection(_id);
206
207 // Check for skin that is to be cleared
208 BaseObjectData* bod = 0;
209 if (!PluginFunctions::getObject(_id, bod)) {
210 return;
211 }
212
213 if (bod->hasObjectData(OBJECTDATA_SKIN)) {
214
215 BaseSkin* baseSkin = 0;
216
217 if (bod->dataType(DATA_TRIANGLE_MESH))
218 baseSkin = dynamic_cast<BaseSkin*> (bod->objectData(OBJECTDATA_SKIN));
219 else if (bod->dataType(DATA_POLY_MESH))
220 baseSkin = dynamic_cast<BaseSkin*> (bod->objectData(OBJECTDATA_SKIN));
221
222 if (baseSkin) {
223 BaseObjectData* skeletonObj = PluginFunctions::skeletonObject(baseSkin->skeletonId());
224
225 if(skeletonObj) {
226 // Detach skin from skeleton
227 detachSkin(bod, skeletonObj);
228 }
229 }
230 }
231 }
232
233 //------------------------------------------------------------------------------
234
238 void SkeletalAnimationPlugin::checkObjectSelection(const int _objectId){
239
240 BaseObject* object;
241 PluginFunctions::getObject(_objectId,object);
242
243 if ( !object ) {
244 std::cerr << "SkeletalAnimationPlugin::checkObjectSelection : unable to get object! " << std::endl;
245 return;
246 }
247
248 if ( object->dataType() == DataType(DATA_SKELETON) ) {
249 activeSkeletons_.clear();
250
251 // get target skeletons
252 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS, DataType(DATA_SKELETON)) ; o_it != PluginFunctions::objectsEnd(); ++o_it)
253 activeSkeletons_.push_back( o_it->id() );
254
255 // if no target skeleton there check if there is only one skeleton
256 if ( activeSkeletons_.empty() ){
257 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DataType(DATA_SKELETON)) ; o_it != PluginFunctions::objectsEnd(); ++o_it)
258 activeSkeletons_.push_back( o_it->id() );
259
260 if (activeSkeletons_.size() != 1)
261 activeSkeletons_.clear();
262 }
263
264 }
265
266 UpdateUI();
267 }
268
269 //------------------------------------------------------------------------------
270
271 void SkeletalAnimationPlugin::slotAnimationNameChanged() {
272
273 if(pToolbox_->cbAnimation->currentText() == "Reference Pose") {
274
275 QMessageBox::warning(0, "Not editable!", "You cannot change the reference pose's name!");
276 return;
277 }
278
279 QString newName = QInputDialog::getText(0, tr("Change Animation's Name"), tr("New Name:"),
280 QLineEdit::Normal, pToolbox_->cbAnimation->currentText());
281
282 // Set animation's name
283 for (unsigned int i=0; i < activeSkeletons_.size(); i++){
284
285 // Get active skeleton
286 BaseObjectData* baseObject = 0;
287 PluginFunctions::getObject(activeSkeletons_[i], baseObject);
288
289 if ( baseObject == 0 )
290 continue;
291
292 SkeletonObject* skeletonObject = dynamic_cast<SkeletonObject*>(baseObject);
293 if(!skeletonObject) continue;
294 Skeleton* skeleton = PluginFunctions::skeleton(skeletonObject);
295 if(!skeleton) continue;
296
297 AnimationHandle h = skeleton->animationHandle(pToolbox_->cbAnimation->currentText().toStdString());
298 if(skeleton != 0 && h.isValid()) {
299 skeleton->animation(h)->setName(newName.toStdString());
300 skeleton->replaceAnimationName(pToolbox_->cbAnimation->currentText().toStdString(), newName.toStdString());
301 } else {
302 return;
303 }
304 }
305
306 pToolbox_->cbAnimation->setItemText(pToolbox_->cbAnimation->currentIndex(), newName);
307 }
308
309 //------------------------------------------------------------------------------
310
314 int SkeletalAnimationPlugin::getNumberOfFrames()
315 {
316
317 for (unsigned int i=0; i < activeSkeletons_.size(); i++){
318
319 //get active skeleton
320 BaseObjectData* baseObject = 0;
321 PluginFunctions::getObject(activeSkeletons_[i], baseObject);
322
323 if ( baseObject == 0 )
324 continue;
325
326 SkeletonObject* skeletonObject = dynamic_cast<SkeletonObject*>(baseObject);
327 Skeleton* skeleton = PluginFunctions::skeleton(skeletonObject);
328
329 if(skeleton != 0 && skeleton->animation( currentAnimationHandle() ) != 0)
330 return skeleton->animation( currentAnimationHandle() )->frameCount();
331 }
332
333 return 0;
334 }
335
336 //------------------------------------------------------------------------------
337
341 void SkeletalAnimationPlugin::setFrame(int _iFrame)
342 {
343 pToolbox_->hsFrame->setValue(_iFrame);
344 }
345
346 //------------------------------------------------------------------------------
347
351 int SkeletalAnimationPlugin::getFrame() {
352 return pToolbox_->hsFrame->value();
353 }
354
355 //------------------------------------------------------------------------------
356
360 void SkeletalAnimationPlugin::changeFPS(int _fps) {
361 pToolbox_->sbFPS->blockSignals(true);
362 pToolbox_->sbFPS->setValue(_fps);
363 pToolbox_->sbFPS->blockSignals(false);
364
365 animationTimer_.setInterval(1000/_fps);
366 }
367
368 //------------------------------------------------------------------------------
369
376 void SkeletalAnimationPlugin::UpdateSkins(BaseObjectData *_skeletonObject, AnimationHandle &_hAni)
377 {
378
379 if( !_skeletonObject->hasObjectData(OBJECTDATA_SKELETON) )
380 return;
381
382 SkeletonObjectData* skeletonData = dynamic_cast< SkeletonObjectData* >( _skeletonObject->objectData(OBJECTDATA_SKELETON) );
383
384 for (unsigned int i=0; i < skeletonData->skinCount(); i++){
385
386 // deform all attached skin meshes
387 int meshId = skeletonData->skin(i);
388
389 BaseObjectData* object = 0;
390 PluginFunctions::getObject(meshId, object);
391
392 if (object == 0)
393 continue;
394
395 if ( !object->hasObjectData(OBJECTDATA_SKIN) ){
396 emit log(LOGERR, tr("Error: Attached skin mesh has no skin-object-data."));
397 continue;
398 }
399
400 BaseSkin* skin = dynamic_cast< BaseSkin* > ( object->objectData(OBJECTDATA_SKIN) );
401 skin->deformSkin(_hAni, method_ );
402
403 emit updatedObject(object->id(), UPDATE_GEOMETRY);
404 }
405 }
406
407 //------------------------------------------------------------------------------
408
412 void SkeletalAnimationPlugin::slotObjectUpdated( int _id, const UpdateType& /*_type*/ )
413 {
414 // do nothing during animation
415 if ( animationTimer_.isActive() )
416 return;
417
418 BaseObjectData* obj = 0;
419
420 PluginFunctions::getObject(_id, obj);
421
422 if ( (obj != 0) && (obj->dataType(DATA_SKELETON)) ){
423
424 SkeletonObject* sObj = PluginFunctions::skeletonObject(obj);
425
426 //check if pose changed
427 if ( sObj->activePose() != currentAnimationHandle() ){
428
429 AnimationHandle newHandle = sObj->activePose();
430
431 if ( !newHandle.isValid() ) //refPose
432 pToolbox_->cbAnimation->setCurrentIndex( 0 );
433 else
434 setComboBoxPosition(newHandle.animationIndex());
435 }
436
437 //check if animationCount changed
438 if ( (int)PluginFunctions::skeleton(sObj)->animationCount() != pToolbox_->cbAnimation->count()-1 )
439 UpdateUI();
440 }
441 }
442
443 //------------------------------------------------------------------------------
444
448 void SkeletalAnimationPlugin::slotAnimationIndexChanged(int /*_index*/)
449 {
450 if(bGuiUpdating_) // do not update while the gui is updating
451 return;
452
453 if ( activeSkeletons_.empty() ){
454 pToolbox_->hsFrame->setRange( 0, 0 );
455 pToolbox_->hsFrame->setTickInterval(1);
456 pToolbox_->hsFrame->setValue(0);
457
458 pToolbox_->cbAnimation->clear();
459
460 } else {
461
462 //get first active skeleton
463 BaseObjectData* skelObject = 0;
464 PluginFunctions::getObject(activeSkeletons_[0], skelObject);
465
466 if ( skelObject == 0 )
467 return;
468
469 Skeleton* skeleton = PluginFunctions::skeleton(skelObject);
470
471 // equip the frame slider with the new range
472 AnimationT<ACG::Vec3d> *pAnimation = skeleton->animation(currentAnimationHandle());
473 if(pAnimation != 0){
474 pToolbox_->hsFrame->setRange( 0, pAnimation->frameCount() - 1 );
475 changeFPS( pAnimation->fps() );
476 }else
477 pToolbox_->hsFrame->setRange( 0, 0 );
478
479 pToolbox_->hsFrame->setTickInterval(1);
480 pToolbox_->hsFrame->setValue(0);
481
482 // pass the current frame
483 AnimationHandle hAni = currentAnimationHandle();
484 dynamic_cast<SkeletonObject*>(skelObject)->setActivePose(hAni);
485
486 emit updatedObject(skelObject->id(), UPDATE_GEOMETRY);
487
488 // update skins if available
489 UpdateSkins(skelObject, hAni);
490
491 slotFrameChanged(0);
492 }
493 }
494
495 //------------------------------------------------------------------------------
496
500 void SkeletalAnimationPlugin::slotFrameChanged(int /*_index*/)
501 {
502 // do not update while the gui is updating
503 if(bGuiUpdating_)
504 return;
505
506 for (unsigned int i=0; i < activeSkeletons_.size(); i++){
507
508 //get active skeleton
509 BaseObjectData* skelObject = 0;
510 PluginFunctions::getObject(activeSkeletons_[i], skelObject);
511
512 if ( skelObject == 0 )
513 return;
514
515 // pass the current frame
516 AnimationHandle hAni = currentAnimationHandle();
517 PluginFunctions::skeletonObject(skelObject)->setActivePose(hAni);
518
519 // and update the skin if available
520 UpdateSkins(skelObject, hAni);
521
522 emit updatedObject(skelObject->id(), UPDATE_GEOMETRY);
523 }
524 }
525
526 //------------------------------------------------------------------------------
527
531 void SkeletalAnimationPlugin::playAnimation() {
532 disconnect(&animationTimer_, 0, 0, 0);
533 animationTimer_.stop();
534 animationTimer_.setSingleShot(false);
535 animationTimer_.setInterval(1000 / pToolbox_->sbFPS->value());
536 connect(&animationTimer_,SIGNAL(timeout()),this,SLOT(animate()));
537 animationTimer_.start();
538 animationTime_.start();
539 animationOffset_ = pToolbox_->hsFrame->value();
540
541 //The Play button will just toggle between play and pause mode
542 connect( pToolbox_->pbPlay, SIGNAL(clicked()), this, SLOT( pauseAnimation() ) );
543 }
544
545 //------------------------------------------------------------------------------
546
550 void SkeletalAnimationPlugin::pauseAnimation() {
551 animationTimer_.stop();
552 disconnect(&animationTimer_, 0, 0, 0);
553
554 connect( pToolbox_->pbPlay, SIGNAL(clicked()), this, SLOT( playAnimation() ) );
555 }
556
557 //------------------------------------------------------------------------------
558
562 void SkeletalAnimationPlugin::stopAnimation() {
563 pauseAnimation();
564 pToolbox_->hsFrame->setSliderPosition(0); //Reset the playback
565 }
566
567 //------------------------------------------------------------------------------
568
572 void SkeletalAnimationPlugin::prevFrame() {
573 pauseAnimation();
574 pToolbox_->hsFrame->setSliderPosition(pToolbox_->hsFrame->sliderPosition() - 1);
575 }
576
577 //------------------------------------------------------------------------------
578
582 void SkeletalAnimationPlugin::nextFrame() {
583 pauseAnimation();
584 pToolbox_->hsFrame->setSliderPosition(pToolbox_->hsFrame->sliderPosition() + 1);
585 }
586
587 //------------------------------------------------------------------------------
588
595 void SkeletalAnimationPlugin::animate()
596 {
597 unsigned long frameCount = getNumberOfFrames();
598 if(frameCount <= 1) // 0: invalid animation, 1: just a pose
599 {
600 setFrame(0);
601 stopAnimation();
602 return;
603 }
604 --frameCount;
605
606 if(pToolbox_->cbSkipFrames->isChecked())
607 {
608 int fps = pToolbox_->sbFPS->value();
609 unsigned long currentFrame = animationOffset_ + (unsigned long)floor(double(animationTime_.elapsed()) / 1000.0 * fps);
610 setFrame(currentFrame % frameCount);
611 }else{
612 setFrame((getFrame() + 1) % frameCount);
613 }
614 }
615
616 //------------------------------------------------------------------------------
617
623 void SkeletalAnimationPlugin::slotSkipFramesChanged(int _state)
624 {
625 if(_state == Qt::Checked)
626 {
627 // changing to skip frames as necessary
628 animationTime_.start();
629 animationOffset_ = pToolbox_->hsFrame->value();
630 }else{
631 // changing to display all frames
632 }
633 }
634
635 //------------------------------------------------------------------------------
636
642 void SkeletalAnimationPlugin::slotMethodChanged(int _index)
643 {
644 // change the method
645 switch(_index)
646 {
647 case 0:
648 method_ = BaseSkin::M_LBS;
649 break;
650 default:
651 case 1:
652 method_ = BaseSkin::M_DBS;
653 break;
654 }
655
656 // deform the skin(s) using the new method
657 for (unsigned int i=0; i < activeSkeletons_.size(); i++){
658
659 //get active skeleton
660 BaseObjectData* baseObject = 0;
661 PluginFunctions::getObject(activeSkeletons_[i], baseObject);
662
663 if ( baseObject == 0 )
664 return;
665
666 SkeletonObject* skeletonObject = dynamic_cast<SkeletonObject*>(baseObject);
667 AnimationHandle hAni = skeletonObject->skeletonNode()->activePose();
668
669 // and update the skin
670 UpdateSkins(skeletonObject, hAni);
671 }
672
673 emit updateView();
674 }
675
676 //------------------------------------------------------------------------------
677
682 class GuiUpdatingScopeGuard
683 {
684 bool& v_;
685 public:
686 GuiUpdatingScopeGuard(bool &_in):v_(_in){v_ = true;}
687 ~GuiUpdatingScopeGuard(){v_ = false;}
688 };
689
693 void SkeletalAnimationPlugin::UpdateUI()
694 {
695 if(bGuiUpdating_) // gui updates object -> object is updated so gui gets updated -> loop forever
696 return;
697
698 GuiUpdatingScopeGuard guard(bGuiUpdating_);
699
700 if( ! activeSkeletons_.empty() )
701 {
702 //get first active skeleton
703 BaseObjectData* baseObject = 0;
704 PluginFunctions::getObject(activeSkeletons_[0], baseObject);
705
706 if ( baseObject == 0 )
707 return;
708
709 SkeletonObject* skeletonObj = PluginFunctions::skeletonObject(baseObject);
710 Skeleton* skeleton = PluginFunctions::skeleton(baseObject);
711
712 // update the rigging and skinning group
713 // enable UI
714 if(skeletonObj->objectData(OBJECTDATA_SKELETON) == 0)
715 {
716 pToolbox_->pbAttachSkin->setEnabled(true);
717 pToolbox_->pbClearSkins->setEnabled(false);
718 pToolbox_->skinningBox->setTitle(tr("Attached Skins"));
719 }else{
720 pToolbox_->pbAttachSkin->setEnabled(true);
721 pToolbox_->pbClearSkins->setEnabled(true);
722
723 SkeletonObjectData* skelData = dynamic_cast<SkeletonObjectData*>( skeletonObj->objectData(OBJECTDATA_SKELETON) );
724 pToolbox_->skinningBox->setTitle(tr("Attached Skins (Currently: %1)").arg(skelData->skinCount()) );
725 }
726
727 // update the Skeleton group
728 AnimationHandle hAni = skeletonObj->skeletonNode()->activePose();
729
730 pToolbox_->pbAddAnimation->setEnabled(true);
731 pToolbox_->cbAnimation->setEnabled(true);
732 pToolbox_->cbAnimation->clear();
733
734 // create the reference pose
735 pToolbox_->cbAnimation->addItem("Reference Pose");
736
737 Skeleton::AnimationIterator animations = skeleton->animationsBegin();
738
739 while ( animations ) {
740 AnimationHandle anim = *animations;
741 pToolbox_->cbAnimation->addItem(skeleton->animationName(anim.animationIndex()).c_str(),QVariant(anim.animationIndex()));
742 ++animations;
743 }
744
745 setComboBoxPosition(hAni.animationIndex());
746
747 // get the number of frames in the animation
748 pToolbox_->hsFrame->setEnabled(true);
749 if(skeleton->animation(hAni) != 0)
750 pToolbox_->hsFrame->setRange( 0, skeleton->animation(hAni)->frameCount() - 1 );
751 pToolbox_->hsFrame->setTickInterval(1);
752 pToolbox_->hsFrame->setValue(hAni.frame());
753
754 }else{
755 // disable UI
756 pToolbox_->pbAddAnimation->setEnabled(false);
757 pToolbox_->cbAnimation->setEnabled(false);
758 pToolbox_->cbAnimation->clear();
759 pToolbox_->hsFrame->setEnabled(false);
760 pToolbox_->hsFrame->setRange(0, 0);
761 pToolbox_->hsFrame->setTickInterval(1);
762
763 pToolbox_->pbAttachSkin->setEnabled(false);
764 pToolbox_->pbClearSkins->setEnabled(false);
765 pToolbox_->skinningBox->setTitle(tr("Attached Skins"));
766 }
767 }
768
769 //------------------------------------------------------------------------------
770
774 void SkeletalAnimationPlugin::slotAttachSkin()
775 {
776
777 if( activeSkeletons_.size() != 1 ){
778 emit log(LOGERR, tr("Cannot bind mesh. Please select only one skeleton."));
779 return;
780 }
781
782 int meshCount = 0;
783
784 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS, DataType(DATA_TRIANGLE_MESH|DATA_POLY_MESH)) ; o_it != PluginFunctions::objectsEnd(); ++o_it)
785 {
786 attachSkin(activeSkeletons_[0], o_it->id());
787 meshCount++;
788 }
789
790 if (meshCount == 0){
791 emit log(LOGERR, tr("Cannot bind mesh. Please select at least one mesh as target."));
792 return;
793 }
794 }
795
796 //------------------------------------------------------------------------------
797
798 void SkeletalAnimationPlugin::attachSkin(BaseObjectData* _skin, BaseObjectData* _skeletonObj) {
799
800 // get the skeleton and make it prepare the mesh
801 Skeleton* skeleton = dynamic_cast<SkeletonObject*>(_skeletonObj)->skeleton();
802
803 //check if mesh is already a skin
804 if (_skin->hasObjectData(OBJECTDATA_SKIN) ){
805 emit log(LOGERR, tr("Cannot bind mesh as skin. Mesh is already a skin."));
806 return;
807 }
808
809 // prepare the skin template class used to deform the skin
810 SkeletonObjectData* skelData = 0;
811
812 if ( _skeletonObj->hasObjectData(OBJECTDATA_SKELETON) )
813 skelData = dynamic_cast< SkeletonObjectData* >(_skeletonObj->objectData(OBJECTDATA_SKELETON));
814 else {
815 skelData = new SkeletonObjectData();
816 _skeletonObj->setObjectData(OBJECTDATA_SKELETON, skelData);
817 }
818
819 skelData->addSkin( _skin->id() );
820
821 BaseSkin* baseSkin = 0;
822
823 OpenMesh::VPropHandleT<BaseSkin::SkinWeights> propWeights;
824 bool hasSkinWeights = true;
825
826 if(_skin->dataType(DATA_TRIANGLE_MESH)){
827 hasSkinWeights = PluginFunctions::triMesh(_skin)->get_property_handle(propWeights, SKIN_WEIGHTS_PROP);
828 baseSkin = dynamic_cast<BaseSkin*>( new TriMeshSkin(skeleton, PluginFunctions::triMesh(_skin),_skeletonObj->id()) );
829 }else if(_skin->dataType(DATA_POLY_MESH)){
830 hasSkinWeights = PluginFunctions::polyMesh(_skin)->get_property_handle(propWeights, SKIN_WEIGHTS_PROP);
831 baseSkin = dynamic_cast<BaseSkin*>( new PolyMeshSkin(skeleton, PluginFunctions::polyMesh(_skin) ,_skeletonObj->id() ));
832 }
833
834 baseSkin->attachSkin();
835
836 if (hasSkinWeights)
837 baseSkin->deformSkin(currentAnimationHandle(), method_);
838
839 emit updatedObject(_skin->id(), UPDATE_GEOMETRY);
840 _skin->setObjectData(OBJECTDATA_SKIN, baseSkin);
841
842 _skeletonObj->target(true);
843 _skeletonObj->source(false);
844
845 if( !hasSkinWeights ){
846 //ask if they should be computed automatically
847 bool canCompute;
848 emit pluginExists("skinningplugin", canCompute);
849
850 if (canCompute){
851 QMessageBox msgBox;
852 msgBox.setText("The mesh is not equipped with skin weights.");
853 msgBox.setInformativeText("Do you want to compute them automatically?");
854 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
855 msgBox.setDefaultButton(QMessageBox::Yes);
856 int ret = msgBox.exec();
857
858 if (ret == QMessageBox::Yes)
859 RPC::callFunction("skinningplugin", "computeSkinWeights");
860 }
861 }
862
863 UpdateUI();
864 }
865
866 //------------------------------------------------------------------------------
867
871 void SkeletalAnimationPlugin::slotClearSkins()
872 {
873 for (unsigned int i=0; i < activeSkeletons_.size(); i++)
874 clearSkins( activeSkeletons_[i] );
875 }
876
877 //------------------------------------------------------------------------------
878
879 void SkeletalAnimationPlugin::clearSkins(BaseObjectData* _skeletonObj) {
880
881 // prepare the skin template class used to deform the skin
882 SkeletonObjectData* skelData = 0;
883
884 if ( !_skeletonObj->hasObjectData(OBJECTDATA_SKELETON) )
885 return;
886
887 skelData = dynamic_cast< SkeletonObjectData* >(_skeletonObj->objectData(OBJECTDATA_SKELETON));
888
889 for (int i=skelData->skinCount()-1; i >= 0; i--){
890 //deform all attached skin meshes
891 int meshId = skelData->skin(i);
892
893 BaseObjectData* object = 0;
894 PluginFunctions::getObject(meshId, object);
895
896 if (object == 0)
897 continue;
898
899 detachSkin(object, _skeletonObj);
900 }
901 }
902
903 //------------------------------------------------------------------------------
904
905 void SkeletalAnimationPlugin::detachSkin(BaseObjectData* _skin, BaseObjectData* _skeletonObj) {
906
907 // get the skeleton and make it prepare the mesh
908 Skeleton* skeleton = dynamic_cast<SkeletonObject*>(_skeletonObj)->skeleton();
909
910 if ( !_skeletonObj->hasObjectData(OBJECTDATA_SKELETON) ){
911 emit log(LOGERR, tr("Cannot detach skin. Skeleton has no object data."));
912 return;
913 }
914
915 //first try to remove the skin from the mesh
916 if (_skin->hasObjectData(OBJECTDATA_SKIN) ){
917
918 BaseSkin* baseSkin = 0;
919
920 if(_skin->dataType(DATA_TRIANGLE_MESH))
921 baseSkin = dynamic_cast<BaseSkin*>( new TriMeshSkin(skeleton, PluginFunctions::triMesh(_skin) ,_skeletonObj->id()));
922 else if(_skin->dataType(DATA_POLY_MESH))
923 baseSkin = dynamic_cast<BaseSkin*>( new PolyMeshSkin(skeleton, PluginFunctions::polyMesh(_skin) ,_skeletonObj->id()));
924
925 baseSkin->releaseSkin();
926 _skin->clearObjectData(OBJECTDATA_SKIN);
927 delete baseSkin;
928
929 emit updatedObject(_skin->id(), UPDATE_GEOMETRY);
930 }
931
932 // then remove the skin from the skeleton data
933 SkeletonObjectData* skelData = dynamic_cast< SkeletonObjectData* >(_skeletonObj->objectData(OBJECTDATA_SKELETON));
934
935 skelData->removeSkin( _skin->id() );
936
937 //remove the objectData if all skins are removed
938 if ( skelData->skinCount() == 0 ){
939 _skeletonObj->clearObjectData(OBJECTDATA_SKELETON);
940 delete skelData;
941 }
942
943 UpdateUI();
944 }
945
946 //------------------------------------------------------------------------------
947
948 void SkeletalAnimationPlugin::slotAddAnimation()
949 {
950
951 if( activeSkeletons_.size() != 1 ){
952 emit log(LOGERR, tr("Cannot add animation. Please select only one skeleton."));
953 return;
954 }
955
956 AddAnimationDialog dialog;
957 dialog.animationName->selectAll();
958 dialog.animationName->setFocus();
959
960 if ( dialog.exec() == QDialog::Accepted ){
961 if ( dialog.animationName->text() == "" ){
962 emit log(LOGERR, tr("Cannot add animation with empty name"));
963 return;
964 }
965
966 BaseObjectData* obj = 0;
967
968 PluginFunctions::getObject(activeSkeletons_[0], obj);
969
970 if (obj == 0){
971 emit log(LOGERR, tr("Unable to get object"));
972 return;
973 }
974
975 SkeletonObject* skeletonObj = PluginFunctions::skeletonObject(obj);
976
977 if (skeletonObj == 0){
978 emit log(LOGERR, tr("Unable to get skeletonObject"));
979 return;
980 }
981
982 Skeleton* skeleton = PluginFunctions::skeleton(obj);
983
984 std::string stdName = dialog.animationName->text().toStdString();
985
986 if ( skeleton->animation(stdName) != 0 ){
987 emit log(LOGERR, tr("Animation with this name already exists"));
988 return;
989 }
990
991 FrameAnimationT<ACG::Vec3d>* animation = new FrameAnimationT<ACG::Vec3d>(skeleton, dialog.frames->value());
992 AnimationHandle handle = skeleton->addAnimation(stdName, animation);
993
994 //init pose to refPose
995 for (unsigned int i=0; i < skeleton->animation(handle)->frameCount(); i++){
996 handle.setFrame(i);
997 Skeleton::Pose* pose = skeleton->pose(handle);
998
999 for (unsigned int j=0; j < skeleton->jointCount(); j++)
1000 pose->setGlobalMatrix(j, skeleton->referencePose()->globalMatrix(j) );
1001 }
1002
1003 emit updatedObject(activeSkeletons_[0], UPDATE_ALL);
1004
1005 //select the new animation
1006 setComboBoxPosition(handle.animationIndex());
1007 }
1008 }
1009
1010 //------------------------------------------------------------------------------
1011
1012 void SkeletalAnimationPlugin::slotDeleteAnimation()
1013 {
1014 int iAnimation = pToolbox_->cbAnimation->currentIndex();
1015 unsigned int animationIndex = pToolbox_->cbAnimation->itemData(iAnimation).toUInt();
1016
1017 if ( iAnimation == 0 ) {
1018 emit log(LOGERR,"Reference pose could never be removed!");
1019 } else {
1020 pToolbox_->cbAnimation->removeItem(iAnimation);
1021
1022 for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS, DataType(DATA_SKELETON)) ; o_it != PluginFunctions::objectsEnd(); ++o_it) {
1023
1024 SkeletonObject* skeletonObject = dynamic_cast<SkeletonObject*>(*o_it);
1025 Skeleton* skeleton = PluginFunctions::skeleton(skeletonObject);
1026
1027 skeleton->removeAnimation(AnimationHandle(animationIndex));
1028
1029 }
1030
1031 UpdateUI();
1032 }
1033 }
1034
1035 //------------------------------------------------------------------------------
1036
1042 AnimationHandle SkeletalAnimationPlugin::currentAnimationHandle()
1043 {
1044 int iAnimation = pToolbox_->cbAnimation->currentIndex();
1045 unsigned int animationId = pToolbox_->cbAnimation->itemData(iAnimation).toUInt();
1046
1047 if(iAnimation == 0)
1048 return AnimationHandle(); //This will be the reference pose, i.e. an empty animation
1049 else if(iAnimation > 0)
1050 return AnimationHandle(animationId, pToolbox_->hsFrame->value());
1051 return AnimationHandle(); // should not happen
1052 }
1053
1054 //------------------------------------------------------------------------------
1055
1060 void SkeletalAnimationPlugin::setComboBoxPosition(unsigned int _animationIndex)
1061 {
1062 for ( int i = 0 ; i < pToolbox_->cbAnimation->count(); ++i ) {
1063 unsigned int animationId = pToolbox_->cbAnimation->itemData(i).toUInt();
1064
1065 if ( animationId == _animationIndex ) {
1066 pToolbox_->cbAnimation->setCurrentIndex(i);
1067 return;
1068 }
1069
1070 }
1071
1072 }
1073
1074 //------------------------------------------------------------------------------
1075
1076 #if QT_VERSION < 0x050000
1077 Q_EXPORT_PLUGIN2(skeletalAnimationplugin, SkeletalAnimationPlugin);
1078 #endif
1079
1080
SkinT
General skin class, used to bind skeleton and mesh and deform the mesh.
Definition: SkinT.hh:12
AnimationHandle::isValid
bool isValid() const
Returns true if the handle is valid.
Definition: AnimationHandle.hh:64
SkeletalAnimationPlugin::stopAnimation
void stopAnimation()
Called by the ui and stops the current animation.
Definition: SkeletalAnimationPlugin.cc:562
PoseT::setGlobalMatrix
void setGlobalMatrix(unsigned int _joint, const Matrix &_global, bool _keepGlobalChildPositions=true)
Sets the global coordinate system.
Definition: PoseT.cc:217
SkeletalAnimationPlugin::method_
BaseSkin::Method method_
The current blending method for the skin.
Definition: SkeletalAnimationPlugin.hh:189
SkeletalAnimationPlugin::pauseAnimation
void pauseAnimation()
Called by the ui and stops the current animation.
Definition: SkeletalAnimationPlugin.cc:550
PluginFunctions::skeletonObject
SkeletonObject * skeletonObject(BaseObjectData *_object)
Cast an BaseObject to a SkeletonObject if possible.
Definition: PluginFunctionsSkeleton.cc:105
SkeletalAnimationPlugin::description
QString description()
returns a plugin description
Definition: SkeletalAnimationPlugin.cc:89
SkeletalAnimationPlugin::initializePlugin
void initializePlugin()
initialize the plugin
Definition: SkeletalAnimationPlugin.cc:99
PluginFunctions::ALL_OBJECTS
const QStringList ALL_OBJECTS
Iterable object range.
Definition: PluginFunctions.hh:441
UPDATE_GEOMETRY
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
SkeletonObject::setActivePose
void setActivePose(const AnimationHandle &_hAni)
Call this to set the active pose.
Definition: SkeletonObject.cc:288
SkeletalAnimationPlugin::name
QString name()
returns the plugin name
Definition: SkeletalAnimationPlugin.cc:79
BaseObject::objectData
PerObjectData * objectData(QString _dataName)
Returns the object data pointer.
Definition: BaseObject.cc:814
SkeletalAnimationPlugin::objectDeleted
void objectDeleted(int _id)
Update ui when the object is deleted.
Definition: SkeletalAnimationPlugin.cc:203
SkeletalAnimationPlugin::pluginsInitialized
void pluginsInitialized()
final initializations
Definition: SkeletalAnimationPlugin.cc:143
LOGERR
Definition: LoggingInterface.hh:107
BaseObjectData
Definition: BaseObjectData.hh:105
SkeletalAnimationPlugin::slotFrameChanged
void slotFrameChanged(int)
Called by the framework when a different frame was selected.
Definition: SkeletalAnimationPlugin.cc:500
SkeletalAnimationPlugin::slotMethodChanged
void slotMethodChanged(int _index)
Called as the skin deformation method changed.
Definition: SkeletalAnimationPlugin.cc:642
SkeletonT::AnimationIterator
Iterator class for the animations attached to a skeleton.
Definition: SkeletonT.hh:120
SkeletalAnimationPlugin::attachSkin
bool attachSkin(int skeletonId, int skinId)
Returns the number of frames in the currently active animation.
Definition: SkeletalAnimationScripting.cc:66
UpdateType
Update type class.
Definition: UpdateType.hh:70
UPDATE_ALL
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
SkeletalAnimationPlugin::slotObjectUpdated
void slotObjectUpdated(int _id, const UpdateType &_type)
Check activePose if a skeleton was updated.
Definition: SkeletalAnimationPlugin.cc:412
GuiUpdatingScopeGuard
Helper Class for UpdateUI. assigns a bool value and set it to "true". after leaving the scope...
Definition: SkeletalAnimationPlugin.cc:682
PluginFunctions::getObject
bool getObject(int _identifier, BSplineCurveObject *&_object)
Definition: PluginFunctionsBSplineCurve.cc:75
PluginFunctions::polyMesh
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
Definition: PluginFunctionsPolyMesh.cc:134
SkeletalAnimationPlugin::exit
void exit()
Plugin gets closed.
Definition: SkeletalAnimationPlugin.cc:153
SkeletalAnimationPlugin::UpdateSkins
void UpdateSkins(BaseObjectData *_pSkeletonObject, AnimationHandle &_hAni)
Changes the mesh's pose to represent the frame given by the animation handle.
Definition: SkeletalAnimationPlugin.cc:376
SkeletonT::animation
Animation * animation(std::string _name)
Returns a pointer to the animation to the given name.
Definition: SkeletonT.cc:858
SkeletonT::removeAnimation
void removeAnimation(std::string _name)
Removes an animation from the list.
Definition: SkeletonT.cc:886
SkeletonObject
Definition: SkeletonObject.hh:82
SkeletalAnimationPlugin::fileOpened
void fileOpened(int _id)
Update ui when the object is loaded.
Definition: SkeletalAnimationPlugin.cc:184
PoseT
A general pose, used to store the frames of the animation.
Definition: PoseT.hh:68
AnimationHandle::animationIndex
unsigned int animationIndex() const
Returns the animation index (zero based)
Definition: AnimationHandle.hh:66
SkeletalAnimationPlugin::slotObjectSelectionChanged
void slotObjectSelectionChanged(int _id)
Update ui when the object selection changes.
Definition: SkeletalAnimationPlugin.cc:174
BaseSkin
Abstract base class for the skin template, wrapping all template versions of the skin.
Definition: BaseSkin.hh:67
PluginFunctions::TARGET_OBJECTS
const QStringList TARGET_OBJECTS("target")
Iterable object range.
SkeletalAnimationPlugin::nextFrame
void nextFrame()
Called by the ui and goes to next frame of the current animation.
Definition: SkeletalAnimationPlugin.cc:582
BaseObject::dataType
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
SkeletalAnimationPlugin::checkObjectSelection
void checkObjectSelection(const int _objectId)
Check source/target selection of objects.
Definition: SkeletalAnimationPlugin.cc:238
SkeletonT::animationHandle
AnimationHandle animationHandle(std::string _name)
Get an AnimationHandle to the animation with the given name.
Definition: SkeletonT.cc:843
SkeletalAnimationPlugin::animationOffset_
int animationOffset_
This frame was selected as the animation was started.
Definition: SkeletalAnimationPlugin.hh:194
BaseObject::source
bool source()
Definition: BaseObject.cc:302
SkeletonObjectData::removeSkin
void removeSkin(int _objectId)
Remove a skin from the skeleton.
Definition: SkeletonObjectData.hh:116
SkeletalAnimationPlugin::slotAllCleared
void slotAllCleared()
clear all occurred
Definition: SkeletalAnimationPlugin.cc:162
PluginFunctions::triMesh
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
Definition: PluginFunctionsTriangleMesh.cc:140
SkeletalAnimationPlugin::addedEmptyObject
void addedEmptyObject(int _id)
Update ui when the object is added.
Definition: SkeletalAnimationPlugin.cc:193
AnimationToolboxWidget
Definition: AnimationToolbox.hh:59
OpenMesh::VPropHandleT
Definition: Property.hh:487
BaseObject::hasObjectData
bool hasObjectData(QString _dataName)
Checks if object data with given name is available.
Definition: BaseObject.cc:806
SkeletalAnimationPlugin::prevFrame
void prevFrame()
Called by the ui and goes to previous frame of the current animation.
Definition: SkeletalAnimationPlugin.cc:572
BaseObject::setObjectData
void setObjectData(QString _dataName, PerObjectData *_data)
Definition: BaseObject.cc:792
PluginFunctions::ObjectIterator
Core Data Iterator.
Definition: PluginFunctions.hh:452
PluginFunctions::objectsEnd
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Definition: PluginFunctionsIterator.cc:187
SkeletonT::replaceAnimationName
void replaceAnimationName(const std::string &_strOld, const std::string &_strNew)
Returns a pointer to the pose with the given animation handle.
Definition: SkeletonT.hh:196
SkeletonObjectData::skinCount
unsigned int skinCount()
Get the number of associated skins.
Definition: SkeletonObjectData.hh:97
BaseObject
Definition: BaseObject.hh:94
FrameAnimationT::pose
Pose * pose(unsigned int _iFrame)
Returns a pointer to the pose stored in the given frame.
Definition: FrameAnimationT.cc:151
SkeletalAnimationPlugin::slotSkipFramesChanged
void slotSkipFramesChanged(int _state)
Called as the skip frames check box changes state.
Definition: SkeletalAnimationPlugin.cc:623
SkeletonT::animationCount
unsigned int animationCount()
Returns the number of animations stored in this skeleton.
Definition: SkeletonT.cc:971
RPC::callFunction
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
Definition: RPCWrappers.cc:63
SkeletonT
Definition: JointT.hh:56
DATA_POLY_MESH
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
BaseObject::clearObjectData
void clearObjectData(QString _dataName)
Clear the object data pointer ( this will not delete the object!! )
Definition: BaseObject.cc:798
SkeletalAnimationPlugin::setComboBoxPosition
void setComboBoxPosition(unsigned int _animationIndex)
Sets the animations combo box to the right entry.
Definition: SkeletalAnimationPlugin.cc:1060
AnimationHandle::frame
unsigned int frame() const
Returns the selected frame (zero based)
Definition: AnimationHandle.hh:69
AddAnimationDialog
Definition: AddAnimationDialog.hh:59
SkeletalAnimationPlugin::animationTime_
QTime animationTime_
Time since the animation was started, used to meet the given fps.
Definition: SkeletalAnimationPlugin.hh:193
SkeletalAnimationPlugin::getFrame
int getFrame()
Gets the current frame number.
Definition: SkeletalAnimationPlugin.cc:351
SkeletalAnimationPlugin
The skeletal animation plugin is used to interact with the skeleton.
Definition: SkeletalAnimationPlugin.hh:72
SkeletonObjectData::addSkin
void addSkin(int _objectId)
Add a skin to the skeleton.
Definition: SkeletonObjectData.hh:104
SkeletalAnimationPlugin::SkeletalAnimationPlugin
SkeletalAnimationPlugin()
Constructor.
Definition: SkeletalAnimationPlugin.cc:66
SkeletalAnimationPlugin::detachSkin
bool detachSkin(int skeletonId, int skinId)
Returns the number of frames in the currently active animation.
Definition: SkeletalAnimationScripting.cc:84
SkeletalAnimationPlugin::slotAnimationIndexChanged
void slotAnimationIndexChanged(int)
Called by the framework when the animation index changed.
Definition: SkeletalAnimationPlugin.cc:448
OpenMesh::Attributes::Normal
Add normals to mesh item (vertices/faces)
Definition: Attributes.hh:87
SkeletalAnimationPlugin::setFrame
void setFrame(int _iFrame)
Displays the given frame from the current animation and updates the view.
Definition: SkeletalAnimationPlugin.cc:341
AnimationHandle
A handle used to refer to an animation or to a specific frame in an animation.
Definition: AnimationHandle.hh:56
SkeletalAnimationPlugin::currentAnimationHandle
AnimationHandle currentAnimationHandle()
Returns a handle describing the current frame in the active animation.
Definition: SkeletalAnimationPlugin.cc:1042
SkeletalAnimationPlugin::changeFPS
void changeFPS(int _fps)
Change the frames per second (FPS)
Definition: SkeletalAnimationPlugin.cc:360
std
STL namespace.
SkeletonObjectData::skin
int skin(unsigned int _index)
Get the skin with given index (0 <= _index < skinCount())
Definition: SkeletonObjectData.hh:88
SkeletalAnimationPlugin::UpdateUI
void UpdateUI()
Called when the active object changes and the interface needs to be updated.
Definition: SkeletalAnimationPlugin.cc:693
AnimationT< ACG::Vec3d >
DataType
Predefined datatypes.
Definition: DataTypes.hh:96
DATA_SKELETON
#define DATA_SKELETON
Definition: Skeleton.hh:70
SkeletonT::animationName
const std::string & animationName(unsigned int _index)
Returns the name of the animation with the given index.
Definition: SkeletonT.cc:984
SkeletalAnimationPlugin::bGuiUpdating_
bool bGuiUpdating_
Used to drop a few messages while the gui is being updated.
Definition: SkeletalAnimationPlugin.hh:191
BaseObject::target
bool target()
Definition: BaseObject.cc:284
PluginFunctions::skeleton
Skeleton * skeleton(BaseObjectData *_object)
Get a skeleton from an object.
Definition: PluginFunctionsSkeleton.cc:86
DATA_TRIANGLE_MESH
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
SkeletalAnimationPlugin::slotAttachSkin
void slotAttachSkin()
Called by Qt as the user is trying to connect a mesh to a skeleton.
Definition: SkeletalAnimationPlugin.cc:774
SkeletalAnimationPlugin::slotClearSkins
void slotClearSkins()
Called by Qt as the user is trying to unbind a mesh from as a skeleton.
Definition: SkeletalAnimationPlugin.cc:871
SkeletonObject::skeletonNode
ACG::SceneGraph::SkeletonNodeT< Skeleton > * skeletonNode()
Returns the skeleton scenegraph node.
Definition: SkeletonObject.cc:218
SkeletalAnimationPlugin::clearSkins
bool clearSkins(int skeletonId)
Returns the number of frames in the currently active animation.
Definition: SkeletalAnimationScripting.cc:102
SkeletonObjectData
Data object attached to the skeleton.
Definition: SkeletonObjectData.hh:63
FrameAnimationT
Definition: FrameAnimationT.hh:56
SkeletonT::animationsBegin
AnimationIterator animationsBegin()
Iterator over the animations.
Definition: SkeletonT.cc:945
BaseObject::id
int id() const
Definition: BaseObject.cc:201
SkeletalAnimationPlugin::getNumberOfFrames
int getNumberOfFrames()
Returns the number of frames in the currently active animation.
Definition: SkeletalAnimationPlugin.cc:314
SkeletalAnimationPlugin::animate
void animate()
Iterates the animation.
Definition: SkeletalAnimationPlugin.cc:595
SkeletalAnimationPlugin::animationTimer_
QTimer animationTimer_
Timer used to control animations.
Definition: SkeletalAnimationPlugin.hh:192
SkeletalAnimationPlugin::playAnimation
void playAnimation()
Called by the ui and starts an automatic animation.
Definition: SkeletalAnimationPlugin.cc:531
SkeletalAnimationPlugin::pToolbox_
AnimationToolboxWidget * pToolbox_
A pointer to the toolbox widget.
Definition: SkeletalAnimationPlugin.hh:185
FrameAnimationT::frameCount
unsigned int frameCount()
Returns the number of frames stored in this pose.
Definition: FrameAnimationT.cc:161