|
@@ -22,6 +22,7 @@ var BABYLON;
|
|
* - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
|
|
* - position: the X & Y positions relative to its parent. Alternatively the x and y properties can be set. Default is [0;0]
|
|
* - rotation: the initial rotation (in radian) of the primitive. default is 0
|
|
* - rotation: the initial rotation (in radian) of the primitive. default is 0
|
|
* - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
|
|
* - scale: the initial scale of the primitive. default is 1. You can alternatively use scaleX &| scaleY to apply non uniform scale
|
|
|
|
+ * - dontInheritParentScale: if set the parent's scale won't be taken into consideration to compute the actualScale property
|
|
* - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
|
|
* - opacity: set the overall opacity of the primitive, 1 to be opaque (default), less than 1 to be transparent.
|
|
* - zOrder: override the zOrder with the specified value
|
|
* - zOrder: override the zOrder with the specified value
|
|
* - origin: define the normalized origin point location, default [0.5;0.5]
|
|
* - origin: define the normalized origin point location, default [0.5;0.5]
|
|
@@ -60,11 +61,16 @@ var BABYLON;
|
|
this.owner._registerTrackedNode(this);
|
|
this.owner._registerTrackedNode(this);
|
|
}
|
|
}
|
|
this._cacheBehavior = (settings.cacheBehavior == null) ? Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY : settings.cacheBehavior;
|
|
this._cacheBehavior = (settings.cacheBehavior == null) ? Group2D.GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY : settings.cacheBehavior;
|
|
|
|
+ var rd = this._renderableData;
|
|
|
|
+ if (rd) {
|
|
|
|
+ rd._noResizeOnScale = (this.cacheBehavior & Group2D.GROUPCACHEBEHAVIOR_NORESIZEONSCALE) !== 0;
|
|
|
|
+ }
|
|
this.size = size;
|
|
this.size = size;
|
|
this._viewportPosition = BABYLON.Vector2.Zero();
|
|
this._viewportPosition = BABYLON.Vector2.Zero();
|
|
|
|
+ this._viewportSize = BABYLON.Size.Zero();
|
|
}
|
|
}
|
|
Group2D._createCachedCanvasGroup = function (owner) {
|
|
Group2D._createCachedCanvasGroup = function (owner) {
|
|
- var g = new Group2D({ parent: owner, id: "__cachedCanvasGroup__", position: BABYLON.Vector2.Zero(), origin: BABYLON.Vector2.Zero(), size: null, isVisible: true, isPickable: false });
|
|
|
|
|
|
+ var g = new Group2D({ parent: owner, id: "__cachedCanvasGroup__", position: BABYLON.Vector2.Zero(), origin: BABYLON.Vector2.Zero(), size: null, isVisible: true, isPickable: false, dontInheritParentScale: true });
|
|
return g;
|
|
return g;
|
|
};
|
|
};
|
|
Group2D.prototype.applyCachedTexture = function (vertexData, material) {
|
|
Group2D.prototype.applyCachedTexture = function (vertexData, material) {
|
|
@@ -150,7 +156,7 @@ var BABYLON;
|
|
this._trackedNode = null;
|
|
this._trackedNode = null;
|
|
}
|
|
}
|
|
if (this._renderableData) {
|
|
if (this._renderableData) {
|
|
- this._renderableData.dispose(this.owner.engine);
|
|
|
|
|
|
+ this._renderableData.dispose(this.owner);
|
|
this._renderableData = null;
|
|
this._renderableData = null;
|
|
}
|
|
}
|
|
return true;
|
|
return true;
|
|
@@ -222,6 +228,7 @@ var BABYLON;
|
|
Object.defineProperty(Group2D.prototype, "cacheBehavior", {
|
|
Object.defineProperty(Group2D.prototype, "cacheBehavior", {
|
|
/**
|
|
/**
|
|
* Get/set the Cache Behavior, used in case the Canvas Cache Strategy is set to CACHESTRATEGY_ALLGROUPS. Can be either GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP, GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE or GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY. See their documentation for more information.
|
|
* Get/set the Cache Behavior, used in case the Canvas Cache Strategy is set to CACHESTRATEGY_ALLGROUPS. Can be either GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP, GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE or GROUPCACHEBEHAVIOR_FOLLOWCACHESTRATEGY. See their documentation for more information.
|
|
|
|
+ * GROUPCACHEBEHAVIOR_NORESIZEONSCALE can also be set if you set it at creation time.
|
|
* It is critical to understand than you HAVE TO play with this behavior in order to achieve a good performance/memory ratio. Caching all groups would certainly be the worst strategy of all.
|
|
* It is critical to understand than you HAVE TO play with this behavior in order to achieve a good performance/memory ratio. Caching all groups would certainly be the worst strategy of all.
|
|
*/
|
|
*/
|
|
get: function () {
|
|
get: function () {
|
|
@@ -288,39 +295,29 @@ var BABYLON;
|
|
sortedDirtyList = rd._primDirtyList.sort(function (a, b) { return a.hierarchyDepth - b.hierarchyDepth; });
|
|
sortedDirtyList = rd._primDirtyList.sort(function (a, b) { return a.hierarchyDepth - b.hierarchyDepth; });
|
|
this.updateCachedStatesOf(sortedDirtyList, true);
|
|
this.updateCachedStatesOf(sortedDirtyList, true);
|
|
}
|
|
}
|
|
|
|
+ var s = this.actualSize;
|
|
|
|
+ var a = this.actualScale;
|
|
|
|
+ var sw = Math.ceil(s.width * a.x);
|
|
|
|
+ var sh = Math.ceil(s.height * a.y);
|
|
// Setup the size of the rendering viewport
|
|
// Setup the size of the rendering viewport
|
|
// In non cache mode, we're rendering directly to the rendering canvas, in this case we have to detect if the canvas size changed since the previous iteration, if it's the case all primitives must be prepared again because their transformation must be recompute
|
|
// In non cache mode, we're rendering directly to the rendering canvas, in this case we have to detect if the canvas size changed since the previous iteration, if it's the case all primitives must be prepared again because their transformation must be recompute
|
|
if (!this._isCachedGroup) {
|
|
if (!this._isCachedGroup) {
|
|
// Compute the WebGL viewport's location/size
|
|
// Compute the WebGL viewport's location/size
|
|
var t = this._globalTransform.getTranslation();
|
|
var t = this._globalTransform.getTranslation();
|
|
- var s = this.actualSize.clone();
|
|
|
|
var rs = this.owner._renderingSize;
|
|
var rs = this.owner._renderingSize;
|
|
- s.height = Math.min(s.height, rs.height - t.y);
|
|
|
|
- s.width = Math.min(s.width, rs.width - t.x);
|
|
|
|
|
|
+ sh = Math.min(sh, rs.height - t.y);
|
|
|
|
+ sw = Math.min(sw, rs.width - t.x);
|
|
var x = t.x;
|
|
var x = t.x;
|
|
var y = t.y;
|
|
var y = t.y;
|
|
// The viewport where we're rendering must be the size of the canvas if this one fit in the rendering screen or clipped to the screen dimensions if needed
|
|
// The viewport where we're rendering must be the size of the canvas if this one fit in the rendering screen or clipped to the screen dimensions if needed
|
|
this._viewportPosition.x = x;
|
|
this._viewportPosition.x = x;
|
|
this._viewportPosition.y = y;
|
|
this._viewportPosition.y = y;
|
|
- var vw = s.width;
|
|
|
|
- var vh = s.height;
|
|
|
|
- if (!this._viewportSize) {
|
|
|
|
- this._viewportSize = new BABYLON.Size(vw, vh);
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- if (this._viewportSize.width !== vw || this._viewportSize.height !== vh) {
|
|
|
|
- context.forceRefreshPrimitive = true;
|
|
|
|
- }
|
|
|
|
- this._viewportSize.width = vw;
|
|
|
|
- this._viewportSize.height = vh;
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
- else {
|
|
|
|
- var newSize = this.actualSize.clone();
|
|
|
|
- if (!newSize.equals(this._viewportSize)) {
|
|
|
|
- context.forceRefreshPrimitive = true;
|
|
|
|
- }
|
|
|
|
- this._viewportSize = newSize;
|
|
|
|
|
|
+ // For a cachedGroup we also check of the group's actualSize is changing, if it's the case then the rendering zone will be change so we also have to dirty all primitives to prepare them again.
|
|
|
|
+ if (this._viewportSize.width !== sw || this._viewportSize.height !== sh) {
|
|
|
|
+ context.forceRefreshPrimitive = true;
|
|
|
|
+ this._viewportSize.width = sw;
|
|
|
|
+ this._viewportSize.height = sh;
|
|
}
|
|
}
|
|
if ((rd._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
|
|
if ((rd._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
|
|
// If the group is cached, set the dirty flag to true because of the incoming changes
|
|
// If the group is cached, set the dirty flag to true because of the incoming changes
|
|
@@ -664,8 +661,17 @@ var BABYLON;
|
|
var curHeight;
|
|
var curHeight;
|
|
var rd = this._renderableData;
|
|
var rd = this._renderableData;
|
|
var rs = rd._renderingScale;
|
|
var rs = rd._renderingScale;
|
|
- Group2D._s.width = Math.ceil(this.actualSize.width * rs);
|
|
|
|
- Group2D._s.height = Math.ceil(this.actualSize.height * rs);
|
|
|
|
|
|
+ var noResizeScale = rd._noResizeOnScale;
|
|
|
|
+ var isCanvas = this.parent == null;
|
|
|
|
+ var scale;
|
|
|
|
+ if (noResizeScale) {
|
|
|
|
+ scale = isCanvas ? Group2D._uV : this.parent.actualScale;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ scale = this.actualScale;
|
|
|
|
+ }
|
|
|
|
+ Group2D._s.width = Math.ceil(this.actualSize.width * scale.x * rs);
|
|
|
|
+ Group2D._s.height = Math.ceil(this.actualSize.height * scale.y * rs);
|
|
var sizeChanged = !Group2D._s.equals(rd._cacheSize);
|
|
var sizeChanged = !Group2D._s.equals(rd._cacheSize);
|
|
if (rd._cacheNode) {
|
|
if (rd._cacheNode) {
|
|
var size = rd._cacheNode.contentSize;
|
|
var size = rd._cacheNode.contentSize;
|
|
@@ -692,7 +698,6 @@ var BABYLON;
|
|
if (sizeChanged) {
|
|
if (sizeChanged) {
|
|
rd._cacheSize.copyFrom(Group2D._s);
|
|
rd._cacheSize.copyFrom(Group2D._s);
|
|
rd._cacheNodeUVs = rd._cacheNode.getUVsForCustomSize(rd._cacheSize);
|
|
rd._cacheNodeUVs = rd._cacheNode.getUVsForCustomSize(rd._cacheSize);
|
|
- this.scale = this._renderableData._renderingScale;
|
|
|
|
if (rd._cacheNodeUVsChangedObservable && rd._cacheNodeUVsChangedObservable.hasObservers()) {
|
|
if (rd._cacheNodeUVsChangedObservable && rd._cacheNodeUVsChangedObservable.hasObservers()) {
|
|
rd._cacheNodeUVsChangedObservable.notifyObservers(rd._cacheNodeUVs);
|
|
rd._cacheNodeUVsChangedObservable.notifyObservers(rd._cacheNodeUVs);
|
|
}
|
|
}
|
|
@@ -772,7 +777,7 @@ var BABYLON;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (canvasStrat === BABYLON.Canvas2D.CACHESTRATEGY_ALLGROUPS) {
|
|
else if (canvasStrat === BABYLON.Canvas2D.CACHESTRATEGY_ALLGROUPS) {
|
|
- var gcb = this.cacheBehavior;
|
|
|
|
|
|
+ var gcb = this.cacheBehavior & Group2D.GROUPCACHEBEHAVIOR_OPTIONMASK;
|
|
if ((gcb === Group2D.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE) || (gcb === Group2D.GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP)) {
|
|
if ((gcb === Group2D.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE) || (gcb === Group2D.GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP)) {
|
|
this._isRenderableGroup = gcb === Group2D.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE;
|
|
this._isRenderableGroup = gcb === Group2D.GROUPCACHEBEHAVIOR_DONTCACHEOVERRIDE;
|
|
this._isCachedGroup = false;
|
|
this._isCachedGroup = false;
|
|
@@ -790,6 +795,7 @@ var BABYLON;
|
|
}
|
|
}
|
|
// If the group is tagged as renderable we add it to the renderable tree
|
|
// If the group is tagged as renderable we add it to the renderable tree
|
|
if (this._isCachedGroup) {
|
|
if (this._isCachedGroup) {
|
|
|
|
+ this._renderableData._noResizeOnScale = (this.cacheBehavior & Group2D.GROUPCACHEBEHAVIOR_NORESIZEONSCALE) !== 0;
|
|
var cur = this.parent;
|
|
var cur = this.parent;
|
|
while (cur) {
|
|
while (cur) {
|
|
if (cur instanceof Group2D && cur._isRenderableGroup) {
|
|
if (cur instanceof Group2D && cur._isRenderableGroup) {
|
|
@@ -816,6 +822,12 @@ var BABYLON;
|
|
* When used, the group's content will be cached in the nearest cached parent group/canvas
|
|
* When used, the group's content will be cached in the nearest cached parent group/canvas
|
|
*/
|
|
*/
|
|
Group2D.GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP = 2;
|
|
Group2D.GROUPCACHEBEHAVIOR_CACHEINPARENTGROUP = 2;
|
|
|
|
+ /**
|
|
|
|
+ * You can specify this behavior to any cached Group2D to indicate that you don't want the cached content to be resized when the Group's actualScale is changing. It will draw the content stretched or shrink which is faster than a resize. This setting is obviously for performance consideration, don't use it if you want the best rendering quality
|
|
|
|
+ */
|
|
|
|
+ Group2D.GROUPCACHEBEHAVIOR_NORESIZEONSCALE = 0x100;
|
|
|
|
+ Group2D.GROUPCACHEBEHAVIOR_OPTIONMASK = 0xFF;
|
|
|
|
+ Group2D._uV = new BABYLON.Vector2(1, 1);
|
|
Group2D._s = BABYLON.Size.Zero();
|
|
Group2D._s = BABYLON.Size.Zero();
|
|
__decorate([
|
|
__decorate([
|
|
BABYLON.instanceLevelProperty(BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 1, function (pi) { return Group2D.sizeProperty = pi; }, false, true)
|
|
BABYLON.instanceLevelProperty(BABYLON.Prim2DBase.PRIM2DBASE_PROPCOUNT + 1, function (pi) { return Group2D.sizeProperty = pi; }, false, true)
|
|
@@ -847,8 +859,10 @@ var BABYLON;
|
|
this._cacheSize = BABYLON.Size.Zero();
|
|
this._cacheSize = BABYLON.Size.Zero();
|
|
this._useMipMap = false;
|
|
this._useMipMap = false;
|
|
this._anisotropicLevel = 1;
|
|
this._anisotropicLevel = 1;
|
|
|
|
+ this._noResizeOnScale = false;
|
|
}
|
|
}
|
|
- RenderableGroupData.prototype.dispose = function (engine) {
|
|
|
|
|
|
+ RenderableGroupData.prototype.dispose = function (owner) {
|
|
|
|
+ var engine = owner.engine;
|
|
if (this._cacheRenderSprite) {
|
|
if (this._cacheRenderSprite) {
|
|
this._cacheRenderSprite.dispose();
|
|
this._cacheRenderSprite.dispose();
|
|
this._cacheRenderSprite = null;
|
|
this._cacheRenderSprite = null;
|