From fb8a8e14638ca59f1fe6ae8958c6e355d0601a10 Mon Sep 17 00:00:00 2001 From: Pete Shand Date: Tue, 3 Dec 2013 21:17:23 +1100 Subject: [PATCH 1/3] GifMaterial added --- src/away3d/materials/GifMaterial.as | 42 +++++ src/away3d/materials/methods/GifMethod.as | 69 ++++++++ src/away3d/textures/GifTexture.as | 196 ++++++++++++++++++++++ 3 files changed, 307 insertions(+) create mode 100644 src/away3d/materials/GifMaterial.as create mode 100644 src/away3d/materials/methods/GifMethod.as create mode 100644 src/away3d/textures/GifTexture.as diff --git a/src/away3d/materials/GifMaterial.as b/src/away3d/materials/GifMaterial.as new file mode 100644 index 000000000..03a591b23 --- /dev/null +++ b/src/away3d/materials/GifMaterial.as @@ -0,0 +1,42 @@ +package away3d.materials +{ + import away3d.materials.methods.GifMethod; + import away3d.materials.TextureMaterial; + import away3d.textures.BitmapTexture; + import away3d.textures.GifTexture; + import away3d.textures.Texture2DBase; + import flash.events.Event; + + /** + * ... + * @author Pete Shand + */ + public class GifMaterial extends TextureMaterial + { + private var gifMethod:GifMethod; + private var gifTexture:GifTexture; + + public function GifMaterial(gifTexture:GifTexture=null, smooth:Boolean=true, repeat:Boolean=false, mipmap:Boolean=true) + { + super(null, smooth, repeat, mipmap); + this.gifTexture = gifTexture; + + gifTexture.addEventListener(GifTexture.EVENT_TEXTURE_CHANGE, OnTextureChange); + gifTexture.addEventListener(GifTexture.EVENT_FRAME_CHANGE, OnFrameChange); + + gifMethod = new GifMethod(); + this.addMethod(gifMethod); + } + + private function OnFrameChange(e:Event):void + { + gifMethod.placement = gifTexture.placement; + gifMethod.scale = gifTexture.scale; + } + + private function OnTextureChange(e:Event):void + { + this.texture = gifTexture.currentTexture; + } + } +} \ No newline at end of file diff --git a/src/away3d/materials/methods/GifMethod.as b/src/away3d/materials/methods/GifMethod.as new file mode 100644 index 000000000..7f60bba06 --- /dev/null +++ b/src/away3d/materials/methods/GifMethod.as @@ -0,0 +1,69 @@ +package away3d.materials.methods +{ + import away3d.arcane; + import away3d.core.managers.Stage3DProxy; + import away3d.materials.compilation.ShaderRegisterCache; + import away3d.materials.compilation.ShaderRegisterElement; + import away3d.materials.methods.EffectMethodBase; + import away3d.materials.methods.MethodVO; + import flash.display3D.Context3D; + import flash.display3D.Context3DProgramType; + import flash.geom.Point; + + use namespace arcane; + + public class GifMethod extends EffectMethodBase + { + public var placement:Point = new Point(0, 0); + public var scale:Point = new Point(1, 1); + private var _vertexData:Vector.; + + public function GifMethod() + { + super(); + _vertexData = new Vector.(4); + } + + override arcane function initVO(vo : MethodVO) : void + { + vo.needsProjection = true; + } + + arcane override function activate(vo : MethodVO, stage3DProxy : Stage3DProxy) : void + { + _vertexData[0] = placement.x; + _vertexData[1] = placement.y; + _vertexData[2] = scale.x; + _vertexData[3] = scale.y; + stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 10, _vertexData, 1); + } + + arcane override function getVertexCode(vo:MethodVO, regCache:ShaderRegisterCache):String + { + var code : String = ""; + code += "// test \n"; + code += "mov vt2, va1 \n"; + code += "mul vt2.xy, vt2.xy, vc10.zw \n"; + code += "add vt2.xy, vt2.xy, vc10.xy \n"; + code += "mov v1, vt2 \n"; + return code; + } + + arcane override function getFragmentCode(vo:MethodVO, regCache:ShaderRegisterCache, targetReg:ShaderRegisterElement) : String + { + var fogColor : ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var fogData : ShaderRegisterElement = regCache.getFreeFragmentConstant(); + var temp : ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + regCache.addFragmentTempUsages(temp, 1); + var temp2 : ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + var temp3 : ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + var temp4 : ShaderRegisterElement = regCache.getFreeFragmentVectorTemp(); + var code : String = ""; + vo.fragmentConstantsIndex = fogColor.index * 4; + + regCache.removeFragmentTempUsage(temp); + + return code; + } + } +} diff --git a/src/away3d/textures/GifTexture.as b/src/away3d/textures/GifTexture.as new file mode 100644 index 000000000..7d1b91ef4 --- /dev/null +++ b/src/away3d/textures/GifTexture.as @@ -0,0 +1,196 @@ +package away3d.textures +{ + import away3d.textures.BitmapTexture; + import com.worlize.gif.events.GIFPlayerEvent; + import com.worlize.gif.GIFPlayer; + import flash.display.BitmapData; + import flash.events.Event; + import flash.events.EventDispatcher; + import flash.geom.Matrix; + import flash.geom.Point; + import flash.geom.Rectangle; + import flash.utils.ByteArray; + + /** + * ... + * @author Pete Shand + */ + public class GifTexture extends EventDispatcher + { + public var gifPlayer:GIFPlayer; + private var generateMipmaps:Boolean; + private var textureBmds:Vector.; + private var textures:Vector.; + + private var maxFrameWidth:int = 512; + private var maxFrameHeight:int = 512; + private var maxTextureWidth:int = 2048; + private var maxTextureHeight:int = 2048; + + private var placements:Vector.; + + private var _currentTexture:BitmapTexture; + private var _currentTextureIndex:int = 0; + + public static const EVENT_TEXTURE_CHANGE:String = 'textureChange'; + public static const EVENT_FRAME_CHANGE:String = 'frameChange'; + + public var placement:Point = new Point(0, 0); + public var scale:Point = new Point(0.5, 0.5); + + public function GifTexture(gifPlayer:GIFPlayer, generateMipmaps:Boolean = true) + { + this.gifPlayer = gifPlayer; + this.generateMipmaps = generateMipmaps; + + + + + + var frameBmds:Vector. = gifPlayer.getFrames(); + var placement:Rectangle = new Rectangle(0, 0, gifPlayer.width, gifPlayer.height); + //if (maxFrameWidth != -1 && placement.width > maxFrameWidth) placement.width = maxFrameWidth; + //if (maxFrameHeight != -1 && placement.height > maxFrameHeight) placement.height = maxFrameHeight; + + var currentIndex:int = 0; + placements = new Vector.(frameBmds.length); + for (var i:int = 0; i < frameBmds.length; ++i) + { + placements[i] = new Placement(currentIndex, maxFrameWidth, maxFrameHeight); + placements[i]._width = placement.width; + placements[i]._height = placement.height; + placements[i]._x = placement.x; + placements[i]._y = placement.y; + + if (i == frameBmds.length - 1) break; + + placement.x += placement.width; + + if (placement.x + placement.width > maxTextureWidth / placements[k].scale.x) { + placement.x = 0; + placement.y += placement.height; + if (placement.y + placement.height > maxTextureHeight / placements[k].scale.y) { + // new bitmapdata required + currentIndex++; + placement.x = 0; + placement.y = 0; + } + } + + } + + textureBmds = new Vector.(currentIndex+1); + for (var j:int = 0; j < textureBmds.length; ++j) { + textureBmds[j] = new BitmapData(maxTextureWidth, maxTextureHeight, true, 0x00000000); + } + + var matrix:Matrix; + var sx:Number; + var sy:Number; + + for (var k:int = 0; k < placements.length; ++k) { + matrix = new Matrix(); + sx = placements[k].scale.x; + sy = placements[k].scale.y; + matrix.scale(sx, sy); + matrix.tx = placements[k].x; + matrix.ty = placements[k].y; + + var textureIndex:int = placements[k].index; + var frameBmd:BitmapData = frameBmds[k]; + textureBmds[textureIndex].draw(frameBmd, matrix, null, null, null, true); + } + + textures = new Vector.(textureBmds.length); + for (var l:int = 0; l < textureBmds.length; ++l) { + textures[l] = new BitmapTexture(textureBmds[l], generateMipmaps); + } + + + currentTexture = textures[0]; + + gifPlayer.addEventListener(GIFPlayerEvent.FRAME_RENDERED, handleFrameRendered); + } + + private function handleFrameRendered(e:GIFPlayerEvent):void + { + scale.x = placements[gifPlayer.currentFrame-1].width / maxTextureWidth; + scale.y = placements[gifPlayer.currentFrame-1].height / maxTextureHeight; + + placement.x = placements[gifPlayer.currentFrame-1].position.x / maxTextureWidth; + placement.y = placements[gifPlayer.currentFrame-1].position.y / maxTextureHeight; + + if (placements[gifPlayer.currentFrame-1].index != _currentTextureIndex) { + currentTexture = textures[placements[gifPlayer.currentFrame-1].index]; + } + this.dispatchEvent(new Event(GifTexture.EVENT_FRAME_CHANGE)); + } + + public function get currentTexture():BitmapTexture + { + return _currentTexture; + } + + public function set currentTexture(value:BitmapTexture):void + { + _currentTexture = value; + for (var i:int = 0; i < textures.length; ++i) { + if (textures[i] == value) _currentTextureIndex = i; + } + //onTextureChange(); + this.dispatchEvent(new Event(GifTexture.EVENT_TEXTURE_CHANGE)); + } + } +} + +import flash.geom.Rectangle; +import flash.geom.Point; + +class Placement extends Rectangle { + + public var index:int = 0; + public var scale:Point = new Point(1, 1); + public var position:Point = new Point(); + public var maxFrameWidth:Number; + public var maxFrameHeight:Number; + + public function Placement(index:int, maxFrameWidth:Number, maxFrameHeight:Number) + { + this.index = index; + this.maxFrameWidth = maxFrameWidth; + this.maxFrameHeight = maxFrameHeight; + + super(0, 0, 0, 0); + } + + public function set _width(value:Number):void + { + if (value > maxFrameWidth) { + scale.x = maxFrameWidth / value; + value = maxFrameWidth; + } + else scale.x = 1; + width = value; + } + public function set _height(value:Number):void + { + if (value > maxFrameHeight) { + scale.y = maxFrameHeight / value; + value = maxFrameHeight; + } + else scale.y = 1; + height = value; + } + + public function set _x(value:Number):void + { + x = value * scale.x; + position.x = x; + } + + public function set _y(value:Number):void + { + y = value * scale.y; + position.y = y; + } +} \ No newline at end of file From e02279c86c17d05e744a722dcfb1d323561e1746 Mon Sep 17 00:00:00 2001 From: Pete Shand Date: Sun, 8 Dec 2013 10:53:00 +1100 Subject: [PATCH 2/3] GifTexture.as updated single spritesheet now working spritesheet bitmapdata max size reduced if whole 2048x2048 isn't used padding added to packing --- src/away3d/textures/GifTexture.as | 73 +++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/src/away3d/textures/GifTexture.as b/src/away3d/textures/GifTexture.as index 7d1b91ef4..f17965a55 100644 --- a/src/away3d/textures/GifTexture.as +++ b/src/away3d/textures/GifTexture.as @@ -19,18 +19,19 @@ package away3d.textures { public var gifPlayer:GIFPlayer; private var generateMipmaps:Boolean; - private var textureBmds:Vector.; + public var textureBmds:Vector.; private var textures:Vector.; private var maxFrameWidth:int = 512; private var maxFrameHeight:int = 512; - private var maxTextureWidth:int = 2048; - private var maxTextureHeight:int = 2048; + private var maxTextureSize:uint = 2048; + private var padding:int = 1; private var placements:Vector.; + private var maxPlacements:Vector. = new Vector.(); private var _currentTexture:BitmapTexture; - private var _currentTextureIndex:int = 0; + private var _currentTextureIndex:int = -1; public static const EVENT_TEXTURE_CHANGE:String = 'textureChange'; public static const EVENT_FRAME_CHANGE:String = 'frameChange'; @@ -43,16 +44,11 @@ package away3d.textures this.gifPlayer = gifPlayer; this.generateMipmaps = generateMipmaps; - - - - var frameBmds:Vector. = gifPlayer.getFrames(); var placement:Rectangle = new Rectangle(0, 0, gifPlayer.width, gifPlayer.height); - //if (maxFrameWidth != -1 && placement.width > maxFrameWidth) placement.width = maxFrameWidth; - //if (maxFrameHeight != -1 && placement.height > maxFrameHeight) placement.height = maxFrameHeight; var currentIndex:int = 0; + maxPlacements.push(new Point()); placements = new Vector.(frameBmds.length); for (var i:int = 0; i < frameBmds.length; ++i) { @@ -62,16 +58,19 @@ package away3d.textures placements[i]._x = placement.x; placements[i]._y = placement.y; + maxPlacements[currentIndex] = placements[i].checkMaxPlacement(maxPlacements[currentIndex]); + if (i == frameBmds.length - 1) break; - placement.x += placement.width; + placement.x += placement.width + padding; - if (placement.x + placement.width > maxTextureWidth / placements[k].scale.x) { + if (placement.x + placement.width > maxTextureSize / placements[k].scale.x) { placement.x = 0; - placement.y += placement.height; - if (placement.y + placement.height > maxTextureHeight / placements[k].scale.y) { + placement.y += placement.height + padding; + if (placement.y + placement.height > maxTextureSize / placements[k].scale.y) { // new bitmapdata required currentIndex++; + maxPlacements.push(new Point()); placement.x = 0; placement.y = 0; } @@ -80,8 +79,11 @@ package away3d.textures } textureBmds = new Vector.(currentIndex+1); - for (var j:int = 0; j < textureBmds.length; ++j) { - textureBmds[j] = new BitmapData(maxTextureWidth, maxTextureHeight, true, 0x00000000); + for (var j:int = 0; j < textureBmds.length; ++j) + { + maxPlacements[j].x = getBestPowerOf2(maxPlacements[j].x); + maxPlacements[j].y = getBestPowerOf2(maxPlacements[j].y); + textureBmds[j] = new BitmapData(maxPlacements[j].x, maxPlacements[j].y, true, 0x00000000); } var matrix:Matrix; @@ -96,6 +98,9 @@ package away3d.textures matrix.tx = placements[k].x; matrix.ty = placements[k].y; + placements[k].textureMaxWidth = maxPlacements[placements[k].index].x; + placements[k].textureMaxHeight = maxPlacements[placements[k].index].y; + var textureIndex:int = placements[k].index; var frameBmd:BitmapData = frameBmds[k]; textureBmds[textureIndex].draw(frameBmd, matrix, null, null, null, true); @@ -106,19 +111,16 @@ package away3d.textures textures[l] = new BitmapTexture(textureBmds[l], generateMipmaps); } - - currentTexture = textures[0]; - gifPlayer.addEventListener(GIFPlayerEvent.FRAME_RENDERED, handleFrameRendered); } private function handleFrameRendered(e:GIFPlayerEvent):void { - scale.x = placements[gifPlayer.currentFrame-1].width / maxTextureWidth; - scale.y = placements[gifPlayer.currentFrame-1].height / maxTextureHeight; + scale.x = placements[gifPlayer.currentFrame-1].width / placements[gifPlayer.currentFrame-1].textureMaxWidth; + scale.y = placements[gifPlayer.currentFrame-1].height / placements[gifPlayer.currentFrame-1].textureMaxHeight; - placement.x = placements[gifPlayer.currentFrame-1].position.x / maxTextureWidth; - placement.y = placements[gifPlayer.currentFrame-1].position.y / maxTextureHeight; + placement.x = placements[gifPlayer.currentFrame-1].position.x / placements[gifPlayer.currentFrame-1].textureMaxWidth; + placement.y = placements[gifPlayer.currentFrame-1].position.y / placements[gifPlayer.currentFrame-1].textureMaxHeight; if (placements[gifPlayer.currentFrame-1].index != _currentTextureIndex) { currentTexture = textures[placements[gifPlayer.currentFrame-1].index]; @@ -137,9 +139,23 @@ package away3d.textures for (var i:int = 0; i < textures.length; ++i) { if (textures[i] == value) _currentTextureIndex = i; } - //onTextureChange(); this.dispatchEvent(new Event(GifTexture.EVENT_TEXTURE_CHANGE)); } + + + + private function getBestPowerOf2(value:uint):Number + { + var p:uint = 1; + + while (p < value) + p <<= 1; + + if (p > maxTextureSize) + p = maxTextureSize; + + return p; + } } } @@ -153,6 +169,8 @@ class Placement extends Rectangle { public var position:Point = new Point(); public var maxFrameWidth:Number; public var maxFrameHeight:Number; + public var textureMaxWidth:int; + public var textureMaxHeight:int; public function Placement(index:int, maxFrameWidth:Number, maxFrameHeight:Number) { @@ -163,6 +181,13 @@ class Placement extends Rectangle { super(0, 0, 0, 0); } + public function checkMaxPlacement(maxPlacement:Point):Point + { + if (maxPlacement.x < this.x + this.width) maxPlacement.x = this.x + this.width; + if (maxPlacement.y < this.y + this.height) maxPlacement.y = this.y + this.height; + return maxPlacement; + } + public function set _width(value:Number):void { if (value > maxFrameWidth) { From 647d02f71f5c99db75001a1b698f3bd72bb378ad Mon Sep 17 00:00:00 2001 From: peter shand Date: Thu, 24 Apr 2014 10:44:42 +1000 Subject: [PATCH 3/3] update --- src/away3d/animators/states/ParticleColorState.as | 2 +- src/away3d/animators/states/ParticlePositionState.as | 2 +- src/away3d/containers/View3D.as | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/away3d/animators/states/ParticleColorState.as b/src/away3d/animators/states/ParticleColorState.as index 4e3b497bf..1544e60b7 100644 --- a/src/away3d/animators/states/ParticleColorState.as +++ b/src/away3d/animators/states/ParticleColorState.as @@ -20,7 +20,7 @@ package away3d.animators.states /** * ... - * @author ... + * @author P.J.Shand */ public class ParticleColorState extends ParticleStateBase { diff --git a/src/away3d/animators/states/ParticlePositionState.as b/src/away3d/animators/states/ParticlePositionState.as index 3adbcba94..94eca868d 100644 --- a/src/away3d/animators/states/ParticlePositionState.as +++ b/src/away3d/animators/states/ParticlePositionState.as @@ -18,7 +18,7 @@ package away3d.animators.states /** * ... - * @author ... + * @author P.J.Shand */ public class ParticlePositionState extends ParticleStateBase { diff --git a/src/away3d/containers/View3D.as b/src/away3d/containers/View3D.as index 0270df353..d23fcafde 100644 --- a/src/away3d/containers/View3D.as +++ b/src/away3d/containers/View3D.as @@ -955,8 +955,10 @@ { _parentIsStage = (parent == stage); - _globalPos = parent.localToGlobal(_localPos); - _globalPosDirty = true; + if (parent){ + _globalPos = parent.localToGlobal(_localPos); + _globalPosDirty = true; + } } private function onViewportUpdated(event:Stage3DEvent):void