From 5242c9cac9d198cb0c18b97fc00bc6b03b11b54b Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Sat, 11 Apr 2020 00:11:38 -0300 Subject: [PATCH] chore: move more components around --- scene-api/engine/Animator.ts | 37 -- scene-api/engine/AvatarShape.ts | 2 +- scene-api/engine/Billboard.ts | 1 + scene-api/engine/Components.ts | 427 +----------------- scene-api/engine/GLTFShape.ts | 3 +- scene-api/engine/Gizmos.ts | 3 +- scene-api/engine/Systems.ts | 2 +- scene-api/engine/Transform.ts | 55 +++ scene-api/engine/UIShapes.ts | 5 +- scene-api/engine/animation/OnAnimationEnd.ts | 11 + scene-api/engine/basic-shapes/BoxShape.ts | 6 +- scene-api/engine/basic-shapes/CircleShape.ts | 7 +- scene-api/engine/basic-shapes/ConeShape.ts | 6 +- .../engine/basic-shapes/CylinderShape.ts | 7 +- scene-api/engine/basic-shapes/PlaneShape.ts | 6 +- scene-api/engine/basic-shapes/SphereShape.ts | 6 +- scene-api/engine/basic-shapes/TextShape.ts | 68 +++ scene-api/engine/events/OnPointerLock.ts | 11 + scene-api/engine/events/OnUUIDEvent.ts | 57 +++ scene-api/engine/{ => events}/UIEvents.ts | 9 +- scene-api/engine/materials/BasicMaterial.ts | 20 + scene-api/engine/materials/Material.ts | 145 ++++++ .../{basic-shapes => materials}/Shape.ts | 2 +- scene-api/engine/{ => materials}/Texture.ts | 0 scene-api/index.ts | 2 +- 25 files changed, 405 insertions(+), 493 deletions(-) delete mode 100644 scene-api/engine/Animator.ts create mode 100644 scene-api/engine/Transform.ts create mode 100644 scene-api/engine/animation/OnAnimationEnd.ts create mode 100644 scene-api/engine/basic-shapes/TextShape.ts create mode 100644 scene-api/engine/events/OnPointerLock.ts create mode 100644 scene-api/engine/events/OnUUIDEvent.ts rename scene-api/engine/{ => events}/UIEvents.ts (93%) create mode 100644 scene-api/engine/materials/BasicMaterial.ts create mode 100644 scene-api/engine/materials/Material.ts rename scene-api/engine/{basic-shapes => materials}/Shape.ts (85%) rename scene-api/engine/{ => materials}/Texture.ts (100%) diff --git a/scene-api/engine/Animator.ts b/scene-api/engine/Animator.ts deleted file mode 100644 index f456da47d..000000000 --- a/scene-api/engine/Animator.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Component, ObservableComponent } from '../ecs/Component' -import { AnimationState } from './animation/AnimationState' -import { Shape } from './Shape' -import { CLASS_ID } from './Components' -/** - * @public - */ -@Component('engine.animator', CLASS_ID.ANIMATION) -export class Animator extends Shape { - @ObservableComponent.readonly - private states: AnimationState[] = [] - /** - * Adds an AnimationState to the animation lists. - */ - addClip(clip: AnimationState) { - this.states.push(clip) - clip.onChange(() => { - this.dirty = true - }) - return this - } - /** - * Gets the animation clip instance for the specified clip name. - * If the clip doesn't exist a new one will be created. - */ - getClip(clipName: string): AnimationState { - for (let i = 0; i < this.states.length; i++) { - const clip = this.states[i] - if (clip.clip === clipName) { - return clip - } - } - const newClip = new AnimationState(clipName) - this.addClip(newClip) - return newClip - } -} diff --git a/scene-api/engine/AvatarShape.ts b/scene-api/engine/AvatarShape.ts index e9d2144ef..5d15c3794 100644 --- a/scene-api/engine/AvatarShape.ts +++ b/scene-api/engine/AvatarShape.ts @@ -1,4 +1,4 @@ -import { ObservableComponent, Component } from '../ecs/Component' +import { ObservableComponent, Component } from './../ecs/Component' import { CLASS_ID } from './Components' import { Color4 } from 'dcl/utils/math/Color4' diff --git a/scene-api/engine/Billboard.ts b/scene-api/engine/Billboard.ts index 741c0688e..a835a837f 100644 --- a/scene-api/engine/Billboard.ts +++ b/scene-api/engine/Billboard.ts @@ -1,5 +1,6 @@ import { Component, ObservableComponent } from '../ecs/Component' import { CLASS_ID } from './Components' + /** * Billboard defines a behavior that makes the entity face the camera in any moment. * @public diff --git a/scene-api/engine/Components.ts b/scene-api/engine/Components.ts index 4db70239a..e4230bb3f 100644 --- a/scene-api/engine/Components.ts +++ b/scene-api/engine/Components.ts @@ -1,10 +1,4 @@ -import { MVector3, MQuaternion, Matrix, MathTmp, Color3 } from 'dcl/utils' - -import { Component, ObservableComponent, DisposableComponent } from '../ecs/Component' -import { newId } from '../ecs/IdGenerator' -import { IEvents } from './Types' -import { Shape } from './Shape' -import { Texture } from './Texture' +import { MVector3, MQuaternion } from 'dcl/utils' /** @public */ export type TranformConstructorArgs = { @@ -60,422 +54,3 @@ export enum CLASS_ID { AUDIO_SOURCE = 201, GIZMOS = 203, } - -/** - * @public - */ -@Component('engine.transform', CLASS_ID.TRANSFORM) -export class Transform extends ObservableComponent { - @ObservableComponent.field - position!: MVector3 - - @ObservableComponent.field - rotation!: MQuaternion - - @ObservableComponent.field - scale!: MVector3 - - constructor(args: TranformConstructorArgs = {}) { - super() - this.position = args.position || MVector3.Zero() - this.rotation = args.rotation || MQuaternion.Identity - this.scale = args.scale || new MVector3(1, 1, 1) - } - - /** - * @public - * The rotation as Euler angles in degrees. - */ - get eulerAngles() { - return this.rotation.eulerAngles - } - - /** - * @public - * Rotates the transform so the forward vector points at target's current position. - */ - lookAt(target: MVector3, worldUp: MVector3 = MathTmp.staticUp) { - const result = new Matrix() - Matrix.LookAtLHToRef(this.position, target, worldUp, result) - result.invert() - MQuaternion.FromRotationMatrixToRef(result, this.rotation) - return this - } - - /** - * @public - * Applies a rotation of euler angles around the x, y and z axis. - */ - rotate(axis: MVector3, angle: number) { - this.rotation.multiplyInPlace(this.rotation.angleAxis(angle, axis)) - return this - } - - /** - * @public - * Moves the transform in the direction and distance of translation. - */ - translate(vec: MVector3) { - this.position.addInPlace(vec) - return this - } -} - -/** - * @public - */ -@Component('engine.text', CLASS_ID.TEXT_SHAPE) -export class TextShape extends Shape { - @ObservableComponent.field - outlineWidth: number = 0 - - @ObservableComponent.field - outlineColor: Color3 = new Color3(1, 1, 1) - - @ObservableComponent.field - color: Color3 = new Color3(1, 1, 1) - - @ObservableComponent.field - fontSize: number = 10 - - @ObservableComponent.field - fontWeight: string = 'normal' - - @ObservableComponent.field - opacity: number = 1.0 - - @ObservableComponent.field - value: string = '' - - @ObservableComponent.field - lineSpacing: string = '0px' - - @ObservableComponent.field - lineCount: number = 0 - - @ObservableComponent.field - resizeToFit: boolean = false - - @ObservableComponent.field - textWrapping: boolean = false - - @ObservableComponent.field - shadowBlur: number = 0 - - @ObservableComponent.field - shadowOffsetX: number = 0 - - @ObservableComponent.field - shadowOffsetY: number = 0 - - @ObservableComponent.field - shadowColor: Color3 = new Color3(1, 1, 1) - - @ObservableComponent.field - zIndex: number = 0 - - @ObservableComponent.field - hTextAlign: string = 'center' - - @ObservableComponent.field - vTextAlign: string = 'center' - - @ObservableComponent.field - width: number = 1 - - @ObservableComponent.field - height: number = 1 - - @ObservableComponent.field - paddingTop: number = 0 - - @ObservableComponent.field - paddingRight: number = 0 - - @ObservableComponent.field - paddingBottom: number = 0 - - @ObservableComponent.field - paddingLeft: number = 0 - - @ObservableComponent.field - isPickable: boolean = false - - @ObservableComponent.field - billboard: boolean = false - - constructor(value?: string) { - super() - - if (value) { - this.value = value - } - } -} - -/** - * @public - */ -@DisposableComponent('engine.material', CLASS_ID.PRB_MATERIAL) -export class Material extends ObservableComponent { - /** - * Opacity level between 0 and 1. - * Defaults to 1. - */ - @ObservableComponent.field - alpha?: number - - /** - * AKA Diffuse Color in other nomenclature. - * Defaults to #CCCCCC. - */ - @ObservableComponent.field - albedoColor?: Color3 - - /** - * The color emitted from the material. - * Defaults to black. - */ - @ObservableComponent.field - emissiveColor?: Color3 - - /** - * Specifies the metallic scalar of the metallic/roughness workflow. - * Can also be used to scale the metalness values of the metallic texture. - * Defaults to 0.5. - */ - @ObservableComponent.field - metallic?: number - - /** - * Specifies the roughness scalar of the metallic/roughness workflow. - * Can also be used to scale the roughness values of the metallic texture. - * Defaults to 0.5. - */ - @ObservableComponent.field - roughness?: number - - /** - * AKA Diffuse Color in other nomenclature. - * Defaults to black. - */ - @ObservableComponent.field - ambientColor?: Color3 - - /** - * The color reflected from the material. - * Defaults to white. - */ - @ObservableComponent.field - reflectionColor?: Color3 - - /** - * AKA Specular Color in other nomenclature. - * Defaults to white. - */ - @ObservableComponent.field - reflectivityColor?: Color3 - - /** - * Intensity of the direct lights e.g. the four lights available in scene. - * This impacts both the direct diffuse and specular highlights. - * Defaults to 1. - */ - @ObservableComponent.field - directIntensity?: number - - /** - * AKA Glossiness in other nomenclature. - * Defaults to 1. - */ - @ObservableComponent.field - microSurface?: number - - /** - * Intensity of the emissive part of the material. - * This helps controlling the emissive effect without modifying the emissive color. - * Defaults to 1. - */ - @ObservableComponent.field - emissiveIntensity?: number - - /** - * Intensity of the environment e.g. how much the environment will light the object - * either through harmonics for rough material or through the refelction for shiny ones. - * Defaults to 1. - */ - @ObservableComponent.field - environmentIntensity?: number - - /** - * This is a special control allowing the reduction of the specular highlights coming from the - * four lights of the scene. Those highlights may not be needed in full environment lighting. - * Defaults to 1. - */ - @ObservableComponent.field - specularIntensity?: number - - /** - * Texture applied as material. - */ - @ObservableComponent.component - albedoTexture?: Texture - - /** - * Texture applied as opacity. Default: the same texture used in albedoTexture. - */ - @ObservableComponent.component - alphaTexture?: Texture - - /** - * Emissive texture. - */ - @ObservableComponent.component - emissiveTexture?: Texture - - /** - * Stores surface normal data used to displace a mesh in a texture. - */ - @ObservableComponent.component - bumpTexture?: Texture - - /** - * Stores the refracted light information in a texture. - */ - @ObservableComponent.component - refractionTexture?: Texture - - /** - * If sets to true, disables all the lights affecting the material. - * Defaults to false. - */ - @ObservableComponent.field - disableLighting?: boolean - - /** - * Sets the transparency mode of the material. - * Defaults to -1. - * - * | Value | Type | - * | ----- | ---------------------------------------------- | - * | 0 | OPAQUE (default) | - * | 1 | ALPHATEST | - * | 2 | ALPHABLEND | - * | 3 | ALPHATESTANDBLEND | - * | 4 | AUTO (ALPHABLEND if alpha OPAQUE otherwise | - */ - @ObservableComponent.field - transparencyMode: number = 4 - - /** - * Does the albedo texture has alpha? - * Defaults to false. - */ - @ObservableComponent.field - hasAlpha?: boolean -} - -/** - * @public - */ -@DisposableComponent('engine.material', CLASS_ID.BASIC_MATERIAL) -export class BasicMaterial extends ObservableComponent { - /** - * The source of the texture image. - */ - @ObservableComponent.component - texture?: Texture - - /** - * A number between 0 and 1. - * Any pixel with an alpha lower than this value will be shown as transparent. - */ - @ObservableComponent.field - alphaTest: number = 0.5 -} - -/** - * @public - */ -export class OnUUIDEvent extends ObservableComponent { - readonly type: string | undefined - - readonly uuid: string = newId('UUID') - - @ObservableComponent.field - callback!: (event: any) => void - - constructor(callback: (event: IEvents[T]) => void) { - super() - - if (!callback || !('apply' in callback) || !('call' in callback)) { - throw new Error('Callback is not a function') - } - - this.callback = callback - } - - static uuidEvent(target: ObservableComponent, propertyKey: string) { - if (delete (target as any)[propertyKey]) { - const componentSymbol = propertyKey + '_' + Math.random() - ;(target as any)[componentSymbol] = undefined - - Object.defineProperty(target, componentSymbol, { - ...Object.getOwnPropertyDescriptor(target, componentSymbol), - enumerable: false, - }) - - Object.defineProperty(target, propertyKey.toString(), { - get: function () { - return this[componentSymbol] - }, - set: function (value) { - const oldValue = this[componentSymbol] - - if (value) { - if (value instanceof OnUUIDEvent) { - this.data[propertyKey] = value.uuid - } else { - throw new Error('value is not an OnUUIDEvent') - } - } else { - this.data[propertyKey] = null - } - - this[componentSymbol] = value - - if (value !== oldValue) { - this.dirty = true - - for (let i = 0; i < this.subscriptions.length; i++) { - this.subscriptions[i](propertyKey, value, oldValue) - } - } - }, - enumerable: true, - }) - } - } - - toJSON() { - return { uuid: this.uuid, type: this.type } - } -} - -/** - * @internal - */ -@Component('engine.onPointerLock', CLASS_ID.UUID_CALLBACK) -export class OnPointerLock extends OnUUIDEvent<'onPointerLock'> { - @ObservableComponent.readonly - readonly type: string = 'onPointerLock' -} - -/** - * @public - */ -@Component('engine.onAnimationEnd', CLASS_ID.UUID_CALLBACK) -export class OnAnimationEnd extends OnUUIDEvent<'onAnimationEnd'> { - @ObservableComponent.readonly - readonly type: string = 'onAnimationEnd' -} diff --git a/scene-api/engine/GLTFShape.ts b/scene-api/engine/GLTFShape.ts index 17aeb90d1..fed07ec81 100644 --- a/scene-api/engine/GLTFShape.ts +++ b/scene-api/engine/GLTFShape.ts @@ -1,6 +1,7 @@ import { DisposableComponent } from '../ecs/Component' -import { Shape } from './Shape' import { CLASS_ID } from './Components' +import { Shape } from './Shape' + /** * @public */ diff --git a/scene-api/engine/Gizmos.ts b/scene-api/engine/Gizmos.ts index 30e4d99eb..3db934a4f 100644 --- a/scene-api/engine/Gizmos.ts +++ b/scene-api/engine/Gizmos.ts @@ -1,5 +1,6 @@ import { Component, ObservableComponent } from '../ecs/Component' -import { CLASS_ID, OnUUIDEvent } from './Components' +import { CLASS_ID } from './Components' +import { OnUUIDEvent } from './events/OnUUIDEvent' /** * Gizmo identifiers diff --git a/scene-api/engine/Systems.ts b/scene-api/engine/Systems.ts index 4dff56b54..8243c0993 100644 --- a/scene-api/engine/Systems.ts +++ b/scene-api/engine/Systems.ts @@ -1,6 +1,6 @@ import { UUIDEvent } from './Events' import { DecentralandInterface } from './Types' -import { OnUUIDEvent } from './Components' +import { OnUUIDEvent } from './events/OnUUIDEvent' import { ISystem, ComponentAdded, ComponentRemoved, IEntity } from '../ecs/IEntity' import { ECSEngine } from '../ecs/ECSEngine' diff --git a/scene-api/engine/Transform.ts b/scene-api/engine/Transform.ts new file mode 100644 index 000000000..844b37e4d --- /dev/null +++ b/scene-api/engine/Transform.ts @@ -0,0 +1,55 @@ +import { MVector3, MQuaternion, Matrix, MathTmp } from 'dcl/utils' +import { Component, ObservableComponent } from '../ecs/Component' +import { CLASS_ID, TranformConstructorArgs } from './Components' +/** + * @public + */ +@Component('engine.transform', CLASS_ID.TRANSFORM) +export class Transform extends ObservableComponent { + @ObservableComponent.field + position!: MVector3 + @ObservableComponent.field + rotation!: MQuaternion + @ObservableComponent.field + scale!: MVector3 + constructor(args: TranformConstructorArgs = {}) { + super() + this.position = args.position || MVector3.Zero() + this.rotation = args.rotation || MQuaternion.Identity + this.scale = args.scale || new MVector3(1, 1, 1) + } + /** + * @public + * The rotation as Euler angles in degrees. + */ + get eulerAngles() { + return this.rotation.eulerAngles + } + /** + * @public + * Rotates the transform so the forward vector points at target's current position. + */ + lookAt(target: MVector3, worldUp: MVector3 = MathTmp.staticUp) { + const result = new Matrix() + Matrix.LookAtLHToRef(this.position, target, worldUp, result) + result.invert() + MQuaternion.FromRotationMatrixToRef(result, this.rotation) + return this + } + /** + * @public + * Applies a rotation of euler angles around the x, y and z axis. + */ + rotate(axis: MVector3, angle: number) { + this.rotation.multiplyInPlace(this.rotation.angleAxis(angle, axis)) + return this + } + /** + * @public + * Moves the transform in the direction and distance of translation. + */ + translate(vec: MVector3) { + this.position.addInPlace(vec) + return this + } +} diff --git a/scene-api/engine/UIShapes.ts b/scene-api/engine/UIShapes.ts index 97717a114..ecc058eac 100644 --- a/scene-api/engine/UIShapes.ts +++ b/scene-api/engine/UIShapes.ts @@ -1,8 +1,9 @@ import { Color4 } from 'dcl/utils' -import { CLASS_ID, OnUUIDEvent } from './Components' +import { CLASS_ID } from './Components' +import { OnUUIDEvent } from './events/OnUUIDEvent' import { Texture } from './Texture' -import { OnTextSubmit, OnBlur, OnChanged, OnClick, OnFocus } from './UIEvents' +import { OnTextSubmit, OnBlur, OnChanged, OnClick, OnFocus } from './events/UIEvents' import { ObservableComponent, DisposableComponent, getComponentId } from '../ecs/Component' diff --git a/scene-api/engine/animation/OnAnimationEnd.ts b/scene-api/engine/animation/OnAnimationEnd.ts new file mode 100644 index 000000000..b643a771f --- /dev/null +++ b/scene-api/engine/animation/OnAnimationEnd.ts @@ -0,0 +1,11 @@ +import { Component, ObservableComponent } from '../../ecs/Component' +import { OnUUIDEvent } from './OnUUIDEvent' +import { CLASS_ID } from '../Components' +/** + * @public + */ +@Component('engine.onAnimationEnd', CLASS_ID.UUID_CALLBACK) +export class OnAnimationEnd extends OnUUIDEvent<'onAnimationEnd'> { + @ObservableComponent.readonly + readonly type: string = 'onAnimationEnd' +} diff --git a/scene-api/engine/basic-shapes/BoxShape.ts b/scene-api/engine/basic-shapes/BoxShape.ts index 9b78254b8..fb7e82e23 100644 --- a/scene-api/engine/basic-shapes/BoxShape.ts +++ b/scene-api/engine/basic-shapes/BoxShape.ts @@ -1,6 +1,6 @@ -import { DisposableComponent } from '../ecs/Component' -import { Shape } from './Shape' -import { CLASS_ID } from './Components' +import { DisposableComponent } from '../../ecs/Component' +import { Shape } from '../Shape' +import { CLASS_ID } from './../Components' /** * @public */ diff --git a/scene-api/engine/basic-shapes/CircleShape.ts b/scene-api/engine/basic-shapes/CircleShape.ts index b2a96a4ce..e9b48cc0f 100644 --- a/scene-api/engine/basic-shapes/CircleShape.ts +++ b/scene-api/engine/basic-shapes/CircleShape.ts @@ -1,6 +1,7 @@ -import { ObservableComponent, DisposableComponent } from '../ecs/Component' -import { Shape } from './Shape' -import { CLASS_ID } from './Components' +import { ObservableComponent, DisposableComponent } from '../../ecs/Component' +import { Shape } from '../Shape' +import { CLASS_ID } from '../Components' + /** * @public */ diff --git a/scene-api/engine/basic-shapes/ConeShape.ts b/scene-api/engine/basic-shapes/ConeShape.ts index e958a7504..076e25805 100644 --- a/scene-api/engine/basic-shapes/ConeShape.ts +++ b/scene-api/engine/basic-shapes/ConeShape.ts @@ -1,6 +1,6 @@ -import { ObservableComponent, DisposableComponent } from '../ecs/Component' -import { Shape } from './Shape' -import { CLASS_ID } from './Components' +import { DisposableComponent, ObservableComponent } from '../../ecs/Component' +import { Shape } from '../Shape' +import { CLASS_ID } from './../Components' /** * @public */ diff --git a/scene-api/engine/basic-shapes/CylinderShape.ts b/scene-api/engine/basic-shapes/CylinderShape.ts index d7aa43c99..22abc94af 100644 --- a/scene-api/engine/basic-shapes/CylinderShape.ts +++ b/scene-api/engine/basic-shapes/CylinderShape.ts @@ -1,6 +1,7 @@ -import { ObservableComponent, DisposableComponent } from '../ecs/Component' -import { Shape } from './Shape' -import { CLASS_ID } from './Components' +import { DisposableComponent, ObservableComponent } from '../../ecs/Component' +import { Shape } from '../Shape' +import { CLASS_ID } from './../Components' + /** * @public */ diff --git a/scene-api/engine/basic-shapes/PlaneShape.ts b/scene-api/engine/basic-shapes/PlaneShape.ts index 8e574fda2..eac4c1468 100644 --- a/scene-api/engine/basic-shapes/PlaneShape.ts +++ b/scene-api/engine/basic-shapes/PlaneShape.ts @@ -1,6 +1,6 @@ -import { ObservableComponent, DisposableComponent } from '../ecs/Component' -import { Shape } from './Shape' -import { CLASS_ID } from './Components' +import { ObservableComponent, DisposableComponent } from '../../ecs/Component' +import { Shape } from '../Shape' +import { CLASS_ID } from '../Components' /** * @public */ diff --git a/scene-api/engine/basic-shapes/SphereShape.ts b/scene-api/engine/basic-shapes/SphereShape.ts index 33012f97f..4b0788a46 100644 --- a/scene-api/engine/basic-shapes/SphereShape.ts +++ b/scene-api/engine/basic-shapes/SphereShape.ts @@ -1,6 +1,6 @@ -import { DisposableComponent } from '../ecs/Component' -import { Shape } from './Shape' -import { CLASS_ID } from './Components' +import { DisposableComponent } from '../../ecs/Component' +import { Shape } from '../Shape' +import { CLASS_ID } from '../Components' /** * @public */ diff --git a/scene-api/engine/basic-shapes/TextShape.ts b/scene-api/engine/basic-shapes/TextShape.ts new file mode 100644 index 000000000..56872bcd3 --- /dev/null +++ b/scene-api/engine/basic-shapes/TextShape.ts @@ -0,0 +1,68 @@ +import { Color3 } from 'dcl/utils' +import { Component, ObservableComponent } from '../../ecs/Component' +import { Shape } from '../Shape' +import { CLASS_ID } from '../Components' +/** + * @public + */ +@Component('engine.text', CLASS_ID.TEXT_SHAPE) +export class TextShape extends Shape { + @ObservableComponent.field + outlineWidth: number = 0 + @ObservableComponent.field + outlineColor: Color3 = new Color3(1, 1, 1) + @ObservableComponent.field + color: Color3 = new Color3(1, 1, 1) + @ObservableComponent.field + fontSize: number = 10 + @ObservableComponent.field + fontWeight: string = 'normal' + @ObservableComponent.field + opacity: number = 1.0 + @ObservableComponent.field + value: string = '' + @ObservableComponent.field + lineSpacing: string = '0px' + @ObservableComponent.field + lineCount: number = 0 + @ObservableComponent.field + resizeToFit: boolean = false + @ObservableComponent.field + textWrapping: boolean = false + @ObservableComponent.field + shadowBlur: number = 0 + @ObservableComponent.field + shadowOffsetX: number = 0 + @ObservableComponent.field + shadowOffsetY: number = 0 + @ObservableComponent.field + shadowColor: Color3 = new Color3(1, 1, 1) + @ObservableComponent.field + zIndex: number = 0 + @ObservableComponent.field + hTextAlign: string = 'center' + @ObservableComponent.field + vTextAlign: string = 'center' + @ObservableComponent.field + width: number = 1 + @ObservableComponent.field + height: number = 1 + @ObservableComponent.field + paddingTop: number = 0 + @ObservableComponent.field + paddingRight: number = 0 + @ObservableComponent.field + paddingBottom: number = 0 + @ObservableComponent.field + paddingLeft: number = 0 + @ObservableComponent.field + isPickable: boolean = false + @ObservableComponent.field + billboard: boolean = false + constructor(value?: string) { + super() + if (value) { + this.value = value + } + } +} diff --git a/scene-api/engine/events/OnPointerLock.ts b/scene-api/engine/events/OnPointerLock.ts new file mode 100644 index 000000000..4ecbfa1cc --- /dev/null +++ b/scene-api/engine/events/OnPointerLock.ts @@ -0,0 +1,11 @@ +import { Component, ObservableComponent } from '../../ecs/Component' +import { OnUUIDEvent } from './OnUUIDEvent' +import { CLASS_ID } from '../Components' +/** + * @internal + */ +@Component('engine.onPointerLock', CLASS_ID.UUID_CALLBACK) +export class OnPointerLock extends OnUUIDEvent<'onPointerLock'> { + @ObservableComponent.readonly + readonly type: string = 'onPointerLock' +} diff --git a/scene-api/engine/events/OnUUIDEvent.ts b/scene-api/engine/events/OnUUIDEvent.ts new file mode 100644 index 000000000..d3415a51e --- /dev/null +++ b/scene-api/engine/events/OnUUIDEvent.ts @@ -0,0 +1,57 @@ +import { ObservableComponent } from '../../ecs/Component' +import { newId } from '../../ecs/IdGenerator' +import { IEvents } from '../Types' +/** + * @public + */ +export class OnUUIDEvent extends ObservableComponent { + readonly type: string | undefined + readonly uuid: string = newId('UUID') + @ObservableComponent.field + callback!: (event: any) => void + constructor(callback: (event: IEvents[T]) => void) { + super() + if (!callback || !('apply' in callback) || !('call' in callback)) { + throw new Error('Callback is not a function') + } + this.callback = callback + } + static uuidEvent(target: ObservableComponent, propertyKey: string) { + if (delete (target as any)[propertyKey]) { + const componentSymbol = propertyKey + '_' + Math.random() + ;(target as any)[componentSymbol] = undefined + Object.defineProperty(target, componentSymbol, { + ...Object.getOwnPropertyDescriptor(target, componentSymbol), + enumerable: false, + }) + Object.defineProperty(target, propertyKey.toString(), { + get: function () { + return this[componentSymbol] + }, + set: function (value) { + const oldValue = this[componentSymbol] + if (value) { + if (value instanceof OnUUIDEvent) { + this.data[propertyKey] = value.uuid + } else { + throw new Error('value is not an OnUUIDEvent') + } + } else { + this.data[propertyKey] = null + } + this[componentSymbol] = value + if (value !== oldValue) { + this.dirty = true + for (let i = 0; i < this.subscriptions.length; i++) { + this.subscriptions[i](propertyKey, value, oldValue) + } + } + }, + enumerable: true, + }) + } + } + toJSON() { + return { uuid: this.uuid, type: this.type } + } +} diff --git a/scene-api/engine/UIEvents.ts b/scene-api/engine/events/UIEvents.ts similarity index 93% rename from scene-api/engine/UIEvents.ts rename to scene-api/engine/events/UIEvents.ts index 05509d4a6..e0ce2dd5f 100644 --- a/scene-api/engine/UIEvents.ts +++ b/scene-api/engine/events/UIEvents.ts @@ -1,8 +1,9 @@ -import { IEvents } from './Types' -import { uuidEventSystem } from './Systems' -import { CLASS_ID, OnUUIDEvent } from './Components' +import { IEvents } from '../Types' +import { uuidEventSystem } from '../Systems' +import { CLASS_ID } from '../Components' +import { OnUUIDEvent } from './OnUUIDEvent' -import { Component, ObservableComponent } from '../ecs/Component' +import { Component, ObservableComponent } from '../../ecs/Component' /** * @public diff --git a/scene-api/engine/materials/BasicMaterial.ts b/scene-api/engine/materials/BasicMaterial.ts new file mode 100644 index 000000000..c658e7d21 --- /dev/null +++ b/scene-api/engine/materials/BasicMaterial.ts @@ -0,0 +1,20 @@ +import { ObservableComponent, DisposableComponent } from '../ecs/Component' +import { Texture } from './Texture' +import { CLASS_ID } from './Components' +/** + * @public + */ +@DisposableComponent('engine.material', CLASS_ID.BASIC_MATERIAL) +export class BasicMaterial extends ObservableComponent { + /** + * The source of the texture image. + */ + @ObservableComponent.component + texture?: Texture + /** + * A number between 0 and 1. + * Any pixel with an alpha lower than this value will be shown as transparent. + */ + @ObservableComponent.field + alphaTest: number = 0.5 +} diff --git a/scene-api/engine/materials/Material.ts b/scene-api/engine/materials/Material.ts new file mode 100644 index 000000000..b265eccbb --- /dev/null +++ b/scene-api/engine/materials/Material.ts @@ -0,0 +1,145 @@ +import { Color3 } from 'dcl/utils' +import { ObservableComponent, DisposableComponent } from '../ecs/Component' +import { Texture } from './Texture' +import { CLASS_ID } from './Components' +/** + * @public + */ +@DisposableComponent('engine.material', CLASS_ID.PRB_MATERIAL) +export class Material extends ObservableComponent { + /** + * Opacity level between 0 and 1. + * Defaults to 1. + */ + @ObservableComponent.field + alpha?: number + /** + * AKA Diffuse Color in other nomenclature. + * Defaults to #CCCCCC. + */ + @ObservableComponent.field + albedoColor?: Color3 + /** + * The color emitted from the material. + * Defaults to black. + */ + @ObservableComponent.field + emissiveColor?: Color3 + /** + * Specifies the metallic scalar of the metallic/roughness workflow. + * Can also be used to scale the metalness values of the metallic texture. + * Defaults to 0.5. + */ + @ObservableComponent.field + metallic?: number + /** + * Specifies the roughness scalar of the metallic/roughness workflow. + * Can also be used to scale the roughness values of the metallic texture. + * Defaults to 0.5. + */ + @ObservableComponent.field + roughness?: number + /** + * AKA Diffuse Color in other nomenclature. + * Defaults to black. + */ + @ObservableComponent.field + ambientColor?: Color3 + /** + * The color reflected from the material. + * Defaults to white. + */ + @ObservableComponent.field + reflectionColor?: Color3 + /** + * AKA Specular Color in other nomenclature. + * Defaults to white. + */ + @ObservableComponent.field + reflectivityColor?: Color3 + /** + * Intensity of the direct lights e.g. the four lights available in scene. + * This impacts both the direct diffuse and specular highlights. + * Defaults to 1. + */ + @ObservableComponent.field + directIntensity?: number + /** + * AKA Glossiness in other nomenclature. + * Defaults to 1. + */ + @ObservableComponent.field + microSurface?: number + /** + * Intensity of the emissive part of the material. + * This helps controlling the emissive effect without modifying the emissive color. + * Defaults to 1. + */ + @ObservableComponent.field + emissiveIntensity?: number + /** + * Intensity of the environment e.g. how much the environment will light the object + * either through harmonics for rough material or through the refelction for shiny ones. + * Defaults to 1. + */ + @ObservableComponent.field + environmentIntensity?: number + /** + * This is a special control allowing the reduction of the specular highlights coming from the + * four lights of the scene. Those highlights may not be needed in full environment lighting. + * Defaults to 1. + */ + @ObservableComponent.field + specularIntensity?: number + /** + * Texture applied as material. + */ + @ObservableComponent.component + albedoTexture?: Texture + /** + * Texture applied as opacity. Default: the same texture used in albedoTexture. + */ + @ObservableComponent.component + alphaTexture?: Texture + /** + * Emissive texture. + */ + @ObservableComponent.component + emissiveTexture?: Texture + /** + * Stores surface normal data used to displace a mesh in a texture. + */ + @ObservableComponent.component + bumpTexture?: Texture + /** + * Stores the refracted light information in a texture. + */ + @ObservableComponent.component + refractionTexture?: Texture + /** + * If sets to true, disables all the lights affecting the material. + * Defaults to false. + */ + @ObservableComponent.field + disableLighting?: boolean + /** + * Sets the transparency mode of the material. + * Defaults to -1. + * + * | Value | Type | + * | ----- | ---------------------------------------------- | + * | 0 | OPAQUE (default) | + * | 1 | ALPHATEST | + * | 2 | ALPHABLEND | + * | 3 | ALPHATESTANDBLEND | + * | 4 | AUTO (ALPHABLEND if alpha OPAQUE otherwise | + */ + @ObservableComponent.field + transparencyMode: number = 4 + /** + * Does the albedo texture has alpha? + * Defaults to false. + */ + @ObservableComponent.field + hasAlpha?: boolean +} diff --git a/scene-api/engine/basic-shapes/Shape.ts b/scene-api/engine/materials/Shape.ts similarity index 85% rename from scene-api/engine/basic-shapes/Shape.ts rename to scene-api/engine/materials/Shape.ts index 1575efb42..44721a0b6 100644 --- a/scene-api/engine/basic-shapes/Shape.ts +++ b/scene-api/engine/materials/Shape.ts @@ -1,4 +1,4 @@ -import { ObservableComponent } from '../ecs/Component' +import { ObservableComponent } from '../../ecs/Component' /** * @public */ diff --git a/scene-api/engine/Texture.ts b/scene-api/engine/materials/Texture.ts similarity index 100% rename from scene-api/engine/Texture.ts rename to scene-api/engine/materials/Texture.ts diff --git a/scene-api/index.ts b/scene-api/index.ts index 780423532..c165cbf27 100644 --- a/scene-api/index.ts +++ b/scene-api/index.ts @@ -23,5 +23,5 @@ export * from './engine/Audio' export * from './engine/Gizmos' export * from './engine/UIShapes' export * from './engine/AvatarShape' -export * from './engine/UIEvents' +export * from './engine/events/UIEvents' export * from './engine/MessageBus'