1

マウス ボタンをクリックすると、図を 2 軸で回転させることができます。マウス ボタンを離すと、Figure は元の位置で回転します。少し回すとすべてが正常に進みますが、図を大きく回転させると (<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 に答える