3D数学基础 第二章:向量/矢量(续)
Drag
计算Collider到中心的偏移量
- 首先3D应用不同于2D,多了一个方向之后很多情况都不太一样,需要考虑的更细致一点
- 当拖拽开始时,计算并记录一个初始的偏移量
mBeginDrag,用于后续在拖拽过程中计算物体位置的变化。计算方法是将物体的世界位置减去碰撞器的世界位置,这个偏移量表示物体初始位置与碰撞点的偏移 - 获取当前碰撞器的世界位置
worldPos - 将
worldPos与初始偏移量mBeginDrag相加,得到更新后的物体位置updatePos1
const updatePos = glvec3.add([], worldPos, this.mBeginDrag) as vec3; - 更新物体位置
手柄到物体的距离固定 防止物体远离
-
在
onDrag的Begin标志位,记录设备位置与碰撞点位置之间的距离mDistance,以及碰撞盒(Collider)到物体中心点的方向向量mDiffVec3- 只有在
Begin设置isDrag为true,让物体在这一帧的update更新坐标
1
2
3
4
5
6
7
8const deviceObj = EventSystem.current().getInputDeviceObject(args.device());
this.mDistance = glm.vec3.distance(deviceObj.worldPosition(), collider.worldPosition);
this.mDiffVec3 = glm.vec3.subtract(
[],
collider.worldPosition,
this.mSceneObj.worldPosition(),
) as vec3; - 只有在
-
使用输入设备的旋转信息将初始方向向量
[0, 0, -1]转换为世界坐标系中的方向向量。这个方向向量表示了物体应该移动的方向。1
const dir = glm.vec3.transformQuat([], [0, 0, -1], deviceRotation); -
计算更新后的物体位置。首先,将设备位置和方向向量的缩放(根据
mDistance)相加,以计算出物体在输入设备方向上移动的距离。然后,从这个总的位置变量中减去之前计算得到的差向量mDiffVec3,这样就得到了物体的新位置。glm.vec3.scale([], dir, this.mDistance): 这部分代码使用glm.vec3.scale函数,将方向向量dir缩放(按照this.mDistance的大小),以计算在输入设备方向上移动的距离。这里的dir是表示拖拽方向的一个单位向量。glm.vec3.add([], devicePosition, ...):这部分代码将devicePosition(输入设备的位置)和上一步中计算得到的移动距离相加。这样,我们得到了物体应该移动到的位置。glm.vec3.subtract([], ..., this.mDiffVec3):最后,这部分代码使用glm.vec3.subtract函数,将上一步计算得到的新位置和之前计算得到的差向量this.mDiffVec3相减。这个差向量表示了物体相对于拖拽点的初始偏移。通过将新位置和差向量相减,我们就得到了物体的最终更新位置。1
2
3
4
5
6
7
8
9const updatePosition = glm.vec3.subtract(
[],
glm.vec3.add(
[],
devicePosition,
glm.vec3.scale([], dir, this.mDistance),
),
this.mDiffVec3,
) as vec3;
1 | |
Rotation
四元数进行旋转
- 监听
onDrag事件 - 在
onDrag的Begin中获取当前元素的localPosition记做startPosition - 在
onDrag的Update/End中获取当前元素的localPosition记做endPosition - 计算两个向量夹角的四元数表示形式
- 获取到上一帧的
rotation四元数 - 将两个四元数进行叠加得到新的四元数
优点很明显:四元数本身自带方向,不需要额外计算旋转方向;但是需要理解旋转四元数的概念
欧拉角进行旋转
- 监听
onDrag事件 - 在
onDrag的Begin中获取当前元素的localPosition记做startPosition - 在
onDrag的Update/End中获取当前元素的localPosition记做endPosition - 计算两个向量的点积得到两个向量的
cosθ然后反解出对应的角度θ从而计算出欧拉角 - 根据两个向量的叉积计算出旋转方向
- 拿到上一帧的
euler乘上计算出的旋转方向,进行更新
缺点很多:比如不能一次更新x,y,z三个轴的欧拉角,同时可能会有卡顿(亲测),而且需要计算旋转方向
1 | |
3D数学基础 第二章:向量/矢量(续)
https://jing-jiu.github.io/jing-jiu/2023/08/26/notebooks/3D数学基础:图形和游戏开发/第二章:向量(续)/