Animate rigged model according to given commands

Started by aeroxr1, June 05, 2014, 10:14:22 PM

Previous topic - Next topic

raft

well, to tell the truth I'm not proficient in those calculations too :-[

a few points:

* each joint's transform is in its parent's space.
* as the name suggests invertBindPose is the invert of bindPose of joint. we use it in calculations, so instead of inverting bindPose each time, we keep a reference to its invert.

have a look at SkeletonPose updateTransforms and setToBindPose methods, they may give some clue.

aeroxr1

#61
private void targetJoint(SkeletonPose pose, int jointIndex, SimpleVector bindPoseDirection,
    SimpleVector targetPos, final float targetStrength) {
   
        final int parentIndex = pose.getSkeleton().getJoint(jointIndex).getParentIndex();

        // neckBindGlobalTransform is the neck bone -> model space transform. essentially, it is the world transform of
        // the neck bone in bind pose.
   1-     final Matrix jointInverseBindPose = pose.getSkeleton().getJoint(jointIndex).getInverseBindPose();
        final Matrix jointBindPose = jointInverseBindPose.invert();

      .........................
       
        // now remove the global/world transform of the neck's parent bone, leaving us with just the local transform of
        // neck + rotation.
        subGlobal.matMul(jointBindPose);
     2-   subGlobal.matMul(pose.getSkeleton().getJoint(parentIndex).getInverseBindPose());

      .........................
    }


But the inverseBindPose matrix is not the same for all the bones ?

In 2 can I use the inverseBindPose calculated in 1 ? No ? why ?


raft

Quote from: aeroxr1 on September 09, 2014, 04:03:05 PM
But the inverseBindPose matrix is not the same for all the bones ?
of course not, why should it be?

aeroxr1

#63
Boh, I thought I read this  :-[

I'm trying to positionate the left arm close to the model's body but I can't :(

This is the code that I used :

Logger.log("rotazione");
Tpose = modello.get(0).getSkeletonPose();
Tpose.setToBindPose(); //setto la posa iniziale del modello
final Joint LUpperArm  = Tpose.getSkeleton().getJoint(17);
final Joint parentJoint = Tpose.getSkeleton().getJoint(LUpperArm.getParentIndex());
skeletonDebugger=new SkeletonDebugger(Tpose);
skeletonDebugger.addToWorld(world);
rotation=new Matrix(LUpperArm.getBindPose());
rotation.rotateX(90); //ruoto il braccio dalla bindPose di 90gradi
rotation.matMul(parentJoint.getInverseBindPose());
        Tpose.getLocal(17).setTo(rotation);
        Tpose.updateTransforms();
        skeletonDebugger.update(Tpose);
        modello.applySkeletonPose();
        modello.applyAnimation();


What did I do wrong ?

I have this problems because I don't know the math behind bind matrices,inverse bind matrices and local trasformation ecc ecc :( Could you suggest me some guides ?


raft

well, not really sorry. as i said i'm not proficient in those calculations. i never did such kinnd of programatic positioning before.

aeroxr1

#65
thanks anyway  :)

EgonOlsen

I'm not sure about this either, but this is obviously wrong:


rotation.rotateX(90);


All methods in jPCT that want an angle use radians, not degrees. I should make this more clear in the docs...

aeroxr1

#67
I edit the code from degree to radiant and I will try :)

aeroxr1

In this post I attach the model's skeleton xml files.

I posted it, because I did in this way.

In public void onSurfaceChanged(GL10 gl, int width, int height) :

protected void rotazionebraccio()
{
Logger.log("rotazionebraccio");

final Joint LUpperArm  = currentPose.getSkeleton().getJoint(17);
final Joint parentJoint = currentPose.getSkeleton().getJoint(LUpperArm.getParentIndex());
final Matrix global= new Matrix(LUpperArm.getBindPose());
float angle=(float)Math.toRadians(90);
global.rotateZ(angle);
global.matMul(parentJoint.getInverseBindPose());
currentPose.getLocal(17).setTo(global);

currentPose.updateTransforms();
skeletonDebugger.update(currentPose);
modello.applySkeletonPose();
modello.applyAnimation();

}


