简体   繁体   中英

onObjectPicked is never called on Rajawali

I'm using the following code to display an OBJ model and I need to move it according to user gestures, however the onObjectPicked() is never called, just the onNoObjectPicked() .

What is wrong? And can I detect clicks on specific parts of my model?

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.MotionEvent;

import org.rajawali3d.Object3D;
import org.rajawali3d.cameras.Camera;
import org.rajawali3d.lights.DirectionalLight;
import org.rajawali3d.loader.LoaderOBJ;
import org.rajawali3d.loader.ParsingException;
import org.rajawali3d.materials.textures.TextureManager;
import org.rajawali3d.math.Matrix4;
import org.rajawali3d.math.vector.Vector3;
import org.rajawali3d.renderer.Renderer;
import org.rajawali3d.util.GLU;
import org.rajawali3d.util.ObjectColorPicker;
import org.rajawali3d.util.OnObjectPickedListener;

import javax.microedition.khronos.opengles.GL10;

/**
 * Created by juliano on 2/15/2017.
 */

public class CarRenderer extends Renderer implements OnObjectPickedListener {
    public Context mContext;

    private Camera mCamera;
    private Object3D mSelectedObject;
    private ObjectColorPicker mPicker;
    private Matrix4 mViewMatrix;
    private Matrix4 mProjectionMatrix;
    private int[] mViewport;
    private double[] mNearPos4;
    private double[] mFarPos4;
    private Vector3 mNearPos;
    private Vector3 mFarPos;
    private Vector3 mNewObjPos;


    public CarRenderer(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    protected void initScene() {
        getCurrentScene().setBackgroundColor(Color.WHITE);

        DirectionalLight key = new DirectionalLight(-8, 8, 8);
        key.setPosition(new Vector3(8,8,8));
        key.setPower(8);
        getCurrentScene().addLight(key);

        mCamera = getCurrentCamera();
        mCamera.setPosition(12, 12, 12);
        mCamera.setLookAt(Vector3.ZERO);

        mViewport = new int[] { 0, 0, getViewportWidth(), getViewportHeight() };
        mViewMatrix = getCurrentCamera().getViewMatrix();
        mProjectionMatrix = getCurrentCamera().getProjectionMatrix();
        mNearPos4 = new double[4];
        mFarPos4 = new double[4];
        mNearPos = new Vector3();
        mFarPos = new Vector3();
        mNewObjPos = new Vector3();

        try {
            mPicker = new ObjectColorPicker(this);
            mPicker.setOnObjectPickedListener(this);

            LoaderOBJ parser = new LoaderOBJ(mContext.getResources(), TextureManager.getInstance(), R.raw.ferrari_obj);
            parser.parse();

            Object3D o = parser.getParsedObject();
            getCurrentScene().addChild(o);
            mPicker.registerObject(o);

        } catch (ParsingException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onRenderSurfaceSizeChanged(GL10 gl, int width, int height) {
        super.onRenderSurfaceSizeChanged(gl, width, height);
        mViewport[2] = getViewportWidth();
        mViewport[3] = getViewportHeight();
        mViewMatrix = getCurrentCamera().getViewMatrix();
        mProjectionMatrix = getCurrentCamera().getProjectionMatrix();
    }

    @Override
    public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {

    }

    @Override //This method moves the camera using direct touch events. Tracking a flick and turning it into a procedural animation for smoothing
    public void onTouchEvent(MotionEvent me) {
    }

    @Override
    public void onObjectPicked(@NonNull Object3D object) {
        mSelectedObject = object;
    }

    @Override
    public void onNoObjectPicked() {
        Log.d("CarRenderer", "No object picked");
    }

    public void getObjectAt(float x, float y) {
        mPicker.getObjectAt(x, y);
    }

    public void moveSelectedObject(float x, float y) {
        if (mSelectedObject == null)
            return;

        //
        // -- unproject the screen coordinate (2D) to the camera's near plane
        //

        GLU.gluUnProject(x, getViewportHeight() - y, 0, mViewMatrix.getDoubleValues(), 0,
                mProjectionMatrix.getDoubleValues(), 0, mViewport, 0, mNearPos4, 0);

        //
        // -- unproject the screen coordinate (2D) to the camera's far plane
        //

        GLU.gluUnProject(x, getViewportHeight() - y, 1.f, mViewMatrix.getDoubleValues(), 0,
                mProjectionMatrix.getDoubleValues(), 0, mViewport, 0, mFarPos4, 0);

        //
        // -- transform 4D coordinates (x, y, z, w) to 3D (x, y, z) by dividing
        // each coordinate (x, y, z) by w.
        //

        mNearPos.setAll(mNearPos4[0] / mNearPos4[3], mNearPos4[1]
                / mNearPos4[3], mNearPos4[2] / mNearPos4[3]);
        mFarPos.setAll(mFarPos4[0] / mFarPos4[3],
                mFarPos4[1] / mFarPos4[3], mFarPos4[2] / mFarPos4[3]);

        //
        // -- now get the coordinates for the selected object
        //

        double factor = (Math.abs(mSelectedObject.getZ()) + mNearPos.z)
                / (getCurrentCamera().getFarPlane() - getCurrentCamera()
                .getNearPlane());

        mNewObjPos.setAll(mFarPos);
        mNewObjPos.subtract(mNearPos);
        mNewObjPos.multiply(factor);
        mNewObjPos.add(mNearPos);

        mSelectedObject.setX(mNewObjPos.x);
        mSelectedObject.setY(mNewObjPos.y);
    }

    public void stopMovingSelectedObject() {
        mSelectedObject = null;
    }
}

Also add the method that is called from the activity when the touch event was fired:

@Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub
    renderer.onTouchEvent(event);
    return super.onTouchEvent(event);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM