Вращение вокруг 3D-объекта при касании с использованием фреймворка min3d/Rajawali (android)

Я работаю над алгоритмом вращения камеры вокруг 3D-объекта с использованием фреймворка Min3d/Rajawali.

В моей реализации вращение вокруг оси X работает неправильно. Я думаю, что метод setLookAt() не работает должным образом.

Проблема:

Когда я поворачиваю сферу вертикально, я не вижу ее полностью. Например, поворачивая планету Земля, я не могу полностью увидеть Антарктиду, потому что алгоритм сбрасывает камеру вниз.

Можно ли реализовать вращение камеры вокруг объекта без использования метода setLookAt?

Я пробовал разные решения, но не смог заставить его работать правильно.

Ниже мой код:

initScene:
    scene.camera().position.z = 90;
    scene.camera().target = raketeOBJ.position();

onTouchEvent:
    public boolean onTouchEvent(MotionEvent me) {
     if (me.getAction() == MotionEvent.ACTION_DOWN) {
        xpos = me.getX();
        ypos = me.getY();
        return true;
    }

    if (me.getAction() == MotionEvent.ACTION_UP) {
        xpos = -1;
        ypos = -1;
        touchTurn = 0;
        touchTurnUp = 0;
        return true;
    }

    if (me.getAction() == MotionEvent.ACTION_MOVE) {
        float xd = me.getX() - xpos;
        float yd = me.getY() - ypos;

        xpos = me.getX();
        ypos = me.getY();

        touchTurn = xd / -200f;
        touchTurnUp = yd / -200f;
        return true;
    }

    try {
        Thread.sleep(15);
    } catch (Exception e) {

    }

    return super.onTouchEvent(me);
}

UpdateScene:

    if (touchTurn != 0) {
        scene.camera().position.rotateY(touchTurn);
        touchTurn = 0;
    }

    if (touchTurnUp != 0) {
        scene.camera().position.rotateX(touchTurnUp);
        touchTurnUp = 0;
    }

Number3d target = scene.camera.target;
Number3d cp = scene.camera.position.clone();
// move position like target is (0,0,0)
cp.x -= target.x;
cp.y -= target.y;
cp.z -= target.z;

cp.roateX(angle);

// restore offset
cp.x += target.x;
cp.y += target.y;
cp.z += target.z;
scene.camera.position.setAllFrom(cp);

person Timur Gudkov    schedule 04.08.2012    source источник
comment
Этот Stack Exchange предназначен для конкретных вопросов. Этот вопрос слишком широк. Пожалуйста, покажите нам, что вы пытались и какие проблемы у вас возникли. Тогда люди здесь могут помочь вам. Спасибо   -  person prolink007    schedule 05.08.2012
comment
Я попытался реализовать вращение камеры вокруг сферы. Проблема в том, что вращение вокруг оси X работает неправильно. Я использовал этот код: pastebin.com/g9pLa61M Я думаю, что метод setLookAt() работает неправильно.   -  person Timur Gudkov    schedule 05.08.2012
comment
Когда я поворачиваю сферу вертикально, я не вижу ее полностью. Например, поворачивая планету Земля, я не могу полностью увидеть Антарктиду, потому что алгоритм сбрасывает камеру вниз. Подскажите, пожалуйста, можно ли реализовать вращение камеры вокруг объекта без использования метода setLookAt?   -  person Timur Gudkov    schedule 05.08.2012


Ответы (3)


Немного поздно, но на случай, если у кого-то возникнут проблемы с этим, как у меня.

Rajawali предлагает камеру под названием ArcballCamera, которая делает именно то, что вы/мы пытаетесь сделать.

В вашем Renderer добавьте следующее:

 ArcballCamera arcball = new ArcballCamera(mContext, ((Activity)mContext).findViewById(R.id.contentView)); 
 arcball.setTarget(mObjectGroup); //your 3D Object

 arcball.setPosition(0,0,4); //optional

 getCurrentScene().replaceAndSwitchCamera(getCurrentCamera(), arcball);

теперь вы можете вращать и масштабировать объект без дюжины строк кода.

person freg    schedule 17.12.2015
comment
как мы можем установить положение ArcballCamera относительно 3D-объекта. В настоящее время мне нужно изменить положение камеры при изменении размера 3D-объекта. - person dilz; 12.01.2016

setLookAt() необходимо вызывать onDrawFrame, если вы хотите, чтобы камера регулярно обновлялась. Но вам нужно больше заботиться о создании «RotateAroundAnimation». Подробнее см. здесь: http://www.rozengain.com/blog/2012/03/26/rajawali-tutorial-12-animation-classes/

Вам нужно будет сделать yourAnimation.setTransformable3D(mCamera), и тогда он должен управлять вашей основной камерой. Я часто использую эту методологию, а затем вызываю «yourAnimation.start()» при касании или другом внешнем стимуле.

person Davhed    schedule 21.01.2013

Это мой способ повернуть 3D-модель по осям x и y.

в классе рендеринга

public boolean left, right;
public boolean up, down;

и в onDrawFrame

@Override
public void onDrawFrame(GL10 glUnused) {
    super.onDrawFrame(glUnused);
    // getCurrentCamera().setRotY(getCurrentCamera().getRotY() + 1);
    if (left) {
        getCurrentCamera().setRotX(getCurrentCamera().getRotX() - 1);
    }
    if (right) {
        getCurrentCamera().setRotX(getCurrentCamera().getRotX() + 1);
    }
    if (up) {
        getCurrentCamera().setRotY(getCurrentCamera().getRotY() - 1);
    }
    if (down) {
        getCurrentCamera().setRotY(getCurrentCamera().getRotY() + 1);
    }
}

и в MainActivity

@Override
public boolean onTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        xpos = event.getX();
        ypos = event.getY();
    }

    if (event.getAction() == MotionEvent.ACTION_UP) {
        xpos = -1;
        ypos = -1;
        mRender.left = false;
        mRender.right = false;
        mRender.up = false;
        mRender.down = false;

    }

    if (event.getAction() == MotionEvent.ACTION_MOVE) {
        xd = event.getX() - xpos;
        yd = event.getY() - ypos;

        xpos = event.getX();
        ypos = event.getY();

        if (xd < 0) {
            mRender.up = true;
        } else {
            mRender.down = true;
        }
        if (yd < 0) {
            mRender.left = true;
        } else {
            mRender.right = true;
        }

    }

    return super.onTouchEvent(event);
}

таким образом, я могу вращать свою модель :)

person user3758792    schedule 02.10.2014