50 #include "SkeletonEditingPlugin.hh"
53 #include <ObjectTypes/Skeleton/Helper/SkeletonTransform.hh>
54 #include <ACG/Geometry/Algorithms.hh>
63 emit setSlotDescription(
"splitBone(int,int)",
64 tr(
"insert a joint in the middle of a bone."),
65 QString(tr(
"objectId,jointId")).split(
","),
66 QString(tr(
"ID of an object,ID of tail joint")).split(
","));
70 "addJoint(int,int,Vector)",
71 tr(
"add a joint to the skeleton."),
72 QString(tr(
"objectId,jointId,Vector")).split(
","),
75 "ID of an object,ID of parent joint,Position for the new joint")).split(
78 emit setSlotDescription(
"deleteJoint(int,int)",
79 tr(
"delete a joint from the skeleton."),
80 QString(tr(
"objectId,jointId")).split(
","),
81 QString(tr(
"ID of an object,ID of a joint")).split(
","));
83 emit setSlotDescription(
84 "transformJoint(int,int,Matrix4x4)",
85 tr(
"transform a joint with a matrix."),
86 QString(tr(
"objectId,jointId,Matrix")).split(
","),
87 QString(tr(
"ID of an object,ID of a joint,transformation matrix")).split(
90 emit setSlotDescription(
"globalMatrix(int,int)",
91 tr(
"get the global matrix of a joint in the active pose."),
92 QString(tr(
"objectId,jointId")).split(
","),
93 QString(tr(
"ID of an object,ID of a joint")).split(
","));
95 emit setSlotDescription(
"localMatrix(int,int)",
96 tr(
"get the local matrix of a joint in the active pose."),
97 QString(tr(
"objectId,jointId")).split(
","),
98 QString(tr(
"ID of an object,ID of a joint")).split(
","));
100 emit setSlotDescription(
"globalTranslation(int,int)",
101 tr(
"get the global translation of a joint in the active pose."),
102 QString(tr(
"objectId,jointId")).split(
","),
103 QString(tr(
"ID of an object,ID of a joint")).split(
","));
105 emit setSlotDescription(
"localTranslation(int,int)",
106 tr(
"get the local translation of a joint in the active pose."),
107 QString(tr(
"objectId,jointId")).split(
","),
108 QString(tr(
"ID of an object,ID of a joint")).split(
","));
110 emit setSlotDescription(
"animationCount(int)",
111 tr(
"get the number of animations the skeleton has."),
112 QString(tr(
"objectId")).split(
","),
113 QString(tr(
"ID of an object")).split(
","));
115 emit setSlotDescription(
"frameCount(int,int)",
116 tr(
"get the number of frames a given animation has."),
117 QString(tr(
"objectId,animationIndex")).split(
","),
118 QString(tr(
"ID of an object,Index of an animation")).split(
","));
120 emit setSlotDescription(
"activeAnimation(int)",
121 tr(
"get the animation which is currently active."),
122 QString(tr(
"objectId")).split(
","),
123 QString(tr(
"ID of an object")).split(
","));
125 emit setSlotDescription(
"activeFrame(int)",
126 tr(
"get the frame which is currently active"),
127 QString(tr(
"objectId")).split(
","),
128 QString(tr(
"ID of an object")).split(
","));
132 "setActivePose(int,int,int)",
133 tr(
"set the active pose of the skeleton."),
134 QString(tr(
"objectId,animationIndex,frame")).split(
","),
135 QString(tr(
"ID of an object,Index of an animation,Index of a frame")).split(
140 "addAnimation(int,QString,int)",
141 tr(
"add an animation to the skeleton."),
142 QString(tr(
"objectId,AnimationName,frameCount")).split(
","),
145 "ID of an object,name for the animation,number of frames the animation should have")).split(
167 if (tailJoint == 0) {
170 tr(
"Cannot split bone. Unable to find joint with id ")
171 + QString::number(_tailJoint));
179 skeleton->
addJoint(headJoint, jointNew);
180 tailJoint->
setParent(jointNew, *skeleton);
196 if (animation != 0) {
199 for (
int iFrame = 0; iFrame < (int) animation->frameCount(); iFrame++) {
215 emit scriptInfo(
"splitBone( ObjectId, " + QString::number(_tailJoint) +
" )");
243 tr(
"Cannot add joint. Unable to find joint with id ")
244 + QString::number(_parent));
250 skeleton->
addJoint(parent, jointNew);
259 "addJoint( ObjectId, " + QString::number(_parent) +
", Vector("
260 + QString::number(_position[0]) +
"," + QString::number(_position[1])
261 +
"," + QString::number(_position[2]) +
") )");
270 void SkeletonEditingPlugin::deleteJoint(
int _objectId,
int _jointId) {
288 tr(
"Cannot Remove joint. Unable to find joint with id ")
289 + QString::number(_jointId));
295 emit scriptInfo(
"deleteJoint( ObjectId, " + QString::number(_jointId) +
" )");
314 emit log(
LOGERR, tr(
"Unable to get object"));
320 if (skeletonObj == 0) {
321 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
328 emit log(
LOGERR, tr(
"Unable to get skeleton"));
335 emit log(
LOGERR, tr(
"Unable to get joint"));
339 bool recursiveJointTransformation = transformChildJoints_;
353 recursiveJointTransformation =
true;
370 transformer.
rotateJoint(joint, activePose, _matrix, transformAllFrames_);
383 if (_matrix(0, 0) != 1 || _matrix(1, 1) != 1 || _matrix(2, 2) != 1
384 || _matrix(0, 1) != 0 || _matrix(0, 2) != 0 || _matrix(1, 0) != 0
385 || _matrix(1, 2) != 0 || _matrix(2, 0) != 0 || _matrix(2, 1) != 0) {
387 transformer.
transformJoint(joint, _matrix, !recursiveJointTransformation);
391 if (_matrix(0, 3) == 0 && _matrix(1, 3) == 0 && _matrix(2, 3) == 0)
394 if (joint->isRoot()) {
425 bool parentIsNotBranch = (joint->
parent()->
size() == 1);
426 bool hasOneChild = (joint->
size() == 1);
433 double parentRotAngle = 0.0;
434 double jointRotAngle = 0.0;
444 std::vector<ACG::Vec3d> oldAnimJoint, oldAnimParent;
446 for (
unsigned int iFrame = 0; iFrame < skeleton->
animation(a)->frameCount(); iFrame++) {
470 if (!ACG::Geometry::rotationOfTwoVectors<double>(oldParentAxis, transParentAxis, parentRotAxis, parentRotAngle))
475 if (!ACG::Geometry::rotationOfTwoVectors<double>(oldJointAxis, transJointAxis, jointRotAxis, jointRotAngle))
479 if (parentIsNotBranch) {
483 parentRotMatrix.
rotate(parentRotAngle, parentRotAxis);
487 localParent *= parentRotMatrix;
495 jointRotMatrix.
rotate(jointRotAngle, jointRotAxis);
499 localJoint *= jointRotMatrix;
504 std::vector<ACG::Vec3d>::iterator jointIt, parentIt;
505 jointIt = oldAnimJoint.begin();
506 parentIt = oldAnimParent.begin();
508 for (
unsigned int iFrame = 0; iFrame < skeleton->
animation(a)->frameCount(); iFrame++) {
512 if (parentIsNotBranch) {
517 double parentRotAngle = 0.0;
518 if (!ACG::Geometry::rotationOfTwoVectors<double>(*parentIt, translatedParent, parentRotAxis,
525 parentRotMatrix.
rotate(parentRotAngle, parentRotAxis);
529 parentMat *= parentRotMatrix;
539 double jointRotAngle = 0.0;
541 if (!ACG::Geometry::rotationOfTwoVectors<double>(*jointIt, translatedAxis, jointRotAxis, jointRotAngle))
547 jointRotMatrix.
rotate(jointRotAngle, jointRotAxis);
551 localMat *= jointRotMatrix;
565 for (
int i = 0; i < 4; i++)
566 for (
int j = 0; j < 4; j++)
567 matString +=
" , " + QString::number(_matrix(i, j));
569 matString = matString.right(matString.length() - 3);
572 "transformJoint( ObjectId, " + QString::number(_jointId) +
", Matrix4x4("
573 + matString +
" ) )");
591 emit log(
LOGERR, tr(
"Unable to get object"));
597 if (skeletonObj == 0) {
598 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
606 emit log(
LOGERR, tr(
"Unable to get joint"));
621 scriptInfo(
"globalMatrix( ObjectId, " + QString::number(_jointId) +
" )");
635 emit log(
LOGERR, tr(
"Unable to get object"));
641 if (skeletonObj == 0) {
642 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
650 emit log(
LOGERR, tr(
"Unable to get joint"));
664 emit scriptInfo(
"localMatrix( ObjectId, " + QString::number(_jointId) +
" )");
678 emit log(
LOGERR, tr(
"Unable to get object"));
684 if (skeletonObj == 0) {
685 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
693 emit log(
LOGERR, tr(
"Unable to get joint"));
708 "globalTranslation( ObjectId, " + QString::number(_jointId) +
" )");
722 emit log(
LOGERR, tr(
"Unable to get object"));
728 if (skeletonObj == 0) {
729 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
737 emit log(
LOGERR, tr(
"Unable to get joint"));
752 "localTranslation( ObjectId, " + QString::number(_jointId) +
" )");
766 emit log(
LOGERR, tr(
"Unable to get object"));
772 if (skeletonObj == 0) {
773 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
779 emit scriptInfo(
"animationCount( ObjectId )");
793 emit log(
LOGERR, tr(
"Unable to get object"));
799 if (skeletonObj == 0) {
800 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
806 if ((_animationIndex < 0) || (_animationIndex
808 emit log(
LOGERR, tr(
"Invalid animationIndex"));
813 "frameCount( ObjectId, " + QString::number(_animationIndex) +
" )");
814 return skeleton->
animation(_animationIndex)->frameCount();
827 emit log(
LOGERR, tr(
"Unable to get object"));
833 if (skeletonObj == 0) {
834 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
840 emit scriptInfo(
"activeAnimation( ObjectId )");
853 emit log(
LOGERR, tr(
"Unable to get object"));
859 if (skeletonObj == 0) {
860 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
866 emit scriptInfo(
"activeFrame( ObjectId )");
867 return handle.
frame();
880 emit log(
LOGERR, tr(
"Unable to get object"));
886 if (skeletonObj == 0) {
887 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
893 if ((_animationIndex < 0) || (_animationIndex
895 emit log(
LOGERR, tr(
"Invalid animationIndex"));
899 if ((_frame < 0) || (_frame
900 > (
int) skeleton->
animation(_animationIndex)->frameCount())) {
901 emit log(
LOGERR, tr(
"Invalid frame"));
910 "setActivePose( ObjectId, " + QString::number(_animationIndex) +
", "
911 + QString::number(_frame) +
")");
924 emit log(
LOGERR, tr(
"Unable to get object"));
930 if (skeletonObj == 0) {
931 emit log(
LOGERR, tr(
"Unable to get skeletonObject"));
938 emit log(
LOGERR, tr(
"Invalid frame count"));
942 std::string stdName = _name.toStdString();
945 emit log(
LOGERR, tr(
"Animation with this name already exists"));
954 for (
unsigned int i = 0; i < skeleton->animation(handle)->
frameCount(); i++) {
958 for (
unsigned int j = 0; j < skeleton->jointCount(); j++)
964 "addAnimation( ObjectId, " + _name +
", " + QString::number(_frames)
968 emit createBackup(_objectId,
"Add Animation",
UPDATE_ALL);
Represents a single joint in the skeleton.
void addJoint(int _objectId, int _parent, Vector _position)
add joint to the skeleton
Animation * animation(std::string _name)
Returns a pointer to the animation to the given name.
void addJoint(typename SkeletonT< PointT >::Joint *_pParent, typename SkeletonT< PointT >::Joint *_pJoint)
Adds a joint as child of a given parent joint.
Vector localTranslation(int _objectId, int _jointId)
get local translation of a joint in the active pose
Skeleton transformation class.
A handle used to refer to an animation or to a specific frame in an animation.
Pose * referencePose()
Returns a pointer to the reference pose.
const Matrix & globalMatrix(unsigned int _joint) const
Returns the global matrix for the given joint.
bool is_identity() const
check if the matrix is the identity ( up to an epsilon )
void setGlobalTranslation(unsigned int _joint, const Vector &_position, bool _keepGlobalChildPositions=true)
Sets the global translation vector.
void translateJoint(Skeleton::Joint *_joint, ACG::Vec3d _translation, bool _keepChildPositions=true)
apply a translation to a joint in the refPose
int activeFrame(int _objectId)
get active frame
Pose * pose(unsigned int _iFrame)
Returns a pointer to the pose stored in the given frame.
void addAnimation(int _objectId, QString _name, int _frames)
add animation
size_t id() const
returns the joint id
bool getObject(int _identifier, BSplineCurveObject *&_object)
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
Joint * child(size_t _index)
Returns the child joint with the given index.
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
int activeAnimation(int _objectId)
get active animation
SkeletonObject * skeletonObject(BaseObjectData *_object)
Cast an BaseObject to a SkeletonObject if possible.
virtual void functionExists(QString _pluginName, QString _functionName, bool &_exists)
unsigned int frameCount()
Returns the number of frames stored in this pose.
void transformJoint(int _objectId, int _jointId, Matrix4x4 _matrix)
transform joint with given matrix
size_t size() const
Returns the number of children.
Matrix4x4 globalMatrix(int _objectId, int _jointId)
get global matrix of a joint in the active pose
int animationCount(int _objectId)
get the number of animations
void removeJoint(typename SkeletonT< PointT >::Joint *_pJoint)
Remove the given joint from the tree.
void setActivePose(int _objectId, int _animationIndex, int _frame)
set active pose
size_t frame() const
Returns the selected frame (zero based)
const Matrix & localMatrix(unsigned int _joint) const
Returns the local matrix for the given joint.
ACG::SceneGraph::SkeletonNodeT< Skeleton > * skeletonNode()
Returns the skeleton scenegraph node.
void setDescriptions()
Set Descriptions for Scripting Slots.
Vector globalTranslation(int _objectId, int _jointId)
get global translation of a joint in the active pose
A general pose, used to store the frames of the animation.
size_t animationIndex() const
Returns the animation index (zero based)
ACG::Matrix4x4d Matrix4x4
Standard Type for a 4x4 Matrix used for scripting.
void setParent(Joint *_newParent, SkeletonT< PointT > &_skeleton)
access parent of the joint
void splitBone(int _objectId, int _tailJoint)
insert a joint in the middle of a bone given by its (unique) tailJoint
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
Matrix4x4 localMatrix(int _objectId, int _jointId)
get local matrix of a joint in the active pose
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
Joint * parent()
Returns the parent joint.
size_t animationCount()
Returns the number of animations stored in this skeleton.
Pose * pose(const AnimationHandle &_hAni)
Returns a pointer to the pose with the given animation handle.
ACG::Vec3d Vector
Standard Type for 3d Vector used for scripting.
int frameCount(int _objectId, int _animationIndex)
get the number of frames
bool isValid() const
Returns true if the handle is valid.
void setLocalMatrix(unsigned int _joint, const Matrix &_local, bool _keepLocalChildPositions=true)
Sets the local coordinate system.
void setGlobalMatrix(unsigned int _joint, const Matrix &_global, bool _keepGlobalChildPositions=true)
Sets the global coordinate system.
void identity()
setup an identity matrix
Vector globalTranslation(unsigned int _joint)
Returns the global translation vector.
Skeleton * skeleton(BaseObjectData *_object)
Get a skeleton from an object.
Vector localTranslation(unsigned int _joint)
Returns the local translation vector.
Joint * joint(const size_t &_index)
Returns the joint with the given index.
void transformJoint(Skeleton::Joint *_joint, Matrix4x4 _matrix, bool _keepChildPositions=true)
apply a transformation to a joint in the refPose
void rotateJoint(Skeleton::Joint *_joint, Skeleton::Pose *_pose, Matrix4x4 _rotation, bool _applyToWholeAnimation=true)
rotate a joint in an arbitrary Pose