and

public void onDrawFrame(GL10 gl)
{
if (frameBuffer == null)
return;

frameBuffer.clear(back); //ripulisco il frameBuffer e lo setto con il colore di sfondo voluto
world.renderScene(frameBuffer);
world.draw(frameBuffer);
frameBuffer.display();

}


I want to rotate the left arm, that in skeleton xml file is :
<bone id="17" name="Vincent L UpperArm">

I run the application and the left foot rotated and not the arm... do you know what did I do wrong  ?

aeroxr1

#69
I think that the ids present in skeleton.xml file are wrong. I think, because I have tried to move the left arm and it has moved but in wrong way -.-"

I try to move the model's Left Thigh and the result is :


>:(

The code that I have used is :
protected void rotazionebraccio()
{
Logger.log("rotazionebraccio");

final Joint LUpperArm  = currentPose.getSkeleton().getJoint(3);
final Joint parentJoint = currentPose.getSkeleton().getJoint(LUpperArm.getParentIndex());
final Matrix global= new Matrix(LUpperArm.getBindPose());
float angle=(float)Math.toRadians(-90);
global.rotateX(angle);
global.matMul(parentJoint.getInverseBindPose());
currentPose.getLocal(3).setTo(global);

currentPose.updateTransforms();
skeletonDebugger.update(currentPose);
modello.applySkeletonPose();
modello.applyAnimation();

}


I have committed an error in the code or maybe is ogre's exporter fault ?   


EDIT :now I have replaced in code but the right thigh has moved .. I take the id from this file :

         <bone id="2" name="Vincent Spine">
            <position x="4.90153" y="5.88984e-006" z="-0.624106"/>
            <rotation angle="0">
                <axis x="-0.82569" y="-0.0201387" z="0.563765"/>
            </rotation>
        </bone>
        <bone id="3" name="Vincent L Thigh">
            <position x="-4.90153" y="3.78952" z="0.624106"/>
            <rotation angle="3.14159">
                <axis x="0.0181571" y="1.91597e-007" z="0.999835"/>
            </rotation>
        </bone>
        <bone id="4" name="Vincent L Calf">
            <position x="18.4395" y="0" z="-1.19209e-007"/>
            <rotation angle="0.00851348">
                <axis x="-3.32428e-012" y="1" z="-4.37102e-008"/>
            </rotation>
        </bone>
        <bone id="5" name="Vincent L Foot">
            <position x="13.4731" y="0" z="-1.19209e-007"/>
            <rotation angle="0.0277679">
                <axis x="-2.55262e-005" y="1" z="-7.32838e-006"/>
            </rotation>
        </bone>


Did I do wrong ? :(

I hope you can help me  :D

raft

the index of joints in skeleton.xml file is not related to id's in Bones. indeed joints in Bones has no id's but zero based indices. such that first joint in skeleton is at index zero, the second one is at index one, and so on. the ordering may be totally different from skeleton.xml file.

but assuming joint names are unique, you can retrieve a joint by its name:

Skeleton.findJointByName(jointName)

once a joint is found you can later retrieve it by its index.

raft

btw, i will suggest you making yout trials at desktop jPCT not on Android. it will be much easier to do so. and using Bones' samples as a starting point may also save you some time.

aeroxr1

Quote from: raft on September 11, 2014, 11:04:39 AM
the index of joints in skeleton.xml file is not related to id's in Bones. indeed joints in Bones has no id's but zero based indices. such that first joint in skeleton is at index zero, the second one is at index one, and so on. the ordering may be totally different from skeleton.xml file.

but assuming joint names are unique, you can retrieve a joint by its name:

Skeleton.findJointByName(jointName)

once a joint is found you can later retrieve it by its index.

Thank you a lot !!!!!!!!!!!!!!!!!!!!!1  ;D

raft

Quote from: raft on September 11, 2014, 11:04:39 AM
the ordering may be totally different from skeleton.xml file.
this is worth mentioning, the joints are ordered such that, parent of a joint always comes before the joint itself.