我在我的应用程序中使用 min3D 库成功渲染了一个 3D 模型。
我使用四元数数据 (x,y,z,w) 进行旋转和翻转。
旋转非常适合正面,当我将其翻转到另一面时,旋转与实际方向相反。
我所说的“在相反的面上”是指当我向右旋转时,立方体向左旋转,反之亦然。
我使用的代码:
@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());
用于旋转