BabylonJS-相机与相机行为

在Babylon.js提供的许多相机中,两个最常用的可能是通用摄像机UniversalCamera/FreeCamera, 弧形旋转摄像机ArcRotateCamera

一、通用摄像机UniversalCamera/FreeCamera

现在是Babylon.js使用的默认摄像机,它由键盘、鼠标、触摸或 手柄 控制,具体取决于所使用的输入设备,不需要指定控制器。

默认操作为:

  1. 键盘------左右箭头键可以左右移动摄像机,上下箭头键可以前后移动;
  2. 鼠标-以相机为原点绕轴旋转相机;
  3. 触控------左右滑动可左右移动摄像机,上下滑动可前后移动摄像机;
  4. 游戏手柄-对应设备。

可选操作有:

  1. 鼠标滚轮-他在鼠标上滚动滚轮或在触摸板上滚动动作
kotlin 复制代码
import {
  Engine,
  Scene,
  UniversalCamera,
  FreeCamera,
  ArcRotateCamera,
  FollowCamera,
  AnaglyphUniversalCamera,
  AnaglyphArcRotateCamera,
  DeviceOrientationCamera,
  Vector3,
  MeshBuilder,
  HemisphericLight,
} from '@babylonjs/core'

//创建一个名为 BabylonScene 的类
export class BabylonScene {
  engine: Engine
  scene: Scene

  //private将属性或方法标记为私有,表示它们只能在类的内部被访问,外部无法直接访问。
  constructor(private canvas: HTMLCanvasElement) {
    this.engine = new Engine(this.canvas, true) //渲染引擎
    this.scene = this.CreateScene() //场景
    // 渲染场景
    this.engine.runRenderLoop(() => {
      this.scene.render()
    })
  }

  CreateScene(): Scene {
    const scene = new Scene(this.engine) // 创建场景

    /**
     * 通用摄像机UniversalCamera/FreeCamera
     * 配置项:相机名称,位置,场景
     */
    const camera = new UniversalCamera(
      'UniversalCamera',
      new Vector3(0, 0, -10),
      scene
    )
    // const camera = new FreeCamera("FreeCamera", new Vector3(0, 5, -10), scene);

    //启用鼠标滚轮输入
    camera.inputs.addMouseWheel();
    // 相机定位到原点
    camera.setTarget(Vector3.Zero())

    camera.attachControl(this.canvas, true) //让相机控制画布

    // 创建半球形光源
    const light = new HemisphericLight('light', new Vector3(0, 1, 0), scene)

    // 创建球形
    const sphere = MeshBuilder.CreateSphere(
      'sphere',
      { diameter: 2, segments: 32 },
      scene
    )
    // 将球向上移动球高度的1/2
    sphere.position.y = 1
    sphere.position.x = 2

    return scene
  }
}

示例链接

二、弧形旋转摄像机ArcRotateCamera

这个摄像机总是指向一个给定的目标位置,并且可以以目标为旋转中心围绕该目标旋转。 把这个相机想象成一个围绕目标位置旋转的相机,或者想象成一个围绕地球旋转的卫星。它相对于目标("地球")的位置可以通过三个参数来设置:

  • α(以弧度表示的纵向旋转)
  • β(以弧度表示的纬向旋转),以及
  • 半径(与目标的距离)

beta顺时针方向增加,而 alpha逆时针方向增加。

无论是使用键盘、鼠标还是触摸式滑动,左/右方向都会改变 alpha,向上/向下方向改变 beta.

默认情况下,弧形旋转摄像机也可以通过使用 Ctrl+ 鼠标左键/右键移动模型。可以通过camera.panningSensibility = 0;停用摇摄

javascript 复制代码
     /**
     * 弧形旋转摄像机ArcRotateCamera
     * 配置项:相机名称,初始经度,初始纬度,与焦点距离,位置,场景
     */
    const camera = new ArcRotateCamera(
      'ArcRotateCamera',
      Math.PI / 8,
      Math.PI / 8,
      10,
      new Vector3(0, 0, 0),
      scene
    )

    // 相机定位
    camera.setPosition(new Vector3(10, 0, 10));
    //禁用相机平移
    camera.panningSensibility = 0;
    camera.attachControl(this.canvas, true) //让相机控制画布

示例链接

弧形旋转摄像机也可以跟随角色,将摄像机作为角色的父代即可(camera.parent = dude;)

示例链接

三、跟随相机FollowCamera

Follow Camera的初始位置是在创建时设置的,然后通过三个参数设置目标位置:

  1. 半径:与目标的距离
  2. 高度偏移:高于目标的高度;
  3. 旋转偏移量:在x-y平面上,目标以度为单位的目标角。

