0

I successfully rendered a 3D model using the min3D library in my application.
I used quaternion data (x,y,z,w) for rotation and flipping.

enter image description here

The rotation is perfect for the front face and when I flip it to the opposite face the rotation becomes opposite to the actual direction.
What I mean with "on the opposite face", is that when I rotate to right, the cube rotates to left and vice-versa.

The code I used:

 @Override
public void initScene() {    
    Light light = new Light();
    light.position.setAllFrom(scene.camera().position);
    scene.lights().add(light);
    scene.backgroundColor().setAll(0xffffff);
    try {
        IParser parser = Parser.createParser(Parser.Type.OBJ,
                getResources(), "---:raw/cube_obj", true);
        parser.parse();
        cube = parser.getParsedObject();
        cube.scale().x = cube.scale().y = cube.scale().z = .08f;
        cube.position().x = .3f;
        scene.addChild(cube);
        scene.camera().target = cube.position();
        mDoPlotting =true;
    } catch (OutOfMemoryError e) {
        e.printStackTrace();         
    }

In Object3D.java

private Quaternion _quaternion = new Quaternion(new Vector3(0.0,0.0,0.0),Math.toRadians(0));
public Quaternion quaternion() {
    return _quaternion;
}

In Quaternion.java

public final class Quaternion {
public double x;
public double y;
public double z;
public double w;

public Quaternion(final Quaternion q) {
    this(q.x, q.y, q.z, q.w);
}

public Quaternion(double x, double y, double z, double w) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.w = w;
}

public void set(final Quaternion q) {
    this.x = q.x;
    this.y = q.y;
    this.z = q.z;
    this.w = q.w;
}

public Quaternion(Vector3 axis, double angle) {
    set(axis, angle);
}

public double norm() {
    return Math.sqrt(dot(this));
}

public double getW() {
    return w;
}

public double getX() {
    return x;
}

public double getY() {
    return y;
}

public double getZ() {
    return z;
}


public Quaternion set(Vector3 axis, double angle) {
    double s =  Math.sin(angle / 2);
    w = Math.cos(angle / 2);
    x = axis.getX() * s;
    y = axis.getY() * s;
    z = axis.getZ() * s;
    return this;
}

public Quaternion mulThis(Quaternion q) {
    double nw = w * q.w - x * q.x - y * q.y - z * q.z;
    double nx = w * q.x + x * q.w + y * q.z - z * q.y;
    double ny = w * q.y + y * q.w + z * q.x - x * q.z;
    z = w * q.z + z * q.w + x * q.y - y * q.x;
    w = nw;
    x = nx;
    y = ny;
    return this;
}

public Quaternion setRotation( Vector3 v, float angle){
double s = (double) Math.sin(angle / 2);
w = (double) Math.cos(angle / 2);
x = v.x*s;
y = v.y*s;
z = v.z*s;
return this;
}
public void setRotation(double x, double y, double z, double angle){
    //        float half = angle*0.5f;
    double s = (double) Math.sin(angle / 2);
    this.x = x*s;
    this.y = y*s;
    this.z = z*s;
    w = (double) Math.cos(angle / 2);

}

public void rotateThis(double x,double y,double z,double w){
    this.x = x;
    this.y = y;
    this.z = z;
    this.w = w;
}

public Quaternion scaleThis(double scale) {
    if (scale != 1) {
        w *= scale;
        x *= scale;
        y *= scale;
        z *= scale;
    }
    return this;
}

public Quaternion divThis(double scale) {
    if (scale != 1) {
        w /= scale;
        x /= scale;
        y /= scale;
        z /= scale;
    }
    return this;
}

public double dot(Quaternion q) {
    return x * q.x + y * q.y + z * q.z + w * q.w;
}

public boolean equals(Quaternion q) {
    return x == q.x && y == q.y && z == q.z && w == q.w;
}

public Quaternion interpolateThis(Quaternion q, double t) {
    if (!equals(q)) {
        double d = dot(q);
        double qx, qy, qz, qw;

        if (d < 0f) {
            qx = -q.x;
            qy = -q.y;
            qz = -q.z;
            qw = -q.w;
            d = -d;
        } else {
            qx = q.x;
            qy = q.y;
            qz = q.z;
            qw = q.w;
        }

        double f0, f1;

        if ((1 - d) > 0.1f) {
            double angle = (double) Math.acos(d);
            double s = (double) Math.sin(angle);
            double tAngle = t * angle;
            f0 = (double) Math.sin(angle - tAngle) / s;
            f1 = (double) Math.sin(tAngle) / s;
        } else {
            f0 = 1 - t;
            f1 = t;
        }

        x = f0 * x + f1 * qx;
        y = f0 * y + f1 * qy;
        z = f0 * z + f1 * qz;
        w = f0 * w + f1 * qw;
    }

    return this;
}

public Quaternion normalizeThis() {
    return divThis(norm());
}

public Quaternion interpolate(Quaternion q, double t) {
    return new Quaternion(this).interpolateThis(q, t);
}


public float[] toMatrix() {
    float[] matrixs = new float[16];
    toMatrix(matrixs);
    return matrixs;
}

public final void toMatrix(float[] matrixs) {
    matrixs[3] = 0.0f;
    matrixs[7] = 0.0f;
    matrixs[11] = 0.0f;
    matrixs[12] = 0.0f;
    matrixs[13] = 0.0f;
    matrixs[14] = 0.0f;
    matrixs[15] = 1.0f;

    matrixs[0] = (float) (1.0f - (2.0f * ((y * y) + (z * z))));
    matrixs[1] = (float) (2.0f * ((x * y) - (z * w)));
    matrixs[2] = (float) (2.0f * ((x * z) + (y * w)));

    matrixs[4] = (float) (2.0f * ((x * y) + (z * w)));
    matrixs[5] = (float) (1.0f - (2.0f * ((x * x) + (z * z))));
    matrixs[6] = (float) (2.0f * ((y * z) - (x * w)));

    matrixs[8] = (float) (2.0f * ((x * z) - (y * w)));
    matrixs[9] = (float) (2.0f * ((y * z) + (x * w)));
    matrixs[10] = (float) (1.0f - (2.0f * ((x * x) + (y * y))));
}

}

