Skip to content

Commit

Permalink
Merge latest dev/0.8 to dev/asset-file (#860)
Browse files Browse the repository at this point in the history
* Test: Use Floss and Chai to Replace Jest (#778)

test: Use Floss and Chai to Replace Jest

* refactor: remove toolkit features (#780)

* v0.7.0-beta.4 (#795)

* Fix:local translate (#706)

* fix(transform):local translate

* Add component denpendent decorator (#796)

* feat: add `dependentComponents` decorator

* ci: remove ci on node 12 (#801)

* Update README.md

* Fix Test Version Error (#802)

* ci: remove ci on node 12

* test: fix version

* feat: add `priority` for renderer to order(#803)

* feat(renderer): add `priority` for renderer to order

* Fix SkyBox render mirror problem (#816)

* refactor: fix skybox mirror problem

* fix:   change `region` and `pivot` origin to left-bottom (#809)

* fix:   change `region` and `pivot` origin to left-bottom

* Merge latest main (#820)

* v0.7.0-beta.4

* Update README.md

* Update README.md

* Update README.md

* Add component denpendent decorator (#796) (#807)

* feat: add `dependentComponents` decorator

* fix(Renderer): destroy crash when material is null (#808)

* Improve BlendShape when use attribute mode (#804)

* feat: improve BlendShape when use attribute mode

* v0.7.0-beta.5

* refactor: fix skybox mirror problem

* fix: fixed the bug of animator revert when blendWeight length exceeds 4 (#817)

* fix: fixed the bug of animator revert when blendWeight length exceeds 4

* v0.7.0-beta.6

* refactor: fix shader

* fix(text): fix horizontal and vertical alignment error (#772)

* fix(text): fix horizontal alignment error

Co-authored-by: luzhuang <[email protected]>
Co-authored-by: singlecoder <[email protected]>

* refactor: rename (#827)

* v0.7.0-beta.7

* feat: physics character controller (#818)

* feat: add `CharacterController` for physX backend

* optimization camera code (#830)

refactor: optimization camera code

* Refactor `cloneTo` to `copyFrom` for math library and rename `setValue` to `set` (#844)

* feat: refactor `cloneTo` to `copyFrom` for math library
* feat: rename `setValue` to `set` for math library

* Fix transform`translate` and `rotate` space bug (#847)

* fix: transform`translate` and `rotate` space bug
* refactor: opt comments

* Feat(core): add more clear flag item for Camera.clearFlags (#843)

* feat(core): add more clear flag item for Camera.clearFlags

* v0.8.0-alpha.0

* v0.8.0-alpha.1

* Add SpriteRenderer drawMode property(support simple and sliced)  (#828)

* feat: add sprite draw mode(support simple and sliced)

* fix: TextureCube is left-hand,so x need inverse (#855)

* `InputManager` support pointer button and wheel (#831)

* feat: `InputManager` support pointer button and wheel

* Add basic physics joint component include `FixedJoint`, `SpringJoint`, `HingeJoint`  (#853)

* feat: basic physics joint

* Use char cache mode for TextRenderer (#837)

* feat(text): use char cache mode for TextRenderer

* v0.8.0-alpha.2

* v0.8.0-alpha.3

* fix: resolve conflict

* fix: resolve conflict

Co-authored-by: Hu Song <[email protected]>
Co-authored-by: AZhan <[email protected]>
Co-authored-by: singlecoder <[email protected]>
Co-authored-by: luzhuang <[email protected]>
Co-authored-by: zhuxudong <[email protected]>
Co-authored-by: yangfengzzz <[email protected]>
  • Loading branch information
7 people authored Jul 11, 2022
1 parent f57b7bc commit fbbf57a
Show file tree
Hide file tree
Showing 85 changed files with 3,323 additions and 1,402 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"npmClient": "npm",
"version": "0.7.0-beta.7",
"version": "0.8.0-alpha.3",
"bootstrap": {
"hoist": true
},
Expand Down
10 changes: 7 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"name": "@oasis-engine/core",
"version": "0.7.0-beta.7",
"version": "0.8.0-alpha.3",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org"
},
"license": "MIT",
"main": "dist/main.js",
"module": "dist/module.js",
Expand All @@ -15,9 +19,9 @@
"types/**/*"
],
"dependencies": {
"@oasis-engine/math": "0.7.0-beta.7"
"@oasis-engine/math": "0.8.0-alpha.3"
},
"devDependencies": {
"@oasis-engine/design": "0.7.0-beta.7"
"@oasis-engine/design": "0.8.0-alpha.3"
}
}
11 changes: 11 additions & 0 deletions packages/core/src/2d/assembler/IAssembler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Renderer } from "../../Renderer";

/**
* @internal
*/
export interface IAssembler {
resetData(renderer: Renderer): void;
updateData(renderer: Renderer): void;
updatePositions?(renderer: Renderer): void;
updateUVs?(renderer: Renderer): void;
}
77 changes: 77 additions & 0 deletions packages/core/src/2d/assembler/SimpleSpriteAssembler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { BoundingBox, Matrix, Vector2, Vector3 } from "@oasis-engine/math";
import { SpriteMask } from "../sprite";
import { SpriteRenderer } from "../sprite/SpriteRenderer";
import { IAssembler } from "./IAssembler";
import { StaticInterfaceImplement } from "./StaticInterfaceImplement";

/**
* @internal
*/
@StaticInterfaceImplement<IAssembler>()
export class SimpleSpriteAssembler {
static _rectangleTriangles: number[] = [0, 1, 2, 2, 1, 3];
static _worldMatrix: Matrix = new Matrix();

static resetData(renderer: SpriteRenderer | SpriteMask): void {
const { _renderData: renderData } = renderer;
const vertexCount = (renderData.vertexCount = 4);
const { positions, uvs } = renderData;
if (positions.length < vertexCount) {
for (let i = positions.length; i < vertexCount; i++) {
positions.push(new Vector3());
uvs.push(new Vector2());
}
}
renderData.triangles = SimpleSpriteAssembler._rectangleTriangles;
}

static updateData(renderer: SpriteRenderer | SpriteMask): void {}

static updatePositions(renderer: SpriteRenderer | SpriteMask): void {
const { width, height } = renderer;
if (width === 0 || height === 0) {
return;
}
const { sprite } = renderer;
const { x: pivotX, y: pivotY } = sprite.pivot;
// Renderer's worldMatrix;
const { _worldMatrix: worldMatrix } = SimpleSpriteAssembler;
const { elements: wE } = worldMatrix;
// Parent's worldMatrix.
const { elements: pWE } = renderer.entity.transform.worldMatrix;
const sx = renderer.flipX ? -width : width;
const sy = renderer.flipY ? -height : height;
(wE[0] = pWE[0] * sx), (wE[1] = pWE[1] * sx), (wE[2] = pWE[2] * sx);
(wE[4] = pWE[4] * sy), (wE[5] = pWE[5] * sy), (wE[6] = pWE[6] * sy);
(wE[8] = pWE[8]), (wE[9] = pWE[9]), (wE[10] = pWE[10]);
wE[12] = pWE[12] - pivotX * wE[0] - pivotY * wE[4];
wE[13] = pWE[13] - pivotX * wE[1] - pivotY * wE[5];
wE[14] = pWE[14];

// ---------------
// 2 - 3
// | |
// 0 - 1
// ---------------
// Update positions.
const spritePositions = sprite._getPositions();
const { positions } = renderer._renderData;
for (let i = 0; i < 4; i++) {
const { x, y } = spritePositions[i];
positions[i].set(wE[0] * x + wE[4] * y + wE[12], wE[1] * x + wE[5] * y + wE[13], wE[2] * x + wE[6] * y + wE[14]);
}

BoundingBox.transform(sprite._getBounds(), worldMatrix, renderer._bounds);
}

static updateUVs(renderer: SpriteRenderer | SpriteMask): void {
const spriteUVs = renderer.sprite._getUVs();
const renderUVs = renderer._renderData.uvs;
const { x: left, y: bottom } = spriteUVs[0];
const { x: right, y: top } = spriteUVs[3];
renderUVs[0].set(left, bottom);
renderUVs[1].set(right, bottom);
renderUVs[2].set(left, top);
renderUVs[3].set(right, top);
}
}
151 changes: 151 additions & 0 deletions packages/core/src/2d/assembler/SlicedSpriteAssembler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { Matrix, Vector2, Vector3 } from "@oasis-engine/math";
import { SpriteMask } from "../sprite";
import { SpriteRenderer } from "../sprite/SpriteRenderer";
import { IAssembler } from "./IAssembler";
import { StaticInterfaceImplement } from "./StaticInterfaceImplement";

/**
* @internal
*/
@StaticInterfaceImplement<IAssembler>()
export class SlicedSpriteAssembler {
static _worldMatrix: Matrix = new Matrix();
static resetData(renderer: SpriteRenderer | SpriteMask): void {
const { _renderData: renderData } = renderer;
const { positions, uvs } = renderData;
if (positions.length < 16) {
for (let i = positions.length; i < 16; i++) {
positions.push(new Vector3());
uvs.push(new Vector2());
}
}
renderData.triangles = [];
}

static updateData(renderer: SpriteRenderer | SpriteMask): void {}

static updatePositions(renderer: SpriteRenderer | SpriteMask): void {
const { width, height } = renderer;
if (width === 0 || height === 0) {
return;
}
const { sprite } = renderer;
const { positions, uvs, triangles } = renderer._renderData;
const { border } = sprite;
const spriteUVs = sprite._getUVs();
// Update local positions.
const spritePositions = sprite._getPositions();
const { x: left, y: bottom } = spritePositions[0];
const { x: right, y: top } = spritePositions[3];
const { width: expectWidth, height: expectHeight } = sprite;
const fixedLeft = expectWidth * border.x;
const fixedBottom = expectHeight * border.y;
const fixedRight = expectHeight * border.z;
const fixedTop = expectWidth * border.w;

// ------------------------
// [3]
// |
// [2]
// |
// [1]
// |
// row [0] - [1] - [2] - [3]
// column
// ------------------------
// Calculate row and column.
let row: number[], column: number[];
if (fixedLeft + fixedRight > width) {
const widthScale = width / (fixedLeft + fixedRight);
row = [
expectWidth * left * widthScale,
fixedLeft * widthScale,
fixedLeft * widthScale,
width - expectWidth * (1 - right) * widthScale
];
} else {
row = [expectWidth * left, fixedLeft, width - fixedRight, width - expectWidth * (1 - right)];
}

if (fixedTop + fixedBottom > height) {
const heightScale = height / (fixedTop + fixedBottom);
column = [
expectHeight * bottom * heightScale,
fixedBottom * heightScale,
fixedBottom * heightScale,
height - expectHeight * (1 - top) * heightScale
];
} else {
column = [expectHeight * bottom, fixedBottom, height - fixedTop, height - expectHeight * (1 - top)];
}

// Update renderer's worldMatrix.
const { x: pivotX, y: pivotY } = renderer.sprite.pivot;
const localTransX = renderer.width * pivotX;
const localTransY = renderer.height * pivotY;
// Renderer's worldMatrix.
const { _worldMatrix: worldMatrix } = SlicedSpriteAssembler;
const { elements: wE } = worldMatrix;
// Parent's worldMatrix.
const { elements: pWE } = renderer.entity.transform.worldMatrix;
const sx = renderer.flipX ? -1 : 1;
const sy = renderer.flipY ? -1 : 1;
(wE[0] = pWE[0] * sx), (wE[1] = pWE[1] * sx), (wE[2] = pWE[2] * sx);
(wE[4] = pWE[4] * sy), (wE[5] = pWE[5] * sy), (wE[6] = pWE[6] * sy);
(wE[8] = pWE[8]), (wE[9] = pWE[9]), (wE[10] = pWE[10]);
wE[12] = pWE[12] - localTransX * wE[0] - localTransY * wE[4];
wE[13] = pWE[13] - localTransX * wE[1] - localTransY * wE[5];
wE[14] = pWE[14];

// ------------------------
// 3 - 7 - 11 - 15
// | | | |
// 2 - 6 - 10 - 14
// | | | |
// 1 - 5 - 9 - 13
// | | | |
// 0 - 4 - 8 - 12
// ------------------------
// Assemble position and uv.
let vertexCount = 0;
let realICount = 0;
for (let i = 0; i < 4; i++) {
const rowValue = row[i];
const rowU = spriteUVs[i].x;
for (let j = 0; j < 4; j++) {
const columnValue = column[j];
positions[vertexCount].set(
wE[0] * rowValue + wE[4] * columnValue + wE[12],
wE[1] * rowValue + wE[5] * columnValue + wE[13],
wE[2] * rowValue + wE[6] * columnValue + wE[14]
);
uvs[vertexCount].set(rowU, spriteUVs[j].y);
++vertexCount;
}
++realICount;
}

const realJCount = vertexCount / realICount;
let indexOffset = 0;
for (let i = 0; i < realICount - 1; ++i) {
for (let j = 0; j < realJCount - 1; ++j) {
const start = i * realJCount + j;
triangles[indexOffset++] = start;
triangles[indexOffset++] = start + 1;
triangles[indexOffset++] = start + realJCount;
triangles[indexOffset++] = start + 1;
triangles[indexOffset++] = start + realJCount + 1;
triangles[indexOffset++] = start + realJCount;
}
}
renderer._renderData.vertexCount = realICount * realJCount;
triangles.length = (realICount - 1) * (realJCount - 1) * 6;

const { min, max } = renderer._bounds;
min.set(row[0], column[0], 0);
max.set(row[3], column[3], 0);
renderer._bounds.transform(worldMatrix);
}

static updateUVs(renderer: SpriteRenderer | SpriteMask): void {}
}
10 changes: 10 additions & 0 deletions packages/core/src/2d/assembler/StaticInterfaceImplement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Static interface implement decorator.
* https://stackoverflow.com/questions/13955157/how-to-define-static-property-in-typescript-interface
*/
export function StaticInterfaceImplement<T>() {
return <U extends T>(constructor: U) => {
constructor;
};
}

93 changes: 93 additions & 0 deletions packages/core/src/2d/atlas/FontAtlas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { RefObject } from "../../asset/RefObject";
import { Engine } from "../../Engine";
import { Texture2D } from "../../texture/Texture2D";
import { CharInfo } from "../text/CharInfo";

/**
* @internal
* Font Atlas.
*/
export class FontAtlas extends RefObject {
private _charInfoMap: Record<number, CharInfo> = {};
private _texture: Texture2D;
private _space: number = 1;
private _curX: number = 1;
private _curY: number = 1;
private _nextY: number = 1;

get texture(): Texture2D {
return this._texture;
}

set texture(value: Texture2D) {
this._texture = value;
}

/**
* Constructor a FontAtlas.
* @param engine - Engine to which the FontAtlas belongs
*/
constructor(engine: Engine) {
super(engine);
}

/**
* @override
*/
_onDestroy(): void {
this._texture.destroy();
this._texture = null;
this._charInfoMap = {};
}

uploadCharTexture(charInfo: CharInfo, imageSource: TexImageSource | OffscreenCanvas): boolean {
const { w: width, h: height } = charInfo;
const { _space: space, texture } = this;
const textureSize = texture.width;
const offsetWidth = width + space;
const offsetHeight = height + space;
if ((1 + offsetWidth) >= textureSize || (1 + offsetHeight) >= textureSize) {
throw Error("The char fontSize is too large.");
}

const endX = this._curX + offsetWidth;
if (endX >= textureSize) {
this._curX = space;
this._curY = this._nextY + space;
}
const endY = this._curY + offsetHeight;
if (endY > this._nextY) {
this._nextY = endY;
}
if (endY >= textureSize) {
return false;
}

if (width > 0 && height > 0) {
texture.setImageSource(imageSource, 0, false, false, this._curX, this._curY);
texture.generateMipmaps();
}

const textureSizeReciprocal = 1.0 / textureSize;
const x = this._curX;
const y = this._curY;
const w = width;
const h = height;
charInfo.x = x;
charInfo.y = y;
charInfo.u0 = x * textureSizeReciprocal;
charInfo.u1 = (x + w) * textureSizeReciprocal;
charInfo.v0 = y * textureSizeReciprocal;
charInfo.v1 = (y + h) * textureSizeReciprocal;
this._curX += offsetWidth + space;
return true;
}

addCharInfo(char: string, charInfo: CharInfo) {
this._charInfoMap[char.charCodeAt(0)] = charInfo;
}

getCharInfo(char: string): CharInfo {
return this._charInfoMap[char.charCodeAt(0)];
}
}
14 changes: 14 additions & 0 deletions packages/core/src/2d/data/RenderData2D.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Color, Vector2, Vector3 } from "@oasis-engine/math";

/**
* @internal
*/
export class RenderData2D {
constructor(
public vertexCount: number,
public positions: Vector3[],
public uvs: Vector2[],
public triangles: number[] = null,
public color: Color = null
) {}
}
Loading

0 comments on commit fbbf57a

Please sign in to comment.