Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions packages/core/src/2d/assembler/ISpriteAssembler.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
import { Matrix, Vector2 } from "@galacean/engine-math";
import { ISpriteRenderer } from "./ISpriteRenderer";
import { BoundingBox, Color, Matrix, Vector2 } from "@galacean/engine-math";
import { PrimitiveChunkManager } from "../../RenderPipeline/PrimitiveChunkManager";
import { SpriteTileMode } from "../enums/SpriteTileMode";
import { SpritePrimitive } from "../sprite/SpritePrimitive";

/**
* Interface for sprite assembler.
*/
export interface ISpriteAssembler {
resetData(renderer: ISpriteRenderer, vertexCount?: number): void;
resetData(primitive: SpritePrimitive, chunkManager: PrimitiveChunkManager, vertexCount?: number): void;
updatePositions(
renderer: ISpriteRenderer,
primitive: SpritePrimitive,
chunkManager: PrimitiveChunkManager,
worldMatrix: Matrix,
width: number,
height: number,
pivot: Vector2,
flipX: boolean,
flipY: boolean,
referenceResolutionPerUnit?: number
outBounds: BoundingBox,
referenceResolutionPerUnit?: number,
tileMode?: SpriteTileMode,
tiledAdaptiveThreshold?: number
): void;
updateUVs(renderer: ISpriteRenderer): void;
updateColor(renderer: ISpriteRenderer, alpha: number): void;
updateUVs(primitive: SpritePrimitive): void;
updateColor(primitive: SpritePrimitive, color: Color, alpha: number): void;
}
17 changes: 0 additions & 17 deletions packages/core/src/2d/assembler/ISpriteRenderer.ts

This file was deleted.

40 changes: 21 additions & 19 deletions packages/core/src/2d/assembler/SimpleSpriteAssembler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { BoundingBox, Matrix, Vector2 } from "@galacean/engine-math";
import { BoundingBox, Color, Matrix, Vector2 } from "@galacean/engine-math";
import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement";
import { PrimitiveChunkManager } from "../../RenderPipeline/PrimitiveChunkManager";
import { SpritePrimitive } from "../sprite/SpritePrimitive";
import { ISpriteAssembler } from "./ISpriteAssembler";
import { ISpriteRenderer } from "./ISpriteRenderer";