I used

 cube.quaternion().rotateThis( event3D.getX(),event3D.getY(),event3D.getZ(),event3D.getW());

for rotation

Sanu
  • 455
  • 1
  • 6
  • 17
  • Its only a model class. – Sanu Feb 03 '16 at 05:45
  • I tried with Rajawali. But the result is same :( – Sanu Feb 04 '16 at 06:49
  • `rotateThis` is setting the quaternion - is `event3D` a quaternion or is it a point in space? If not you will need to convert it into a meaningful rotation. For example picking a fixed axis to start with and then using `event3D` to define the angle. Then you can set the quaternion with `setRotation` – Stephen O'Connor Feb 04 '16 at 13:31
  • event3D.getX(),event3D.getY(),event3D.getZ(),event3D.getW() are quaternion values – Sanu Feb 05 '16 at 04:40

1 Answers1

0

I am not so sure will this because of your touch event (if you are using OnTouch for user rotating cube), the x axis of the screen is take from left of screen to right as positive. And the 3d model/camera rotating positively in anti-clockwise. So, maybe that is the reason why it's in reverse direction. To confirm may you so some code how you track down user action rotating the cube. I am sorry can't use comment.

CbL
  • 734
  • 5
  • 22
  • I am not handling any touch event here. The Quaternion values are get from an external device. – Sanu Feb 08 '16 at 06:12
  • Just want to comfirm the matrix calculation you consider. it seems you like to use relative coordinate system but it is not in that way or you want to calculate every time from its origin? Some inf of 3d rotation (https://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/3drota.htm) – CbL Feb 08 '16 at 12:09