欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > rajawali-自定义MapControls控制器实现缩放和拖拽

rajawali-自定义MapControls控制器实现缩放和拖拽

2026/6/3 15:08:33 来源:https://blog.csdn.net/sunboylife/article/details/143972056  浏览:    关键词:rajawali-自定义MapControls控制器实现缩放和拖拽

调用

new MapControls(CARME_OPERATOR.getObject(), getElementById(rajawaliSurfaceViewId));

MapControls控制器

MapControls

import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import com.wz.dhy.enums.GlobalViewTypeEnum;
import com.wz.dhy.enums.ScaleTypeEnum;
import com.wz.dhy.utils.pool.RequestAnimationFrame;
import com.wz.dhy.utils.three.ThreeObject;
import com.wz.dhy.utils.three.operator.CarOperator;
import org.rajawali3d.math.vector.Vector3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class MapControls {private static final Logger LOGGER = LoggerFactory.getLogger(MapControls.class);private static final ThreeObject THREE_OBJECT = ThreeObject.getInstance();private static final CarOperator CAR_OPERATOR = CarOperator.getInstance();private GestureDetector gestureDetector;private ScaleGestureDetector scaleGestureDetector;private final MyCarme myCarme;private final MyRajawaliSurfaceView myRajawaliSurfaceView;public MapControls(MyCarme myCarme, MyRajawaliSurfaceView myRajawaliSurfaceView) {this.myRajawaliSurfaceView = myRajawaliSurfaceView;this.myCarme = myCarme;bindEvent();}private void bindEvent() {gestureDetector = new GestureDetector(myRajawaliSurfaceView.getContext(), new GestureDetector.SimpleOnGestureListener());scaleGestureDetector = new ScaleGestureDetector(myRajawaliSurfaceView.getContext(), new ScaleGestureDetector.OnScaleGestureListener() {@Overridepublic boolean onScale(ScaleGestureDetector detector) {float scaleFactor = detector.getScaleFactor();double oldHeight = myCarme.getPosition().z;double newHeight = oldHeight / scaleFactor;LOGGER.debug("缩放");if (newHeight < oldHeight) {//增加相机高度} else if (newHeight > oldHeight) {//减少相机高度}return true;}@Overridepublic boolean onScaleBegin(ScaleGestureDetector detector) {LOGGER.info("开始缩放");return true;}@Overridepublic void onScaleEnd(ScaleGestureDetector detector) {// 结束缩放LOGGER.info("结束缩放");}});myRajawaliSurfaceView.setOnTouchListener(new View.OnTouchListener() {private float mX;private float mY;@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {gestureDetector.onTouchEvent(motionEvent);scaleGestureDetector.onTouchEvent(motionEvent);if (GlobalViewTypeEnum.NORMAL == THREE_OBJECT.getGlobal()) {return true;}switch (motionEvent.getAction()) {case MotionEvent.ACTION_DOWN:mX = motionEvent.getRawX();mY = motionEvent.getRawY();break;case MotionEvent.ACTION_MOVE:float moveX = motionEvent.getRawX() - mX;float moveY = motionEvent.getY() - mY;updateCameraRotation(moveX, moveY);mX = motionEvent.getRawX();mY = motionEvent.getRawY();// 更新位置break;}return true;}});}private void updateCameraRotation(float dx, float dy) {LOGGER.info("*******updateCameraRotation*******");float dx2 = -dx;float dy2 = -dy;if(GlobalViewTypeEnum.GLOBAL == THREE_OBJECT.getGlobal()){dx2 *= 10;dy2 *= 10;}float[] viewMatrix = myCarme.getTarget().getViewMatrix().getFloatValues();// 提取右侧和上方向量Vector3 right = new Vector3(viewMatrix[0], viewMatrix[4], viewMatrix[8]);Vector3 up = new Vector3(viewMatrix[1], viewMatrix[5], viewMatrix[9]);// 计算触摸变化量在世界坐标系中的投影Vector3 delta = new Vector3(dx2 * 0.01f, -dy2 * 0.01f, 0);Vector3 worldDelta = new Vector3(right.x * delta.x + up.x * delta.y,right.y * delta.x + up.y * delta.y,right.z * delta.x + up.z * delta.y);// 调整相机位置Vector3 cameraPosition = myCarme.getTarget().getPosition();cameraPosition.add(worldDelta);myCarme.getTarget().setPosition(cameraPosition);}
}

让我们重新整理一下代码,确保逻辑更加清晰:
解释
获取触摸点的变化量:
dx = x - mLastTouchX;:计算水平方向上的触摸变化量。
dy = y - mLastTouchY;:计算垂直方向上的触摸变化量。
获取相机的视图矩阵:
float[] viewMatrix = new float[16];:创建一个长度为16的浮点数组。
getCurrentCamera().getViewMatrix(viewMatrix);:获取相机的视图矩阵。
提取右侧和上方向量:
Vector3 right = new Vector3(viewMatrix[0], viewMatrix[4], viewMatrix[8]);:从视图矩阵中提取右侧向量。
Vector3 up = new Vector3(viewMatrix[1], viewMatrix[5], viewMatrix[9]);:从视图矩阵中提取上方向量。
计算触摸变化量在世界坐标系中的投影:
Vector3 delta = new Vector3(dx * 0.01f, -dy * 0.01f, 0);:计算触摸变化量 dx 和 dy 在世界坐标系中的投影,乘以一个小的系数(如0.01)来控制拖拽的灵敏度。
Vector3 worldDelta = new Vector3(…);:将触摸变化量 delta 投影到相机的右侧向量和上方向量上。
调整相机位置:
Vector3 cameraPosition = getCurrentCamera().getPosition();:获取当前相机的位置。
cameraPosition.add(worldDelta);:将计算得到的世界坐标系中的变化量 worldDelta 加到相机的位置上。
getCurrentCamera().setPosition(cameraPosition);:更新相机的位置。
更新触摸点位置:
mLastTouchX = x; 和 mLastTouchY = y;:更新上一次触摸点的位置,以便在下一次移动时计算新的变化量。
通过这种方式,你可以确保拖拽操作在任何相机姿态下都能正确工作,从而实现更自然的场景拖拽效果。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词