Skip to content

Commit

Permalink
feat: atlas support rotate
Browse files Browse the repository at this point in the history
  • Loading branch information
cptbtptpbcptdtptp committed Jan 9, 2024
1 parent 1d7fc34 commit ac3d661
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 124 deletions.
108 changes: 41 additions & 67 deletions packages/core/src/2d/assembler/TiledSpriteAssembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class TiledSpriteAssembler {
const { x: pivotX, y: pivotY } = renderer.sprite.pivot;
const localTransX = renderer.width * pivotX;
const localTransY = renderer.height * pivotY;
const spriteUVs = sprite._getUVs();
const spUVs = sprite._getUVs();
// Renderer's worldMatrix
const { _worldMatrix: worldMatrix } = TiledSpriteAssembler;
const { elements: wE } = worldMatrix;
Expand All @@ -60,11 +60,11 @@ export class TiledSpriteAssembler {
for (let j = 0; j < columnLength; j++) {
const doubleJ = 2 * j;
for (let i = 0; i < rowLength; i++) {
const rowForm = uvRow.get(2 * i);
const rowTo = uvRow.get(2 * i + 1);
const colFrom = uvColumn.get(doubleJ);
const colTo = uvColumn.get(doubleJ + 1);
if (isNaN(rowForm) || isNaN(rowTo) || isNaN(colFrom) || isNaN(colTo)) {
const rFrom = uvRow.get(2 * i);
const rTo = uvRow.get(2 * i + 1);
const cFrom = uvColumn.get(doubleJ);
const cTo = uvColumn.get(doubleJ + 1);
if (isNaN(rFrom) || isNaN(rTo) || isNaN(cFrom) || isNaN(cTo)) {
continue;
}
triangles[trianglesOffset++] = count;
Expand All @@ -73,56 +73,50 @@ export class TiledSpriteAssembler {
triangles[trianglesOffset++] = count + 2;
triangles[trianglesOffset++] = count + 1;
triangles[trianglesOffset++] = count + 3;
const l = posRow.get(i);
const b = posColumn.get(j);
const r = posRow.get(i + 1);
const t = posColumn.get(j + 1);

TiledSpriteAssembler._getCorners(
spriteUVs,
rowForm,
rowTo,
colFrom,
colTo,
(uvs[count] ||= new Vector2()),
(uvs[count + 1] ||= new Vector2()),
(uvs[count + 2] ||= new Vector2()),
(uvs[count + 3] ||= new Vector2())
);
let pos = positions[count];
if (pos) {
pos.set(wE0 * l + wE4 * b + wE12, wE1 * l + wE5 * b + wE13, wE2 * l + wE6 * b + wE14);
} else {
positions[count] = new Vector3(wE0 * l + wE4 * b + wE12, wE1 * l + wE5 * b + wE13, wE2 * l + wE6 * b + wE14);
}
// left and bottom
const LBPos = (positions[count] ||= new Vector3());
const LBUV = (uvs[count] ||= new Vector2());
count++;

// right and bottom
pos = positions[count];
if (pos) {
pos.set(wE0 * r + wE4 * b + wE12, wE1 * r + wE5 * b + wE13, wE2 * r + wE6 * b + wE14);
} else {
positions[count] = new Vector3(wE0 * r + wE4 * b + wE12, wE1 * r + wE5 * b + wE13, wE2 * r + wE6 * b + wE14);
}
const RBPos = (positions[count] ||= new Vector3());
const RBUV = (uvs[count] ||= new Vector2());
count++;

// left and top
pos = positions[count];
if (pos) {
pos.set(wE0 * l + wE4 * t + wE12, wE1 * l + wE5 * t + wE13, wE2 * l + wE6 * t + wE14);
} else {
positions[count] = new Vector3(wE0 * l + wE4 * t + wE12, wE1 * l + wE5 * t + wE13, wE2 * l + wE6 * t + wE14);
}
const LTPos = (positions[count] ||= new Vector3());
const LTUV = (uvs[count] ||= new Vector2());
count++;

// right and top
pos = positions[count];
if (pos) {
pos.set(wE0 * r + wE4 * t + wE12, wE1 * r + wE5 * t + wE13, wE2 * r + wE6 * t + wE14);
const RTPos = (positions[count] ||= new Vector3());
const RTUV = (uvs[count] ||= new Vector2());
count++;

// update position
const l = posRow.get(i);
const b = posColumn.get(j);
const r = posRow.get(i + 1);
const t = posColumn.get(j + 1);
LBPos.set(wE0 * l + wE4 * b + wE12, wE1 * l + wE5 * b + wE13, wE2 * l + wE6 * b + wE14);
RBPos.set(wE0 * r + wE4 * b + wE12, wE1 * r + wE5 * b + wE13, wE2 * r + wE6 * b + wE14);
LTPos.set(wE0 * l + wE4 * t + wE12, wE1 * l + wE5 * t + wE13, wE2 * l + wE6 * t + wE14);
RTPos.set(wE0 * r + wE4 * t + wE12, wE1 * r + wE5 * t + wE13, wE2 * r + wE6 * t + wE14);

// update uv
LBUV.copyFrom(spUVs[rFrom + cFrom * 4]);
const rowToInteger = rTo % 1;
const colToInteger = cTo % 1;
if (rowToInteger) {
Vector2.lerp(spUVs[Math.floor(rTo) + cFrom * 4], spUVs[Math.ceil(rTo) + cFrom * 4], rowToInteger, RBUV);
} else {
positions[count] = new Vector3(wE0 * r + wE4 * t + wE12, wE1 * r + wE5 * t + wE13, wE2 * r + wE6 * t + wE14);
RBUV.copyFrom(spUVs[rTo + cFrom * 4]);
}
count++;
if (colToInteger) {
Vector2.lerp(spUVs[rFrom + Math.floor(cTo) * 4], spUVs[rFrom + Math.ceil(cTo) * 4], colToInteger, LTUV);
} else {
LTUV.copyFrom(spUVs[rFrom + cTo * 4]);
}
Vector2.add(RBUV, LTUV, RTUV);
RTUV.subtract(LBUV);
}
}

Expand Down Expand Up @@ -374,26 +368,6 @@ export class TiledSpriteAssembler {
break;
}
}

private static _getCorners(
uvs: Vector2[],
rowFrom: number,
rowTo: number,
colFrom: number,
colTo: number,
leftBottom: Vector2,
rightBottom: Vector2,
leftTop: Vector2,
rightTop: Vector2
): void {
leftBottom.copyFrom(uvs[rowFrom + colFrom * 4]);
const rowToInteger = rowTo % 1;
const colToInteger = colTo % 1;
Vector2.lerp(uvs[Math.floor(rowTo) + colFrom * 4], uvs[Math.ceil(rowTo) + colFrom * 4], rowToInteger, rightBottom);
Vector2.lerp(uvs[rowFrom + Math.floor(colTo) * 4], uvs[rowFrom + Math.ceil(colTo) * 4], colToInteger, leftTop);
Vector2.add(rightBottom, leftTop, rightTop);
rightTop.subtract(leftBottom);
}
}

enum TiledType {
Expand Down
79 changes: 22 additions & 57 deletions packages/core/src/2d/sprite/Sprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,12 @@ export class Sprite extends ReferResource {
private _customHeight: number = undefined;

private _positions: Vector2[] = [new Vector2(), new Vector2(), new Vector2(), new Vector2()];
// prettier-ignore
private _uvs: Vector2[] = [
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2(),
new Vector2()
new Vector2(), new Vector2(), new Vector2(), new Vector2(),
new Vector2(), new Vector2(), new Vector2(), new Vector2(),
new Vector2(), new Vector2(), new Vector2(), new Vector2(),
new Vector2(), new Vector2(), new Vector2(), new Vector2(),
];
private _bounds: BoundingBox = new BoundingBox();

Expand Down Expand Up @@ -357,61 +346,37 @@ export class Sprite extends ReferResource {
const realHeight = atlasRegionH / (1 - offsetTop - offsetBottom);
// Coordinates of the boundaries.
let left: number, top: number, right: number, bottom: number;
let borderLeft: number, borderTop: number, borderRight: number, borderBottom: number;
let bLeft: number, bTop: number, bRight: number, bBottom: number;
if (atlasRotated) {
left = Math.max(regionBottom - offsetLeft, 0) * realWidth + atlasRegionX;
top = Math.max(regionLeft - offsetTop, 0) * realHeight + atlasRegionY;
right = atlasRegionW + atlasRegionX - Math.max(regionTop - offsetRight, 0) * realWidth;
bottom = atlasRegionH + atlasRegionY - Math.max(regionRight - offsetBottom, 0) * realHeight;
borderLeft = (regionBottom - offsetLeft + border.y * regionH) * realWidth + atlasRegionX;
borderTop = (regionLeft - offsetTop + border.x * regionW) * realHeight + atlasRegionY;
borderRight = atlasRegionW + atlasRegionX - (regionTop - offsetRight + border.w * regionH) * realWidth;
borderBottom = atlasRegionH + atlasRegionY - (regionRight - offsetBottom + border.z * regionW) * realHeight;
bLeft = (regionBottom - offsetLeft + border.y * regionH) * realWidth + atlasRegionX;
bTop = (regionLeft - offsetTop + border.x * regionW) * realHeight + atlasRegionY;
bRight = atlasRegionW + atlasRegionX - (regionTop - offsetRight + border.w * regionH) * realWidth;
bBottom = atlasRegionH + atlasRegionY - (regionRight - offsetBottom + border.z * regionW) * realHeight;
} else {
left = Math.max(regionLeft - offsetLeft, 0) * realWidth + atlasRegionX;
top = Math.max(regionBottom - offsetTop, 0) * realHeight + atlasRegionY;
right = atlasRegionW + atlasRegionX - Math.max(regionRight - offsetRight, 0) * realWidth;
bottom = atlasRegionH + atlasRegionY - Math.max(regionTop - offsetBottom, 0) * realHeight;
borderLeft = (regionLeft - offsetLeft + border.x * regionW) * realWidth + atlasRegionX;
borderTop = (regionBottom - offsetTop + border.w * regionH) * realHeight + atlasRegionY;
borderRight = atlasRegionW + atlasRegionX - (regionRight - offsetRight + border.z * regionW) * realWidth;
borderBottom = atlasRegionH + atlasRegionY - (regionTop - offsetBottom + border.y * regionH) * realHeight;
bLeft = (regionLeft - offsetLeft + border.x * regionW) * realWidth + atlasRegionX;
bTop = (regionBottom - offsetTop + border.w * regionH) * realHeight + atlasRegionY;
bRight = atlasRegionW + atlasRegionX - (regionRight - offsetRight + border.z * regionW) * realWidth;
bBottom = atlasRegionH + atlasRegionY - (regionTop - offsetBottom + border.y * regionH) * realHeight;
}

if (atlasRotated) {
uvs[0].set(left, top);
uvs[1].set(left, borderTop);
uvs[2].set(left, borderBottom);
uvs[3].set(left, bottom);
uvs[4].set(borderLeft, top);
uvs[5].set(borderLeft, borderTop);
uvs[6].set(borderLeft, borderBottom);
uvs[7].set(borderLeft, bottom);
uvs[8].set(borderRight, top);
uvs[9].set(borderRight, borderTop);
uvs[10].set(borderRight, borderBottom);
uvs[11].set(borderRight, bottom);
uvs[12].set(right, top);
uvs[13].set(right, borderTop);
uvs[14].set(right, borderBottom);
uvs[15].set(right, bottom);
uvs[0].set(left, top), uvs[1].set(left, bTop), uvs[2].set(left, bBottom), uvs[3].set(left, bottom);
uvs[4].set(bLeft, top), uvs[5].set(bLeft, bTop), uvs[6].set(bLeft, bBottom), uvs[7].set(bLeft, bottom);
uvs[8].set(bRight, top), uvs[9].set(bRight, bTop), uvs[10].set(bRight, bBottom), uvs[11].set(bRight, bottom);
uvs[12].set(right, top), uvs[13].set(right, bTop), uvs[14].set(right, bBottom), uvs[15].set(right, bottom);
} else {
uvs[0].set(left, bottom);
uvs[1].set(borderLeft, bottom);
uvs[2].set(borderRight, bottom);
uvs[3].set(right, bottom);
uvs[4].set(left, borderBottom);
uvs[5].set(borderLeft, borderBottom);
uvs[6].set(borderRight, borderBottom);
uvs[7].set(right, borderBottom);
uvs[8].set(left, borderTop);
uvs[9].set(borderLeft, borderTop);
uvs[10].set(borderRight, borderTop);
uvs[11].set(right, borderTop);
uvs[12].set(left, top);
uvs[13].set(borderLeft, top);
uvs[14].set(borderRight, top);
uvs[15].set(right, top);
uvs[0].set(left, bottom), uvs[1].set(bLeft, bottom), uvs[2].set(bRight, bottom), uvs[3].set(right, bottom);
uvs[4].set(left, bBottom), uvs[5].set(bLeft, bBottom), uvs[6].set(bRight, bBottom), uvs[7].set(right, bBottom);
uvs[8].set(left, bTop), uvs[9].set(bLeft, bTop), uvs[10].set(bRight, bTop), uvs[11].set(right, bTop);
uvs[12].set(left, top), uvs[13].set(bLeft, top), uvs[14].set(bRight, top), uvs[15].set(right, top);
}
this._dirtyUpdateFlag &= ~SpriteUpdateFlags.uvs;
}
Expand Down

0 comments on commit ac3d661

Please sign in to comment.