1

我需要单击鼠标按钮,您可以在 2 个轴上旋转图形。当您松开鼠标按钮时,图形会旋转到原始位置。稍微转动一下,一切都按原样进行,但在剧烈旋转 (<180) 时,图形不会回到原来的位置。

我没有看到任何错误。帮我。

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

    }
}
4

2 回答 2

1

如果没有相关的图书馆,我很难确定,但我认为你可能会陷入轮换顺序问题;也就是说,如果您围绕 y 轴旋转 90 度,然后围绕 z 轴旋转 90 度,这与围绕 z 然后 y 旋转不同。因此,当您撤消旋转时,您始终围绕 y 旋转然后围绕 x 旋转,您并没有真正撤消它,您正在执行另一个旋转。

为了证明这一点,让我们从一个指向 x 轴的向量开始,我们将围绕 y 和 z 旋转 90 度,但顺序不同

首先是关于 y 然后是关于 z

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

首先关于 z 然后关于 y

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

结论

如您所见,操作顺序非常重要,因此如果先旋转 x 再旋转 y,为了撤消该操作,您需要先旋转 -y 然后旋转 -x。

于 2013-09-20T20:13:55.447 回答
0

我已经达到了预期的结果。我希望这对某人有用。

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;
        }
    }
}
于 2013-09-23T21:29:39.017 回答