/**
* Assemble vertex data for the sprite renderer in simple mode.
Expand All @@ -11,25 +12,26 @@ export class SimpleSpriteAssembler {
private static _rectangleTriangles = [0, 1, 2, 2, 1, 3];
private static _matrix = new Matrix();

static resetData(renderer: ISpriteRenderer): void {
const manager = renderer._getChunkManager();
const lastSubChunk = renderer._subChunk;
lastSubChunk && manager.freeSubChunk(lastSubChunk);
const subChunk = manager.allocateSubChunk(4);
static resetData(primitive: SpritePrimitive, chunkManager: PrimitiveChunkManager): void {
const lastSubChunk = primitive.subChunk;
lastSubChunk && chunkManager.freeSubChunk(lastSubChunk);
const subChunk = chunkManager.allocateSubChunk(4);
subChunk.indices = SimpleSpriteAssembler._rectangleTriangles;
renderer._subChunk = subChunk;
primitive.subChunk = subChunk;
}

static updatePositions(
renderer: ISpriteRenderer,
primitive: SpritePrimitive,
chunkManager: PrimitiveChunkManager,
worldMatrix: Matrix,
width: number,
height: number,
pivot: Vector2,
flipX: boolean,
flipY: boolean
flipY: boolean,
outBounds: BoundingBox
): void {
const { sprite } = renderer;
const { sprite } = primitive;
const { x: pivotX, y: pivotY } = pivot;
// Position to World
const modelMatrix = SimpleSpriteAssembler._matrix;
Expand All @@ -52,7 +54,7 @@ export class SimpleSpriteAssembler {
// ---------------
// Update positions
const spritePositions = sprite._getPositions();
const subChunk = renderer._subChunk;
const subChunk = primitive.subChunk;
const vertices = subChunk.chunk.vertices;
for (let i = 0, o = subChunk.vertexArea.start; i < 4; ++i, o += 9) {
const { x, y } = spritePositions[i];
Expand All @@ -62,14 +64,14 @@ export class SimpleSpriteAssembler {
}

// @ts-ignore
BoundingBox.transform(sprite._getBounds(), modelMatrix, renderer._bounds);
BoundingBox.transform(sprite._getBounds(), modelMatrix, outBounds);
}

static updateUVs(renderer: ISpriteRenderer): void {
const spriteUVs = renderer.sprite._getUVs();
static updateUVs(primitive: SpritePrimitive): void {
const spriteUVs = primitive.sprite._getUVs();
const { x: left, y: bottom } = spriteUVs[0];
const { x: right, y: top } = spriteUVs[3];
const subChunk = renderer._subChunk;
const subChunk = primitive.subChunk;
const vertices = subChunk.chunk.vertices;
const offset = subChunk.vertexArea.start + 3;
vertices[offset] = left;
Expand All @@ -82,9 +84,9 @@ export class SimpleSpriteAssembler {
vertices[offset + 28] = top;
}

static updateColor(renderer: ISpriteRenderer, alpha: number): void {
const subChunk = renderer._subChunk;
const { r, g, b, a } = renderer.color;
static updateColor(primitive: SpritePrimitive, color: Color, alpha: number): void {
const subChunk = primitive.subChunk;
const { r, g, b, a } = color;
const finalAlpha = a * alpha;
const vertices = subChunk.chunk.vertices;
for (let i = 0, o = subChunk.vertexArea.start + 5; i < 4; ++i, o += 9) {
Expand Down
44 changes: 22 additions & 22 deletions packages/core/src/2d/assembler/SlicedSpriteAssembler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Matrix, Vector2 } from "@galacean/engine-math";
import { BoundingBox, Color, Matrix, Vector2 } from "@galacean/engine-math";
import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement";
import { PrimitiveChunkManager } from "../../RenderPipeline/PrimitiveChunkManager";
import { SpritePrimitive } from "../sprite/SpritePrimitive";
import { ISpriteAssembler } from "./ISpriteAssembler";
import { ISpriteRenderer } from "./ISpriteRenderer";

/**
* Assemble vertex data for the sprite renderer in sliced mode.
Expand All @@ -16,26 +17,27 @@ export class SlicedSpriteAssembler {
private static _row = new Array<number>(4);
private static _column = new Array<number>(4);

static resetData(renderer: ISpriteRenderer): void {
const manager = renderer._getChunkManager();
const lastSubChunk = renderer._subChunk;
lastSubChunk && manager.freeSubChunk(lastSubChunk);
const subChunk = manager.allocateSubChunk(16);
static resetData(primitive: SpritePrimitive, chunkManager: PrimitiveChunkManager): void {
const lastSubChunk = primitive.subChunk;
lastSubChunk && chunkManager.freeSubChunk(lastSubChunk);
const subChunk = chunkManager.allocateSubChunk(16);
subChunk.indices = SlicedSpriteAssembler._rectangleTriangles;
renderer._subChunk = subChunk;
primitive.subChunk = subChunk;
}

static updatePositions(
renderer: ISpriteRenderer,
primitive: SpritePrimitive,
chunkManager: PrimitiveChunkManager,
worldMatrix: Matrix,
width: number,
height: number,
pivot: Vector2,
flipX: boolean,
flipY: boolean,
outBounds: BoundingBox,
referenceResolutionPerUnit: number = 1
): void {
const { sprite } = renderer;
const { sprite } = primitive;
const { border } = sprite;
// Update local positions.
const spritePositions = sprite._getPositions();
Expand Down Expand Up @@ -106,7 +108,7 @@ export class SlicedSpriteAssembler {
// 0 - 4 - 8 - 12
// ------------------------
// Assemble position and uv.
const subChunk = renderer._subChunk;
const subChunk = primitive.subChunk;
const vertices = subChunk.chunk.vertices;
for (let i = 0, o = subChunk.vertexArea.start; i < 4; i++) {
const rowValue = row[i];
Expand All @@ -118,17 +120,15 @@ export class SlicedSpriteAssembler {
}
}

// @ts-ignore
const bounds = renderer._bounds;
bounds.min.set(row[0], column[0], 0);
bounds.max.set(row[3], column[3], 0);
bounds.transform(modelMatrix);
outBounds.min.set(row[0], column[0], 0);
outBounds.max.set(row[3], column[3], 0);
outBounds.transform(modelMatrix);
}

static updateUVs(renderer: ISpriteRenderer): void {
const subChunk = renderer._subChunk;
static updateUVs(primitive: SpritePrimitive): void {
const subChunk = primitive.subChunk;
const vertices = subChunk.chunk.vertices;
const spriteUVs = renderer.sprite._getUVs();
const spriteUVs = primitive.sprite._getUVs();
for (let i = 0, o = subChunk.vertexArea.start + 3; i < 4; i++) {
const rowU = spriteUVs[i].x;
for (let j = 0; j < 4; j++, o += 9) {
Expand All @@ -138,9 +138,9 @@ export class SlicedSpriteAssembler {
}
}

static updateColor(renderer: ISpriteRenderer, alpha: number): void {
const subChunk = renderer._subChunk;
const { r, g, b, a } = renderer.color;
static updateColor(primitive: SpritePrimitive, color: Color, alpha: number): void {
const subChunk = primitive.subChunk;
const { r, g, b, a } = color;
const finalAlpha = a * alpha;
const vertices = subChunk.chunk.vertices;
for (let i = 0, o = subChunk.vertexArea.start + 5; i < 16; ++i, o += 9) {
Expand Down
71 changes: 44 additions & 27 deletions packages/core/src/2d/assembler/TiledSpriteAssembler.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { MathUtil, Matrix, Vector2 } from "@galacean/engine-math";
import { BoundingBox, Color, MathUtil, Matrix, Vector2 } from "@galacean/engine-math";
import { Logger } from "../../base";
import { StaticInterfaceImplement } from "../../base/StaticInterfaceImplement";
import { PrimitiveChunkManager } from "../../RenderPipeline/PrimitiveChunkManager";
import { DisorderedArray } from "../../utils/DisorderedArray";
import { SpriteTileMode } from "../enums/SpriteTileMode";
import { Sprite } from "../sprite/Sprite";
import { SpritePrimitive } from "../sprite/SpritePrimitive";
import { ISpriteAssembler } from "./ISpriteAssembler";
import { ISpriteRenderer } from "./ISpriteRenderer";

/**
* Assemble vertex data for the sprite renderer in tiled mode.
Expand All @@ -17,36 +19,52 @@ export class TiledSpriteAssembler {
private static _uvRow = new DisorderedArray<number>();
private static _uvColumn = new DisorderedArray<number>();

static resetData(renderer: ISpriteRenderer, vertexCount: number): void {
static resetData(primitive: SpritePrimitive, chunkManager: PrimitiveChunkManager, vertexCount: number): void {
if (vertexCount) {
const manager = renderer._getChunkManager();
const lastSubChunk = renderer._subChunk;
const lastSubChunk = primitive.subChunk;
const sizeChanged = lastSubChunk && lastSubChunk.vertexArea.size !== vertexCount * 9;
sizeChanged && manager.freeSubChunk(lastSubChunk);
sizeChanged && chunkManager.freeSubChunk(lastSubChunk);

if (!lastSubChunk || sizeChanged) {
const newSubChunk = manager.allocateSubChunk(vertexCount);
const newSubChunk = chunkManager.allocateSubChunk(vertexCount);
newSubChunk.indices = [];
renderer._subChunk = newSubChunk;
primitive.subChunk = newSubChunk;
}
}
}

static updatePositions(
renderer: ISpriteRenderer,
primitive: SpritePrimitive,
chunkManager: PrimitiveChunkManager,
worldMatrix: Matrix,
width: number,
height: number,
pivot: Vector2,
flipX: boolean,
flipY: boolean,
referenceResolutionPerUnit: number = 1
outBounds: BoundingBox,
referenceResolutionPerUnit: number = 1,
tileMode?: SpriteTileMode,
tiledAdaptiveThreshold?: number
): void {
// Calculate row and column
const { _posRow: rPos, _posColumn: cPos, _uvRow: rUV, _uvColumn: cUV } = TiledSpriteAssembler;
TiledSpriteAssembler.resetData(
renderer,
TiledSpriteAssembler._calculateDividing(renderer, width, height, rPos, cPos, rUV, cUV, referenceResolutionPerUnit)
primitive,
chunkManager,
TiledSpriteAssembler._calculateDividing(
primitive.sprite,
tileMode,
tiledAdaptiveThreshold,
chunkManager.maxVertexCount,
width,
height,
rPos,
cPos,
rUV,
cUV,
referenceResolutionPerUnit
)
);
// Update renderer's worldMatrix
const { x: pivotX, y: pivotY } = pivot;
Expand All @@ -71,7 +89,7 @@ export class TiledSpriteAssembler {
const rowLength = rPos.length - 1;
const columnLength = cPos.length - 1;

const subChunk = renderer._subChunk;
const subChunk = primitive.subChunk;
const vertices = subChunk.chunk.vertices;
const indices = subChunk.indices;
let count = 0;
Expand Down Expand Up @@ -118,18 +136,16 @@ export class TiledSpriteAssembler {
}
}

// @ts-ignore
const bounds = renderer._bounds;
bounds.min.set(rPos.get(0), cPos.get(0), 0);
bounds.max.set(rPos.get(rowLength), cPos.get(columnLength), 0);
bounds.transform(modelMatrix);
outBounds.min.set(rPos.get(0), cPos.get(0), 0);
outBounds.max.set(rPos.get(rowLength), cPos.get(columnLength), 0);
outBounds.transform(modelMatrix);
}

static updateUVs(renderer: ISpriteRenderer): void {
static updateUVs(primitive: SpritePrimitive): void {
const { _posRow: posRow, _posColumn: posColumn, _uvRow: uvRow, _uvColumn: uvColumn } = TiledSpriteAssembler;
const rowLength = posRow.length - 1;
const columnLength = posColumn.length - 1;
const subChunk = renderer._subChunk;
const subChunk = primitive.subChunk;
const vertices = subChunk.chunk.vertices;
for (let j = 0, o = subChunk.vertexArea.start + 3; j < columnLength; j++) {
const doubleJ = 2 * j;
Expand Down Expand Up @@ -159,9 +175,9 @@ export class TiledSpriteAssembler {
}
}

static updateColor(renderer: ISpriteRenderer, alpha: number): void {
const subChunk = renderer._subChunk;
const { r, g, b, a } = renderer.color;
static updateColor(primitive: SpritePrimitive, color: Color, alpha: number): void {
const subChunk = primitive.subChunk;
const { r, g, b, a } = color;
const finalAlpha = a * alpha;
const vertices = subChunk.chunk.vertices;
const vertexArea = subChunk.vertexArea;
Expand All @@ -174,7 +190,10 @@ export class TiledSpriteAssembler {
}

private static _calculateDividing(
renderer: ISpriteRenderer,
sprite: Sprite,
tileMode: SpriteTileMode,
threshold: number,
maxVertexCount: number,
width: number,
height: number,
rPos: DisorderedArray<number>,
Expand All @@ -183,7 +202,6 @@ export class TiledSpriteAssembler {
cUV: DisorderedArray<number>,
referenceResolutionPerUnit: number
): number {
const { sprite, tiledAdaptiveThreshold: threshold } = renderer;
const { border } = sprite;
const spritePositions = sprite._getPositions();
const { x: left, y: bottom } = spritePositions[0];
Expand All @@ -199,7 +217,7 @@ export class TiledSpriteAssembler {
const fixedB = expectHeight * border.y;
const fixedTB = fixedT + fixedB;
const fixedCH = expectHeight - fixedTB;
const isAdaptive = renderer.tileMode === SpriteTileMode.Adaptive;
const isAdaptive = tileMode === SpriteTileMode.Adaptive;
let rType: TiledType, rBlocksCount: number, rTiledCount: number;
let cType: TiledType, cBlocksCount: number, cTiledCount: number;
if (fixedLR >= width) {
Expand Down Expand Up @@ -241,7 +259,6 @@ export class TiledSpriteAssembler {

rPos.length = cPos.length = rUV.length = cUV.length = 0;
const vertexCount = rBlocksCount * cBlocksCount * 4;
const maxVertexCount = renderer._getChunkManager().maxVertexCount;
if (vertexCount > maxVertexCount) {
rPos.add(width * left), rPos.add(width * right);
cPos.add(height * bottom), cPos.add(height * top);
Expand Down
Loading
Loading