当前位置: 首页 > 工具软件 > ClayGL > 使用案例 >

2021SC@SDUSC ClayGL Camera类分析(一)

云京
2023-12-01

2021SC@SDUSC ClayGL Camera类分析(一)


Camera类定义

Camera类主要定义了视角、物体、世界矩阵向相机矩阵的变换以及在相机进行变换后的坐标更新,也具有定义光线向量的函数,该光线是从相机开始定义的发射的。

new Camera()

该函数包含Camera节点扩展及实例对象函数定义。

Camera节点扩展其成员及类型定义:

成员类型
projectionMatrixMatrix4()
invProjectionMatrixMatrix4()
viewMatrixMatrix4()
frustumFrustum()

代码如下:

var Camera = Node.extend(function () {
    return {

        projectionMatrix: new Matrix4(),

        invProjectionMatrix: new Matrix4(),

        viewMatrix: new Matrix4(),

        frustum: new Frustum()
    };
}, function () {
    this.update(true);
},

从源码中可以看出,projectionMatrix、invProjectionMatrix 、viewMatrix的类型均为返回一个4维矩阵的函数的结果,frustum 的类型为返回Frustum() 函数的结果。

实例对象函数定义:

1.update 更新函数:

调用对象采用call方法,将一个函数的对象上下文从初始的上下文改变为force指定的新对象;

在Matrix4函数中用世界坐标变换求视角矩阵,并更新投影矩阵;

在Matrix4函数中根据投影矩阵转换求逆投影矩阵;

根据投影矩阵定义视野锥体。

源码如下:

{
    update: function (force) {
        Node.prototype.update.call(this, force);
        Matrix4.invert(this.viewMatrix, this.worldTransform);
        this.updateProjectionMatrix();
        Matrix4.invert(this.invProjectionMatrix, this.projectionMatrix);
        this.frustum.setFromProjection(this.projectionMatrix);
    },
 

2.设置相机视角矩阵函数:

复制投影矩阵;
根据投影矩阵求得逆投影矩阵;

{
    setViewMatrix: function (viewMatrix) {
        Matrix4.copy(this.viewMatrix, viewMatrix);
        Matrix4.invert(this.worldTransform, viewMatrix);
        this.decomposeWorldTransform();
    },

 

3.相机投影矩阵函数:

  • 分解投影矩阵;

  • 设置投影矩阵:
    复制投影矩阵;
    根据投影矩阵求得逆投影矩阵;

  • 更新投影矩阵;

    decomposeProjectionMatrix: function () {},

    setProjectionMatrix: function (projectionMatrix) {
        Matrix4.copy(this.projectionMatrix, projectionMatrix);
        Matrix4.invert(this.invProjectionMatrix, projectionMatrix);
        this.decomposeProjectionMatrix();
    },
    updateProjectionMatrix: function () {},

4.光线追迹函数:

将光线从近平面的相机投射到远平面
castRay函数中参数origin(光束起点)是世界坐标系下相机的位置;参数direction也就是光束的方向向量,并对方向向量归一化,返回的光束ray是世界坐标系下的坐标表达。

    castRay: (function () {
        var v4 = vec4.create();
        return function (ndc, out) {
            var ray = out !== undefined ? out : new Ray();
            var x = ndc.array[0];
            var y = ndc.array[1];
            vec4.set(v4, x, y, -1, 1);
            vec4.transformMat4(v4, v4, this.invProjectionMatrix.array);
            vec4.transformMat4(v4, v4, this.worldTransform.array);
            vec3.scale(ray.origin.array, v4, 1 / v4[3]);
            vec4.set(v4, x, y, 1, 1);
            vec4.transformMat4(v4, v4, this.invProjectionMatrix.array);
            vec4.transformMat4(v4, v4, this.worldTransform.array);
            vec3.scale(v4, v4, 1 / v4[3]);
            vec3.sub(ray.direction.array, v4, ray.origin.array);
            vec3.normalize(ray.direction.array, ray.direction.array);
            ray.direction._dirty = true;
            ray.origin._dirty = true;
            return ray;
        };
    })(),
});
 类似资料: