Skip to content

Commit

Permalink
fix(2d): can not update world position for sprite renderer when call … (
Browse files Browse the repository at this point in the history
#635)

* fix(2d): can not update wrold position for sprite renderer when call bounds in the same frame
  • Loading branch information
singlecoder authored Mar 3, 2022
1 parent bec99aa commit 339a4a5
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 53 deletions.
69 changes: 34 additions & 35 deletions packages/core/src/2d/sprite/Sprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { BoundingBox, MathUtil, Rect, Vector2, Vector4 } from "@oasis-engine/mat
import { RefObject } from "../../asset/RefObject";
import { Engine } from "../../Engine";
import { Texture2D } from "../../texture/Texture2D";
import { UpdateFlag } from "../../UpdateFlag";
import { UpdateFlagManager } from "../../UpdateFlagManager";

/**
* 2D sprite.
Expand Down Expand Up @@ -31,6 +33,7 @@ export class Sprite extends RefObject {
private _atlasRegion: Rect = new Rect(0, 0, 1, 1);
private _atlasRegionOffset: Vector4 = new Vector4(0, 0, 0, 0);
private _dirtyFlag: DirtyFlag = DirtyFlag.all;
private _updateFlagManager: UpdateFlagManager = new UpdateFlagManager();

/**
* The reference to the used texture.
Expand Down Expand Up @@ -146,26 +149,6 @@ export class Sprite extends RefObject {
}
}

/**
* Clone.
* @returns Cloned sprite
*/
clone(): Sprite {
const cloneSprite = new Sprite(
this._engine,
this._texture,
this._region,
this._pivot,
this._pixelsPerUnit,
this.name
);
cloneSprite._assetID = this._assetID;
cloneSprite._atlasRotated = this._atlasRotated;
this._atlasRegion.cloneTo(cloneSprite._atlasRegion);
this._atlasRegionOffset.cloneTo(cloneSprite._atlasRegionOffset);
return cloneSprite;
}

/**
* Constructor a Sprite.
* @param engine - Engine to which the sprite belongs
Expand Down Expand Up @@ -195,6 +178,33 @@ export class Sprite extends RefObject {
this._triangles = Sprite._rectangleTriangles;
}

/**
* Clone.
* @returns Cloned sprite
*/
clone(): Sprite {
const cloneSprite = new Sprite(
this._engine,
this._texture,
this._region,
this._pivot,
this._pixelsPerUnit,
this.name
);
cloneSprite._assetID = this._assetID;
cloneSprite._atlasRotated = this._atlasRotated;
this._atlasRegion.cloneTo(cloneSprite._atlasRegion);
this._atlasRegionOffset.cloneTo(cloneSprite._atlasRegionOffset);
return cloneSprite;
}

/**
* @internal
*/
_registerUpdateFlag(): UpdateFlag {
return this._updateFlagManager.register();
}

/**
* @override
*/
Expand Down Expand Up @@ -271,9 +281,9 @@ export class Sprite extends RefObject {
}

/**
* Update mesh.
* @internal
*/
private _updateMesh(): void {
_updateMesh(): void {
if (this._isContainDirtyFlag(DirtyFlag.positions)) {
this._updatePositionsAndBounds();
}
Expand Down Expand Up @@ -343,20 +353,8 @@ export class Sprite extends RefObject {
uv[3].setValue(left, bottom);
}
}
}

/**
* @internal
* Update mesh data of the sprite.
* @returns True if the data is refreshed, false otherwise.
*/
_updateMeshData(): boolean {
if (this._isContainDirtyFlag(DirtyFlag.all)) {
this._updateMesh();
this._setDirtyFlagFalse(DirtyFlag.all);
return true;
}
return false;
this._setDirtyFlagFalse(DirtyFlag.all);
}

private _isContainDirtyFlag(type: number): boolean {
Expand All @@ -365,6 +363,7 @@ export class Sprite extends RefObject {

private _setDirtyFlagTrue(type: number): void {
this._dirtyFlag |= type;
this._updateFlagManager.distribute();
}

private _setDirtyFlagFalse(type: number): void {
Expand Down
28 changes: 20 additions & 8 deletions packages/core/src/2d/sprite/SpriteMask.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Vector3 } from "@oasis-engine/math";
import { Camera } from "../../Camera";
import { assignmentClone, deepClone, ignoreClone } from "../../clone/CloneManager";
import { ICustomClone } from "../../clone/ComponentCloner";
import { Entity } from "../../Entity";
import { Renderer } from "../../Renderer";
import { SpriteMaskElement } from "../../RenderPipeline/SpriteMaskElement";
Expand All @@ -13,7 +14,7 @@ import { Sprite } from "./Sprite";
/**
* A component for masking Sprites.
*/
export class SpriteMask extends Renderer {
export class SpriteMask extends Renderer implements ICustomClone {
/** @internal */
static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_maskTexture");
/** @internal */
Expand All @@ -27,13 +28,13 @@ export class SpriteMask extends Renderer {
@deepClone
private _positions: Vector3[] = [new Vector3(), new Vector3(), new Vector3(), new Vector3()];
@ignoreClone
private _isSpriteDirty: boolean = true;
@ignoreClone
private _worldMatrixDirtyFlag: UpdateFlag;
@assignmentClone
@ignoreClone
private _sprite: Sprite = null;
@assignmentClone
private _alphaCutoff: number = 0.5;
@ignoreClone
private _spriteDirty: UpdateFlag;

/** The mask layers the sprite mask influence to. */
@assignmentClone
Expand All @@ -48,8 +49,11 @@ export class SpriteMask extends Renderer {

set sprite(value: Sprite) {
if (this._sprite !== value) {
this._spriteDirty && this._spriteDirty.destroy();
this._sprite = value;
this._isSpriteDirty = true;
if (value) {
this._spriteDirty = value._registerUpdateFlag();
}
}
}

Expand Down Expand Up @@ -83,6 +87,7 @@ export class SpriteMask extends Renderer {
*/
_onDestroy(): void {
this._worldMatrixDirtyFlag.destroy();
this._spriteDirty && this._spriteDirty.destroy();
super._onDestroy();
}

Expand All @@ -104,9 +109,9 @@ export class SpriteMask extends Renderer {
const transform = this.entity.transform;

// Update sprite data.
const localDirty = sprite._updateMeshData();
sprite._updateMesh();

if (this._worldMatrixDirtyFlag.flag || localDirty || this._isSpriteDirty) {
if (this._worldMatrixDirtyFlag.flag || this._spriteDirty.flag) {
const localPositions = sprite._positions;
const localVertexPos = SpriteMask._tempVec3;
const worldMatrix = transform.worldMatrix;
Expand All @@ -117,7 +122,7 @@ export class SpriteMask extends Renderer {
Vector3.transformToVec3(localVertexPos, worldMatrix, positions[i]);
}

this._isSpriteDirty = false;
this._spriteDirty.flag = false;
this._worldMatrixDirtyFlag.flag = false;
}

Expand All @@ -130,4 +135,11 @@ export class SpriteMask extends Renderer {
camera._renderPipeline._allSpriteMasks.add(this);
this._maskElement = maskElement;
}

/**
* @internal
*/
_cloneTo(target: SpriteMask): void {
target.sprite = this._sprite;
}
}
32 changes: 22 additions & 10 deletions packages/core/src/2d/sprite/SpriteRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BoundingBox, Color, Vector3 } from "@oasis-engine/math";
import { Camera } from "../../Camera";
import { assignmentClone, deepClone, ignoreClone } from "../../clone/CloneManager";
import { ICustomClone } from "../../clone/ComponentCloner";
import { Entity } from "../../Entity";
import { Renderer } from "../../Renderer";
import { CompareFunction } from "../../shader/enums/CompareFunction";
Expand All @@ -14,7 +15,7 @@ import { Sprite } from "./Sprite";
/**
* Renders a Sprite for 2D graphics.
*/
export class SpriteRenderer extends Renderer {
export class SpriteRenderer extends Renderer implements ICustomClone {
private static _textureProperty: ShaderProperty = Shader.getPropertyByName("u_spriteTexture");
private static _tempVec3: Vector3 = new Vector3();

Expand All @@ -27,7 +28,7 @@ export class SpriteRenderer extends Renderer {

@deepClone
private _positions: Vector3[] = [new Vector3(), new Vector3(), new Vector3(), new Vector3()];
@assignmentClone
@ignoreClone
private _sprite: Sprite = null;
@deepClone
private _color: Color = new Color(1, 1, 1, 1);
Expand All @@ -40,9 +41,11 @@ export class SpriteRenderer extends Renderer {
@assignmentClone
private _cacheFlipY: boolean = false;
@ignoreClone
private _dirtyFlag: number = DirtyFlag.All;
private _dirtyFlag: number = 0;
@ignoreClone
private _isWorldMatrixDirty: UpdateFlag;
@ignoreClone
private _spriteDirty: UpdateFlag;
@assignmentClone
private _maskInteraction: SpriteMaskInteraction = SpriteMaskInteraction.None;
@assignmentClone
Expand All @@ -57,8 +60,11 @@ export class SpriteRenderer extends Renderer {

set sprite(value: Sprite | null) {
if (this._sprite !== value) {
this._spriteDirty && this._spriteDirty.destroy();
this._sprite = value;
this._setDirtyFlagTrue(DirtyFlag.Sprite);
if (value) {
this._spriteDirty = value._registerUpdateFlag();
}
}
}

Expand Down Expand Up @@ -154,9 +160,9 @@ export class SpriteRenderer extends Renderer {
const { transform } = this.entity;

// Update sprite data.
const localDirty = sprite._updateMeshData();
sprite._updateMesh();

if (this._isWorldMatrixDirty.flag || localDirty || this._isContainDirtyFlag(DirtyFlag.Sprite)) {
if (this._isWorldMatrixDirty.flag || this._spriteDirty.flag) {
const localPositions = sprite._positions;
const localVertexPos = SpriteRenderer._tempVec3;
const worldMatrix = transform.worldMatrix;
Expand All @@ -169,8 +175,8 @@ export class SpriteRenderer extends Renderer {
}

this._setDirtyFlagFalse(DirtyFlag.Flip);
this._setDirtyFlagFalse(DirtyFlag.Sprite);
this._isWorldMatrixDirty.flag = false;
this._spriteDirty.flag = false;
this._cacheFlipX = flipX;
this._cacheFlipY = flipY;
} else if (this._isContainDirtyFlag(DirtyFlag.Flip)) {
Expand Down Expand Up @@ -217,6 +223,7 @@ export class SpriteRenderer extends Renderer {
*/
_onDestroy(): void {
this._isWorldMatrixDirty.destroy();
this._spriteDirty && this._spriteDirty.destroy();
super._onDestroy();
}

Expand All @@ -232,6 +239,13 @@ export class SpriteRenderer extends Renderer {
this._dirtyFlag &= ~type;
}

/**
* @internal
*/
_cloneTo(target: SpriteRenderer): void {
target.sprite = this._sprite;
}

/**
* @override
*/
Expand Down Expand Up @@ -279,7 +293,5 @@ export class SpriteRenderer extends Renderer {

enum DirtyFlag {
Flip = 0x1,
Sprite = 0x2,
All = 0x3,
MaskInteraction = 0x4
MaskInteraction = 0x2
}

0 comments on commit 339a4a5

Please sign in to comment.