SkinAnimation not displaying on android

Started by Tangomajom, March 26, 2016, 08:26:10 PM

Previous topic - Next topic

Tangomajom

Hi Raft,

First of all sorry for my English. I try to do my best, but I'm not a professional. I'm also a beginer with 3D modelling, therefore I asked your help.

So the problem in nutshell:

I succesfully imported a rigged object from Blender to JPCT. I already find out how can I move and rotate the joints. The next step should be to create a skin animation.
Basicly I just would like to rotate the joints, so only the rotation quaternions will change in the keyframes. The translation and scale vectors don't need to be changed.
The results of my code is not what I expected. My character is still not moving.

Please have a look at to my code, possibly I'm not using your library right, or just missing some neccessary method call. 

This is how I apply the animation in the OnSurfaceChanged() method:

SkinClipSequence clipSeq = new SkinClipSequence(createSkinClip());
MaleBody.setSkinClipSequence(clipSeq);
MaleBody.animateSkin(0, 0);
MaleBody.applyAnimation();



And this is the createSkinClip method :

I'm just planning to rotate the shin of my character with 90 degrees and, then back to the init position.



private SkinClip createSkinClip() {

        List<JointChannel> jointChannels = new ArrayList<>();
        Joint shin = skeletonHelper.getJoint("shin.L");
        int animationLength = 3;

        SimpleVector jointStartDirection= skeletonHelper.getBoneDirection(shin);
        SimpleVector jointEndDirection =  new SimpleVector(jointStartDirection);
        jointEndDirection.rotateX((float) (Math.PI / 2));

        Quaternion quat = new Quaternion();
        quat.fromVectorToVector(jointStartDirection, jointStartDirection);
        Quaternion quat2 = new Quaternion();
        quat.fromVectorToVector(jointStartDirection,jointEndDirection);
        Quaternion quat3 = new Quaternion();
        quat.fromVectorToVector(jointEndDirection,jointStartDirection);

        float[] times = new float[animationLength];
        times[0] = 0.0f;
        times[1] = 1.0f;
        times[2] = 2.0f;
        SimpleVector[] translations = new SimpleVector[animationLength];
        translations[0] = shin.getBindPose().getTranslation();
        translations[1] = shin.getBindPose().getTranslation();
        translations[2] = shin.getBindPose().getTranslation();
        Quaternion[] rotations = new Quaternion[animationLength];
        rotations[0] = quat;
        rotations[1] = quat2;
        rotations[2] = quat3;
        SimpleVector[] scales = new SimpleVector[animationLength];
        scales[0] = new SimpleVector(1f,1f,1f);
        scales[1] = new SimpleVector(1f,1f,1f);
        scales[2] = new SimpleVector(1f,1f,1f);

        JointChannel chShin = new JointChannel(shin.getIndex(),times,translations,rotations,scales);

        jointChannels.add(chShin);

        SkinClip clip = new SkinClip(MaleBody.get(0).getSkeleton(),jointChannels);


        return clip;
    }


I added the animateSkin method to the OnDrawFrame() method, which runs at every frame.
My code look like this:


if(animtime >= 1.0f){
                animtime= 0.0f;
            }else{
                MaleBody.animateSkin(animtime,0);
                animtime+=0.01f;
            }


It is moving but it's runs on 7-10 fps, instead of 40-60 like without the animation. Am I used the animateSkin method wrong?


Thank you in advance,

Tamás O.

raft

first make sure you didnt call AnimatedGroup/Animated3D.setAutoApplyAnimation(false), otherwsie you need to call AnimatedGroup/Animated3D.applyAnimation manually each frame.

looking at your code, you dont update quat2 and quat3 but update quat 3 times.

and also try adding some translation to your joint, rotations sometimes behave very unexpectedly.

Tangomajom

Hi,

Thank you. After I fixed these, the animation played correctly. Meanwhile I found the reason of the low fps: my mesh was too detailed. It contained almost 140K of triangles, which killed my mobile... :D

You're right. These translations generated invalid positions. As you can see in the attachment the shin of my human model relocated to front of the body and to the level of hips... :D


Is there a best practice to get the current translation of a joint? I tried via Skeletonhelper ->GetJointDirection(),  Joint.getBindPose().getTranslation(), Joint.getInverseBindPose().getTranslation(), but none of them worked. If I can get the current position of the bone I guess I just need to copy it to the channel keyframes, to avoid any position change.

raft

Joint.getBindPose()/getInverseBindPose() gives you information about the bind pose, not current translation/rotation.

you need pull that information from the matrices in SkeletonPose

Tangomajom

Great! mCurrentPose.getLocal(<Index of joint>).getTranslation() solved the problem. Now everything is running perfectly. Thank you for your support and for this library as well. Good job! :)