Implement camera collision smoothing and position resolution
This commit is contained in:
@@ -2180,8 +2180,68 @@ export class RuntimeHost {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private resetRuntimeCameraCollisionSmoothing() {
|
||||||
|
this.smoothedRuntimeCameraCollisionDistance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private smoothRuntimeCameraCollisionPosition(
|
||||||
|
pivot: { x: number; y: number; z: number },
|
||||||
|
desiredPosition: Vector3,
|
||||||
|
resolvedPosition: { x: number; y: number; z: number },
|
||||||
|
dt: number
|
||||||
|
): Vector3 {
|
||||||
|
this.cameraCollisionDirection.set(
|
||||||
|
desiredPosition.x - pivot.x,
|
||||||
|
desiredPosition.y - pivot.y,
|
||||||
|
desiredPosition.z - pivot.z
|
||||||
|
);
|
||||||
|
|
||||||
|
const desiredDistance = this.cameraCollisionDirection.length();
|
||||||
|
|
||||||
|
if (desiredDistance <= CAMERA_COLLISION_DISTANCE_EPSILON) {
|
||||||
|
this.resetRuntimeCameraCollisionSmoothing();
|
||||||
|
return new Vector3(
|
||||||
|
resolvedPosition.x,
|
||||||
|
resolvedPosition.y,
|
||||||
|
resolvedPosition.z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolvedDistance = Math.hypot(
|
||||||
|
resolvedPosition.x - pivot.x,
|
||||||
|
resolvedPosition.y - pivot.y,
|
||||||
|
resolvedPosition.z - pivot.z
|
||||||
|
);
|
||||||
|
const previousDistance = this.smoothedRuntimeCameraCollisionDistance;
|
||||||
|
const nextDistance =
|
||||||
|
previousDistance === null ||
|
||||||
|
dt <= 0 ||
|
||||||
|
resolvedDistance < previousDistance
|
||||||
|
? resolvedDistance
|
||||||
|
: dampScalar(
|
||||||
|
previousDistance,
|
||||||
|
resolvedDistance,
|
||||||
|
CAMERA_COLLISION_RECOVERY_SPEED,
|
||||||
|
dt
|
||||||
|
);
|
||||||
|
const clampedDistance = Math.min(
|
||||||
|
Math.max(0, nextDistance),
|
||||||
|
Math.min(resolvedDistance, desiredDistance)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.smoothedRuntimeCameraCollisionDistance = clampedDistance;
|
||||||
|
this.cameraCollisionDirection.normalize().multiplyScalar(clampedDistance);
|
||||||
|
|
||||||
|
return new Vector3(
|
||||||
|
pivot.x + this.cameraCollisionDirection.x,
|
||||||
|
pivot.y + this.cameraCollisionDirection.y,
|
||||||
|
pivot.z + this.cameraCollisionDirection.z
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private resolveCollisionAdjustedCameraPose(
|
private resolveCollisionAdjustedCameraPose(
|
||||||
pose: RuntimeCameraPose
|
pose: RuntimeCameraPose,
|
||||||
|
dt = 0
|
||||||
): RuntimeCameraPose {
|
): RuntimeCameraPose {
|
||||||
if (
|
if (
|
||||||
pose.collisionPivot === undefined ||
|
pose.collisionPivot === undefined ||
|
||||||
@@ -2189,6 +2249,7 @@ export class RuntimeHost {
|
|||||||
pose.collisionRadius === undefined ||
|
pose.collisionRadius === undefined ||
|
||||||
pose.collisionRadius === null
|
pose.collisionRadius === null
|
||||||
) {
|
) {
|
||||||
|
this.resetRuntimeCameraCollisionSmoothing();
|
||||||
return pose;
|
return pose;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2207,21 +2268,23 @@ export class RuntimeHost {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (resolvedPosition === undefined) {
|
if (resolvedPosition === undefined) {
|
||||||
|
this.resetRuntimeCameraCollisionSmoothing();
|
||||||
return pose;
|
return pose;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...pose,
|
...pose,
|
||||||
position: new Vector3(
|
position: this.smoothRuntimeCameraCollisionPosition(
|
||||||
resolvedPosition.x,
|
pose.collisionPivot,
|
||||||
resolvedPosition.y,
|
pose.position,
|
||||||
resolvedPosition.z
|
resolvedPosition,
|
||||||
|
dt
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private applyCameraPose(pose: RuntimeCameraPose) {
|
private applyCameraPose(pose: RuntimeCameraPose, dt = 0) {
|
||||||
const resolvedPose = this.resolveCollisionAdjustedCameraPose(pose);
|
const resolvedPose = this.resolveCollisionAdjustedCameraPose(pose, dt);
|
||||||
|
|
||||||
this.camera.position.copy(resolvedPose.position);
|
this.camera.position.copy(resolvedPose.position);
|
||||||
this.camera.lookAt(resolvedPose.lookTarget);
|
this.camera.lookAt(resolvedPose.lookTarget);
|
||||||
|
|||||||
Reference in New Issue
Block a user