OpenGL添加触控

1.glSurfaceView添加监听触控事件

//4.glSurfaceView添加监听触控事件
        glSurfaceView.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                if(event!=null){
                    //触屏坐标转化成归一化坐标,即[-1,1]
                    final float normalizedX = (event.getX()/(float)v.getWidth())*2-1;
                    final float normalizedY = -((event.getY()/(float)v.getHeight())*2-1);
                    //转发触控事件给渲染器
                    if(event.getAction() == MotionEvent.ACTION_DOWN){
                        glSurfaceView.queueEvent(new Runnable() {

                            @Override
                            public void run() {
                                //调用渲染器按压事件
                                renderer.handleTouchPress(normalizedX,normalizedY);
                            }
                        });
                    } else if(event.getAction() == MotionEvent.ACTION_MOVE){
                        glSurfaceView.queueEvent(new Runnable() {

                            @Override
                            public void run() {
                                //调用渲染器拖拽事件
                                renderer.handleTouchDrag(normalizedX,normalizedY);
                            }
                        });
                    }
                    return true;
                } else {
                    return false;
                }
            }
        });

2.屏幕坐标归一化坐标转化成三维射线
2.1采用反转视图投影矩阵
2.2定义归一化坐标为其次在投影近远平面上
2.3撤销透视除法
2.4得到射线在投影近远平面上的交点
2.5得到射线

private Ray convertNormalized2DPointToRay(float normalizedX, float normalizedY){
        //定义归一化坐标为其次在投影近远平面上
        final float[] nearPointNdc = {normalizedX, normalizedY, -1, 1}; 
        final float[] farPointNdc = {normalizedX, normalizedY, 1, 1}; 

        final float[] nearPointWorld = new float[4];
        final float[] farPointWorld = new float[4];
        //撤销透视除法
        multiplyMV(nearPointWorld, 0, invertedViewProjectionMatrix, 0, nearPointNdc, 0);
        multiplyMV(farPointWorld, 0, invertedViewProjectionMatrix, 0, farPointNdc, 0);

        divideByW(nearPointWorld);
        divideByW(farPointWorld);
        //得到射线在投影近远平面上的交点
        Point nearPointRay = new Point(nearPointWorld[0], nearPointWorld[1], nearPointWorld[2]);
        Point farPointRay = new Point(farPointWorld[0], farPointWorld[1], farPointWorld[2]);
        //得到射线
        return new Ray(nearPointRay, Geometry.vectorBetween(nearPointRay, farPointRay));
    }

3.射线与球距离计算
3.1射线起点和终点到球心的向量
3.2以上三点构成三角形,两向量的交叉乘积向量长度为三角形面积的两倍
3.3射线与球距离 = 两向量的交叉乘积向量长度/射线长度

    private static float distanceBetween(Point point, Ray ray) {
        //射线起点和终点到球心的向量
        Vector p1ToPoint = vectorBetween(ray.point, point);
        Vector p2ToPoint = vectorBetween(ray.point.translate(ray.vector), point);
        //以上三点构成三角形,两向量的交叉乘积向量长度为三角形面积的两倍
        float areaOfTriangleTimesTwo = p1ToPoint.crossProduce(p2ToPoint).length();
        float lengthOfBase = ray.vector.length();
        //射线与球距离 = 两向量的交叉乘积向量长度/射线长度
        return areaOfTriangleTimesTwo/lengthOfBase;
    }

4.通过拖动移动物体
4.1实际是射线与一平面的相交点来替代物体坐标
4.2计算射线到平面的向量
4.3缩放因子 = 射线到平面的向量与平面法向量向量之间的点积 / 射线向量与平面法向量向量的点积
4.4使用缩放因子平移射线点找出相交点

public static Point intersectionPoint(Ray ray, Plane plane){
        //计算射线到平面的向量
        Vector rayToPlaneVector = vectorBetween(ray.point, plane.point);
        //缩放因子 = 射线到平面的向量与平面法向量向量之间的点积 / 射线向量与平面法向量向量的点积
        float scaleFactor = rayToPlaneVector.dotProduct(plane.normal)
                / ray.vector.dotProduct(plane.normal);
        //使用缩放因子平移射线点找出相交点
        Point intersectionPoint = ray.point.translate(ray.vector.scale(scaleFactor));
        return intersectionPoint;
    }

5.碰撞后的速度与方向
5.1速度:向量长度大小(摩擦与加速度)
5.2方向:向量的方向(反弹)
5.3实现:当前点+向量
5.4向量由主动碰撞物上帧位置到当前位置向量决定
6.源码:https://github.com/HQlin/ShaderOpenGL/commits/master

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值