UNPKG

foam-framework

Version:
244 lines (224 loc) 6.71 kB
/** * @license * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ CLASS({ package: 'foam.graphics.webgl.core', name: 'Object', requires: [ 'foam.graphics.webgl.matrix.StackMatrix4', 'foam.graphics.webgl.matrix.TransMatrix4', 'foam.graphics.webgl.matrix.RotMatrix4', 'foam.graphics.webgl.matrix.InverseMatrix4', 'foam.graphics.webgl.matrix.TransposeMatrix4', 'foam.graphics.webgl.matrix.Matrix4', 'foam.graphics.webgl.Matrix4Uniform' ], extends: 'foam.graphics.webgl.GLView', imports: [ 'projectionMatrix$', 'glMeshLibrary', ], exports: [ 'gl$', ], properties: [ { name: 'relativePosition', type: 'foam.graphics.webgl.matrix.Matrix4', lazyFactory: function() { return this.StackMatrix4.create({ stack: [ this.RotMatrix4.create({ angle$: this.angle$, axis$: this.axis$ }), this.TransMatrix4.create({ x$: this.x$, y$: this.y$, z$: this.z$ }) ] }); }, }, { name: 'x', defaultValue: 0.0, }, { name: 'y', defaultValue: 0.0, }, { name: 'z', defaultValue: -0.01, }, { name: 'angle', defaultValue: 0.0, }, { name: 'axis', defaultValueFn: function() { return [0,0,1]; } }, { name: 'positionMatrix', type: 'foam.graphics.webgl.matrix.Matrix4', lazyFactory: function() { return this.updatePosition(); } }, { name: 'mesh', type: 'foam.graphics.webgl.core.ArrayBuffer' }, { name: 'meshNormals', type: 'foam.graphics.webgl.core.ArrayBuffer', postSet: function(old, nu) { this.doUpdatePosition(); } }, { name: 'meshMatrix', help: 'Transformations to apply to the mesh, but not pass on to children.', type: 'foam.graphics.webgl.matrix.Matrix4', lazyFactory: function() { return this.Matrix4.create(); } }, { name: 'normalMatrix', help: 'The inverse transpose of the positioning matrix (pos*rel*mesh)', type: 'foam.graphics.webgl.matrix.Matrix4', lazyFactory: function() { // only fill this in if normals are set return this.Matrix4.create(); }, }, { name: 'program', }, { name: 'parent', postSet: function(old, nu) { if (old) old.positionMatrix$.removeListener(this.doUpdatePosition); if (nu) nu.positionMatrix$.addListener(this.doUpdatePosition); this.doUpdatePosition(); } }, { name: 'parentPosition_' }, { model_: 'BooleanProperty', name: 'translucent', defaultValue: false } ], listeners: [ { name: 'doUpdatePosition', code: function(obj, topic) { this.positionMatrix = this.updatePosition(); this.parentPosition_ = this.parent.positionMatrix; if (this.meshNormals) { this.normalMatrix = this.TransposeMatrix4.create({ source: this.InverseMatrix4.create({ source: this.positionMatrix // TODO: adding the mesh matrix can mess up the normals when scaling+rotating // this.StackMatrix4.create({ stack: [ // this.positionMatrix, this.meshMatrix // ]}) }) }); } } } ], methods: [ function init() { this.Matrix4Uniform.create({ name: 'relativeMatrix', matrix$: this.relativePosition$, program$: this.program$ }); this.Matrix4Uniform.create({ name: 'positionMatrix', matrix$: this.parentPosition_$, program$: this.program$ }); this.Matrix4Uniform.create({ name: 'meshMatrix', matrix$: this.meshMatrix$, program$: this.program$ }); this.Matrix4Uniform.create({ name: 'projectionMatrix', matrix$: this.projectionMatrix$, program$: this.program$ }); this.Matrix4Uniform.create({ name: 'normalMatrix', matrix$: this.normalMatrix$, program$: this.program$ }); }, function updatePosition() { return this.StackMatrix4.create({ stack: [ ( this.parent && this.parent.positionMatrix ) ? this.parent.positionMatrix : this.Matrix4.create(), this.relativePosition ] }); }, function paintSelf(translucent) { // only render on the correct pass if ( this.translucent !== translucent ) return; var gl = this.gl; if ( ! gl || ! this.mesh ) return; this.program.use(); // normals if (this.meshNormals) { var norms = this.gl.getAttribLocation(this.program.program, "aNormal"); if (norms >= 0) { this.meshNormals.bind(); this.gl.vertexAttribPointer(norms, 3, gl.FLOAT, false, 0, 0); this.gl.enableVertexAttribArray(norms); } } // vertices this.mesh.bind(); vertexPositionAttribute = this.gl.getAttribLocation(this.program.program, "aVertexPosition"); this.gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); this.gl.enableVertexAttribArray(vertexPositionAttribute); // color if ( this.color && Array.isArray(this.color) ) { var colorUniform = this.gl.getUniformLocation(this.program.program, "color"); this.gl.uniform4fv(colorUniform, new Float32Array(this.color)); } //console.log("Object ", this.$UID, this.name_, " ", this.projectionMatrix.flat, this.parent.positionMatrix.flat, this.relativePosition.flat, this.meshMatrix.flat) //console.log("Object ", this.$UID, this.name_, " ", this.x, this.y); if (translucent) { gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.enable(gl.BLEND); //gl.depthMask(false); //gl.disable(gl.DEPTH_TEST); } this.mesh.draw(); if (translucent) { gl.disable(gl.BLEND); //gl.depthMask(true); //gl.enable(gl.DEPTH_TEST); } }, ], });