Author Topic: setRotationPivot / Config.useRotationPivotFrom3DS on AE  (Read 4181 times)

Offline lomac

  • byte
  • *
  • Posts: 9
    • View Profile
setRotationPivot / Config.useRotationPivotFrom3DS on AE
« on: February 14, 2013, 08:51:48 pm »
Hi, I have set up my projects in such a way that I can run my game on both PC and on android for easy testing and debugging. I did this by separating out the game code from the Activity code. Say I created a class called Game. I then created a desktop project and linked it to the android project. It then uses the Game class (and all related..) from the android project.

For things that differ that differ between android and desktop and jpct-ae and jpct, like file loading, I created an interface called GLoader, with an implementation in each project (DLoader and MLoader), and pass the instance in, and this instance is then used to load files in the generic game code.  (I did the same for control input, mouse<>touchscreen, gsens<>keyboard arrows). This is working great.

The problem I have is that my player model does not rotate around it's .3ds center in the android jpct-ae version, but it works in the desktop jpct version. All the code is identical, except the InputStream creation. Here in my MLoader code. The function that loads the model, private Object3D loadModel(InputStream is, float scale) is identical in both desktop and and AE versions. (Adding o3d.setRotationPivot(SimpleVector.ORIGIN); is what made the desktop version work, but adding it does not work in the AE version.)

Code: [Select]
   
package com.example.mrunner;

import java.io.IOException;
import java.io.InputStream;

import android.content.res.AssetManager;

import com.threed.jpct.Loader;
import com.threed.jpct.Matrix;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;

public class MLoader implements GLoader {

AssetManager assets;

public MLoader(AssetManager assets) {
this.assets = assets;
}

@Override
public Object3D loadModel(String file, float scale) {
InputStream is = null;
try {
is = assets.open(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(file.endsWith(".3ds")) {
return loadModel(is, scale);
}
else if(file.endsWith(".ser")) {
return loadSerializedModel(is, scale);
}
return null;
}

@Override
public Texture loadTexture(String file) {
InputStream is = null;
try {
is = assets.open(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Texture tex = new Texture(is);
TextureManager.getInstance().addTexture(file, tex);
return tex;
}

    private Object3D loadModel(InputStream is, float scale) {
   
        Object3D[] model = Loader.load3DS(is, scale);
        Object3D o3d = new Object3D(1);
        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.rotateMesh();
            temp.setRotationMatrix(new Matrix());
            o3d = Object3D.mergeObjects(o3d, temp);
            o3d.build();
        }
        o3d.setRotationPivot(SimpleVector.ORIGIN);
        return o3d;
    }

    private Object3D loadSerializedModel(InputStream is, float scale) {
   
        Object3D o3d = Loader.loadSerializedObject(is);
        o3d.scale(scale);
        Object3D temp = o3d;
        temp.setCenter(SimpleVector.ORIGIN);
        temp.rotateX((float)( -.5*Math.PI));
        temp.rotateMesh();
        temp.setRotationMatrix(new Matrix());
        o3d = Object3D.mergeObjects(o3d, temp);
        o3d.build();
        o3d.setRotationPivot(SimpleVector.ORIGIN);
        return o3d;
    }
}


In the ae version the model does not rotate around the correct pivot, in the desktop version it does. I also tried setting Config.useRotationPivotFrom3DS which did not fix it. I do not call build again. The funny thing is that getRotationPivot() returns 0.0,0.0,0.0 on ae but it still does not rotate right.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #1 on: February 14, 2013, 09:30:06 pm »
And both versions are loading the 3ds version of the file? Apart from that, the loadSerializedModel-method looks wrong to me. It merges the object with itself... ???

Offline lomac

  • byte
  • *
  • Posts: 9
    • View Profile
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #2 on: February 15, 2013, 09:24:59 am »
Yes, both are loading the 3ds version.

p.s. Thanks, I will fix the serialized loading.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #3 on: February 15, 2013, 09:41:43 am »
I don't see any reason why it shouldn't work then. If there would be general problem with setting the rotation pivot, almost everything would go boom. Can you provide a simple Test-Activity that shows the problem?

Offline lomac

  • byte
  • *
  • Posts: 9
    • View Profile
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #4 on: February 15, 2013, 01:35:03 pm »
OK, I will post a test over app over the weekend.

Offline lomac

  • byte
  • *
  • Posts: 9
    • View Profile
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #5 on: February 16, 2013, 11:20:24 am »
OK, I have found the circumstances that cause the problem. It only happens if you extend Object3D to make for instance your player class, as you did in the car demo.

So if my player class looks like this
Code: [Select]
public class Player {
Actions actions;

Object3D model;

public SimpleVector lastFramePos;

public Player(Actions actions, Object3D model) {
this.model = model;
this.actions = actions;

actions.world.addObject(model);
}
}

and I call player.model.rotateY(), then it works correctly everywhere.

But, if my player class looks like this:
Code: [Select]
public class Player extends Object3D {
Actions actions;

public SimpleVector lastFramePos;

public Player(Actions actions, Object3D model) {
super(model);
this.actions = actions;

actions.world.addObject(this);
}
}

and I call player.rotateY(), then the player does not rotate correctly in ae, but does in desktop. The only way to fix it in AE is to call player.setRotationPivot(SimpleVector.ORIGIN); EVERY FRAME in the rendering loop. (It does not matter where in the frame loop, beginning or end, it fixes it)



Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #6 on: February 16, 2013, 12:38:36 pm »
WTF... ??? I'll have a look, but this is really strange...

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #7 on: February 16, 2013, 01:34:02 pm »
Are you getting the log flooded with messages like

Code: [Select]
Object <some name> hasn't been build yet. Forcing build()!

??

Offline lomac

  • byte
  • *
  • Posts: 9
    • View Profile
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #8 on: February 16, 2013, 02:40:06 pm »
Yes, I see it for a short while then it stops.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #9 on: February 16, 2013, 02:47:47 pm »
Have to tried to simply build() all objects (obviously you aren't doing this) before setting the pivots, then set the pivots once, then render? There's a difference between desktop an AE in the default build()-behaviour. AE auto-builds at runtime if your code forgot to do it, desktop doesn't, at least not by default.

Offline lomac

  • byte
  • *
  • Posts: 9
    • View Profile
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #10 on: February 16, 2013, 03:19:01 pm »
Ah, if I call build on the player object (that extends Object3D), and then player.setRotationPivot after that then it works! Previously I only called build on the Object3D "model" prior to it being passed into the constructor of the Player class.

So the bottom line is if you extend Object3D and construct an instance if the class that inherits Object3D, then you have to call build() on this instance, even if the "model" in super(model) already had build() called on it.

Thank you very much for your time to help me sort this out.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: setRotationPivot / Config.useRotationPivotFrom3DS on AE
« Reply #11 on: February 16, 2013, 05:34:58 pm »
So the bottom line is if you extend Object3D and construct an instance if the class that inherits Object3D, then you have to call build() on this instance, even if the "model" in super(model) already had build() called on it.
Yes. That's because you can't be sure that you haven't changed anything in the copy that would affect the build() outcome.