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:
+ *
+ * - {@link pc.LIGHTMODE_FULL}: Affect any meshes in realtime and baking lightmaps when possible.
+ * - {@link pc.LIGHTMODE_DYNAMIC}: Affect only dynamic meshes in realtime.
+ * - {@link pc.LIGHTMODE_BAKE}: Affect only lightmapped meshes by baking lightmaps.
+ *
* @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:
*
* - pc.LAYER_WORLD
@@ -113,6 +115,7 @@ pc.extend(pc, function () {
this.renderStyle = pc.RENDERSTYLE_SOLID;
this.castShadow = false;
this._receiveShadow = true;
+ this._lightmapped = false;
this.drawToDepth = true;
this.cull = true;
this.pick = true;
@@ -290,6 +293,18 @@ pc.extend(pc, function () {
}
});
+ Object.defineProperty(MeshInstance.prototype, 'lightmapped', {
+ get: function () {
+ return this._lightmapped;
+ },
+ set: function (val) {
+ this._lightmapped = val;
+
+ // TODO
+ // remove or add to internal lightmap list
+ }
+ });
+
Object.defineProperty(MeshInstance.prototype, 'skinInstance', {
get: function () {
return this._skinInstance;