Animated 3ds model does not move [Solved]

Started by jaynemesisz, September 07, 2011, 02:53:16 PM

Previous topic - Next topic

jaynemesisz

Hi all,

I am trying to animate a 3ds model in an Android application, but it just doesn't move. I have been following the wiki's implementation closely. Hence I don't understand what could go wrong.

Will be really grateful to anyone who can help to pick out the problem. I've been staring at the code for the longest time and trying all sorts of solutions posted in the forums here, but none has worked for me. My codes are attached below.

If this is any help at all, I am running the app on Android 2.1, HTC flyer.


private void createWorld() {
if (world != null) {
return;
}
world = new World();

TextureManager tm = TextureManager.getInstance();
tm.flush();
Texture eyetex = new Texture(res.openRawResource(R.raw.eyesmall));
tm.addTexture("EYE.TIF", eyetex);

bear = loadModel(res.openRawResource(R.raw.bearb), 1f);

Animation anim = new Animation(4);
                anim.createSubSequence("walk");
                anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk1b), 1).getMesh());
                anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk2b), 1).getMesh());
                anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk3b), 1).getMesh());
                anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk4b), 1).getMesh());
                bear.setAnimationSequence(anim);

                world.addObject(bear);

world.setAmbientLight(127, 127, 127);
//world.buildAllObjects();

// Set lighting
float[] bb = bear.getMesh().getBoundingBox();
float height = (bb[3] - bb[2]);
new Light(world).setPosition(new SimpleVector(0, -height/2, height));

// Set camera
cameraController = new GLCameraOrbitController(world.getCamera());
cameraController.cameraAngle = 0;
}

private Object3D loadModel(InputStream filename, float scale) {
                Loader.setVertexOptimization(false);
               
                Object3D[] model = Loader.load3DS(filename, scale);
                Object3D o3d = new Object3D(0);
                Object3D temp = null;

                for (int i = 0; i < model.length; i++) {
                    temp = model[i];
                    temp.setCenter(SimpleVector.ORIGIN);
                    temp.rotateX((float)( -.5*Math.PI));
                    temp.rotateY((float)(-Math.PI));
                    temp.rotateMesh();
                    temp.setRotationMatrix(new Matrix());
                    o3d = Object3D.mergeObjects(o3d, temp);
           
                }
                o3d.build();
                return o3d;
        }

private float _anim3DS = 0.0f;

private void doAnimate() {

try{
if(_anim3DS > 1.0f)
_anim3DS = 0.0f;
else
_anim3DS += 0.1f;

bear.animate(_anim3DS, bear.getAnimationSequence().getSequence("walk"));

} catch(Exception e){
System.err.println("MoveTest::checkAnimate3DS() " + e.getMessage());
e.printStackTrace();
}
       
}

/****************************************************************
* GLSurfaceView.Renderer methods
*/
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Logger.log("onSurfaceCreated");
}

@Override
public void onSurfaceChanged(GL10 gl, int w, int h) {
Logger.log("onSurfaceChanged");

if (frameBuffer != null) {
frameBuffer.dispose();
}
frameBuffer = new FrameBuffer(gl, w, h);

createWorld();

autoAdjustCamera(bear);
}

@Override
public void onDrawFrame(GL10 gl) {

if (frameBuffer == null) {
return;
}

doAnimate();

cameraController.placeCamera();

frameBuffer.clear();
world.renderScene(frameBuffer);
world.draw(frameBuffer);

frameBuffer.display();
}


jaynemesisz

I probably should add, my model does render out correctly on screen. But it doesn't move at all.

And just fyi in case it helps at all, each of my 3ds models are 177kb and were exported by Blender 2.58.

jaynemesisz

Reading the other posts suggest that build() should be done after setAnimationSequence(). Hence I've modified my code. But am getting another error.

This is the snippet

        bear = loadModel(res.openRawResource(R.raw.bearb), 1, false);

        Animation anim = new Animation(4);
       
        anim.createSubSequence("walk");
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk1b), 1, true).getMesh());
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk2b), 1, true).getMesh());
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk3b), 1, true).getMesh());
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk4b), 1, true).getMesh());
       
        bear.setAnimationSequence(anim);
        bear.build();
        world.addObject(bear);


And this is how loadModel() looks like now

private Object3D loadModel(InputStream filename, float scale, boolean build) {
        Loader.setVertexOptimization(false);
        Object3D[] model = Loader.load3DS(filename, scale);

        Object3D o3d = new Object3D(0);

        Object3D temp = null;

        for (int i = 0; i < model.length; i++) {
            temp = model[i];
            temp.setCenter(SimpleVector.ORIGIN);
            temp.rotateX((float)( -.5*Math.PI));
            temp.rotateY((float)(-Math.PI));
            temp.rotateMesh();
            temp.setRotationMatrix(new Matrix());
            o3d = Object3D.mergeObjects(o3d, temp);
        }
       
        if (build) {
        o3d.build();
        }
       
        return o3d;
}


This is the error:
09-07 22:12:53.227: ERROR/AndroidRuntime(24659): java.lang.RuntimeException: [ 1315404773218 ] - ERROR: The sizes of the Animation's Meshes (5683) and the object's Mesh (5675) don't match!

Previously when I called build on all models, this error did not exist. Hence I'm thinking my model are ok. In fact, my main model was a copy and paste and rename of one of the animation models. So I'm very sure that the models are exactly the same. I also did o3d.getMesh().getVertexCount() on all the models and the numbers are all the same.

Another forum post says to replace o3d.build() in my first posting with o3d.calcNormals(). But if build() is not called on the animation models, then the following error arises:
09-07 22:05:59.013: ERROR/AndroidRuntime(24484): java.lang.RuntimeException: [ 1315404358981 ] - ERROR: Bounding box missing in this mesh!


Sorry for the continuous posting, I just wish someone would point me in the right direction soon. My floor is full of hairs already =P

jaynemesisz

Persistence and an eye for detail saves the day!!!

In the last post I mentioned of 2 implementations I tried. Still not sure why the first one doesn't work, but I managed to solve the second one.

Besides o3d.calcNormals(), o3d.calcBoundingBox() is also needed! Was in one of the posts, but not specially highlighted, hence the oversight.

Now my code snippet looks like this

       bear = loadModel(res.openRawResource(R.raw.bearb), 1);

        Animation anim = new Animation(4);
        anim.createSubSequence("walk");
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk1b), 1).getMesh());
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk2b), 1).getMesh());
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk3b), 1).getMesh());
        anim.addKeyFrame(loadModel(res.openRawResource(R.raw.bear_walk4b), 1).getMesh());
       
        bear.setAnimationSequence(anim);
        bear.build();
        world.addObject(bear);


And loadModel looks like this

private Object3D loadModel(InputStream filename, float scale) {
        Loader.setVertexOptimization(false);
        Object3D[] model = Loader.load3DS(filename, scale);

        Object3D o3d = new Object3D(0);

        Object3D temp = null;

        for (int i = 0; i < model.length; i++) {
            temp = model[i];
            temp.setCenter(SimpleVector.ORIGIN);
            temp.rotateX((float)( -.5*Math.PI));
            temp.rotateY((float)(-Math.PI));
            temp.rotateMesh();
            temp.setRotationMatrix(new Matrix());
            o3d = Object3D.mergeObjects(o3d, temp);
            o3d.calcBoundingBox();
            o3d.calcNormals();
        }

        return o3d;
    }


Hope this helps someone!
           

parantjuma

Hi jaynemesisz , I'm starting with this engine and I was in the same problem.
Thank you very much for your post. Helped me a lot.