跳到主要内容

使用相机库

我们提供了相机库ore.camera,开发者直接使用其中的相机操作接口,避免直接与视角矩阵数学打交道。

快速操纵相机

下面介绍了您可以直接在业务层中使用的几个函数,便捷操纵相机平移、旋转和缩放。

home

home接口是用来自动调整视图矩阵和投影矩阵,使得整个场景模型在设备窗口中完全可见,并且从(1,1,1)方向观察。

import { home } from 'ore.camera';

// 定义了背景,其大小等于窗口的像素大小。
const background = Background({
size: ivec2(canvas.width, canvas.height),
colorMask: clr4(0.9, 0.8, 0.7, 1.0),
depthMask: float(1.0)
});
// 定义了一个相机对象
const camera = Camera();
const pass = Pass({ background, camera, node });
const scene: JScene = {
name: 'scene',
passes: [pass]
};

// 定义了场景中完整模型的几何包围盒
const boundingBox = bbox(-38.21760177612305, 43.67150115966797, -25.4783992767334,25.4783992767334, 0, 40.12839889526367);
// 使用home函数,自动按照几何包围盒、背景大小调整当前的相机
home(camera, boundingBox, background.size);

fit

fit函数可以自动调整投影矩阵,使得在当前观察场景不变的情况下,整个模型场景可见。

import { fit } from 'ore.camera';

// 自适应窗口,以看到整个场景
fit(camera, boundingBox);

look

look函数可以用来自动调整相机位置,使相机从某个指定的轴向去观察场景。

import { look } from 'ore.camera';

// 从z方向观察场景
look(camera, boundingBox, 'z');

navigate是指通过操作鼠标、3D鼠标或者触摸屏等实现对相机的操纵,包括zooming, panning, rotating和orbiting这几类。

这里要求您安装ore.manipulator库,在manipulator库中定义了类Navigation,它包含了几种鼠标操作函数,通过这些操作,可以操控相机的位置、朝向和远近。

import { Navigation } from 'ore.manipulator';

const navigation = new Navigation(canvas, camera, windowSize, boundingBox);

下面给出一个案例,应用了上面所有的Navigation函数,您执行这段程序后,就可以在窗口中使用鼠标自由操纵相机了。

首先您在视图区中创建一个渲染单元,首先您可以创建一个我们提供的几何teapot。然后使用材料phong_color,创建一个光照材料,与teapot共同组成了这个案例的渲染节点node

const geometry = await loadStanford('teapot');
const color = clr3(0.5, 0.6, 0.8);
const material = phong_color(color);
const node: JNode = {
mesh: {
primitives: [{ geometry, material }]
}
};

然后,我们组成渲染场景,详细说就是构造camera, pass和scene。我们使用home函数,自动将摄像机调整到一个合适的视角。

const camera = Camera();
const pass = Pass({
background: background,
camera: camera,
node: {
children: [node],
}
});
const scene: JScene = {
name: 'scene',
passes: [pass],
};

const boundingBox = geometry.boundingBox;
camera.orbitPoint = boundingBox.center();
home(camera, boundingBox, background.size);

最后,创建一个Navigation,并绑定updated事件,来实现当照相机发生变化的时候重绘整个场景。

const windowSize = ivec2(canvas.clientWidth, canvas.clientHeight);
const navigation = new Navigation(canvas, camera, windowSize, boundingBox);
navigation.bind('updated', (): void => {
renderer.render(scene);
});

下面的动图中,给出了鼠标操作的效果:

navigation