diff --git a/VERSION b/VERSION index 1aa25bb67fa..ab4bf870fb5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.176.1-dev +0.177.0-dev diff --git a/src/anim/anim_skeleton.js b/src/anim/anim_skeleton.js index 102acfb1b1d..b0d0789b4d4 100644 --- a/src/anim/anim_skeleton.js +++ b/src/anim/anim_skeleton.js @@ -105,7 +105,7 @@ pc.extend(pc, function () { // For each animated node... // keys index offset - var offset = (delta > 0 ? 1 : -1); + var offset = (delta >= 0 ? 1 : -1); for (i = 0; i < nodes.length; i++) { node = nodes[i]; diff --git a/src/asset/asset_asset.js b/src/asset/asset_asset.js index ab2fc9bdc3a..875bf965d3d 100644 --- a/src/asset/asset_asset.js +++ b/src/asset/asset_asset.js @@ -220,6 +220,9 @@ pc.extend(pc, function () { ASSET_MATERIAL: 'material', ASSET_TEXT: 'text', ASSET_TEXTURE: 'texture', - ASSET_CUBEMAP: 'cubemap' + ASSET_CUBEMAP: 'cubemap', + ASSET_SHADER: 'shader', + ASSET_CSS: 'css', + ASSET_HTML: 'html' }; }()); diff --git a/src/audio/audio_sound.js b/src/audio/audio_sound.js index 38511998a50..f577004ca93 100644 --- a/src/audio/audio_sound.js +++ b/src/audio/audio_sound.js @@ -3,6 +3,26 @@ pc.extend(pc, function () { var Sound; + // checks if user is running IE + var ie = function () { + var ua = window.navigator.userAgent; + + var msie = ua.indexOf('MSIE '); + if (msie > 0) { + // IE 10 or older => return version number + return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); + } + + var trident = ua.indexOf('Trident/'); + if (trident > 0) { + // IE 11 => return version number + var rv = ua.indexOf('rv:'); + return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); + } + + return false; + }; + if (pc.AudioManager.hasAudioContext()) { Sound = function (manager, url, success, error) { this.buffer = null; @@ -46,7 +66,16 @@ pc.extend(pc, function () { console.warn(pc.string.format('Audio format for {0} not supported', url)); success(this); } else { + var isIE = ie(); + // audio needs to be added to the DOM for IE + if (isIE) + document.body.appendChild(this.audio); + this.audio.oncanplaythrough = function () { + // remove from DOM no longer necessary + if (isIE) + document.body.removeChild(this.audio); + if (!this.isLoaded) { this.isLoaded = true; success(this); @@ -54,6 +83,10 @@ pc.extend(pc, function () { }.bind(this); this.audio.onerror = function () { + // remove from DOM no longer necessary + if (isIE) + document.body.removeChild(this.audio); + // continue loading through error success(this); }; diff --git a/src/framework/components/animation/animation_component.js b/src/framework/components/animation/animation_component.js index 71ff0a58180..e94549ab46a 100644 --- a/src/framework/components/animation/animation_component.js +++ b/src/framework/components/animation/animation_component.js @@ -51,7 +51,7 @@ pc.extend(pc, function () { data.currAnim = name; if (data.model) { - data.blending = blendTime > 0; + data.blending = blendTime > 0 && data.prevAnim; if (data.blending) { // Blend from the current time of the current animation to the start of // the newly specified animation over the specified blend time period. diff --git a/src/framework/components/audiosource/audiosource_component.js b/src/framework/components/audiosource/audiosource_component.js index 75acee97f50..273bbd4c0ea 100644 --- a/src/framework/components/audiosource/audiosource_component.js +++ b/src/framework/components/audiosource/audiosource_component.js @@ -245,6 +245,8 @@ pc.extend(pc, function () { }, loadAudioSourceAssets: function (ids) { + var self = this; + var assets = ids.map(function (id) { return this.system.app.assets.get(id); }, this); @@ -290,6 +292,9 @@ pc.extend(pc, function () { _done(); } }); + + if (! asset.resource) + this.system.app.assets.load(asset); } else { // don't wait for assets that aren't in the registry count--; @@ -299,8 +304,11 @@ pc.extend(pc, function () { // but if they are added insert them into source list this.system.app.assets.on("add:" + ids[index], function (asset) { asset.ready(function (asset) { - this.data.sources[asset.name] = asset.resource; + self.data.sources[asset.name] = asset.resource; }); + + if (! asset.resource) + self.system.app.assets.load(asset); }); } }, this); diff --git a/src/graphics/graphics_device.js b/src/graphics/graphics_device.js index 75ff83e7f5c..00537b7c293 100644 --- a/src/graphics/graphics_device.js +++ b/src/graphics/graphics_device.js @@ -916,6 +916,7 @@ pc.extend(pc, function () { gl.generateMipmap(texture._glTarget); } + if (texture._gpuSize) this._vram.tex -= texture._gpuSize; texture._gpuSize = gpuTexSize(gl, texture); this._vram.tex += texture._gpuSize; }, @@ -1061,7 +1062,7 @@ pc.extend(pc, function () { } // Commit the shader program variables - textureUnit = 0; + var textureUnit = 0; for (i = 0, len = samplers.length; i < len; i++) { sampler = samplers[i]; samplerValue = sampler.scopeId.value; @@ -1238,7 +1239,7 @@ pc.extend(pc, function () { * @description Sets the specified render target on the device. If null * is passed as a parameter, the back buffer becomes the current target * for all rendering operations. - * @param {pc.RenderTarget} The render target to activate. + * @param {pc.RenderTarget} renderTarget The render target to activate. * @example * // Set a render target to receive all rendering output * device.setRenderTarget(renderTarget); diff --git a/src/graphics/graphics_vertexformat.js b/src/graphics/graphics_vertexformat.js index 778badc86ea..4958583efa3 100644 --- a/src/graphics/graphics_vertexformat.js +++ b/src/graphics/graphics_vertexformat.js @@ -12,25 +12,58 @@ pc.extend(pc, function () { /** * @name pc.VertexFormat - * @class A vertex format is a descriptor that defines the layout of vertex element data inside - * a pc.VertexBuffer object. - * @description Returns a new pc.VertexFormat object. It is constructed from a description - * that explicitly defines how data is to be laid out inside a vertex buffer (pc.VertexBuffer). - * The description is defined as an array of elements, where each element is an object with the - * following properties: - * semantic: pc.SEMANTIC_. - * components: the number of components used by the element. - * type: (pc.ELEMENTTYPE_). - * normalize: true to remap element values to a range of 0 to 1. Defaults to false. + * @class A vertex format is a descriptor that defines the layout of vertex data inside + * a {@link pc.VertexBuffer}. + * @description Returns a new pc.VertexFormat object. * @param {pc.GraphicsDevice} graphicsDevice The graphics device used to manage this vertex format. - * @param {Object[]} description An array of vertex element descriptions. + * @param {Object[]} description An array of vertex attribute descriptions. + * @param {Number} description[].semantic The meaning of the vertex element. This is used to link + * the vertex data to a shader input. Can be: + * + * If vertex data has a meaning other that one of those listed above, use the user-defined + * semantics: pc.SEMANTIC_ATTR0 to pc.SEMANTIC_ATTR15. + * @param {Number} description[].components The number of components of the vertex attribute. + * Can be 1, 2, 3 or 4. + * @param {Number} description[].type The data type of the attribute. Can be: + * + * @param {Boolean} description[].normalize If true, vertex attribute data will be mapped from a + * 0 to 255 range down to 0 to 1 when fed to a shader. If false, vertex attribute data is left + * unchanged. If this property is unspecified, false is assumed. * @example + * // Specify 3-component positions (x, y, z) + * var vertexFormat = new pc.VertexFormat(graphicsDevice, [ + * { semantic: pc.SEMANTIC_POSITION, components: 3, type: pc.ELEMENTTYPE_FLOAT32 }, + * ]); + * @example + * // Specify 2-component positions (x, y), a texture coordinate (u, v) and a vertex color (r, g, b, a) * var vertexFormat = new pc.VertexFormat(graphicsDevice, [ * { semantic: pc.SEMANTIC_POSITION, components: 2, type: pc.ELEMENTTYPE_FLOAT32 }, * { semantic: pc.SEMANTIC_TEXCOORD0, components: 2, type: pc.ELEMENTTYPE_FLOAT32 }, * { semantic: pc.SEMANTIC_COLOR, components: 4, type: pc.ELEMENTTYPE_UINT8, normalize: true } * ]); - * * @author Will Eastcott */ var VertexFormat = function (graphicsDevice, description) { diff --git a/src/input/input_mouse.js b/src/input/input_mouse.js index 7170dd27279..74a5dfcc2b4 100644 --- a/src/input/input_mouse.js +++ b/src/input/input_mouse.js @@ -218,6 +218,13 @@ pc.extend(pc, function () { * @param {Function} [error] Function called if the request for mouse lock is unsuccessful. */ enablePointerLock: function (success, error) { + if (! document.body.requestPointerLock) { + if (error) + error(); + + return; + } + var s = function () { success(); document.removeEventListener('pointerlockchange', s); @@ -245,6 +252,10 @@ pc.extend(pc, function () { * @param {Function} [success] Function called when the mouse lock is disabled */ disablePointerLock: function (success) { + if (! document.exitPointerLock) { + return; + } + var s = function () { success(); document.removeEventListener('pointerlockchange', s); diff --git a/src/resources/parser_jsonmodel.js b/src/resources/parser_jsonmodel.js index b1d014fabdd..39e80bd16d5 100644 --- a/src/resources/parser_jsonmodel.js +++ b/src/resources/parser_jsonmodel.js @@ -170,7 +170,7 @@ pc.extend(pc, function () { indices = indices.concat(modelData.meshes[j].indices); } } - tangents = pc.calculateTangents(vertexData.position.data, vertexData.normal.data, vertexData.texCoord0.data, indices); + var tangents = pc.calculateTangents(vertexData.position.data, vertexData.normal.data, vertexData.texCoord0.data, indices); vertexData.tangent = { type: "float32", components: 4, data: tangents }; } diff --git a/src/scene/scene_forwardrenderer.js b/src/scene/scene_forwardrenderer.js index f0282be2f2c..f57a6af021f 100644 --- a/src/scene/scene_forwardrenderer.js +++ b/src/scene/scene_forwardrenderer.js @@ -677,6 +677,7 @@ pc.extend(pc, function () { var oldTarget = camera.getRenderTarget(); camera.setRenderTarget(camera._depthTarget); + this.setCamera(camera); var oldBlending = device.getBlending(); device.setBlending(false); diff --git a/src/scene/scene_material.js b/src/scene/scene_material.js index 8e43b52f431..7fb04e271dc 100644 --- a/src/scene/scene_material.js +++ b/src/scene/scene_material.js @@ -103,6 +103,11 @@ pc.extend(pc, function () { (this.blendDst === pc.BLENDMODE_SRC_COLOR) && (this.blendEquation === pc.BLENDEQUATION_ADD)) { return pc.BLEND_MULTIPLICATIVE2X; + } else if ((this.blend) && + (this.blendSrc === pc.BLENDMODE_ONE_MINUS_DST_COLOR) && + (this.blendDst === pc.BLENDMODE_ONE) && + (this.blendEquation === pc.BLENDEQUATION_ADD)) { + return pc.BLEND_SCREEN; } else if ((this.blend) && (this.blendSrc === pc.BLENDMODE_DST_COLOR) && (this.blendDst === pc.BLENDMODE_ZERO) && @@ -155,6 +160,12 @@ pc.extend(pc, function () { this.blendDst = pc.BLENDMODE_SRC_COLOR; this.blendEquation = pc.BLENDEQUATION_ADD; break; + case pc.BLEND_SCREEN: + this.blend = true; + this.blendSrc = pc.BLENDMODE_ONE_MINUS_DST_COLOR; + this.blendDst = pc.BLENDMODE_ONE; + this.blendEquation = pc.BLENDEQUATION_ADD; + break; case pc.BLEND_MULTIPLICATIVE: this.blend = true; this.blendSrc = pc.BLENDMODE_DST_COLOR; diff --git a/src/scene/scene_scene.js b/src/scene/scene_scene.js index 88138766258..193829d62a1 100644 --- a/src/scene/scene_scene.js +++ b/src/scene/scene_scene.js @@ -53,10 +53,17 @@ /** * @enum pc.BLEND * @name pc.BLEND_MULTIPLICATIVE2X - * @description Same as pc.BLEND_ADDITIVE except the source RGB is multiplied by the source alpha. + * @description Multiplies colors and doubles the result */ BLEND_MULTIPLICATIVE2X: 7, + /** + * @enum pc.BLEND + * @name pc.BLEND_SCREEN + * @description Softer version of additive + */ + BLEND_SCREEN: 8, + /** * @enum pc.FOG * @name pc.FOG_NONE @@ -483,6 +490,7 @@ pc.extend(pc, function () { }; meshInstance.updateKey(); meshInstance.cull = false; + meshInstance.drawToDepth = false; var model = new pc.Model(); model.graph = node;