摄像机移动到目标位置的速度通过其加速( 相机加速)到最大速度(最大 摄像速度)来设定。

ini 复制代码
     /**
     * 跟随相机FollowCamera
     * 配置项:相机名称,位置,场景
     */
    const camera = new FollowCamera('FollowCamera', new Vector3(0, 0, 0), scene)
    // 与目标的距离
    camera.radius = 30

    // 高于目标的高度
    camera.heightOffset = 10

    // 在x-y平面上,目标以度为单位的目标角
    camera.rotationOffset = 0

    // 加速度
    camera.cameraAcceleration = 0.0005

    // 最大相机速度
    camera.maxCameraSpeed = 10
    
    //相机要跟随的目标
    camera.lockedTarget = targetMesh;
    camera.attachControl(this.canvas, true) //让相机控制画布

示例链接

四、立体相机(立体通用相机 AnaglyphUniversalCamera/立体弧形旋转相机 AnaglyphArcRotateCamera)

立体相机扩展了通用相机和弧形旋转相机,可用于红蓝3d眼镜查看立体效果。它是通过后处理实现的效果。

arduino 复制代码
     /**
     * 立体通用相机 AnaglyphUniversalCamera
     * 配置项:相机名称,位置,左右眼偏移量,场景
     */
    const camera = new AnaglyphUniversalCamera("af_cam", new Vector3(0, 1, -15), 0.033, scene);
    camera.attachControl(this.canvas, true) //让相机控制画布
arduino 复制代码
     /**
     * 立体弧形旋转相机 AnaglyphArcRotateCamera
     * 配置项:相机名称,初始经度,初始纬度,与焦点距离,位置,左右眼偏移量,场景
     */
    const camera = new AnaglyphUniversalCamera("af_cam", new Vector3(0, 1, -15), 0.033, scene);
    camera.attachControl(this.canvas, true) //让相机控制画布

五、设备定位摄像机DeviceOrientationCamera

设备定位摄像机是专门设计用来对设备定位事件做出反应的,比如现代移动设备被向前、向后、左或右倾斜。

arduino 复制代码
     /**
     * 设备定位摄像机DeviceOrientationCamera
     * 配置项:相机名称,位置,场景
     */
    const camera = new DeviceOrientationCamera(
      'DevOr_camera',
      new Vector3(0, 0, 0),
      scene
    )

    // 相机定位到特定位置
    camera.setTarget(new Vector3(0, 0, -10))

    // 设置相机对移动和旋转的灵敏度
    camera.angularSensibility = 10
    camera.moveSensibility = 10
    camera.attachControl(this.canvas, true) //让相机控制画布

示例链接

六、相机行为

弧形旋转摄像机ArcRotateCamera有三种相机行为:

1、弹跳行为

可以使用以下属性配置此行为:

  • transitionDuration:定义动画的持续时间(以毫秒为单位)。默认值为450ms。
  • lowerRadiusTransitionRange:定义到达较低半径时由过渡动画驱动的距离的长度。默认值为2。
  • upperRadiusTransitionRange:定义到达上半径时由过渡动画驱动的距离的长度。默认值为---2。
  • autoTransitionRange:定义一个值,指示是否 lowerRadiusTransitionRangeupperRadiusTransitionRange都是自动定义的。过渡范围将设置为世界空间中限界框对角线的5%。
javascript 复制代码
     /**
     * 弧形旋转摄像机ArcRotateCamera
     * 配置项:相机名称,初始经度,初始纬度,与焦点距离,位置,场景
     */
    const camera = new ArcRotateCamera(
      'ArcRotateCamera',
      Math.PI / 8,
      Math.PI / 8,
      10,
      new Vector3(0, 0, 0),
      scene
    )

    // 相机定位
    camera.setPosition(new Vector3(10, 0, 10))
    //禁用相机平移
    camera.panningSensibility = 0

    //相机距离焦点的距离范围
    camera.lowerRadiusLimit = 6
    camera.upperRadiusLimit = 20
    // 启用弹跳行为,当距离 小于lowerRadiusLimit 或者大于upperRadiusLimit的值时,会恢复原状
    camera.useBouncingBehavior = true
    camera.attachControl(this.canvas, true) //让相机控制画布

示例链接

2、自动旋转行为

可以使用以下属性配置此行为:

  • idleRotationSpeed:摄像机围绕网格旋转的速度
  • idleRotationWaitTime用户交互后相机开始旋转前等待的时间(毫秒)
  • idleRotationSpinupTime:旋转到完全空闲旋转速度所需的时间(毫秒)
  • zoomStopsAnimation:指示用户缩放是否应停止动画的标志
