min3D库 - 四元数旋转问题

时间:2016-01-28 13:41:26

标签: android opengl-es rotation quaternions min3d

我在我的应用程序中使用min3D库成功渲染了3D模型 我使用四元数据(x,y,z,w)进行旋转和翻转。

enter image description here

旋转对于正面是完美的,当我将其旋转到相对面时,旋转变为与实际方向相反。
我在“对面”的意思是,当我向右旋转时,立方体向左旋转,反之亦然。

我使用的代码:

 @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();         
    }

在Object3D.java中

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

在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))));
}

}

我用过

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

轮换

1 个答案:

答案 0 :(得分:0)

由于你的触摸事件(如果你正在使用OnTouch用户旋转立方体),我不太确定这个,屏幕的x轴从屏幕的左边到正面。 并且3d模型/摄像机逆时针旋转正向。所以,也许这就是它反向的原因。 要确认您是否可以通过一些代码来跟踪旋转多维数据集的用户操作。 对不起,不能用评论。