Home Reference Source

src/core/object3.js

import { vec3, mat4, quat } from 'gl-matrix';

import Vector3 from './vector3';

let uuid = 0;
let axisAngle = 0;
const quaternionAxisAngle = vec3.create();

class Object3 {
    constructor() {
        this.uid = uuid++;

        this.position = new Vector3();
        this.rotation = new Vector3();
        this.scale = new Vector3(1, 1, 1);
        this.quaternion = quat.create();
        this.target = vec3.create();
        this.up = vec3.fromValues(0, 1, 0);

        this.parent = null;
        this.children = [];

        this.parentMatrix = mat4.create();
        this.modelMatrix = mat4.create();
        this.lookAtMatrix = mat4.create();

        // use mat4.targetTo rotation when set to true
        this.lookToTarget = false; // use lookAt rotation when set to true

        // enable polygonOffset (z-fighting)
        this.polygonOffset = false;
        this.polygonOffsetFactor = 0;
        this.polygonOffsetUnits = 1;
    }

    addModel(model) {
        model.parent = this; // eslint-disable-line
        this.children.push(model);
    }

    removeModel(model) {
        const index = this.children.indexOf(model);
        if (index !== -1) {
            model.destroy();
            this.children.splice(index, 1);
        }
    }

    updateMatrices() {
        mat4.identity(this.parentMatrix);
        mat4.identity(this.modelMatrix);
        mat4.identity(this.lookAtMatrix);
        quat.identity(this.quaternion);

        if (this.parent) {
            mat4.copy(this.parentMatrix, this.parent.modelMatrix);
            mat4.multiply(this.modelMatrix, this.modelMatrix, this.parentMatrix);
        }

        if (this.lookToTarget) {
            mat4.targetTo(this.lookAtMatrix, this.position.data, this.target, this.up);
            mat4.multiply(this.modelMatrix, this.modelMatrix, this.lookAtMatrix);
        } else {
            mat4.translate(this.modelMatrix, this.modelMatrix, this.position.data);
            quat.rotateX(this.quaternion, this.quaternion, this.rotation.x);
            quat.rotateY(this.quaternion, this.quaternion, this.rotation.y);
            quat.rotateZ(this.quaternion, this.quaternion, this.rotation.z);
            axisAngle = quat.getAxisAngle(quaternionAxisAngle, this.quaternion);
            mat4.rotate(this.modelMatrix, this.modelMatrix, axisAngle, quaternionAxisAngle);
        }
        mat4.scale(this.modelMatrix, this.modelMatrix, this.scale.data);
    }
}

export default Object3;