API Docs for: 0.5.5
Show:

File: kick/scene/MeshRenderer.js

define(["kick/core/Constants", "kick/material/Material", "kick/core/Util", "kick/mesh/Mesh", "kick/core/EngineSingleton", "kick/core/Observable"],
    function (Constants, Material, Util, Mesh, EngineSingleton, Observable) {
        "use strict";

        var ASSERT = Constants._ASSERT;

        /**
         * Renders a Mesh.
         * To create custom renderable objects you should not inherit from this class, but simple create a component with a
         * render() method.
         * If a mesh with sub-meshes, which uses multiple materials, the renderOrder is taken from the first material
         * @class MeshRenderer
         * @constructor
         * @namespace kick.scene
         * @extends kick.scene.Component
         * @final
         * @param {Object} config configuration
         */
        return function (config) {
            var transform,
                _materials = [],
                _mesh,
                _renderOrder,
                engine = EngineSingleton.engine,
                thisObj = this,
                updateRenderOrder = function() {
                    if (_materials.length > 0 && _renderOrder !== _materials[0].renderOrder){
                        _renderOrder = _materials[0].renderOrder;
                        thisObj.fireEvent("componentUpdated", thisObj);
                    }
                };

            Observable.call(this,
                /**
                 * Fired when mesh is updated
                 * @event contextLost
                 * @param {kick.scene.Component} component
                 */
                ["componentUpdated"]
            );

            /**
             * If no materials are assigned, the ENGINE\_MATERIAL\_DEFAULT is assigned as material.
             * @method activated
             */
            this.activated = function () {
                transform = thisObj.gameObject.transform;
                if (_materials.length === 0) {
                    var project = engine.project;
                    thisObj.material = project.load(project.ENGINE_MATERIAL_DEFAULT);
                }
            };

            Object.defineProperties(this, {
                // inherit documentation from component
                aabb: {
                    get: function () {
                        return _mesh.aabb;
                    }
                },
                /**
                 * The renderOrder for materials[0]
                 * @property renderOrder
                 * @type {Number}
                 */
                renderOrder: {
                    get: function () {
                        return _renderOrder;
                    }
                },
                /**
                 * Shortcut for materials[0]
                 * @property material
                 * @type kick.material.Material
                 */
                material: {
                    get: function () {
                        if (_materials.length === 0) {
                            return null;
                        }
                        return _materials[0];
                    },
                    set: function (newValue) {
                        if (ASSERT) {
                            if (!(newValue instanceof Material)) {
                                Util.fail("MeshRenderer.material must be a kick.material.Material");
                            }
                        }
                        if (_materials.length > 0){
                            _materials[0].removeEventListener("shaderChanged", updateRenderOrder);
                        }
                        _materials[0] = newValue;
                        _materials[0].addEventListener("shaderChanged", updateRenderOrder);
                        _renderOrder = _materials[0].renderOrder;
                        thisObj.fireEvent("componentUpdated", this);
                    }
                },
                /**
                 *
                 * @property materias
                 * @type Array_kick.material.Material
                 */
                materials: {
                    get: function () {
                        return _materials;
                    },
                    set: function (newValue) {
                        var i;
                        for (i = 0;i < _materials.length; i++){
                            _materials[i].removeEventListener("shaderChanged", updateRenderOrder);
                        }
                        _materials = [];
                        for (i = 0; i < newValue.length; i++) {
                            if (ASSERT) {
                                if (!(newValue[i] instanceof Material)) {
                                    Util.fail("MeshRenderer.material must be a kick.material.Material");
                                }
                            }
                            _materials[i] = newValue[i];
                            _materials[i].addEventListener("shaderChanged", updateRenderOrder);
                        }
                        thisObj.fireEvent("componentUpdated", this);
                    },
                    enumerable: true
                },
                /**
                 * @property mesh
                 * @type kick.mesh.Mesh
                 */
                mesh: {
                    get: function () {
                        return _mesh;
                    },
                    set: function (newValue) {
                        if (ASSERT) {
                            if (!(newValue instanceof Mesh)) {
                                Util.fail("MeshRenderer.mesh must be a kick.mesh.Mesh");
                            }
                        }
                        _mesh = newValue;
                    },
                    enumerable: true
                },
                /**
                 * Name of the component type = "meshRenderer".
                 * @example
                 *      var meshRenderer = gameObject.meshRenderer;
                 * @property componentType
                 * @type String
                 * @final
                 */
                componentType: {value:"meshRenderer"}
            });

            /**
             * This method may not be called (the renderer could make the same calls)
             * @method render
             * @param {kick.scene.EngineUniforms} engineUniforms
             * @param {kick.material.Material} [overwriteMaterial]
             */
            this.render = function (engineUniforms, overwriteMaterial) {
                var length = _materials.length,
                    i,
                    shader;
                if (overwriteMaterial) {
                    shader = overwriteMaterial.shader;
                    for (i = 0; i < length; i++) {
                        _mesh.bind(shader);
                        shader.bindUniform(overwriteMaterial, engineUniforms, transform);
                        _mesh.render(i);
                    }
                } else {
                    for (i = 0; i < length; i++) {
                        shader = _materials[i].shader;
                        _mesh.bind(shader);
                        shader.bindUniform(_materials[i], engineUniforms, transform);
                        _mesh.render(i);
                    }
                }
            };

            /**
             * @method toJSON
             * @return {JSON}
             */
            this.toJSON = function () {
                if (!thisObj.gameObject) {
                    return null; // component is destroyed
                } else {
                    return Util.componentToJSON(this, "kick.scene.MeshRenderer");
                }
            };

            Util.applyConfig(this, config);
        };

    });