diff --git a/src/framework/components/light/component.js b/src/framework/components/light/component.js index 74e1a644716..5aaec32b397 100644 --- a/src/framework/components/light/component.js +++ b/src/framework/components/light/component.js @@ -32,6 +32,12 @@ pc.extend(pc, function () { *
  • "spot": A light that illuminates in all directions from a point and is bounded by a cone.
  • * * Defaults to "directional". + * @property {Number} mode The mode of light which defines what meshes it affects. Can be: + * * @property {pc.Color} color The Color of the light. The alpha component of the color is * ignored. Defaults to white (1, 1, 1). * @property {Number} intensity The brightness of the light. Defaults to 1. @@ -64,6 +70,7 @@ pc.extend(pc, function () { */ var LightComponent = function LightComponent(system, entity) { this.on("set_type", this.onSetType, this); + this.on("set_mode", this.onSetMode, this); this.on("set_color", this.onSetColor, this); this.on("set_intensity", this.onSetIntensity, this); this.on("set_castShadows", this.onSetCastShadows, this); @@ -105,7 +112,12 @@ pc.extend(pc, function () { this.refreshProperties(); }, + onSetMode: function (name, oldValue, newValue) { + this.light.setMode(newValue); + }, + refreshProperties: function() { + this.onSetMode("mode", this.mode, this.mode); this.onSetCastShadows("castShadows", this.castShadows, this.castShadows); this.onSetColor("color", this.color, this.color); this.onSetIntensity("intensity", this.intensity, this.intensity); diff --git a/src/framework/components/light/data.js b/src/framework/components/light/data.js index 4f2e46b3d72..c60cfa9ddf4 100644 --- a/src/framework/components/light/data.js +++ b/src/framework/components/light/data.js @@ -2,6 +2,7 @@ pc.extend(pc, function () { var LightComponentData = function () { // Serialized this.type = 'directional'; + this.mode = pc.LIGHTMODE_FULL; this.enabled = true; this.color = new pc.Color(1, 1, 1); this.intensity = 1; diff --git a/src/framework/components/light/system.js b/src/framework/components/light/system.js index 43e48252c9c..9b628595846 100644 --- a/src/framework/components/light/system.js +++ b/src/framework/components/light/system.js @@ -23,6 +23,7 @@ pc.extend(pc, function () { this.schema = [ 'enabled', 'type', + 'mode', 'color', 'intensity', 'castShadows', @@ -48,7 +49,7 @@ pc.extend(pc, function () { pc.extend(LightComponentSystem.prototype, { initializeComponentData: function (component, _data, properties) { - properties = ['type', 'light', 'model', 'enabled', 'color', 'intensity', 'range', 'falloffMode', 'innerConeAngle', 'outerConeAngle', 'castShadows', 'shadowDistance', 'shadowResolution', 'shadowUpdateMode', 'shadowBias', 'normalOffsetBias']; + properties = ['type', 'mode', 'light', 'model', 'enabled', 'color', 'intensity', 'range', 'falloffMode', 'innerConeAngle', 'outerConeAngle', 'castShadows', 'shadowDistance', 'shadowResolution', 'shadowUpdateMode', 'shadowBias', 'normalOffsetBias']; // duplicate because we're modifying the data var data = {}; @@ -88,6 +89,7 @@ pc.extend(pc, function () { // create new data block for clone var data = { type: light.type, + mode: light.mode, enabled: light.enabled, color: [light.color.r, light.color.g, light.color.b], intensity: light.intensity, diff --git a/src/framework/components/model/component.js b/src/framework/components/model/component.js index 9b3106deb4a..f1a2082ca7c 100644 --- a/src/framework/components/model/component.js +++ b/src/framework/components/model/component.js @@ -19,6 +19,7 @@ pc.extend(pc, function () { * @property {pc.Asset} asset The asset for the model (only applies to models of type 'asset') - can also be an asset id. * @property {Boolean} castShadows If true, this model will cast shadows for lights that have shadow casting enabled. * @property {Boolean} receiveShadows If true, shadows will be cast on this model + * @property {Boolean} lightmapped If true, lightmaps will be calculated for this model * @property {Number} materialAsset The material {@link pc.Asset} that will be used to render the model (not used on models of type 'asset') * @property {pc.Model} model The model that is added to the scene graph. * @property {Object} mapping A dictionary that holds material overrides for each mesh instance. Only applies to model components of type 'asset'. The mapping contains pairs of mesh instance index - material asset id. @@ -27,8 +28,9 @@ pc.extend(pc, function () { this.on("set_type", this.onSetType, this); this.on("set_asset", this.onSetAsset, this); this.on("set_castShadows", this.onSetCastShadows, this); - this.on("set_model", this.onSetModel, this); this.on("set_receiveShadows", this.onSetReceiveShadows, this); + this.on("set_lightmapped", this.onSetLightmapped, this); + this.on("set_model", this.onSetModel, this); this.on("set_material", this.onSetMaterial, this); this.on("set_mapping", this.onSetMapping, this); @@ -220,6 +222,15 @@ pc.extend(pc, function () { } }, + onSetLightmapped: function (name, oldValue, newValue) { + var model = this.data.model; + if (model) { + var meshInstances = model.meshInstances; + for (var i = 0; i < meshInstances.length; i++) + meshInstances[i].lightmapped = newValue; + } + }, + onSetModel: function (name, oldValue, newValue) { if (oldValue) { this.system.app.scene.removeModel(oldValue); @@ -233,6 +244,7 @@ pc.extend(pc, function () { for (var i = 0; i < meshInstances.length; i++) { meshInstances[i].castShadow = componentData.castShadows; meshInstances[i].receiveShadow = componentData.receiveShadows; + meshInstances[i].lightmapped = componentData.lightmapped; } this.entity.addChild(newValue.graph); diff --git a/src/framework/components/model/data.js b/src/framework/components/model/data.js index b0b13463dff..b4ad948b46e 100644 --- a/src/framework/components/model/data.js +++ b/src/framework/components/model/data.js @@ -14,6 +14,7 @@ pc.extend(pc, function() { this.asset = null; this.castShadows = false; this.receiveShadows = true; + this.lightmapped = false; this.materialAsset = null; this.mapping = null; diff --git a/src/framework/components/model/system.js b/src/framework/components/model/system.js index 86e7e7dfb20..e9b77535258 100644 --- a/src/framework/components/model/system.js +++ b/src/framework/components/model/system.js @@ -22,6 +22,7 @@ pc.extend(pc, function () { 'materialAsset', 'castShadows', 'receiveShadows', + 'lightmapped', 'material', 'model', 'mapping' @@ -64,7 +65,7 @@ pc.extend(pc, function () { data.material = this.defaultMaterial; // order matters here - properties = ['enabled', 'material', 'materialAsset', 'asset', 'castShadows', 'receiveShadows', 'type', 'mapping']; + properties = ['enabled', 'material', 'materialAsset', 'asset', 'castShadows', 'receiveShadows', 'lightmapped', 'type', 'mapping']; ModelComponentSystem._super.initializeComponentData.call(this, component, data, properties); }, @@ -87,6 +88,7 @@ pc.extend(pc, function () { asset: entity.model.asset, castShadows: entity.model.castShadows, receiveShadows: entity.model.receiveShadows, + lightmapped: entity.model.lightmapped, enabled: entity.model.enabled, mapping: pc.extend({}, entity.model.mapping) }; diff --git a/src/graphics/graphics.js b/src/graphics/graphics.js index b07a994a19a..106b3c5b1b2 100644 --- a/src/graphics/graphics.js +++ b/src/graphics/graphics.js @@ -313,6 +313,25 @@ */ INDEXFORMAT_UINT32: 2, + /** + * @enum pc.LIGHTMODE + * @name pc.LIGHTMODE_FULL + * @description Bake light and shadows for lightmapped meshes and affect dynamic meshes. + */ + LIGHTMODE_FULL: 0, + /** + * @enum pc.LIGHTMODE + * @name pc.LIGHTMODE_DYNAMIC + * @description Only affect dynamic meshes with light and shadows. + */ + LIGHTMODE_DYNAMIC: 1, + /** + * @enum pc.LIGHTMODE + * @name pc.LIGHTMODE_BAKE + * @description Only bake light and shadows for lightmapped meshes. + */ + LIGHTMODE_BAKE: 2, + /** * @enum pc.PIXELFORMAT * @name pc.PIXELFORMAT_A8 diff --git a/src/scene/light.js b/src/scene/light.js index 35758c42840..41e9a764350 100644 --- a/src/scene/light.js +++ b/src/scene/light.js @@ -8,6 +8,7 @@ pc.extend(pc, function () { var Light = function Light() { // Light properties (defaults) this._type = pc.LIGHTTYPE_DIRECTIONAL; + this._mode = pc.LIGHTMODE_FULL; this._color = new pc.Color(0.8, 0.8, 0.8); this._intensity = 1; this._castShadows = false; @@ -58,6 +59,7 @@ pc.extend(pc, function () { // Clone Light properties clone.setType(this.getType()); + clone.setMode(this.getMode()); clone.setColor(this.getColor()); clone.setIntensity(this.getIntensity()); clone.setCastShadows(this.getCastShadows()); @@ -238,6 +240,34 @@ pc.extend(pc, function () { return this._type; }, + /** + * @private + * @function + * @name pc.Light#getMode + * @description Queries mode of light + * @returns {Number} pc.LIGHTMODE enum. + */ + getMode: function () { + return this._mode; + }, + + /** + * @private + * @function + * @name pc.Light#setMode + * @description Specifies light mode which defines how it affects dynamic and + * lightmapped meshes + * @param {Number} mode The mode pc.LIGHTMODE. + */ + setMode: function (mode) { + if (this._mode === mode) + return; + + this._mode = mode; + if (this._scene !== null) + this._scene.updateShaders = true; + }, + /** * @private * @function diff --git a/src/scene/mesh.js b/src/scene/mesh.js index a66b4b46a23..311b7891c6e 100644 --- a/src/scene/mesh.js +++ b/src/scene/mesh.js @@ -80,6 +80,8 @@ pc.extend(pc, function () { * mesh instance. * @property {Boolean} castShadow Controls whether the mesh instances casts shadows. * Defaults to false. + * @property {Boolean} lightmapped Controls whether the mesh instances receives lightmapping. + * Defaults to false. * @property {Number} layer The layer used by this mesh instance. Can be: *