[英]Rotating 3D figure
I need to click the mouse button you can rotate the figure in 2 axes. 我需要单击鼠标按钮,才能沿2个轴旋转图形。 When you release the mouse button Figure be rotated in the original position.
当释放鼠标按钮时,图形将旋转到原始位置。 With a small turning everything goes as it should, but at a heavy rotation (<180) of the figure does not return to its original position.
稍微转弯,一切都会按预期进行,但是如果旋转大(<180),图形将不会返回其原始位置。
I do not see any mistakes. 我没有看到任何错误。 Help me.
帮我。
public class WaitActionScren extends Base3dGameScreen {
private static final int DEFAULT_INERT_VALUE = 5;
private int sumRotateX = 0, sumRotateY = 0;
private boolean isUp = false;
/**
* Constructor.
*
* @param game {@link MagicSphere} instance.
*/
public WaitActionScren(MagicSphere game) {
super(game);
}
@Override
public void create() {
super.create();
bitmapFontCache.setColor(Color.GREEN);
Gdx.input.setInputProcessor(new TouchEvents());
}
@Override
public void render(float deltaTime) {
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(instanceSphere, lights);
modelBatch.end();
}
@Override
public void update(float deltaTime) {
if (isUp) {
int inertValue = getInertValue(sumRotateX);
instanceSphere.transform.rotate(0, 1, 0, inertValue);
System.err.println("rotate_x : " + inertValue);
sumRotateX += inertValue;
inertValue = getInertValue(sumRotateY);
instanceSphere.transform.rotate(1, 0, 0, inertValue);
System.err.println("rotate_y : " + inertValue);
sumRotateY += inertValue;
}
}
// TODO non static.
private static int getInertValue(int sumRotate) {
if(sumRotate > 0) {
if (sumRotate < DEFAULT_INERT_VALUE) {
return -sumRotate;
}
return -DEFAULT_INERT_VALUE;
}
if(sumRotate < 0) {
if (sumRotate > -DEFAULT_INERT_VALUE) {
return -sumRotate;
}
return DEFAULT_INERT_VALUE;
}
return 0;
}
@Override
public void dispose() {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
class TouchEvents implements InputProcessor {
private int oldX = 0, oldY = 0;
@Override
public boolean keyDown(int keycode) {
return false;
}
@Override
public boolean keyUp(int keycode) {
return false;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
oldX = 0;
oldY = 0;
isUp = true;
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
if (oldX != 0 || oldY != 0) {
float change;
change = screenX - oldX;
instanceSphere.transform.rotate(0, 1, 0, change);
System.err.println("X: " + change);
sumRotateX += change;
change = screenY - oldY;
instanceSphere.transform.rotate(1, 0, 0, change);
System.err.println("X: " + change);
sumRotateY += change;
}
oldX = screenX;
oldY = screenY;
isUp = false;
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
}
}
Without having the relevant library its hard for me to be sure but I think you might be falling fowl of the order of rotations problem; 没有相关的库,我很难确定,但是我认为您可能不了解轮换顺序问题; that being that if you rotate around the y axis by 90 degrees then about the z axis by 90 degrees that is not the same as rotating around z then y.
也就是说,如果您绕y轴旋转90度,然后绕z轴旋转90度,则与绕z轴旋转y并不相同。 So given that you always rotate about y then about x when you come to undo a rotation you're not really undoing it, you're performing annother rotation.
因此,假设您总是要绕y旋转,然后绕x旋转,则撤消旋转并不是真的要撤消旋转,而是要进行另一次旋转。
To demonstrate this, lets start with a vector pointed along the x axis, and we're going to rotate 90 degrees about y and z, but in different orders 为了说明这一点,让我们从沿x轴指向的向量开始,我们将围绕y和z旋转90度,但顺序不同
As you can see the order of operations is very important, so if you first rotate x then y, in order to undo that you need to rotate -y then -x. 如您所见,操作顺序非常重要,因此,如果先旋转x然后将y旋转,要撤消操作,需要先旋转-y然后旋转-x。
I have achieved the desired result. 我已经达到了预期的结果。 I hope this will be useful for someone.
我希望这对某人有用。
public class WaitActionScren extends Base3dGameScreen {
private static final float DEFAULT_INERT_VALUE = 7f;
private float sumY = 0;
private float sumX = 0;
private boolean isUp = false;
/**
* Constructor.
*
* @param game {@link MagicSphere} instance.
*/
public WaitActionScren(MagicSphere game) {
super(game);
}
@Override
public void create() {
super.create();
bitmapFontCache.setColor(Color.GREEN);
Gdx.input.setInputProcessor(new TouchEvents());
}
@Override
public void render(float deltaTime) {
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(instanceSphere, lights);
modelBatch.end();
}
@Override
public void update(float deltaTime) {
if (isUp) {
Quaternion rotation = new Quaternion();
instanceSphere.transform.getRotation(rotation);
float xInert = getInertValue(sumX);
float yInert = getInertValue(sumY);
sumX += xInert;
sumY += yInert;
Vector3 v3 = new Vector3(sumY, sumX, 0);
float len = v3.len();
v3 = v3.nor();
rotation.setFromAxis(v3.x, v3.y, v3.z, len);
instanceSphere.transform.set(rotation);
}
}
private float getInertValue(float sumRotate) {
if(sumRotate > 0.0f) {
if (sumRotate < DEFAULT_INERT_VALUE) {
return -sumRotate;
}
return -DEFAULT_INERT_VALUE;
}
if(sumRotate < 0.0f) {
if (sumRotate > -DEFAULT_INERT_VALUE) {
return -sumRotate;
}
return DEFAULT_INERT_VALUE;
}
return 0;
}
@Override
public void dispose() {
}
@Override
public void pause() {
}
@Override
public void resume() {
}
class TouchEvents implements InputProcessor {
private float oldX = 0.0f, oldY = 0.0f;
@Override
public boolean keyDown(int keycode) {
return false;
}
@Override
public boolean keyUp(int keycode) {
return false;
}
@Override
public boolean keyTyped(char character) {
return false;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
oldX = screenX;
oldY = screenY;
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
oldX = 0.0f;
oldY = 0.0f;
isUp = true;
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
float changeX;
float changeY;
changeX = screenX - oldX;
changeY = screenY - oldY;
sumX += changeX;
sumY += changeY;
Vector3 v3 = new Vector3(sumY, sumX, 0.0f);
float length = v3.len();
v3 = v3.nor();
Quaternion rotation = new Quaternion();
instanceSphere.transform.getRotation(rotation);
rotation.setFromAxis(v3.x, v3.y, v3.z, length);
instanceSphere.transform.set(rotation);
oldX = screenX;
oldY = screenY;
isUp = false;
return false;
}
@Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
@Override
public boolean scrolled(int amount) {
return false;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.