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);
bool isValid() const
Returns true if the handle is valid.
void setGlobalMatrix(unsigned int _joint, const Matrix &_global, bool _keepGlobalChildPositions=true)
Sets the global coordinate system.
void setGlobalTranslation(unsigned int _joint, const Vector &_position, bool _keepGlobalChildPositions=true)
Sets the global translation vector.
bool is_identity() const
check if the matrix is the identity ( up to an epsilon )
SkeletonObject * skeletonObject(BaseObjectData *_object)
Cast an BaseObject to a SkeletonObject if possible.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
Matrix4x4 globalMatrix(int _objectId, int _jointId)
get global matrix of a joint in the active pose
Matrix4x4 localMatrix(int _objectId, int _jointId)
get local matrix of a joint in the active pose
Vector globalTranslation(int _objectId, int _jointId)
get global translation of a joint in the active pose
void addJoint(typename SkeletonT< PointT >::Joint *_pParent, typename SkeletonT< PointT >::Joint *_pJoint)
Adds a joint as child of a given parent joint.
virtual void functionExists(QString _pluginName, QString _functionName, bool &_exists)
void setDescriptions()
Set Descriptions for Scripting Slots.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
bool getObject(int _identifier, BSplineCurveObject *&_object)
Pose * pose(const AnimationHandle &_hAni)
Returns a pointer to the pose with the given animation handle.
Skeleton transformation class.
void addAnimation(int _objectId, QString _name, int _frames)
add animation
ACG::Matrix4x4d Matrix4x4
Standard Type for a 4x4 Matrix used for scripting.
Vector localTranslation(unsigned int _joint)
Returns the local translation vector.
Pose * referencePose()
Returns a pointer to the reference pose.
Joint * child(size_t _index)
Returns the child joint with the given index.
Animation * animation(std::string _name)
Returns a pointer to the animation to the given name.
A general pose, used to store the frames of the animation.
unsigned int animationIndex() const
Returns the animation index (zero based)
Joint * joint(const unsigned int &_index)
Returns the joint with the given index.
void removeJoint(typename SkeletonT< PointT >::Joint *_pJoint)
Remove the given joint from the tree.
ACG::Vec3d Vector
Standard Type for 3d Vector used for scripting.
const Matrix & localMatrix(unsigned int _joint) const
Returns the local matrix for the given joint.
Pose * pose(unsigned int _iFrame)
Returns a pointer to the pose stored in the given frame.
Joint * parent()
Returns the parent joint.
unsigned int animationCount()
Returns the number of animations stored in this skeleton.
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
Vector globalTranslation(unsigned int _joint)
Returns the global translation vector.
unsigned int frame() const
Returns the selected frame (zero based)
const UpdateType UPDATE_TOPOLOGY(UpdateTypeSet(1)<< 3)
Topology updated.
void splitBone(int _objectId, int _tailJoint)
insert a joint in the middle of a bone given by its (unique) tailJoint
void identity()
setup an identity matrix
void setLocalMatrix(unsigned int _joint, const Matrix &_local, bool _keepLocalChildPositions=true)
Sets the local coordinate system.
unsigned int id()
returns the joint id
A handle used to refer to an animation or to a specific frame in an animation.
int animationCount(int _objectId)
get the number of animations
void setActivePose(int _objectId, int _animationIndex, int _frame)
set active pose
size_t size()
Returns the number of children.
void transformJoint(int _objectId, int _jointId, Matrix4x4 _matrix)
transform joint with given matrix
const Matrix & globalMatrix(unsigned int _joint) const
Returns the global matrix for the given joint.
Vector localTranslation(int _objectId, int _jointId)
get local translation of a joint in the active pose
int activeFrame(int _objectId)
get active frame
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
Skeleton * skeleton(BaseObjectData *_object)
Get a skeleton from an object.
Represents a single joint in the skeleton.
void translateJoint(Skeleton::Joint *_joint, ACG::Vec3d _translation, bool _keepChildPositions=true)
apply a translation to a joint in the refPose
void setParent(Joint *_newParent, SkeletonT< PointT > &_skeleton)
access parent of the joint
ACG::SceneGraph::SkeletonNodeT< Skeleton > * skeletonNode()
Returns the skeleton scenegraph node.
int frameCount(int _objectId, int _animationIndex)
get the number of frames
void addJoint(int _objectId, int _parent, Vector _position)
add joint to the skeleton
int activeAnimation(int _objectId)
get active animation
unsigned int frameCount()
Returns the number of frames stored in this pose.