Skip to content

Commit

Permalink
feat(ECS): Add ECS files (Orillusion#66)
Browse files Browse the repository at this point in the history
Add ECS framework into engine.
  • Loading branch information
hellmor authored Apr 24, 2023
1 parent 1d6c070 commit 4f18553
Show file tree
Hide file tree
Showing 13 changed files with 2,453 additions and 0 deletions.
98 changes: 98 additions & 0 deletions src/engine/components/AtmosphericComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { SkyRenderer } from "../..";
import { AtmosphericScatteringSky, AtmosphericScatteringSkySetting } from "../textures/AtmosphericScatteringSky";

/**
*
* Atmospheric Sky Box Component
* @group Components
*/
export class AtmosphericComponent extends SkyRenderer {

private _atmosphericScatteringSky: AtmosphericScatteringSky;

public get sunX() {
return this._atmosphericScatteringSky.setting.sunX;
}

public set sunX(value) {
this._atmosphericScatteringSky.setting.sunX = value;
this._atmosphericScatteringSky.apply();
}

public get sunY() {
return this._atmosphericScatteringSky.setting.sunY;
}

public set sunY(value) {
this._atmosphericScatteringSky.setting.sunY = value;
this._atmosphericScatteringSky.apply();
}

public get eyePos() {
return this._atmosphericScatteringSky.setting.eyePos;
}

public set eyePos(value) {
this._atmosphericScatteringSky.setting.eyePos = value;
this._atmosphericScatteringSky.apply();
}

public get sunRadius() {
return this._atmosphericScatteringSky.setting.sunRadius;
}

public set sunRadius(value) {
this._atmosphericScatteringSky.setting.sunRadius = value;
this._atmosphericScatteringSky.apply();
}

public get sunRadiance() {
return this._atmosphericScatteringSky.setting.sunRadiance;
}

public set sunRadiance(value) {
this._atmosphericScatteringSky.setting.sunRadiance = value;
this._atmosphericScatteringSky.apply();
}

public get sunBrightness() {
return this._atmosphericScatteringSky.setting.sunBrightness;
}

public set sunBrightness(value) {
this._atmosphericScatteringSky.setting.sunBrightness = value;
this._atmosphericScatteringSky.apply();
}

public get displaySun() {
return this._atmosphericScatteringSky.setting.displaySun;
}

public set displaySun(value) {
this._atmosphericScatteringSky.setting.displaySun = value;
this._atmosphericScatteringSky.apply();
}

protected init(): void {
super.init();
this._atmosphericScatteringSky = new AtmosphericScatteringSky(new AtmosphericScatteringSkySetting());
}

protected start(): void {
let scene = this.transform.scene3D;
this.map = this._atmosphericScatteringSky;
scene.envMap = this._atmosphericScatteringSky;
super.start();
}

protected onEnable(): void {

}

protected onDisable(): void {

}

public debug() {
}
}
40 changes: 40 additions & 0 deletions src/engine/components/BillboardComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Object3DType } from './gui/data/AssetsInfo';
import { Camera3D } from '../core/Camera3D';
import { Object3D } from '../core/entities/Object3D';
import { Vector3 } from '../math/Vector3';
import { ComponentBase } from './ComponentBase';

export class BillboardComponent extends ComponentBase {
public type: Object3DType;
public camera: Camera3D;
private _cameraDirection: Vector3;

constructor() {
super();
this._cameraDirection = new Vector3();
}

protected onUpdate() {
super.onUpdate();
if (this.enable && this.transform.view3D.camera) {
this.updateBillboardMatrix();
}
}

private updateBillboardMatrix(): void {
let camera = this.transform.view3D.camera;
this._cameraDirection.copyFrom(camera.transform.back);
if (this.type == Object3DType.BillboardXYZ) {
this._cameraDirection.normalize().multiplyScalar(100);
} else if (this.type == Object3DType.BillboardY) {
this._cameraDirection.y = 0;
this._cameraDirection.normalize().multiplyScalar(100);
}
this.transform.lookAt(Vector3.ZERO, this._cameraDirection, camera.transform.up);
}

public cloneTo(obj: Object3D) {
let component = obj.addComponent(BillboardComponent);
component.type = this.type;
}
}
241 changes: 241 additions & 0 deletions src/engine/components/ComponentBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import { View3D } from "../core/View3D";
import { Object3D } from "../core/entities/Object3D";
import { CEventDispatcher } from "../event/CEventDispatcher";
import { ComponentType, SerializeTag } from "../util/SerializeDefine";
import { Transform } from "./Transform";