javascript 复制代码
     /**
     * 弧形旋转摄像机ArcRotateCamera
     * 配置项:相机名称,初始经度,初始纬度,与焦点距离,位置,场景
     */
    const camera = new ArcRotateCamera(
      'ArcRotateCamera',
      Math.PI / 8,
      Math.PI / 8,
      10,
      new Vector3(0, 0, 0),
      scene
    )

    // 相机定位
    camera.setPosition(new Vector3(10, 0, 10))
    //禁用相机平移
    camera.panningSensibility = 0

    // 启用相机默认旋转行为
    camera.useAutoRotationBehavior = true
    // 相机转动的速度
    camera!.autoRotationBehavior!.idleRotationSpeed = 0.5
    // 旋转至全怠速所需的时间
    camera!.autoRotationBehavior!.idleRotationSpinupTime = 1000
    // 用户交互到开始旋转之间的等待时间
    camera.autoRotationBehavior!.idleRotationWaitTime = 2000
    // 缩放停止相机旋转动画
    camera.autoRotationBehavior!.zoomStopsAnimation = true

    camera.attachControl(this.canvas, true) //让相机控制画布

示例链接

3、框架行为

可以使用以下属性配置此行为:

  • mode:行为可以配置为:
  • BABYLON.FramingBehavior.IgnoreBoundsSizeMode:摄像机可以一路移动到网格
  • BABYLON.FramingBehavior.FitFrustumSidesMode:不允许摄像机缩放到比调整的边界球接触平截头体侧面的点更靠近网格的位置
  • radiusScale:定义应用于半径的比例(默认为1)
  • positionScale:设置要在Y轴上应用的刻度,以定位相机焦点。(默认值为0.5,即限界框的中心)
  • defaultElevation:定义触发返回到默认高程空闲行为时要返回的水平面上方/下方的角度(以弧度为单位)(默认值为0.3)
  • elevationReturnTime:定义返回到默认测试位置(默认为1500)所需的时间(以毫秒为单位)。负值表示相机不应返回到默认值。
  • elevationReturnWaitTime:定义相机返回到默认测试位置(默认为1000)之前拍摄的延迟(以毫秒为单位)
  • zoomStopsAnimation:定义用户缩放是否应该停止动画
  • framingTime:定义网格成帧时的过渡时间,以毫秒为单位(默认为1500)
arduino 复制代码
     /**
     * 弧形旋转摄像机ArcRotateCamera
     * 配置项:相机名称,初始经度,初始纬度,与焦点距离,位置,场景
     */
    const camera = new ArcRotateCamera(
      'ArcRotateCamera',
      Math.PI / 8,
      Math.PI / 8,
      10,
      new Vector3(0, 0, 0),
      scene
    )

    // 创建半球形光源
    const light = new HemisphericLight('light', new Vector3(0, 1, 0), scene)

    // 创建球形
    const sphere = MeshBuilder.CreateSphere(
      'sphere',
      { diameter: 2, segments: 32 },
      scene
    )
    // 将球向上移动球高度的1/2
    sphere.position.y = 1
    sphere.position.x = 2

    //启用框架行为
    camera.useFramingBehavior = true
    // 聚焦半径
    camera.framingBehavior!.radiusScale = 1
    // 聚焦时间
    camera.framingBehavior!.framingTime = 4 * 1000
    // 显示网格框架
    sphere.showBoundingBox = true
    // 相机聚焦到网格
    camera.setTarget(sphere)
    camera.attachControl(this.canvas, true) //让相机控制画布

示例链接

相关推荐
驻风丶3 分钟前
el-tooltips设置文字超出省略才显示
前端·javascript·vue.js
nnlss16 分钟前
nvm 安装node 报错
前端
酷盖机车男21 分钟前
封装轮播图 (因为基于微博小程序,语法可能有些出入,如需使用需改标签)
前端·javascript·小程序·uni-app
世界和平�����1 小时前
openlayers中一些问题的解决方案
前端·javascript·vue.js
小菜yh1 小时前
后端人需知
java·前端·javascript·vue.js·设计模式
周万宁.FoBJ1 小时前
vue3 实现文本内容超过N行折叠并显示“...展开”组件
开发语言·前端·javascript
Jiaberrr1 小时前
uniapp视频禁止用户推拽进度条并保留进度条显示的解决方法——方案二
前端·javascript·uni-app·音视频
森叶2 小时前
webpack 的打包target讲解 & node环境打包下的文件存储造成不易察觉的坑点
前端·webpack·node.js
新智元2 小时前
陶哲轩全网悬赏「最强大脑」!AI + 人类颠覆数学难题?凡尔赛网友已下场
前端·人工智能
亿牛云爬虫专家2 小时前
Puppeteer的高级用法:如何在Node.js中实现复杂的Web Scraping
前端·javascript·爬虫·node.js·爬虫代理·puppeteer·代理ip