/**
* Components are used to attach functionality to object3D, it has an owner object3D.
* The component can receive update events at each frame.
* @group Components
*/
export class ComponentBase {
/**
* owner object3D
*/
public object3D: Object3D = null;

/**
* @internal
*/
public eventDispatcher: CEventDispatcher;

/**
* @internal
*/
public componentType: ComponentType = ComponentType.none;

/**
* @internal
*/
public serializeTag?: SerializeTag;

/**
* @internal
*/
protected _enable: boolean = true;

private __isStart: boolean = false;

constructor() {
this.eventDispatcher = new CEventDispatcher();
}

/**
* Return the Transform component attached to the Object3D.
*/
public get transform(): Transform {
return this.object3D.transform;
}


/**
* Enable/disable components. The enabled components can be updated, while the disabled components cannot be updated.
*/
public set enable(value: boolean) {
if (this._enable != value) {
this._enable = value;
if (this._enable) {
this.onEnable();
} else {
this.onDisable();
}
}
}

/**
* Enable/disable components. The enabled components can be updated, while the disabled components cannot be updated.
*/
public get enable(): boolean {
return this._enable;
}

private __init(param?: any) {
this.init(param);
}

private __start() {
if (this.transform && this.transform.scene3D && this.__isStart == false) {
this.start();
this.__isStart = true;
}
if (this.transform && this.transform.scene3D) {
this.onEnable();
}
let hasUpdate = this.onUpdate.toString().replace(/\s+/g, '').length;
if (hasUpdate > 10) {
this._onUpdate(this.onUpdate.bind(this));
}
let hasLateUpdate = this.onLateUpdate.toString().replace(/\s+/g, '').length;
if (hasLateUpdate > 14) {
this._onLateUpdate(this.onLateUpdate.bind(this));
}
let hasBeforeUpdate = this.onBeforeUpdate.toString().replace(/\s+/g, '').length;
if (hasBeforeUpdate > 16) {
this._onBeforeUpdate(this.onBeforeUpdate.bind(this));
}
let hasCompute = this.onCompute.toString().replace(/\s+/g, '').length;
if (hasCompute > 11) {
this._onCompute(this.onCompute.bind(this));
}
let hasOnGraphic = this.onGraphic.toString().replace(/\s+/g, '').length;
if (hasOnGraphic > 11) {
this._onGraphic(this.onGraphic.bind(this));
}
}

private __stop() {
if (this.transform && this.transform.scene3D) {
this.onDisable();
}
this._onUpdate(null);
this._onLateUpdate(null);
this._onBeforeUpdate(null);
this._onCompute(null);
this._onGraphic(null);
}

protected init(param?: any) { }
protected start() { }
protected stop() { }
protected onEnable(view?: View3D) { }
protected onDisable(view?: View3D) { }
protected onUpdate(view?: View3D) { }
protected onLateUpdate(view?: View3D) { }
protected onBeforeUpdate(view?: View3D) { }
protected onCompute(view?: View3D, command?: GPUCommandEncoder) { }
protected onGraphic(view?: View3D) { }

/**
*
* clone component data to target object3D
* @param obj target object3D
*/
public cloneTo(obj: Object3D) { }

/**
* internal
* Add update function. Will be executed at every frame update.
* @param call callback
*/
private _onUpdate(call: Function) {
if (call != null) {
ComponentBase.componentsUpdateList.set(this, call);
} else {
ComponentBase.componentsUpdateList.delete(this);
}
}

/**
* Add a delayed update function.
* @param call callback
*/
private _onLateUpdate(call: Function) {
// if(!this.enable) return;
if (call != null) {
ComponentBase.componentsLateUpdateList.set(this, call);
} else {
ComponentBase.componentsLateUpdateList.delete(this);
}
}

/**
* The function executed before adding frame updates.
* @param call callback
*/
private _onBeforeUpdate(call: Function) {
// if(!this.enable) return;
if (call != null) {
ComponentBase.componentsBeforeUpdateList.set(this, call);
} else {
ComponentBase.componentsBeforeUpdateList.delete(this);
}
}

/**
* @internal
* Add individual execution compute capability
* @param call callback
*/
private _onCompute(call: Function) {
if (call != null) {
ComponentBase.componentsComputeList.set(this, call);
} else {
ComponentBase.componentsComputeList.delete(this);
}
}

/**
* Add individual execution drawing ability
* @param call callback
*/
private _onGraphic(call: Function) {
if (call != null) {
ComponentBase.graphicComponent.set(this, call);
} else {
ComponentBase.graphicComponent.delete(this);
}
}

/**
* release this component
*/
public destroy() {
this.enable = false;
this.stop();
this._onBeforeUpdate(null);
this._onUpdate(null);
this._onLateUpdate(null);
}

/**
* @internal
*/
static componentsUpdateList: Map<any, Function> = new Map<any, Function>();

/**
* @internal
*/
static componentsLateUpdateList: Map<any, Function> = new Map<any, Function>();

/**
* @internal
*/
static componentsBeforeUpdateList: Map<any, Function> = new Map<any, Function>();

/**
* @internal
*/
static componentsComputeList: Map<ComponentBase, Function> = new Map<ComponentBase, Function>();

/**
* @internal
*/
static waitStartComponent: Map<Object3D, ComponentBase[]> = new Map<Object3D, ComponentBase[]>();

/**
* @internal
*/
static graphicComponent: Map<ComponentBase, Function> = new Map<ComponentBase, Function>();
}
Loading

0 comments on commit 4f18553

Please sign in to comment.