From 6ae10cf0edaf73ac091ff14a1af70366fd4f3d19 Mon Sep 17 00:00:00 2001 From: GuoLei1990 Date: Sat, 29 Nov 2025 00:43:01 +0800 Subject: [PATCH] chore: cleanup --- packages/physics-lite/README.md | 34 - packages/physics-lite/package.json | 37 - packages/physics-lite/src/LiteCollider.ts | 100 --- .../physics-lite/src/LiteDynamicCollider.ts | 207 ----- packages/physics-lite/src/LiteHitResult.ts | 16 - packages/physics-lite/src/LitePhysics.ts | 202 ----- .../physics-lite/src/LitePhysicsManager.ts | 3 - .../physics-lite/src/LitePhysicsMaterial.ts | 54 -- packages/physics-lite/src/LitePhysicsScene.ts | 518 ------------- .../physics-lite/src/LiteStaticCollider.ts | 23 - packages/physics-lite/src/LiteTransform.ts | 349 --------- packages/physics-lite/src/LiteUpdateFlag.ts | 21 - .../physics-lite/src/LiteUpdateFlagManager.ts | 19 - packages/physics-lite/src/index.ts | 6 - .../src/shape/LiteBoxColliderShape.ts | 139 ---- .../src/shape/LiteColliderShape.ts | 166 ---- .../src/shape/LiteSphereColliderShape.ts | 90 --- packages/physics-lite/tsconfig.json | 18 - packages/ui/README.md | 67 -- packages/ui/package.json | 37 - packages/ui/src/Utils.ts | 152 ---- packages/ui/src/component/UICanvas.ts | 718 ------------------ packages/ui/src/component/UIGroup.ts | 228 ------ packages/ui/src/component/UIRenderer.ts | 300 -------- packages/ui/src/component/UITransform.ts | 446 ----------- packages/ui/src/component/advanced/Button.ts | 42 - packages/ui/src/component/advanced/Image.ts | 326 -------- packages/ui/src/component/advanced/Text.ts | 675 ---------------- packages/ui/src/component/index.ts | 11 - .../component/interactive/UIInteractive.ts | 302 -------- .../interactive/transition/ColorTransition.ts | 80 -- .../interactive/transition/ScaleTransition.ts | 28 - .../transition/SpriteTransition.ts | 49 -- .../interactive/transition/Transition.ts | 187 ----- packages/ui/src/enums/CanvasRenderMode.ts | 22 - .../ui/src/enums/HorizontalAlignmentMode.ts | 13 - .../ui/src/enums/ResolutionAdaptationMode.ts | 16 - .../ui/src/enums/VerticalAlignmentMode.ts | 13 - packages/ui/src/index.ts | 122 --- packages/ui/src/input/UIHitResult.ts | 13 - .../ui/src/input/UIPointerEventEmitter.ts | 266 ------- packages/ui/src/interface/IElement.ts | 15 - packages/ui/src/interface/IGraphics.ts | 10 - packages/ui/src/interface/IGroupAble.ts | 17 - packages/ui/src/shader/global.d.ts | 9 - packages/ui/src/shader/uiDefault.fs.glsl | 14 - packages/ui/src/shader/uiDefault.vs.glsl | 15 - packages/ui/tsconfig.json | 18 - packages/xr-webxr/README.md | 42 - packages/xr-webxr/package.json | 39 - packages/xr-webxr/src/Util.ts | 53 -- packages/xr-webxr/src/WebXRDevice.ts | 97 --- packages/xr-webxr/src/WebXRFrame.ts | 122 --- packages/xr-webxr/src/WebXRSession.ts | 208 ----- .../src/feature/WebXRAnchorTracking.ts | 122 --- packages/xr-webxr/src/feature/WebXRFeature.ts | 9 - .../src/feature/WebXRImageTracking.ts | 153 ---- .../src/feature/WebXRPlaneTracking.ts | 99 --- .../src/feature/WebXRTrackableFeature.ts | 32 - packages/xr-webxr/src/index.ts | 5 - packages/xr-webxr/tsconfig.json | 18 - packages/xr/README.md | 42 - packages/xr/package.json | 38 - packages/xr/src/XRManagerExtended.ts | 320 -------- packages/xr/src/XRPose.ts | 16 - packages/xr/src/feature/XRFeature.ts | 78 -- packages/xr/src/feature/XRFeatureType.ts | 6 - .../xr/src/feature/camera/XRCameraManager.ts | 156 ---- .../xr/src/feature/hitTest/TrackableType.ts | 10 - .../xr/src/feature/hitTest/XRHitResult.ts | 20 - packages/xr/src/feature/hitTest/XRHitTest.ts | 126 --- .../feature/trackable/XRRequestTracking.ts | 12 - .../trackable/XRRequestTrackingState.ts | 8 - .../feature/trackable/XRTrackableFeature.ts | 156 ---- .../xr/src/feature/trackable/XRTracked.ts | 15 - .../src/feature/trackable/anchor/XRAnchor.ts | 6 - .../trackable/anchor/XRAnchorTracking.ts | 87 --- .../trackable/anchor/XRRequestAnchor.ts | 20 - .../trackable/image/XRImageTracking.ts | 50 -- .../trackable/image/XRReferenceImage.ts | 18 - .../feature/trackable/image/XRRequestImage.ts | 16 - .../feature/trackable/image/XRTrackedImage.ts | 13 - .../feature/trackable/plane/XRPlaneMode.ts | 13 - .../trackable/plane/XRPlaneTracking.ts | 41 - .../feature/trackable/plane/XRRequestPlane.ts | 15 - .../feature/trackable/plane/XRTrackedPlane.ts | 22 - packages/xr/src/index.ts | 45 -- packages/xr/src/input/XRCamera.ts | 19 - packages/xr/src/input/XRController.ts | 48 -- packages/xr/src/input/XRInput.ts | 13 - packages/xr/src/input/XRInputButton.ts | 19 - packages/xr/src/input/XRInputEventType.ts | 8 - packages/xr/src/input/XRInputManager.ts | 215 ------ packages/xr/src/input/XRTargetRayMode.ts | 5 - packages/xr/src/input/XRTrackedInputDevice.ts | 21 - packages/xr/src/input/XRTrackingState.ts | 11 - .../xr/src/loader/XRReferenceImageDecoder.ts | 17 - .../xr/src/loader/XRReferenceImageLoader.ts | 19 - packages/xr/src/session/XRSessionManager.ts | 230 ------ packages/xr/src/session/XRSessionMode.ts | 8 - packages/xr/src/session/XRSessionState.ts | 15 - packages/xr/tsconfig.json | 18 - 102 files changed, 9227 deletions(-) delete mode 100644 packages/physics-lite/README.md delete mode 100644 packages/physics-lite/package.json delete mode 100644 packages/physics-lite/src/LiteCollider.ts delete mode 100644 packages/physics-lite/src/LiteDynamicCollider.ts delete mode 100644 packages/physics-lite/src/LiteHitResult.ts delete mode 100644 packages/physics-lite/src/LitePhysics.ts delete mode 100644 packages/physics-lite/src/LitePhysicsManager.ts delete mode 100644 packages/physics-lite/src/LitePhysicsMaterial.ts delete mode 100644 packages/physics-lite/src/LitePhysicsScene.ts delete mode 100644 packages/physics-lite/src/LiteStaticCollider.ts delete mode 100644 packages/physics-lite/src/LiteTransform.ts delete mode 100644 packages/physics-lite/src/LiteUpdateFlag.ts delete mode 100644 packages/physics-lite/src/LiteUpdateFlagManager.ts delete mode 100644 packages/physics-lite/src/index.ts delete mode 100644 packages/physics-lite/src/shape/LiteBoxColliderShape.ts delete mode 100644 packages/physics-lite/src/shape/LiteColliderShape.ts delete mode 100644 packages/physics-lite/src/shape/LiteSphereColliderShape.ts delete mode 100644 packages/physics-lite/tsconfig.json delete mode 100644 packages/ui/README.md delete mode 100644 packages/ui/package.json delete mode 100644 packages/ui/src/Utils.ts delete mode 100644 packages/ui/src/component/UICanvas.ts delete mode 100644 packages/ui/src/component/UIGroup.ts delete mode 100644 packages/ui/src/component/UIRenderer.ts delete mode 100644 packages/ui/src/component/UITransform.ts delete mode 100644 packages/ui/src/component/advanced/Button.ts delete mode 100644 packages/ui/src/component/advanced/Image.ts delete mode 100644 packages/ui/src/component/advanced/Text.ts delete mode 100644 packages/ui/src/component/index.ts delete mode 100644 packages/ui/src/component/interactive/UIInteractive.ts delete mode 100644 packages/ui/src/component/interactive/transition/ColorTransition.ts delete mode 100644 packages/ui/src/component/interactive/transition/ScaleTransition.ts delete mode 100644 packages/ui/src/component/interactive/transition/SpriteTransition.ts delete mode 100644 packages/ui/src/component/interactive/transition/Transition.ts delete mode 100644 packages/ui/src/enums/CanvasRenderMode.ts delete mode 100644 packages/ui/src/enums/HorizontalAlignmentMode.ts delete mode 100644 packages/ui/src/enums/ResolutionAdaptationMode.ts delete mode 100644 packages/ui/src/enums/VerticalAlignmentMode.ts delete mode 100644 packages/ui/src/index.ts delete mode 100644 packages/ui/src/input/UIHitResult.ts delete mode 100644 packages/ui/src/input/UIPointerEventEmitter.ts delete mode 100644 packages/ui/src/interface/IElement.ts delete mode 100644 packages/ui/src/interface/IGraphics.ts delete mode 100644 packages/ui/src/interface/IGroupAble.ts delete mode 100644 packages/ui/src/shader/global.d.ts delete mode 100644 packages/ui/src/shader/uiDefault.fs.glsl delete mode 100644 packages/ui/src/shader/uiDefault.vs.glsl delete mode 100644 packages/ui/tsconfig.json delete mode 100644 packages/xr-webxr/README.md delete mode 100644 packages/xr-webxr/package.json delete mode 100644 packages/xr-webxr/src/Util.ts delete mode 100644 packages/xr-webxr/src/WebXRDevice.ts delete mode 100644 packages/xr-webxr/src/WebXRFrame.ts delete mode 100644 packages/xr-webxr/src/WebXRSession.ts delete mode 100644 packages/xr-webxr/src/feature/WebXRAnchorTracking.ts delete mode 100644 packages/xr-webxr/src/feature/WebXRFeature.ts delete mode 100644 packages/xr-webxr/src/feature/WebXRImageTracking.ts delete mode 100644 packages/xr-webxr/src/feature/WebXRPlaneTracking.ts delete mode 100644 packages/xr-webxr/src/feature/WebXRTrackableFeature.ts delete mode 100644 packages/xr-webxr/src/index.ts delete mode 100644 packages/xr-webxr/tsconfig.json delete mode 100644 packages/xr/README.md delete mode 100644 packages/xr/package.json delete mode 100644 packages/xr/src/XRManagerExtended.ts delete mode 100644 packages/xr/src/XRPose.ts delete mode 100644 packages/xr/src/feature/XRFeature.ts delete mode 100644 packages/xr/src/feature/XRFeatureType.ts delete mode 100644 packages/xr/src/feature/camera/XRCameraManager.ts delete mode 100644 packages/xr/src/feature/hitTest/TrackableType.ts delete mode 100644 packages/xr/src/feature/hitTest/XRHitResult.ts delete mode 100644 packages/xr/src/feature/hitTest/XRHitTest.ts delete mode 100644 packages/xr/src/feature/trackable/XRRequestTracking.ts delete mode 100644 packages/xr/src/feature/trackable/XRRequestTrackingState.ts delete mode 100644 packages/xr/src/feature/trackable/XRTrackableFeature.ts delete mode 100644 packages/xr/src/feature/trackable/XRTracked.ts delete mode 100644 packages/xr/src/feature/trackable/anchor/XRAnchor.ts delete mode 100644 packages/xr/src/feature/trackable/anchor/XRAnchorTracking.ts delete mode 100644 packages/xr/src/feature/trackable/anchor/XRRequestAnchor.ts delete mode 100644 packages/xr/src/feature/trackable/image/XRImageTracking.ts delete mode 100644 packages/xr/src/feature/trackable/image/XRReferenceImage.ts delete mode 100644 packages/xr/src/feature/trackable/image/XRRequestImage.ts delete mode 100644 packages/xr/src/feature/trackable/image/XRTrackedImage.ts delete mode 100644 packages/xr/src/feature/trackable/plane/XRPlaneMode.ts delete mode 100644 packages/xr/src/feature/trackable/plane/XRPlaneTracking.ts delete mode 100644 packages/xr/src/feature/trackable/plane/XRRequestPlane.ts delete mode 100644 packages/xr/src/feature/trackable/plane/XRTrackedPlane.ts delete mode 100644 packages/xr/src/index.ts delete mode 100644 packages/xr/src/input/XRCamera.ts delete mode 100644 packages/xr/src/input/XRController.ts delete mode 100644 packages/xr/src/input/XRInput.ts delete mode 100644 packages/xr/src/input/XRInputButton.ts delete mode 100644 packages/xr/src/input/XRInputEventType.ts delete mode 100644 packages/xr/src/input/XRInputManager.ts delete mode 100644 packages/xr/src/input/XRTargetRayMode.ts delete mode 100644 packages/xr/src/input/XRTrackedInputDevice.ts delete mode 100644 packages/xr/src/input/XRTrackingState.ts delete mode 100644 packages/xr/src/loader/XRReferenceImageDecoder.ts delete mode 100644 packages/xr/src/loader/XRReferenceImageLoader.ts delete mode 100644 packages/xr/src/session/XRSessionManager.ts delete mode 100644 packages/xr/src/session/XRSessionMode.ts delete mode 100644 packages/xr/src/session/XRSessionState.ts delete mode 100644 packages/xr/tsconfig.json diff --git a/packages/physics-lite/README.md b/packages/physics-lite/README.md deleted file mode 100644 index 1118d5044..000000000 --- a/packages/physics-lite/README.md +++ /dev/null @@ -1,34 +0,0 @@ -## Installation - -To install, use: - -```sh -npm install @galacean/engine-physics-lite -``` - -This will allow you to import engine entirely using: - -```javascript -import * as PHYSICS_LITE from "@galacean/engine-physics-lite"; -``` - -or individual classes using: - -```javascript -import { LitePhysics } from "@galacean/engine-physics-lite"; -``` - -## Usage - -```typescript -// Create engine by passing in the HTMLCanvasElement id and adjust canvas size -const engine = await WebGLEngine.create({ canvas: "canvas-id" }); - -// Initialize physics manager with LitePhysics. -engine.physicsManager.initialize(LitePhysics); - -...... - -// Run engine. -engine.run(); -``` \ No newline at end of file diff --git a/packages/physics-lite/package.json b/packages/physics-lite/package.json deleted file mode 100644 index 48b6c1566..000000000 --- a/packages/physics-lite/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@galacean/engine-physics-lite", - "version": "0.0.0-experimental-backup.4", - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org" - }, - "repository": { - "url": "https://github.com/galacean/engine.git" - }, - "license": "MIT", - "main": "dist/main.js", - "module": "dist/module.js", - "debug": "src/index.ts", - "browser": "dist/browser.js", - "types": "types/index.d.ts", - "scripts": { - "b:types": "tsc" - }, - "umd": { - "name": "Galacean.PhysicsLite", - "globals": { - "@galacean/engine": "Galacean" - } - }, - "files": [ - "dist/**/*", - "types/**/*" - ], - "devDependencies": { - "@galacean/engine-design": "workspace:*", - "@galacean/engine": "workspace:*" - }, - "peerDependencies": { - "@galacean/engine": "workspace:*" - } -} diff --git a/packages/physics-lite/src/LiteCollider.ts b/packages/physics-lite/src/LiteCollider.ts deleted file mode 100644 index bb2b66666..000000000 --- a/packages/physics-lite/src/LiteCollider.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { ICollider } from "@galacean/engine-design"; -import { Layer, Quaternion, Ray, Vector3 } from "@galacean/engine"; -import { LiteHitResult } from "./LiteHitResult"; -import { LiteColliderShape } from "./shape/LiteColliderShape"; -import { LiteTransform } from "./LiteTransform"; -import { LitePhysicsScene } from "./LitePhysicsScene"; -import { LitePhysics } from "./LitePhysics"; - -/** - * Abstract class of physical collider. - */ -export abstract class LiteCollider implements ICollider { - /** @internal */ - abstract readonly _isStaticCollider: boolean; - private _litePhysics: LitePhysics; - - /** @internal */ - _scene: LitePhysicsScene; - /** @internal */ - _shapes: LiteColliderShape[] = []; - /** @internal */ - _transform: LiteTransform = new LiteTransform(); - /** @internal */ - _collisionLayer: number; - - protected constructor(litePhysics: LitePhysics) { - this._transform.owner = this; - this._litePhysics = litePhysics; - } - - /** - * {@inheritDoc ICollider.addShape } - */ - addShape(shape: LiteColliderShape): void { - const oldCollider = shape._collider; - if (oldCollider !== this) { - if (oldCollider) { - oldCollider.removeShape(shape); - } - this._shapes.push(shape); - shape._collider = this; - this._scene?._addColliderShape(shape); - } - } - - /** - * {@inheritDoc ICollider.removeShape } - */ - removeShape(shape: LiteColliderShape): void { - const index = this._shapes.indexOf(shape); - if (index !== -1) { - this._shapes.splice(index, 1); - shape._collider = null; - this._scene?._removeColliderShape(shape); - } - } - - /** - * {@inheritDoc ICollider.setWorldTransform } - */ - setWorldTransform(position: Vector3, rotation: Quaternion): void { - this._transform.setPosition(position.x, position.y, position.z); - this._transform.setRotationQuaternion(rotation.x, rotation.y, rotation.z, rotation.w); - } - - /** - * {@inheritDoc ICollider.getWorldTransform } - */ - getWorldTransform(outPosition: Vector3, outRotation: Quaternion): void { - const { position, rotationQuaternion } = this._transform; - outPosition.set(position.x, position.y, position.z); - outRotation.set(rotationQuaternion.x, rotationQuaternion.y, rotationQuaternion.z, rotationQuaternion.w); - } - - /** - * {@inheritDoc ICollider.setCollisionLayer } - */ - setCollisionLayer(collisionLayer: Layer): void { - this._litePhysics.setColliderLayer(this, collisionLayer); - } - - /** - * {@inheritDoc ICollider.destroy } - */ - destroy(): void {} - - /** - * @internal - */ - _raycast(ray: Ray, onRaycast: (obj: number) => boolean, hit: LiteHitResult): boolean { - hit.distance = Number.MAX_VALUE; - const shapes = this._shapes; - for (let i = 0, n = shapes.length; i < n; i++) { - const shape = shapes[i]; - onRaycast(shape._id) && shape._raycast(ray, hit); - } - - return hit.distance != Number.MAX_VALUE; - } -} diff --git a/packages/physics-lite/src/LiteDynamicCollider.ts b/packages/physics-lite/src/LiteDynamicCollider.ts deleted file mode 100644 index dae27bf3a..000000000 --- a/packages/physics-lite/src/LiteDynamicCollider.ts +++ /dev/null @@ -1,207 +0,0 @@ -import { LiteCollider } from "./LiteCollider"; -import { IDynamicCollider } from "@galacean/engine-design"; -import { Logger, Quaternion, Vector3 } from "@galacean/engine"; -import { LitePhysics } from "./LitePhysics"; - -/** - * A dynamic collider can act with self-defined movement or physical force - */ -export class LiteDynamicCollider extends LiteCollider implements IDynamicCollider { - /** @internal */ - readonly _isStaticCollider: boolean = false; - /** - * Initialize dynamic actor. - * @param position - The global position - * @param rotation - The global rotation - */ - constructor(litePhysics: LitePhysics, position: Vector3, rotation: Quaternion) { - super(litePhysics); - this._transform.setPosition(position.x, position.y, position.z); - this._transform.setRotationQuaternion(rotation.x, rotation.y, rotation.z, rotation.w); - } - - /** - * {@inheritDoc IDynamicCollider.getInertiaTensor } - */ - getInertiaTensor(out: Vector3): Vector3 { - Logger.error("Physics-lite don't support getInertiaTensor. Use Physics-PhysX instead!"); - return out; - } - /** - * {@inheritDoc IDynamicCollider.getCenterOfMass } - */ - getCenterOfMass(out: Vector3): Vector3 { - Logger.error("Physics-lite don't support getCenterOfMass. Use Physics-PhysX instead!"); - return out; - } - - /** - * {@inheritDoc IDynamicCollider.setMassAndUpdateInertia } - */ - setMassAndUpdateInertia(mass: number): void { - Logger.error("Physics-lite don't support setMassAndUpdateInertia. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.addForce } - */ - addForce(force: Vector3): void { - throw "Physics-lite don't support addForce. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IDynamicCollider.addTorque } - */ - addTorque(torque: Vector3): void { - throw "Physics-lite don't support addTorque. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IDynamicCollider.move } - */ - move(positionOrRotation: Vector3 | Quaternion, rotation?: Quaternion): void { - throw "Physics-lite don't support move. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IDynamicCollider.sleep } - */ - sleep(): void { - throw "Physics-lite don't support putToSleep. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IDynamicCollider.isSleeping } - */ - isSleeping(): boolean { - throw "Physics-lite don't support isSleeping. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IDynamicCollider.setAngularDamping } - */ - setAngularDamping(value: number): void { - Logger.error("Physics-lite don't support setAngularDamping. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.getAngularVelocity } - */ - getAngularVelocity(out: Vector3): Vector3 { - Logger.error("Physics-lite don't support getAngularVelocity. Use Physics-PhysX instead!"); - return out; - } - - /** - * {@inheritDoc IDynamicCollider.setAngularVelocity } - */ - setAngularVelocity(value: Vector3): void { - Logger.error("Physics-lite don't support setAngularVelocity. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setCenterOfMass } - */ - setCenterOfMass(value: Vector3): void { - Logger.error("Physics-lite don't support setCenterOfMass. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setCollisionDetectionMode } - */ - setCollisionDetectionMode(value: number): void { - Logger.error("Physics-lite don't support setCollisionDetectionMode. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setConstraints } - */ - setConstraints(flags: number): void { - Logger.error("Physics-lite don't support setConstraints. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setInertiaTensor } - */ - setInertiaTensor(value: Vector3): void { - Logger.error("Physics-lite don't support setInertiaTensor. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setUseGravity } - */ - setUseGravity(value: boolean): void { - Logger.error("Physics-lite don't support setUseGravity. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setIsKinematic } - */ - setIsKinematic(value: boolean): void { - Logger.error("Physics-lite don't support setIsKinematic. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setLinearDamping } - */ - setLinearDamping(value: number): void { - Logger.error("Physics-lite don't support setLinearDamping. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.getLinearVelocity } - */ - getLinearVelocity(out: Vector3): Vector3 { - Logger.error("Physics-lite don't support getLinearVelocity. Use Physics-PhysX instead!"); - return out; - } - - /** - * {@inheritDoc IDynamicCollider.setLinearVelocity } - */ - setLinearVelocity(value: Vector3): void { - Logger.error("Physics-lite don't support setLinearVelocity. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setMass } - */ - setMass(value: number): void { - Logger.error("Physics-lite don't support setMass. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setMaxAngularVelocity } - */ - setMaxAngularVelocity(value: number): void { - Logger.error("Physics-lite don't support setMaxAngularVelocity. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setMaxDepenetrationVelocity } - */ - setMaxDepenetrationVelocity(value: number): void { - Logger.error("Physics-lite don't support setMaxDepenetrationVelocity. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setSleepThreshold } - */ - setSleepThreshold(value: number): void { - Logger.error("Physics-lite don't support setSleepThreshold. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.setSolverIterations } - */ - setSolverIterations(value: number): void { - Logger.error("Physics-lite don't support setSolverIterations. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IDynamicCollider.wakeUp } - */ - wakeUp(): void { - throw "Physics-lite don't support wakeUp. Use Physics-PhysX instead!"; - } -} diff --git a/packages/physics-lite/src/LiteHitResult.ts b/packages/physics-lite/src/LiteHitResult.ts deleted file mode 100644 index 8e338c848..000000000 --- a/packages/physics-lite/src/LiteHitResult.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Vector3 } from "@galacean/engine"; - -/** - * Structure used to get information back from a raycast or a sweep. - * @internal - */ -export class LiteHitResult { - /** The collider that was hit. */ - shapeID: number = -1; - /** The distance from the origin to the hit point. */ - distance: number = 0; - /** The hit point of the collider that was hit in world space. */ - point: Vector3 = new Vector3(); - /** The hit normal of the collider that was hit in world space. */ - normal: Vector3 = new Vector3(); -} diff --git a/packages/physics-lite/src/LitePhysics.ts b/packages/physics-lite/src/LitePhysics.ts deleted file mode 100644 index acdcf6127..000000000 --- a/packages/physics-lite/src/LitePhysics.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { Quaternion, Vector3, Layer } from "@galacean/engine"; -import { - IBoxColliderShape, - ICapsuleColliderShape, - ICharacterController, - ICollider, - ICollision, - IDynamicCollider, - IFixedJoint, - IHingeJoint, - IPhysics, - IPhysicsManager, - IPhysicsMaterial, - IPlaneColliderShape, - ISphereColliderShape, - ISpringJoint, - IStaticCollider -} from "@galacean/engine-design"; -import { LiteCollider } from "./LiteCollider"; -import { LiteDynamicCollider } from "./LiteDynamicCollider"; -import { LitePhysicsMaterial } from "./LitePhysicsMaterial"; -import { LitePhysicsScene } from "./LitePhysicsScene"; -import { LiteStaticCollider } from "./LiteStaticCollider"; -import { LiteBoxColliderShape } from "./shape/LiteBoxColliderShape"; -import { LiteSphereColliderShape } from "./shape/LiteSphereColliderShape"; -import { LitePhysicsManager } from "./LitePhysicsManager"; - -export class LitePhysics implements IPhysics { - private _layerCollisionMatrix: boolean[] = []; - - /** - * {@inheritDoc IPhysics.initialize } - */ - initialize(): Promise { - return Promise.resolve(); - } - - /** - * {@inheritDoc IPhysics.createPhysicsManager } - */ - createPhysicsManager(): IPhysicsManager { - return null; - } - - /** - * {@inheritDoc IPhysics.createPhysicsScene } - */ - createPhysicsScene( - physicsManager: LitePhysicsManager, - onContactBegin?: (collision: ICollision) => void, - onContactEnd?: (collision: ICollision) => void, - onContactPersist?: (collision: ICollision) => void, - onTriggerBegin?: (obj1: number, obj2: number) => void, - onTriggerEnd?: (obj1: number, obj2: number) => void, - onTriggerPersist?: (obj1: number, obj2: number) => void - ): LitePhysicsScene { - return new LitePhysicsScene( - this, - onContactBegin, - onContactEnd, - onContactPersist, - onTriggerBegin, - onTriggerEnd, - onTriggerPersist - ); - } - - /** - * {@inheritDoc IPhysics.createStaticCollider } - */ - createStaticCollider(position: Vector3, rotation: Quaternion): IStaticCollider { - return new LiteStaticCollider(this, position, rotation); - } - - /** - * {@inheritDoc IPhysics.createDynamicCollider } - */ - createDynamicCollider(position: Vector3, rotation: Quaternion): IDynamicCollider { - return new LiteDynamicCollider(this, position, rotation); - } - - /** - * {@inheritDoc IPhysics.createCharacterController } - */ - createCharacterController(): ICharacterController { - throw "Physics-lite don't support createCharacterController. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IPhysics.createPhysicsMaterial } - */ - createPhysicsMaterial( - staticFriction: number, - dynamicFriction: number, - bounciness: number, - frictionCombine: number, - bounceCombine: number - ): IPhysicsMaterial { - return new LitePhysicsMaterial(staticFriction, dynamicFriction, bounciness, frictionCombine, bounceCombine); - } - - /** - * {@inheritDoc IPhysics.createBoxColliderShape } - */ - createBoxColliderShape(uniqueID: number, size: Vector3, material: LitePhysicsMaterial): IBoxColliderShape { - return new LiteBoxColliderShape(uniqueID, size, material); - } - - /** - * {@inheritDoc IPhysics.createSphereColliderShape } - */ - createSphereColliderShape(uniqueID: number, radius: number, material: LitePhysicsMaterial): ISphereColliderShape { - return new LiteSphereColliderShape(uniqueID, radius, material); - } - - /** - * {@inheritDoc IPhysics.createPlaneColliderShape } - */ - createPlaneColliderShape(uniqueID: number, material: LitePhysicsMaterial): IPlaneColliderShape { - throw new Error("Physics-lite doesn't support PlaneColliderShape. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysics.createCapsuleColliderShape } - */ - createCapsuleColliderShape( - uniqueID: number, - radius: number, - height: number, - material: LitePhysicsMaterial - ): ICapsuleColliderShape { - throw new Error("Physics-lite doesn't support CapsuleColliderShape. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysics.createFixedJoint } - */ - createFixedJoint(collider: LiteCollider): IFixedJoint { - throw new Error("Physics-lite doesn't support FixedJoint. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysics.createHingeJoint } - */ - createHingeJoint(collider: LiteCollider): IHingeJoint { - throw new Error("Physics-lite doesn't support HingeJoint. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysics.createSpringJoint } - */ - createSpringJoint(collider: LiteCollider): ISpringJoint { - throw new Error("Physics-lite doesn't support SpringJoint. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysics.setColliderLayer } - */ - setColliderLayer(collider: LiteCollider, layer: Layer): void { - collider._collisionLayer = layer; - } - - /** - * {@inheritDoc IPhysics.getColliderLayerCollision } - */ - getColliderLayerCollision(layer1: number, layer2: number): boolean { - const index = this._getColliderLayerIndex(layer1, layer2); - if (index > -1) { - return this._layerCollisionMatrix[index] ?? true; - } - // If either layer is Layer.Nothing, they cant collide - return false; - } - - /** - * {@inheritDoc IPhysics.setColliderLayerCollision } - */ - setColliderLayerCollision(layer1: number, layer2: number, collide: boolean): void { - const index = this._getColliderLayerIndex(layer1, layer2); - if (index > -1) { - this._layerCollisionMatrix[index] = collide; - } - } - - /** - * {@inheritDoc IPhysics.destroy } - */ - destroy(): void {} - - private _getColliderLayerIndex(layer1: number, layer2: number): number { - if (layer1 === 32 || layer2 === 32) { - return -1; - } - - const min = Math.min(layer1, layer2); - const max = Math.max(layer1, layer2); - - // Calculate a unique index for the layer pair using the triangular number formula - // This ensures that each layer combination maps to a unique index in the collision matrix - return (max * (max + 1)) / 2 + min; - } -} diff --git a/packages/physics-lite/src/LitePhysicsManager.ts b/packages/physics-lite/src/LitePhysicsManager.ts deleted file mode 100644 index faafc8d00..000000000 --- a/packages/physics-lite/src/LitePhysicsManager.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { IPhysicsManager } from "@galacean/engine-design"; - -export class LitePhysicsManager implements IPhysicsManager {} diff --git a/packages/physics-lite/src/LitePhysicsMaterial.ts b/packages/physics-lite/src/LitePhysicsMaterial.ts deleted file mode 100644 index 7983beb39..000000000 --- a/packages/physics-lite/src/LitePhysicsMaterial.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { IPhysicsMaterial } from "@galacean/engine-design"; - -/** - * Physics material describes how to handle colliding objects (friction, bounciness). - */ -export class LitePhysicsMaterial implements IPhysicsMaterial { - constructor( - staticFriction: number, - dynamicFriction: number, - bounciness: number, - frictionCombine: number, - bounceCombine: number - ) {} - - /** - * {@inheritDoc IPhysicsMaterial.setBounciness } - */ - setBounciness(value: number): void { - throw "Physics-lite don't support physics material. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IPhysicsMaterial.setDynamicFriction } - */ - setDynamicFriction(value: number): void { - throw "Physics-lite don't support physics material. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IPhysicsMaterial.setStaticFriction } - */ - setStaticFriction(value: number): void { - throw "Physics-lite don't support physics material. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IPhysicsMaterial.setBounceCombine } - */ - setBounceCombine(value: number): void { - throw "Physics-lite don't support physics material. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IPhysicsMaterial.setFrictionCombine } - */ - setFrictionCombine(value: number): void { - throw "Physics-lite don't support physics material. Use Physics-PhysX instead!"; - } - - /** - * {@inheritDoc IPhysicsMaterial.destroy } - */ - destroy(): void {} -} diff --git a/packages/physics-lite/src/LitePhysicsScene.ts b/packages/physics-lite/src/LitePhysicsScene.ts deleted file mode 100644 index 0a6efaeea..000000000 --- a/packages/physics-lite/src/LitePhysicsScene.ts +++ /dev/null @@ -1,518 +0,0 @@ -import { - BoundingBox, - BoundingSphere, - CollisionUtil, - DisorderedArray, - Quaternion, - Ray, - Vector3 -} from "@galacean/engine"; -import { ICharacterController, ICollision, IPhysicsScene } from "@galacean/engine-design"; -import { LiteCollider } from "./LiteCollider"; -import { LiteDynamicCollider } from "./LiteDynamicCollider"; -import { LiteHitResult } from "./LiteHitResult"; -import { LiteStaticCollider } from "./LiteStaticCollider"; -import { LiteBoxColliderShape } from "./shape/LiteBoxColliderShape"; -import { LiteColliderShape } from "./shape/LiteColliderShape"; -import { LiteSphereColliderShape } from "./shape/LiteSphereColliderShape"; -import { LitePhysics } from "./LitePhysics"; - -/** - * A manager is a collection of colliders and constraints which can interact. - */ -export class LitePhysicsScene implements IPhysicsScene { - private static _tempSphere: BoundingSphere = new BoundingSphere(); - private static _tempBox: BoundingBox = new BoundingBox(); - private static _currentHit: LiteHitResult = new LiteHitResult(); - private static _hitResult: LiteHitResult = new LiteHitResult(); - - private readonly _onContactEnter?: (collision: ICollision) => void; - private readonly _onContactExit?: (collision: ICollision) => void; - private readonly _onContactStay?: (collision: ICollision) => void; - private readonly _onTriggerEnter?: (obj1: number, obj2: number) => void; - private readonly _onTriggerExit?: (obj1: number, obj2: number) => void; - private readonly _onTriggerStay?: (obj1: number, obj2: number) => void; - - private _staticColliders: LiteStaticCollider[] = []; - private _dynamicColliders: LiteDynamicCollider[] = []; - private _sphere: BoundingSphere = new BoundingSphere(); - private _box: BoundingBox = new BoundingBox(); - - private _currentEvents: DisorderedArray = new DisorderedArray(); - private _eventMap: Record> = {}; - private _eventPool: TriggerEvent[] = []; - private _physics: LitePhysics; - - constructor( - physics: LitePhysics, - onContactEnter?: (collision: ICollision) => void, - onContactExit?: (collision: ICollision) => void, - onContactStay?: (collision: ICollision) => void, - onTriggerEnter?: (obj1: number, obj2: number) => void, - onTriggerExit?: (obj1: number, obj2: number) => void, - onTriggerStay?: (obj1: number, obj2: number) => void - ) { - this._physics = physics; - this._onContactEnter = onContactEnter; - this._onContactExit = onContactExit; - this._onContactStay = onContactStay; - this._onTriggerEnter = onTriggerEnter; - this._onTriggerExit = onTriggerExit; - this._onTriggerStay = onTriggerStay; - } - overlapBox( - center: Vector3, - orientation: Quaternion, - halfExtents: Vector3, - onOverlap: (obj: number) => boolean, - outHitResult?: (shapeUniqueID: number) => void - ): boolean { - throw new Error("Method not implemented."); - } - overlapSphere( - center: Vector3, - radius: number, - onOverlap: (obj: number) => boolean, - outHitResult?: (shapeUniqueID: number) => void - ): boolean { - throw new Error("Method not implemented."); - } - overlapCapsule( - center: Vector3, - radius: number, - height: number, - orientation: Quaternion, - onOverlap: (obj: number) => boolean, - outHitResult?: (shapeUniqueID: number) => void - ): boolean { - throw new Error("Method not implemented."); - } - - /** - * {@inheritDoc IPhysicsScene.setGravity } - */ - setGravity(value: Vector3): void { - console.log("Physics-lite don't support gravity. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.addCollider } - */ - addCollider(actor: LiteCollider): void { - actor._scene = this; - const colliders = actor._isStaticCollider ? this._staticColliders : this._dynamicColliders; - colliders.push(actor); - const shapes = actor._shapes; - for (let i = 0, n = shapes.length; i < n; i++) { - this._addColliderShape(shapes[i]); - } - } - - /** - * {@inheritDoc IPhysicsScene.removeCollider } - */ - removeCollider(collider: LiteCollider): void { - collider._scene = null; - const colliders = collider._isStaticCollider ? this._staticColliders : this._dynamicColliders; - const index = colliders.indexOf(collider); - index > -1 && colliders.splice(index, 1); - const shapes = collider._shapes; - for (let i = 0, n = shapes.length; i < n; i++) { - this._removeColliderShape(shapes[i]); - } - } - - /** - * {@inheritDoc IPhysicsScene.update } - */ - update(deltaTime: number): void { - const dynamicColliders = this._dynamicColliders; - for (let i = 0, len = dynamicColliders.length; i < len; i++) { - const collider = dynamicColliders[i]; - this._collisionDetection(collider, this._staticColliders); - this._collisionDetection(collider, dynamicColliders); - } - this._fireEvent(); - } - - /** - * {@inheritDoc IPhysicsScene.raycast } - */ - raycast( - ray: Ray, - distance: number, - onRaycast: (obj: number) => boolean, - hit?: (shapeUniqueID: number, distance: number, position: Vector3, normal: Vector3) => void - ): boolean { - if (!hit) { - return ( - this._raycast(ray, distance, onRaycast, this._staticColliders, hit) || - this._raycast(ray, distance, onRaycast, this._dynamicColliders, hit) - ); - } else { - const raycastStaticRes = this._raycast(ray, distance, onRaycast, this._staticColliders, hit); - - if (raycastStaticRes) { - distance = LitePhysicsScene._currentHit.distance; - } - - const raycastDynamicRes = this._raycast(ray, distance, onRaycast, this._dynamicColliders, hit); - const isHit = raycastStaticRes || raycastDynamicRes; - const hitResult = LitePhysicsScene._hitResult; - - if (!isHit) { - hitResult.shapeID = -1; - hitResult.distance = 0; - hitResult.point.set(0, 0, 0); - hitResult.normal.set(0, 0, 0); - } else { - hit(hitResult.shapeID, hitResult.distance, hitResult.point, hitResult.normal); - } - return isHit; - } - } - - /** - * {@inheritDoc IPhysicsScene.addCharacterController } - */ - addCharacterController(characterController: ICharacterController): void { - throw new Error("Physics-lite doesn't support addCharacterController. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.removeCharacterController } - */ - removeCharacterController(characterController: ICharacterController): void { - throw new Error("Physics-lite doesn't support removeCharacterController. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.boxCast } - */ - boxCast( - center: Vector3, - orientation: Quaternion, - halfExtents: Vector3, - direction: Vector3, - distance: number, - onSweep: (obj: number) => boolean, - outHitResult?: (shapeUniqueID: number, distance: number, position: Vector3, normal: Vector3) => void - ): boolean { - throw new Error("Physics-lite doesn't support boxCast. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.sphereCast } - */ - sphereCast( - center: Vector3, - radius: number, - direction: Vector3, - distance: number, - onSweep: (obj: number) => boolean, - outHitResult?: (shapeUniqueID: number, distance: number, position: Vector3, normal: Vector3) => void - ): boolean { - throw new Error("Physics-lite doesn't support sphereCast. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.capsuleCast } - */ - capsuleCast( - center: Vector3, - radius: number, - height: number, - orientation: Quaternion, - direction: Vector3, - distance: number, - onSweep: (obj: number) => boolean, - outHitResult?: (shapeUniqueID: number, distance: number, position: Vector3, normal: Vector3) => void - ): boolean { - throw new Error("Physics-lite doesn't support capsuleCast. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.overlapBoxAll } - */ - overlapBoxAll( - center: Vector3, - orientation: Quaternion, - halfExtents: Vector3, - onOverlap: (obj: number) => boolean - ): number[] { - throw new Error("Physics-lite doesn't support overlapBoxAll. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.overlapSphereAll } - */ - overlapSphereAll(center: Vector3, radius: number, onOverlap: (obj: number) => boolean): number[] { - throw new Error("Physics-lite doesn't support overlapSphereAll. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.overlapCapsuleAll } - */ - overlapCapsuleAll( - center: Vector3, - radius: number, - height: number, - orientation: Quaternion, - onOverlap: (obj: number) => boolean - ): number[] { - throw new Error("Physics-lite doesn't support overlapCapsuleAll. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IPhysicsScene.destroy } - */ - destroy(): void {} - - /** - * @internal - */ - _addColliderShape(colliderShape: LiteColliderShape): void { - this._eventMap[colliderShape._id] = {}; - } - - /** - * @internal - */ - _removeColliderShape(colliderShape: LiteColliderShape): void { - const { _eventPool: eventPool, _currentEvents: currentEvents, _eventMap: eventMap } = this; - const { _id: id } = colliderShape; - currentEvents.forEach((event, i) => { - if (event.index1 == id) { - currentEvents.deleteByIndex(i); - eventPool.push(event); - } else if (event.index2 == id) { - currentEvents.deleteByIndex(i); - eventPool.push(event); - // If the shape is big index, should clear from the small index shape subMap - eventMap[event.index1][id] = undefined; - } - }); - delete eventMap[id]; - } - - /** - * Calculate the bounding box in world space from boxCollider. - * @param boxCollider - The boxCollider to calculate - * @param out - The calculated boundingBox - */ - private static _updateWorldBox(boxCollider: LiteBoxColliderShape, out: BoundingBox): void { - const mat = boxCollider._transform.worldMatrix; - out.min.copyFrom(boxCollider._boxMin); - out.max.copyFrom(boxCollider._boxMax); - BoundingBox.transform(out, mat, out); - } - - /** - * Get the sphere info of the given sphere collider in world space. - * @param sphereCollider - The given sphere collider - * @param out - The calculated boundingSphere - */ - private static _upWorldSphere(sphereCollider: LiteSphereColliderShape, out: BoundingSphere): void { - Vector3.transformCoordinate(sphereCollider._transform.position, sphereCollider._transform.worldMatrix, out.center); - out.radius = sphereCollider.worldRadius; - } - - private _getTrigger(index1: number, index2: number): TriggerEvent { - let event: TriggerEvent; - if (this._eventPool.length) { - event = this._eventPool.pop(); - event.index1 = index1; - event.index2 = index2; - } else { - event = new TriggerEvent(index1, index2); - } - this._eventMap[index1][index2] = event; - return event; - } - - private _collisionDetection(myCollider: LiteCollider, colliders: LiteCollider[]): void { - const myColliderShapes = myCollider._shapes; - for (let i = 0, len = myColliderShapes.length; i < len; i++) { - const myShape = myColliderShapes[i]; - if (myShape instanceof LiteBoxColliderShape) { - LitePhysicsScene._updateWorldBox(myShape, this._box); - for (let j = 0, len = colliders.length; j < len; j++) { - const collider = colliders[j]; - const colliderShape = collider._shapes; - - // Skip collision check if layers can't collide - if (!this._checkColliderCollide(collider, myCollider)) { - continue; - } - - for (let k = 0, len = colliderShape.length; k < len; k++) { - const shape = colliderShape[k]; - const index1 = shape._id; - const index2 = myShape._id; - const event = index1 < index2 ? this._eventMap[index1][index2] : this._eventMap[index2][index1]; - if (event !== undefined && !event.alreadyInvoked) { - continue; - } - if (shape != myShape && this._boxCollision(shape)) { - if (event === undefined) { - const event = index1 < index2 ? this._getTrigger(index1, index2) : this._getTrigger(index2, index1); - event.state = TriggerEventState.Enter; - event.alreadyInvoked = false; - this._currentEvents.add(event); - } else if (event.state === TriggerEventState.Enter) { - event.state = TriggerEventState.Stay; - event.alreadyInvoked = false; - } else if (event.state === TriggerEventState.Stay) { - event.alreadyInvoked = false; - } - } - } - } - } else if (myShape instanceof LiteSphereColliderShape) { - LitePhysicsScene._upWorldSphere(myShape, this._sphere); - for (let j = 0, len = colliders.length; j < len; j++) { - const collider = colliders[j]; - const colliderShape = collider._shapes; - - // Skip collision check if layers can't collide - if (!this._checkColliderCollide(collider, myCollider)) { - continue; - } - - for (let k = 0, len = colliderShape.length; k < len; k++) { - const shape = colliderShape[k]; - const index1 = shape._id; - const index2 = myShape._id; - const event = index1 < index2 ? this._eventMap[index1][index2] : this._eventMap[index2][index1]; - if (event !== undefined && !event.alreadyInvoked) { - continue; - } - if (shape != myShape && this._sphereCollision(shape)) { - if (event === undefined) { - const event = index1 < index2 ? this._getTrigger(index1, index2) : this._getTrigger(index2, index1); - event.state = TriggerEventState.Enter; - event.alreadyInvoked = false; - this._currentEvents.add(event); - } else if (event.state === TriggerEventState.Enter) { - event.state = TriggerEventState.Stay; - event.alreadyInvoked = false; - } else if (event.state === TriggerEventState.Stay) { - event.alreadyInvoked = false; - } - } - } - } - } - } - } - - private _fireEvent(): void { - const { _eventPool: eventPool, _currentEvents: currentEvents } = this; - currentEvents.forEach((event, i) => { - if (!event.alreadyInvoked) { - if (event.state == TriggerEventState.Enter) { - this._onTriggerEnter(event.index1, event.index2); - event.alreadyInvoked = true; - } else if (event.state == TriggerEventState.Stay) { - this._onTriggerStay(event.index1, event.index2); - event.alreadyInvoked = true; - } - } else { - event.state = TriggerEventState.Exit; - this._eventMap[event.index1][event.index2] = undefined; - - currentEvents.deleteByIndex(i); - this._onTriggerExit(event.index1, event.index2); - eventPool.push(event); - } - }); - } - - private _boxCollision(other: LiteColliderShape): boolean { - if (other instanceof LiteBoxColliderShape) { - const box = LitePhysicsScene._tempBox; - LitePhysicsScene._updateWorldBox(other, box); - return CollisionUtil.intersectsBoxAndBox(box, this._box); - } else if (other instanceof LiteSphereColliderShape) { - const sphere = LitePhysicsScene._tempSphere; - LitePhysicsScene._upWorldSphere(other, sphere); - return CollisionUtil.intersectsSphereAndBox(sphere, this._box); - } - return false; - } - - private _sphereCollision(other: LiteColliderShape): boolean { - if (other instanceof LiteBoxColliderShape) { - const box = LitePhysicsScene._tempBox; - LitePhysicsScene._updateWorldBox(other, box); - return CollisionUtil.intersectsSphereAndBox(this._sphere, box); - } else if (other instanceof LiteSphereColliderShape) { - const sphere = LitePhysicsScene._tempSphere; - LitePhysicsScene._upWorldSphere(other, sphere); - return CollisionUtil.intersectsSphereAndSphere(sphere, this._sphere); - } - return false; - } - - private _raycast( - ray: Ray, - distance: number, - onRaycast: (obj: number) => boolean, - colliders: LiteCollider[], - hit?: (shapeUniqueID: number, distance: number, position: Vector3, normal: Vector3) => void - ): boolean { - let isHit = false; - const curHit = LitePhysicsScene._currentHit; - for (let i = 0, len = colliders.length; i < len; i++) { - if (colliders[i]._raycast(ray, onRaycast, curHit) && curHit.distance < distance) { - if (hit) { - isHit = true; - const hitResult = LitePhysicsScene._hitResult; - hitResult.normal.copyFrom(curHit.normal); - hitResult.point.copyFrom(curHit.point); - hitResult.distance = distance = curHit.distance; - hitResult.shapeID = curHit.shapeID; - } else { - return true; - } - } - } - - return isHit; - } - - private _checkColliderCollide(collider1: LiteCollider, collider2: LiteCollider): boolean { - const group1 = collider1._collisionLayer; - const group2 = collider2._collisionLayer; - - if (group1 === group2) { - return true; - } - - return this._physics.getColliderLayerCollision(group1, group2); - } -} - -/** - * Physics state - */ -enum TriggerEventState { - Enter, - Stay, - Exit -} - -/** - * Trigger event to store interactive object ids and state. - */ -class TriggerEvent { - state: TriggerEventState; - index1: number; - index2: number; - alreadyInvoked: boolean = false; - - constructor(index1: number, index2: number) { - this.index1 = index1; - this.index2 = index2; - } -} diff --git a/packages/physics-lite/src/LiteStaticCollider.ts b/packages/physics-lite/src/LiteStaticCollider.ts deleted file mode 100644 index 84e50bbd0..000000000 --- a/packages/physics-lite/src/LiteStaticCollider.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { IStaticCollider } from "@galacean/engine-design"; -import { LiteCollider } from "./LiteCollider"; -import { Quaternion, Vector3 } from "@galacean/engine"; -import { LitePhysics } from "./LitePhysics"; - -/** - * A static collider component that will not move. - * @remarks Mostly used for object which always stays at the same place and never moves around. - */ -export class LiteStaticCollider extends LiteCollider implements IStaticCollider { - /** @internal */ - readonly _isStaticCollider: boolean = true; - /** - * Initialize static actor. - * @param position - The global position - * @param rotation - The global rotation - */ - constructor(litePhysics: LitePhysics, position: Vector3, rotation: Quaternion) { - super(litePhysics); - this._transform.setPosition(position.x, position.y, position.z); - this._transform.setRotationQuaternion(rotation.x, rotation.y, rotation.z, rotation.w); - } -} diff --git a/packages/physics-lite/src/LiteTransform.ts b/packages/physics-lite/src/LiteTransform.ts deleted file mode 100644 index ab05e23e7..000000000 --- a/packages/physics-lite/src/LiteTransform.ts +++ /dev/null @@ -1,349 +0,0 @@ -import { MathUtil, Matrix, Quaternion, Vector3 } from "@galacean/engine"; -import { LiteCollider } from "./LiteCollider"; -import { LiteUpdateFlag } from "./LiteUpdateFlag"; -import { LiteUpdateFlagManager } from "./LiteUpdateFlagManager"; -import { LiteColliderShape } from "./shape/LiteColliderShape"; - -/** - * Used to implement transformation related functions. - */ -export class LiteTransform { - private static _tempQuat0: Quaternion = new Quaternion(); - private static _tempMat42: Matrix = new Matrix(); - - private _position: Vector3 = new Vector3(); - private _rotation: Vector3 = new Vector3(); - private _rotationQuaternion: Quaternion = new Quaternion(); - private _scale: Vector3 = new Vector3(1, 1, 1); - private _worldRotationQuaternion: Quaternion = new Quaternion(); - private _localMatrix: Matrix = new Matrix(); - private _worldMatrix: Matrix = new Matrix(); - private _updateFlagManager: LiteUpdateFlagManager = new LiteUpdateFlagManager(); - private _isParentDirty: boolean = true; - private _parentTransformCache: LiteTransform = null; - private _dirtyFlag: number = TransformFlag.WmWpWeWqWs; - - private _owner: LiteColliderShape | LiteCollider; - - set owner(value: LiteColliderShape | LiteCollider) { - this._owner = value; - } - - /** - * Local position. - * @remarks Need to re-assign after modification to ensure that the modification takes effect. - */ - get position(): Vector3 { - return this._position; - } - - set position(value: Vector3) { - if (this._position !== value) { - this._position.copyFrom(value); - } - this._setDirtyFlagTrue(TransformFlag.LocalMatrix); - this._updateWorldPositionFlag(); - } - - /** - * Local rotation, defining the rotation by using a unit quaternion. - * @remarks Need to re-assign after modification to ensure that the modification takes effect. - */ - get rotationQuaternion(): Quaternion { - if (this._isContainDirtyFlag(TransformFlag.LocalQuat)) { - Quaternion.rotationEuler( - MathUtil.degreeToRadian(this._rotation.x), - MathUtil.degreeToRadian(this._rotation.y), - MathUtil.degreeToRadian(this._rotation.z), - this._rotationQuaternion - ); - this._setDirtyFlagFalse(TransformFlag.LocalQuat); - } - return this._rotationQuaternion; - } - - set rotationQuaternion(value: Quaternion) { - if (this._rotationQuaternion !== value) { - this._rotationQuaternion.copyFrom(value); - } - this._setDirtyFlagTrue(TransformFlag.LocalMatrix | TransformFlag.LocalEuler); - this._setDirtyFlagFalse(TransformFlag.LocalQuat); - this._updateWorldRotationFlag(); - } - - /** - * World rotation, defining the rotation by using a unit quaternion. - * @remarks Need to re-assign after modification to ensure that the modification takes effect. - */ - get worldRotationQuaternion(): Quaternion { - if (this._isContainDirtyFlag(TransformFlag.WorldQuat)) { - const parent = this._getParentTransform(); - if (parent != null) { - Quaternion.multiply(parent.worldRotationQuaternion, this.rotationQuaternion, this._worldRotationQuaternion); - } else { - this._worldRotationQuaternion.copyFrom(this.rotationQuaternion); - } - this._setDirtyFlagFalse(TransformFlag.WorldQuat); - } - return this._worldRotationQuaternion; - } - - set worldRotationQuaternion(value: Quaternion) { - if (this._worldRotationQuaternion !== value) { - this._worldRotationQuaternion.copyFrom(value); - } - const parent = this._getParentTransform(); - if (parent) { - Quaternion.invert(parent.worldRotationQuaternion, LiteTransform._tempQuat0); - Quaternion.multiply(value, LiteTransform._tempQuat0, this._rotationQuaternion); - } else { - this._rotationQuaternion.copyFrom(value); - } - this.rotationQuaternion = this._rotationQuaternion; - this._setDirtyFlagFalse(TransformFlag.WorldQuat); - } - - /** - * Local scaling. - * @remarks Need to re-assign after modification to ensure that the modification takes effect. - */ - get scale(): Vector3 { - return this._scale; - } - - set scale(value: Vector3) { - if (this._scale !== value) { - this._scale.copyFrom(value); - } - this._setDirtyFlagTrue(TransformFlag.LocalMatrix); - this._updateWorldScaleFlag(); - } - - /** - * Local matrix. - * @remarks Need to re-assign after modification to ensure that the modification takes effect. - */ - get localMatrix(): Matrix { - if (this._isContainDirtyFlag(TransformFlag.LocalMatrix)) { - Matrix.affineTransformation(this._scale, this.rotationQuaternion, this._position, this._localMatrix); - this._setDirtyFlagFalse(TransformFlag.LocalMatrix); - } - return this._localMatrix; - } - - set localMatrix(value: Matrix) { - if (this._localMatrix !== value) { - this._localMatrix.copyFrom(value); - } - this._localMatrix.decompose(this._position, this._rotationQuaternion, this._scale); - this._setDirtyFlagTrue(TransformFlag.LocalEuler); - this._setDirtyFlagFalse(TransformFlag.LocalMatrix); - this._updateAllWorldFlag(); - } - - /** - * World matrix. - * @remarks Need to re-assign after modification to ensure that the modification takes effect. - */ - get worldMatrix(): Matrix { - if (this._isContainDirtyFlag(TransformFlag.WorldMatrix)) { - const parent = this._getParentTransform(); - if (parent) { - Matrix.multiply(parent.worldMatrix, this.localMatrix, this._worldMatrix); - } else { - this._worldMatrix.copyFrom(this.localMatrix); - } - this._setDirtyFlagFalse(TransformFlag.WorldMatrix); - } - return this._worldMatrix; - } - - set worldMatrix(value: Matrix) { - if (this._worldMatrix !== value) { - this._worldMatrix.copyFrom(value); - } - const parent = this._getParentTransform(); - if (parent) { - Matrix.invert(parent.worldMatrix, LiteTransform._tempMat42); - Matrix.multiply(LiteTransform._tempMat42, value, this._localMatrix); - } else { - this._localMatrix.copyFrom(value); - } - this.localMatrix = this._localMatrix; - this._setDirtyFlagFalse(TransformFlag.WorldMatrix); - } - - /** - * Set local position by X, Y, Z value. - * @param x - X coordinate - * @param y - Y coordinate - * @param z - Z coordinate - */ - setPosition(x: number, y: number, z: number): void { - this._position.set(x, y, z); - this.position = this._position; - } - - /** - * Set local rotation by the X, Y, Z, and W components of the quaternion. - * @param x - X component of quaternion - * @param y - Y component of quaternion - * @param z - Z component of quaternion - * @param w - W component of quaternion - */ - setRotationQuaternion(x: number, y: number, z: number, w: number): void { - this._rotationQuaternion.set(x, y, z, w); - this.rotationQuaternion = this._rotationQuaternion; - } - - /** - * Set local scaling by scaling values along X, Y, Z axis. - * @param x - Scaling along X axis - * @param y - Scaling along Y axis - * @param z - Scaling along Z axis - */ - setScale(x: number, y: number, z: number): void { - this._scale.set(x, y, z); - this.scale = this._scale; - } - - /** - * Register world transform change flag. - * @returns Change flag - */ - registerWorldChangeFlag(): LiteUpdateFlag { - return this._updateFlagManager.register(); - } - - /** - * Get worldMatrix: Will trigger the worldMatrix update of itself and all parent entities. - * Get worldPosition: Will trigger the worldMatrix, local position update of itself and the worldMatrix update of all parent entities. - * In summary, any update of related variables will cause the dirty mark of one of the full process (worldMatrix or worldRotationQuaternion) to be false. - */ - private _updateWorldPositionFlag(): void { - if (!this._isContainDirtyFlags(TransformFlag.WmWp)) { - this._worldAssociatedChange(TransformFlag.WmWp); - if (this._owner instanceof LiteCollider) { - const shapes = this._owner._shapes; - for (let i: number = 0, n: number = shapes.length; i < n; i++) { - shapes[i]._transform._updateWorldPositionFlag(); - } - } - } - } - - /** - * Get worldMatrix: Will trigger the worldMatrix update of itself and all parent entities. - * Get worldPosition: Will trigger the worldMatrix, local position update of itself and the worldMatrix update of all parent entities. - * Get worldRotationQuaternion: Will trigger the world rotation (in quaternion) update of itself and all parent entities. - * Get worldRotation: Will trigger the world rotation(in euler and quaternion) update of itself and world rotation(in quaternion) update of all parent entities. - * In summary, any update of related variables will cause the dirty mark of one of the full process (worldMatrix or worldRotationQuaternion) to be false. - */ - private _updateWorldRotationFlag() { - if (!this._isContainDirtyFlags(TransformFlag.WmWeWq)) { - this._worldAssociatedChange(TransformFlag.WmWeWq); - if (this._owner instanceof LiteCollider) { - const shapes = this._owner._shapes; - for (let i: number = 0, n: number = shapes.length; i < n; i++) { - shapes[i]._transform._updateWorldRotationFlag(); - } - } - } - } - - /** - * Get worldMatrix: Will trigger the worldMatrix update of itself and all parent entities. - * Get worldPosition: Will trigger the worldMatrix, local position update of itself and the worldMatrix update of all parent entities. - * Get worldScale: Will trigger the scaling update of itself and all parent entities. - * In summary, any update of related variables will cause the dirty mark of one of the full process (worldMatrix) to be false. - */ - private _updateWorldScaleFlag() { - if (!this._isContainDirtyFlags(TransformFlag.WmWs)) { - this._worldAssociatedChange(TransformFlag.WmWs); - if (this._owner instanceof LiteCollider) { - const shapes = this._owner._shapes; - for (let i: number = 0, n: number = shapes.length; i < n; i++) { - shapes[i]._transform._updateWorldScaleFlag(); - } - } - } - } - - /** - * Update all world transform property dirty flag, the principle is the same as above. - */ - private _updateAllWorldFlag(): void { - if (!this._isContainDirtyFlags(TransformFlag.WmWpWeWqWs)) { - this._worldAssociatedChange(TransformFlag.WmWpWeWqWs); - if (this._owner instanceof LiteCollider) { - const shapes = this._owner._shapes; - for (let i: number = 0, n: number = shapes.length; i < n; i++) { - shapes[i]._transform._updateAllWorldFlag(); - } - } - } - } - - private _getParentTransform(): LiteTransform | null { - if (!this._isParentDirty) { - return this._parentTransformCache; - } - let parentCache: LiteTransform = null; - if (this._owner instanceof LiteColliderShape) { - let parent = this._owner._collider; - parentCache = parent._transform; - } - - this._parentTransformCache = parentCache; - this._isParentDirty = false; - return parentCache; - } - - private _isContainDirtyFlags(targetDirtyFlags: number): boolean { - return (this._dirtyFlag & targetDirtyFlags) === targetDirtyFlags; - } - - private _isContainDirtyFlag(type: number): boolean { - return (this._dirtyFlag & type) != 0; - } - - private _setDirtyFlagTrue(type: number) { - this._dirtyFlag |= type; - } - - private _setDirtyFlagFalse(type: number) { - this._dirtyFlag &= ~type; - } - - private _worldAssociatedChange(type: number): void { - this._dirtyFlag |= type; - this._updateFlagManager.distribute(); - } -} - -/** - * Dirty flag of transform. - */ -enum TransformFlag { - LocalEuler = 0x1, - LocalQuat = 0x2, - WorldPosition = 0x4, - WorldEuler = 0x8, - WorldQuat = 0x10, - WorldScale = 0x20, - LocalMatrix = 0x40, - WorldMatrix = 0x80, - - /** WorldMatrix | WorldPosition */ - WmWp = 0x84, - /** WorldMatrix | WorldEuler | WorldQuat */ - WmWeWq = 0x98, - /** WorldMatrix | WorldPosition | WorldEuler | WorldQuat */ - WmWpWeWq = 0x9c, - /** WorldMatrix | WorldScale */ - WmWs = 0xa0, - /** WorldMatrix | WorldPosition | WorldScale */ - WmWpWs = 0xa4, - /** WorldMatrix | WorldPosition | WorldEuler | WorldQuat | WorldScale */ - WmWpWeWqWs = 0xbc -} diff --git a/packages/physics-lite/src/LiteUpdateFlag.ts b/packages/physics-lite/src/LiteUpdateFlag.ts deleted file mode 100644 index f699c1170..000000000 --- a/packages/physics-lite/src/LiteUpdateFlag.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Utils } from "@galacean/engine"; - -/** - * Used to update tags. - */ -export class LiteUpdateFlag { - /** Flag. */ - flag = true; - - constructor(private _flags: LiteUpdateFlag[] = []) { - this._flags.push(this); - } - - /** - * Destroy. - */ - destroy(): void { - Utils.removeFromArray(this._flags, this); - this._flags = null; - } -} diff --git a/packages/physics-lite/src/LiteUpdateFlagManager.ts b/packages/physics-lite/src/LiteUpdateFlagManager.ts deleted file mode 100644 index 74a71633d..000000000 --- a/packages/physics-lite/src/LiteUpdateFlagManager.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { LiteUpdateFlag } from "./LiteUpdateFlag"; - -/** - * @internal - */ -export class LiteUpdateFlagManager { - private _updateFlags: LiteUpdateFlag[] = []; - - register(): LiteUpdateFlag { - return new LiteUpdateFlag(this._updateFlags); - } - - distribute(): void { - const updateFlags = this._updateFlags; - for (let i = updateFlags.length - 1; i >= 0; i--) { - updateFlags[i].flag = true; - } - } -} diff --git a/packages/physics-lite/src/index.ts b/packages/physics-lite/src/index.ts deleted file mode 100644 index e3f1b15e9..000000000 --- a/packages/physics-lite/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { LitePhysics } from "./LitePhysics"; - -//@ts-ignore -export const version = `__buildVersion`; - -console.log(`Galacean Engine Physics Lite Version: ${version}`); diff --git a/packages/physics-lite/src/shape/LiteBoxColliderShape.ts b/packages/physics-lite/src/shape/LiteBoxColliderShape.ts deleted file mode 100644 index af41c8305..000000000 --- a/packages/physics-lite/src/shape/LiteBoxColliderShape.ts +++ /dev/null @@ -1,139 +0,0 @@ -import { BoundingBox, Matrix, Quaternion, Ray, Vector3, Vector4 } from "@galacean/engine"; -import { IBoxColliderShape } from "@galacean/engine-design"; -import { LiteHitResult } from "../LiteHitResult"; -import { LitePhysicsMaterial } from "../LitePhysicsMaterial"; -import { LiteColliderShape } from "./LiteColliderShape"; - -/** - * Box collider shape in Lite. - */ -export class LiteBoxColliderShape extends LiteColliderShape implements IBoxColliderShape { - private static _tempBox: BoundingBox = new BoundingBox(); - private static _tempMatrix: Matrix = new Matrix(); - private static _tempInvMatrix: Matrix = new Matrix(); - private _halfSize: Vector3 = new Vector3(); - private _sizeScale: Vector3 = new Vector3(1, 1, 1); - - /** @internal */ - _boxMin: Vector3 = new Vector3(-0.5, -0.5, -0.5); - /** @internal */ - _boxMax: Vector3 = new Vector3(0.5, 0.5, 0.5); - - /** - * Init Box Shape. - * @param uniqueID - UniqueID mark Shape. - * @param size - Size of Shape. - * @param material - Material of PhysXCollider. - */ - constructor(uniqueID: number, size: Vector3, material: LitePhysicsMaterial) { - super(); - this._id = uniqueID; - this._halfSize.set(size.x * 0.5, size.y * 0.5, size.z * 0.5); - this._setBondingBox(); - } - - /** - * {@inheritDoc IColliderShape.setPosition } - */ - override setPosition(position: Vector3): void { - super.setPosition(position); - this._setBondingBox(); - } - - /** - * {@inheritDoc IColliderShape.setWorldScale } - */ - override setWorldScale(scale: Vector3): void { - super.setWorldScale(scale); - this._sizeScale.set(Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)); - this._setBondingBox(); - } - - /** - * {@inheritDoc IBoxColliderShape.setSize } - */ - setSize(value: Vector3): void { - this._halfSize.set(value.x * 0.5, value.y * 0.5, value.z * 0.5); - this._setBondingBox(); - } - - /** - * {@inheritDoc IColliderShape.pointDistance } - */ - override pointDistance(point: Vector3): Vector4 { - const position = LiteColliderShape._tempPos; - const rotation = LiteColliderShape._tempRot; - this._transform.worldMatrix.decompose(position, rotation, LiteColliderShape._tempScale); - const { position: shapePosition } = this._transform; - const m = LiteBoxColliderShape._tempMatrix; - const invM = LiteBoxColliderShape._tempInvMatrix; - const p = LiteColliderShape._tempPoint; - const scale = this._sizeScale; - const boundingBox = LiteBoxColliderShape._tempBox; - - const { _boxMin, _boxMax } = this; - p.copyFrom(_boxMin); - p.subtract(shapePosition); - p.divide(scale); - boundingBox.min.copyFrom(p); - p.copyFrom(_boxMax); - p.subtract(shapePosition); - p.divide(scale); - boundingBox.max.copyFrom(p); - - Matrix.affineTransformation(scale, rotation, position, m); - Matrix.invert(m, invM); - Vector3.transformCoordinate(point, invM, p); - const min = boundingBox.min; - const max = boundingBox.max; - p.x = Math.max(min.x, Math.min(p.x, max.x)); - p.y = Math.max(min.y, Math.min(p.y, max.y)); - p.z = Math.max(min.z, Math.min(p.z, max.z)); - Vector3.transformCoordinate(p, m, p); - - const res = LiteColliderShape._tempVector4; - if (Vector3.equals(p, point)) { - res.set(point.x, point.y, point.z, 0); - } else { - res.set(p.x, p.y, p.z, Vector3.distanceSquared(p, point)); - } - - return res; - } - - /** - * @internal - */ - _raycast(ray: Ray, hit: LiteHitResult): boolean { - const localRay = this._getLocalRay(ray); - const sizeScale = this._sizeScale; - const halfSize = this._halfSize; - const boundingBox = LiteBoxColliderShape._tempBox; - boundingBox.min.set(-halfSize.x * sizeScale.x, -halfSize.y * sizeScale.y, -halfSize.z * sizeScale.z); - boundingBox.max.set(halfSize.x * sizeScale.x, halfSize.y * sizeScale.y, halfSize.z * sizeScale.z); - const rayDistance = localRay.intersectBox(boundingBox); - if (rayDistance !== -1) { - this._updateHitResult(localRay, rayDistance, hit, ray.origin); - return true; - } else { - return false; - } - } - - private _setBondingBox(): void { - const { position } = this._transform; - const scale = this._sizeScale; - const halfSize = this._halfSize; - - this._boxMin.set( - -halfSize.x * scale.x + position.x, - -halfSize.y * scale.y + position.y, - -halfSize.z * scale.z + position.z - ); - this._boxMax.set( - halfSize.x * scale.x + position.x, - halfSize.y * scale.y + position.y, - halfSize.z * scale.z + position.z - ); - } -} diff --git a/packages/physics-lite/src/shape/LiteColliderShape.ts b/packages/physics-lite/src/shape/LiteColliderShape.ts deleted file mode 100644 index 295241dfe..000000000 --- a/packages/physics-lite/src/shape/LiteColliderShape.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { MathUtil, Matrix, Quaternion, Ray, Vector3, Vector4 } from "@galacean/engine"; -import { IColliderShape, IPhysicsMaterial } from "@galacean/engine-design"; -import { LiteCollider } from "../LiteCollider"; -import { LiteHitResult } from "../LiteHitResult"; -import { LiteTransform } from "../LiteTransform"; -import { LiteUpdateFlag } from "../LiteUpdateFlag"; - -/** - * Abstract class for collider shapes. - */ -export abstract class LiteColliderShape implements IColliderShape { - protected static _tempPos = new Vector3(); - protected static _tempRot = new Quaternion(); - protected static _tempScale = new Vector3(); - protected static _tempPoint = new Vector3(); - protected static _tempVector4 = new Vector4(); - - private static _ray = new Ray(); - - /** @internal */ - _id: number; - /** @internal */ - _collider: LiteCollider; - /** @internal */ - _position: Vector3 = new Vector3(); - /** @internal */ - _worldScale: Vector3 = new Vector3(1, 1, 1); - /** @internal */ - _transform: LiteTransform = new LiteTransform(); - /** @internal */ - _invModelMatrix: Matrix = new Matrix(); - /** @internal */ - _inverseWorldMatFlag: LiteUpdateFlag; - - private _rotation: Vector3 = new Vector3(); - - protected constructor() { - this._transform.owner = this; - this._inverseWorldMatFlag = this._transform.registerWorldChangeFlag(); - } - - /** - * {@inheritDoc IColliderShape.setRotation } - */ - setRotation(rotation: Vector3): void { - const rotationInRadians = this._rotation.set( - MathUtil.degreeToRadian(rotation.x), - MathUtil.degreeToRadian(rotation.y), - MathUtil.degreeToRadian(rotation.z) - ); - Quaternion.rotationEuler( - rotationInRadians.x, - rotationInRadians.y, - rotationInRadians.z, - this._transform.rotationQuaternion - ); - } - - /** - * {@inheritDoc IColliderShape.setPosition } - */ - setPosition(position: Vector3): void { - if (position !== this._position) { - this._position.copyFrom(position); - } - this._setLocalPose(); - } - - /** - * {@inheritDoc IColliderShape.setWorldScale } - */ - setWorldScale(scale: Vector3): void { - this._worldScale.copyFrom(scale); - this._setLocalPose(); - } - - /** - * {@inheritDoc IColliderShape.setContactOffset } - */ - setContactOffset(offset: number): void { - console.log("Physics-lite don't support setContactOffset. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IColliderShape.setMaterial } - */ - setMaterial(material: IPhysicsMaterial): void { - console.log("Physics-lite don't support setMaterial. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IColliderShape.setUniqueID } - */ - setUniqueID(id: number): void { - this._id = id; - } - - /** - * {@inheritDoc IColliderShape.setIsTrigger } - */ - setIsTrigger(value: boolean): void { - console.log("Physics-lite don't support setIsTrigger. Use Physics-PhysX instead!"); - } - - /** - * {@inheritDoc IColliderShape.pointDistance } - */ - abstract pointDistance(point: Vector3): Vector4; - - /** - * {@inheritDoc IColliderShape.destroy } - */ - destroy(): void {} - - /** - * @internal - */ - abstract _raycast(ray: Ray, hit: LiteHitResult): boolean; - - protected _updateHitResult( - ray: Ray, - rayDistance: number, - outHit: LiteHitResult, - origin: Vector3, - isWorldRay: boolean = false - ): void { - const hitPoint = LiteColliderShape._tempPoint; - ray.getPoint(rayDistance, hitPoint); - if (!isWorldRay) { - Vector3.transformCoordinate(hitPoint, this._transform.worldMatrix, hitPoint); - } - - const distance = Vector3.distance(origin, hitPoint); - - if (distance < outHit.distance) { - outHit.point.copyFrom(hitPoint); - outHit.distance = distance; - outHit.shapeID = this._id; - } - } - - protected _getLocalRay(ray: Ray): Ray { - const worldToLocal = this._getInvModelMatrix(); - const outRay = LiteColliderShape._ray; - - Vector3.transformCoordinate(ray.origin, worldToLocal, outRay.origin); - Vector3.transformNormal(ray.direction, worldToLocal, outRay.direction); - outRay.direction.normalize(); - - return outRay; - } - - private _getInvModelMatrix(): Matrix { - if (this._inverseWorldMatFlag.flag) { - Matrix.invert(this._transform.worldMatrix, this._invModelMatrix); - this._inverseWorldMatFlag.flag = false; - } - return this._invModelMatrix; - } - - private _setLocalPose() { - const shapePosition = LiteColliderShape._tempPoint; - Vector3.multiply(this._position, this._worldScale, shapePosition); - this._transform.position = shapePosition; - } -} diff --git a/packages/physics-lite/src/shape/LiteSphereColliderShape.ts b/packages/physics-lite/src/shape/LiteSphereColliderShape.ts deleted file mode 100644 index 411097468..000000000 --- a/packages/physics-lite/src/shape/LiteSphereColliderShape.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { ISphereColliderShape } from "@galacean/engine-design"; -import { LiteColliderShape } from "./LiteColliderShape"; -import { BoundingSphere, Ray, Vector3, Vector4 } from "@galacean/engine"; -import { LiteHitResult } from "../LiteHitResult"; -import { LitePhysicsMaterial } from "../LitePhysicsMaterial"; - -/** - * Sphere collider shape in Lite. - */ -export class LiteSphereColliderShape extends LiteColliderShape implements ISphereColliderShape { - private static _tempSphere: BoundingSphere = new BoundingSphere(); - - private _radius: number = 1; - private _maxScale: number = 1; - - get worldRadius(): number { - return this._radius * this._maxScale; - } - - /** - * Init sphere shape. - * @param uniqueID - UniqueID mark collider - * @param radius - Size of SphereCollider - * @param material - Material of PhysXCollider - */ - constructor(uniqueID: number, radius: number, material: LitePhysicsMaterial) { - super(); - this._radius = radius; - this._id = uniqueID; - } - - /** - * {@inheritDoc ISphereColliderShape.setRadius } - */ - setRadius(value: number): void { - this._radius = value; - } - - /** - * {@inheritDoc IColliderShape.setWorldScale } - */ - override setWorldScale(scale: Vector3): void { - super.setWorldScale(scale); - this._maxScale = Math.max(Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)); - } - - /** - * {@inheritDoc IColliderShape.pointDistance } - */ - override pointDistance(point: Vector3): Vector4 { - const position = LiteColliderShape._tempPos; - const worldRadius = this.worldRadius; - this._transform.worldMatrix.decompose(position, LiteColliderShape._tempRot, LiteColliderShape._tempScale); - const p = LiteColliderShape._tempPoint; - Vector3.subtract(point, position, p); - const distanceFromCenter = p.lengthSquared(); - const direction = p.normalize(); - - Vector3.scale(direction, worldRadius, p); - p.add(position); - - const res = LiteColliderShape._tempVector4; - const distanceSquared = Vector3.distanceSquared(p, point); - - if (distanceFromCenter <= worldRadius * worldRadius) { - res.set(point.x, point.y, point.z, 0); - } else { - res.set(p.x, p.y, p.z, distanceSquared); - } - - return res; - } - - /** - * @internal - */ - _raycast(ray: Ray, hit: LiteHitResult): boolean { - const boundingSphere = LiteSphereColliderShape._tempSphere; - Vector3.transformCoordinate(this._transform.position, this._collider._transform.worldMatrix, boundingSphere.center); - boundingSphere.radius = this.worldRadius; - - const rayDistance = ray.intersectSphere(boundingSphere); - if (rayDistance !== -1) { - this._updateHitResult(ray, rayDistance, hit, ray.origin, true); - return true; - } else { - return false; - } - } -} diff --git a/packages/physics-lite/tsconfig.json b/packages/physics-lite/tsconfig.json deleted file mode 100644 index 588b0055c..000000000 --- a/packages/physics-lite/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "target": "esnext", - "declaration": true, - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "experimentalDecorators": true, - "declarationDir": "types", - "emitDeclarationOnly": true, - "noImplicitOverride": true, - "sourceMap": true, - "incremental": false, - "skipLibCheck": true, - "stripInternal": true - }, - "include": ["src/**/*"] -} diff --git a/packages/ui/README.md b/packages/ui/README.md deleted file mode 100644 index 06d695907..000000000 --- a/packages/ui/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# @galacean/engine-ui - -`@galacean/engine-ui` is a UI library designed for the `@galacean/engine`, this library enables developers to create and manage user interfaces efficiently within their **Galacean-based** applications. It is important to note that it is currently in an **experimental version**. - -## Features - -- **Rendering components**: Includes `Image` and `Text`. -- **Interactive Components**: Include `Button`, as well as other planned basic rendering components to be added in the future. -- **Event Handling**: Supports the dispatch and bubbling of events such as `onPointerEnter`, `onPointerExit`,`onPointerDown`, `onPointerUp`, `onPointerClick`, `onPointerDrag` and `onPointerDrop`. -- **Optimized Performance**: Designed to run smoothly with the Galacean engine. - -## Installation - -To use `@galacean/engine-ui` in your project, install it via npm: - -```bash -npm install @galacean/engine-ui -``` - -## Getting Started - -Here is a simple example to help you get started: - -```typescript -import { AssetType, Camera, Sprite, Texture2D, Vector3, WebGLEngine } from "@galacean/engine"; -import { CanvasRenderMode, Image, ResolutionAdaptationMode, UICanvas } from "@galacean/engine-ui"; - -// Initialize engine and scene -const engine = await WebGLEngine.create({ canvas: "canvas" }); -const scene = engine.sceneManager.activeScene; -const rootEntity = scene.createRootEntity(); - -// Create camera -const cameraEntity = rootEntity.createChild("Camera"); -cameraEntity.transform.position = new Vector3(0, 0, 10); -const camera = cameraEntity.addComponent(Camera); -camera.farClipPlane = 200; -camera.nearClipPlane = 0.3; - -// Create canvas -const canvasEntity = rootEntity.createChild("canvas"); -const canvas = canvasEntity.addComponent(UICanvas); -canvas.renderMode = CanvasRenderMode.ScreenSpaceCamera; -canvas.resolutionAdaptationMode = ResolutionAdaptationMode.HeightAdaptation; -canvas.distance = 100; -canvas.renderCamera = camera; - -// Create Image -const imageEntity = canvasEntity.createChild("image"); -const image = imageEntity.addComponent(Image); -engine.resourceManager - .load({ - url: "https://xxx.png", - type: AssetType.Texture2D - }) - .then((texture) => { - image.sprite = new Sprite(engine, texture); - }); - -// Run the engine -engine.run(); -``` -Easier operations in the [Editor](https://galacean.antgroup.com/editor/). - -## Documentation - -For detailed documentation, visit [the official documentation site](https://galacean.antgroup.com/engine). diff --git a/packages/ui/package.json b/packages/ui/package.json deleted file mode 100644 index 3c3864d3e..000000000 --- a/packages/ui/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@galacean/engine-ui", - "version": "0.0.0-experimental-backup.4", - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org" - }, - "repository": { - "url": "https://github.com/galacean/engine.git" - }, - "license": "MIT", - "main": "dist/main.js", - "module": "dist/module.js", - "debug": "src/index.ts", - "browser": "dist/browser.js", - "types": "types/index.d.ts", - "scripts": { - "b:types": "tsc" - }, - "umd": { - "name": "Galacean.UI", - "globals": { - "@galacean/engine": "Galacean" - } - }, - "files": [ - "dist/**/*", - "libs/**/*", - "types/**/*" - ], - "devDependencies": { - "@galacean/engine": "workspace:*" - }, - "peerDependencies": { - "@galacean/engine": "workspace:*" - } -} diff --git a/packages/ui/src/Utils.ts b/packages/ui/src/Utils.ts deleted file mode 100644 index f47e0a805..000000000 --- a/packages/ui/src/Utils.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { Entity } from "@galacean/engine"; -import { RootCanvasModifyFlags, UICanvas } from "./component/UICanvas"; -import { GroupModifyFlags, UIGroup } from "./component/UIGroup"; -import { IElement } from "./interface/IElement"; -import { IGroupAble } from "./interface/IGroupAble"; - -export class Utils { - static setRootCanvasDirty(element: IElement): void { - if (element._isRootCanvasDirty) return; - element._isRootCanvasDirty = true; - this._registerRootCanvas(element, null); - element._onRootCanvasModify?.(RootCanvasModifyFlags.All); - } - - static setRootCanvas(element: IElement, rootCanvas: UICanvas): void { - element._isRootCanvasDirty = false; - this._registerRootCanvas(element, rootCanvas); - const fromEntity = element instanceof UICanvas ? element.entity.parent : element.entity; - const toEntity = rootCanvas?.entity.parent ?? null; - this._registerListener(fromEntity, toEntity, element._rootCanvasListener, element._rootCanvasListeningEntities); - } - - static cleanRootCanvas(element: IElement): void { - this._registerRootCanvas(element, null); - this._unRegisterListener(element._rootCanvasListener, element._rootCanvasListeningEntities); - } - - static searchRootCanvasInParents(element: IElement): UICanvas { - let entity = element instanceof UICanvas ? element.entity.parent : element.entity; - while (entity) { - // @ts-ignore - const components = entity._components; - for (let i = 0, n = components.length; i < n; i++) { - const component = components[i]; - if (component.enabled && component instanceof UICanvas && component._isRootCanvas) { - return component; - } - } - entity = entity.parent; - } - return null; - } - - static setGroupDirty(element: IGroupAble): void { - if (element._isGroupDirty) return; - element._isGroupDirty = true; - this._registerGroup(element, null); - element._onGroupModify(GroupModifyFlags.All); - } - - static setGroup(element: IGroupAble, group: UIGroup): void { - element._isGroupDirty = false; - this._registerGroup(element, group); - const rootCanvas = element._getRootCanvas(); - if (rootCanvas) { - const fromEntity = element instanceof UIGroup ? element.entity.parent : element.entity; - const toEntity = group?.entity ?? rootCanvas.entity.parent; - this._registerListener(fromEntity, toEntity, element._groupListener, element._groupListeningEntities); - } else { - this._unRegisterListener(element._groupListener, element._groupListeningEntities); - } - } - - static cleanGroup(element: IGroupAble): void { - this._registerGroup(element, null); - this._unRegisterListener(element._groupListener, element._groupListeningEntities); - } - - static searchGroupInParents(element: IGroupAble): UIGroup { - const rootCanvas = element._getRootCanvas(); - if (!rootCanvas) return null; - let entity = element instanceof UIGroup ? element.entity.parent : element.entity; - const rootCanvasParent = rootCanvas.entity.parent; - while (entity && entity !== rootCanvasParent) { - // @ts-ignore - const components = entity._components; - for (let i = 0, n = components.length; i < n; i++) { - const component = components[i]; - if (component.enabled && component instanceof UIGroup) { - return component; - } - } - entity = entity.parent; - } - return null; - } - - private static _registerRootCanvas(element: IElement, canvas: UICanvas): void { - const preCanvas = element._rootCanvas; - if (preCanvas !== canvas) { - if (preCanvas) { - const replaced = preCanvas._disorderedElements.deleteByIndex(element._indexInRootCanvas); - replaced && (replaced._indexInRootCanvas = element._indexInRootCanvas); - element._indexInRootCanvas = -1; - } - if (canvas) { - const disorderedElements = canvas._disorderedElements; - element._indexInRootCanvas = disorderedElements.length; - disorderedElements.add(element); - } - element._rootCanvas = canvas; - } - } - - private static _registerGroup(element: IGroupAble, group: UIGroup): void { - const preGroup = element._group; - if (preGroup !== group) { - if (preGroup) { - const replaced = preGroup._disorderedElements.deleteByIndex(element._indexInGroup); - replaced && (replaced._indexInGroup = element._indexInGroup); - element._indexInGroup = -1; - } - if (group) { - const disorderedElements = group._disorderedElements; - element._indexInGroup = disorderedElements.length; - disorderedElements.add(element); - } - element._group = group; - element._onGroupModify(GroupModifyFlags.All); - } - } - - private static _registerListener( - entity: Entity, - root: Entity, - listener: (flag: number, param?: any) => void, - listeningEntities: Entity[] - ): void { - let count = 0; - while (entity && entity !== root) { - const preEntity = listeningEntities[count]; - if (preEntity !== entity) { - // @ts-ignore - preEntity?._unRegisterModifyListener(listener); - listeningEntities[count] = entity; - // @ts-ignore - entity._registerModifyListener(listener); - } - entity = entity.parent; - count++; - } - listeningEntities.length = count; - } - - private static _unRegisterListener(listener: (flag: number, param?: any) => void, listeningEntities: Entity[]): void { - for (let i = 0, n = listeningEntities.length; i < n; i++) { - // @ts-ignore - listeningEntities[i]._unRegisterModifyListener(listener); - } - listeningEntities.length = 0; - } -} diff --git a/packages/ui/src/component/UICanvas.ts b/packages/ui/src/component/UICanvas.ts deleted file mode 100644 index 5b25c51ce..000000000 --- a/packages/ui/src/component/UICanvas.ts +++ /dev/null @@ -1,718 +0,0 @@ -import { - BoolUpdateFlag, - Camera, - CameraModifyFlags, - Component, - DependentMode, - DisorderedArray, - Entity, - EntityModifyFlags, - Logger, - MathUtil, - Matrix, - Ray, - Vector2, - Vector3, - assignmentClone, - deepClone, - dependentComponents, - ignoreClone -} from "@galacean/engine"; -import { Utils } from "../Utils"; -import { CanvasRenderMode } from "../enums/CanvasRenderMode"; -import { ResolutionAdaptationMode } from "../enums/ResolutionAdaptationMode"; -import { UIHitResult } from "../input/UIHitResult"; -import { IElement } from "../interface/IElement"; -import { IGroupAble } from "../interface/IGroupAble"; -import { UIGroup } from "./UIGroup"; -import { UIRenderer } from "./UIRenderer"; -import { UITransform } from "./UITransform"; -import { UIInteractive } from "./interactive/UIInteractive"; - -/** - * The UI Canvas component serves as the root node for UI elements, - * handling rendering and events based on it. - */ -@dependentComponents(UITransform, DependentMode.AutoAdd) -export class UICanvas extends Component implements IElement { - /** @internal */ - static _hierarchyCounter: number = 1; - private static _targetTempPath: number[] = []; - private static _tempGroupAbleList: IGroupAble[] = []; - private static _tempVec3: Vector3 = new Vector3(); - private static _tempMat: Matrix = new Matrix(); - - /** @internal */ - @ignoreClone - _canvasIndex: number = -1; - /** @internal */ - @ignoreClone - _rootCanvas: UICanvas; - /** @internal */ - @ignoreClone - _indexInRootCanvas: number = -1; - /** @internal */ - @ignoreClone - _isRootCanvasDirty: boolean = false; - /** @internal */ - @ignoreClone - _rootCanvasListeningEntities: Entity[] = []; - - /** @internal */ - @ignoreClone - _isRootCanvas: boolean = false; - /** @internal */ - @ignoreClone - _renderElement: any; - /** @internal */ - @ignoreClone - _sortDistance: number = 0; - /** @internal */ - @ignoreClone - _orderedRenderers: UIRenderer[] = []; - /** @internal */ - @ignoreClone - _realRenderMode: number = CanvasRealRenderMode.None; - /** @internal */ - @ignoreClone - _disorderedElements: DisorderedArray = new DisorderedArray(); - - @ignoreClone - private _renderMode = CanvasRenderMode.WorldSpace; - @ignoreClone - private _renderCamera: Camera; - @ignoreClone - private _cameraObserver: Camera; - @assignmentClone - private _resolutionAdaptationMode = ResolutionAdaptationMode.HeightAdaptation; - @assignmentClone - private _sortOrder: number = 0; - @assignmentClone - private _distance: number = 10; - @deepClone - private _referenceResolution: Vector2 = new Vector2(800, 600); - @assignmentClone - private _referenceResolutionPerUnit: number = 100; - @ignoreClone - private _hierarchyVersion: number = -1; - @ignoreClone - private _center: Vector3 = new Vector3(); - @ignoreClone - private _centerDirtyFlag: BoolUpdateFlag; - - /** - * The conversion ratio between reference resolution and unit for UI elements in this canvas. - */ - get referenceResolutionPerUnit(): number { - return this._referenceResolutionPerUnit; - } - - set referenceResolutionPerUnit(value: number) { - if (this._referenceResolutionPerUnit !== value) { - this._referenceResolutionPerUnit = value; - this._disorderedElements.forEach((element) => { - element._onRootCanvasModify?.(RootCanvasModifyFlags.ReferenceResolutionPerUnit); - }); - } - } - - /** - * The reference resolution of the UI canvas in `ScreenSpaceCamera` and `ScreenSpaceOverlay` mode. - */ - get referenceResolution(): Vector2 { - return this._referenceResolution; - } - - set referenceResolution(value: Vector2) { - const referenceResolution = this._referenceResolution; - if (referenceResolution === value) return; - (referenceResolution.x !== value.x || referenceResolution.y !== value.y) && referenceResolution.copyFrom(value); - } - - /** - * The rendering mode of the UI canvas. - */ - get renderMode(): CanvasRenderMode { - return this._renderMode; - } - - set renderMode(mode: CanvasRenderMode) { - const preMode = this._renderMode; - if (preMode !== mode) { - this._renderMode = mode; - this._updateCameraObserver(); - this._setRealRenderMode(this._getRealRenderMode()); - } - } - - /** - * The camera used to render the UI canvas in `ScreenSpaceCamera` mode. - * @remarks If set `ScreenSpaceCamera` but no corresponding camera is assigned, the actual rendering mode defaults to `ScreenSpaceOverlay`. - */ - get renderCamera(): Camera { - return this._renderCamera; - } - - set renderCamera(value: Camera) { - const preCamera = this._renderCamera; - if (preCamera !== value) { - value && - this._isSameOrChildEntity(value.entity) && - Logger.warn( - "Camera entity matching or nested within the canvas entity disables canvas auto-adaptation in ScreenSpaceCamera mode." - ); - this._renderCamera = value; - this._updateCameraObserver(); - const preRenderMode = this._realRenderMode; - const curRenderMode = this._getRealRenderMode(); - if (preRenderMode === curRenderMode) { - if (curRenderMode === CanvasRenderMode.ScreenSpaceCamera) { - this._adapterPoseInScreenSpace(); - this._adapterSizeInScreenSpace(); - } - } else { - this._setRealRenderMode(curRenderMode); - } - } - } - - /** - * The screen resolution adaptation mode of the UI canvas in `ScreenSpaceCamera` and `ScreenSpaceOverlay` mode. - */ - get resolutionAdaptationMode(): ResolutionAdaptationMode { - return this._resolutionAdaptationMode; - } - - set resolutionAdaptationMode(value: ResolutionAdaptationMode) { - if (this._resolutionAdaptationMode !== value) { - this._resolutionAdaptationMode = value; - const realRenderMode = this._realRenderMode; - if ( - realRenderMode === CanvasRenderMode.ScreenSpaceCamera || - realRenderMode === CanvasRenderMode.ScreenSpaceOverlay - ) { - this._adapterSizeInScreenSpace(); - } - } - } - - /** - * The rendering order priority of the UI canvas in `ScreenSpaceOverlay` mode. - */ - get sortOrder(): number { - return this._sortOrder; - } - - set sortOrder(value: number) { - if (this._sortOrder !== value) { - this._sortOrder = value; - this._realRenderMode === CanvasRenderMode.ScreenSpaceOverlay && - // @ts-ignore - (this.scene._componentsManager._overlayCanvasesSortingFlag = true); - } - } - - /** - * The distance between the UI canvas and the camera in `ScreenSpaceCamera` mode. - */ - get distance(): number { - return this._distance; - } - - set distance(value: number) { - if (this._distance !== value) { - this._distance = value; - if (this._realRenderMode === CanvasRenderMode.ScreenSpaceCamera) { - this._adapterPoseInScreenSpace(); - this._adapterSizeInScreenSpace(); - } - } - } - - /** - * @internal - */ - constructor(entity: Entity) { - super(entity); - this._onCanvasSizeListener = this._onCanvasSizeListener.bind(this); - this._onCameraModifyListener = this._onCameraModifyListener.bind(this); - this._onCameraTransformListener = this._onCameraTransformListener.bind(this); - this._onReferenceResolutionChanged = this._onReferenceResolutionChanged.bind(this); - // @ts-ignore - this._referenceResolution._onValueChanged = this._onReferenceResolutionChanged; - this._rootCanvasListener = this._rootCanvasListener.bind(this); - this._centerDirtyFlag = entity.registerWorldChangeFlag(); - } - - /** - * @internal - */ - _raycast(ray: Ray, out: UIHitResult, distance: number = Number.MAX_SAFE_INTEGER): boolean { - const renderers = this._getRenderers(); - for (let i = renderers.length - 1; i >= 0; i--) { - const element = renderers[i]; - if (element.raycastEnabled && element._raycast(ray, out, distance)) { - return true; - } - } - out.component = null; - out.entity = null; - out.distance = 0; - out.point.set(0, 0, 0); - out.normal.set(0, 0, 0); - return false; - } - - /** - * @internal - */ - _getRootCanvas(): UICanvas { - return this._rootCanvas; - } - - /** - * @internal - */ - _canRender(camera: Camera): boolean { - return this._renderMode !== CanvasRenderMode.ScreenSpaceCamera || this._renderCamera === camera; - } - - /** - * @internal - */ - _prepareRender(context): void { - const { engine, _realRenderMode: mode } = this; - const { enableFrustumCulling, cullingMask, _frustum: frustum } = context.camera; - const { frameCount } = engine.time; - // @ts-ignore - const renderElement = (this._renderElement = engine._renderElementPool.get()); - const virtualCamera = context.virtualCamera; - this._updateSortDistance(virtualCamera.isOrthographic, virtualCamera.position, virtualCamera.forward); - renderElement.set(this.sortOrder, this._sortDistance); - const { width, height } = engine.canvas; - const renderers = this._getRenderers(); - for (let i = 0, n = renderers.length; i < n; i++) { - const renderer = renderers[i]; - // Filter by camera culling mask - if (!(cullingMask & renderer.entity.layer)) { - continue; - } - // Filter by camera frustum - if (enableFrustumCulling) { - switch (mode) { - case CanvasRenderMode.ScreenSpaceOverlay: - const { min, max } = renderer.bounds; - if (min.x > width || max.x < 0 || min.y > height || max.y < 0) { - continue; - } - break; - case CanvasRenderMode.ScreenSpaceCamera: - case CanvasRenderMode.WorldSpace: - if (!frustum.intersectsBox(renderer.bounds)) { - continue; - } - break; - default: - break; - } - } - renderer._prepareRender(context); - renderer._renderFrameCount = frameCount; - } - } - - /** - * @internal - */ - _updateSortDistance(isOrthographic: boolean, cameraPosition: Vector3, cameraForward: Vector3): void { - switch (this._realRenderMode) { - case CanvasRenderMode.ScreenSpaceOverlay: - this._sortDistance = 0; - break; - case CanvasRenderMode.ScreenSpaceCamera: - this._sortDistance = this._distance; - break; - case CanvasRenderMode.WorldSpace: - const boundsCenter = this._getCenter(); - if (isOrthographic) { - const distance = UICanvas._tempVec3; - Vector3.subtract(boundsCenter, cameraPosition, distance); - this._sortDistance = Vector3.dot(distance, cameraForward); - } else { - this._sortDistance = Vector3.distanceSquared(boundsCenter, cameraPosition); - } - break; - } - } - - // @ts-ignore - override _onEnableInScene(): void { - const entity = this.entity; - // @ts-ignore - entity._dispatchModify(EntityUIModifyFlags.CanvasEnableInScene, this); - const rootCanvas = Utils.searchRootCanvasInParents(this); - this._setIsRootCanvas(!rootCanvas); - Utils.setRootCanvas(this, rootCanvas); - } - - // @ts-ignore - override _onDisableInScene(): void { - this._setIsRootCanvas(false); - Utils.cleanRootCanvas(this); - } - - /** - * @internal - */ - @ignoreClone - _rootCanvasListener(flag: number, param: any): void { - if (this._isRootCanvas) { - if (flag === EntityModifyFlags.Parent) { - const rootCanvas = Utils.searchRootCanvasInParents(this); - this._setIsRootCanvas(!rootCanvas); - Utils.setRootCanvas(this, rootCanvas); - } else if (flag === EntityUIModifyFlags.CanvasEnableInScene) { - this._setIsRootCanvas(false); - Utils.setRootCanvas(this, param); - } - } else { - if (flag === EntityModifyFlags.Parent) { - const rootCanvas = Utils.searchRootCanvasInParents(this); - this._setIsRootCanvas(!rootCanvas); - Utils.setRootCanvas(this, rootCanvas); - } - } - } - - /** - * @internal - */ - _cloneTo(target: UICanvas, srcRoot: Entity, targetRoot: Entity): void { - target.renderMode = this._renderMode; - const renderCamera = this._renderCamera; - if (renderCamera) { - const paths = UICanvas._targetTempPath; - // @ts-ignore - const success = Entity._getEntityHierarchyPath(srcRoot, renderCamera.entity, paths); - // @ts-ignore - target.renderCamera = success - ? // @ts-ignore - Entity._getEntityByHierarchyPath(targetRoot, paths).getComponent(Camera) - : renderCamera; - } - } - - private _getRenderers(): UIRenderer[] { - const { _orderedRenderers: renderers, entity } = this; - const uiHierarchyVersion = entity._uiHierarchyVersion; - if (this._hierarchyVersion !== uiHierarchyVersion) { - renderers.length = this._walk(this.entity, renderers); - UICanvas._tempGroupAbleList.length = 0; - this._hierarchyVersion = uiHierarchyVersion; - ++UICanvas._hierarchyCounter; - } - return renderers; - } - - private _adapterPoseInScreenSpace(): void { - const transform = this.entity.transform; - const realRenderMode = this._realRenderMode; - if (realRenderMode === CanvasRenderMode.ScreenSpaceCamera) { - const cameraEntity = this._renderCamera.entity; - if (!this._isSameOrChildEntity(cameraEntity)) { - const { transform: cameraTransform } = cameraEntity; - const { worldPosition: cameraWorldPosition, worldForward: cameraWorldForward } = cameraTransform; - const distance = this._distance; - transform.setWorldPosition( - cameraWorldPosition.x + cameraWorldForward.x * distance, - cameraWorldPosition.y + cameraWorldForward.y * distance, - cameraWorldPosition.z + cameraWorldForward.z * distance - ); - transform.worldRotationQuaternion.copyFrom(cameraTransform.worldRotationQuaternion); - } - } else { - const { canvas } = this.engine; - transform.setWorldPosition(canvas.width * 0.5, canvas.height * 0.5, 0); - transform.worldRotationQuaternion.set(0, 0, 0, 1); - } - } - - private _adapterSizeInScreenSpace(): void { - const transform = this.entity.transform; - const realRenderMode = this._realRenderMode; - const { x: width, y: height } = this._referenceResolution; - let curWidth: number; - let curHeight: number; - if (realRenderMode === CanvasRenderMode.ScreenSpaceCamera) { - const renderCamera = this._renderCamera; - curHeight = renderCamera.isOrthographic - ? renderCamera.orthographicSize * 2 - : 2 * (Math.tan(MathUtil.degreeToRadian(renderCamera.fieldOfView * 0.5)) * this._distance); - curWidth = renderCamera.aspectRatio * curHeight; - } else { - const canvas = this.engine.canvas; - curHeight = canvas.height; - curWidth = canvas.width; - } - let expectX: number, expectY: number, expectZ: number; - switch (this._resolutionAdaptationMode) { - case ResolutionAdaptationMode.WidthAdaptation: - expectX = expectY = expectZ = curWidth / width; - break; - case ResolutionAdaptationMode.HeightAdaptation: - expectX = expectY = expectZ = curHeight / height; - break; - case ResolutionAdaptationMode.BothAdaptation: - expectX = curWidth / width; - expectY = curHeight / height; - expectZ = (expectX + expectY) * 0.5; - break; - case ResolutionAdaptationMode.ExpandAdaptation: - expectX = expectY = expectZ = Math.min(curWidth / width, curHeight / height); - break; - case ResolutionAdaptationMode.ShrinkAdaptation: - expectX = expectY = expectZ = Math.max(curWidth / width, curHeight / height); - break; - default: - break; - } - - const worldMatrix = UICanvas._tempMat; - Matrix.affineTransformation( - UICanvas._tempVec3.set(expectX, expectY, expectZ), - transform.worldRotationQuaternion, - transform.worldPosition, - worldMatrix - ); - transform.worldMatrix = worldMatrix; - transform.size.set(curWidth / expectX, curHeight / expectY); - } - - private _walk(entity: Entity, renderers: UIRenderer[], depth = 0, group: UIGroup = null): number { - // @ts-ignore - const components: Component[] = entity._components; - const tempGroupAbleList = UICanvas._tempGroupAbleList; - let groupAbleCount = 0; - for (let i = 0, n = components.length; i < n; i++) { - const component = components[i]; - if (!component.enabled) continue; - if (component instanceof UIRenderer) { - renderers[depth] = component; - ++depth; - component._isRootCanvasDirty && Utils.setRootCanvas(component, this); - if (component._isGroupDirty) { - tempGroupAbleList[groupAbleCount++] = component; - } - } else if (component instanceof UIInteractive) { - component._isRootCanvasDirty && Utils.setRootCanvas(component, this); - if (component._isGroupDirty) { - tempGroupAbleList[groupAbleCount++] = component; - } - } else if (component instanceof UIGroup) { - component._isRootCanvasDirty && Utils.setRootCanvas(component, this); - component._isGroupDirty && Utils.setGroup(component, group); - group = component; - } - } - for (let i = 0; i < groupAbleCount; i++) { - Utils.setGroup(tempGroupAbleList[i], group); - } - const children = entity.children; - for (let i = 0, n = children.length; i < n; i++) { - const child = children[i]; - child.isActive && (depth = this._walk(child, renderers, depth, group)); - } - return depth; - } - - private _updateCameraObserver(): void { - const camera = - this._isRootCanvas && this._renderMode === CanvasRenderMode.ScreenSpaceCamera ? this._renderCamera : null; - const preCamera = this._cameraObserver; - if (preCamera !== camera) { - this._cameraObserver = camera; - if (preCamera) { - // @ts-ignore - preCamera.entity._updateFlagManager.removeListener(this._onCameraTransformListener); - // @ts-ignore - preCamera._unRegisterModifyListener(this._onCameraModifyListener); - } - if (camera) { - // @ts-ignore - camera.entity._updateFlagManager.addListener(this._onCameraTransformListener); - // @ts-ignore - camera._registerModifyListener(this._onCameraModifyListener); - } - } - } - - @ignoreClone - private _onCameraModifyListener(flag: CameraModifyFlags): void { - if (this._realRenderMode === CanvasRenderMode.ScreenSpaceCamera) { - switch (flag) { - case CameraModifyFlags.ProjectionType: - case CameraModifyFlags.AspectRatio: - this._adapterSizeInScreenSpace(); - break; - case CameraModifyFlags.FieldOfView: - !this._renderCamera.isOrthographic && this._adapterSizeInScreenSpace(); - break; - case CameraModifyFlags.OrthographicSize: - this._renderCamera.isOrthographic && this._adapterSizeInScreenSpace(); - break; - case CameraModifyFlags.DisableInScene: - this._setRealRenderMode(CanvasRenderMode.ScreenSpaceOverlay); - break; - default: - break; - } - } else { - flag === CameraModifyFlags.EnableInScene && this._setRealRenderMode(CanvasRenderMode.ScreenSpaceCamera); - } - } - - @ignoreClone - private _onCameraTransformListener(): void { - this._realRenderMode === CanvasRenderMode.ScreenSpaceCamera && this._adapterPoseInScreenSpace(); - } - - private _addCanvasListener(): void { - // @ts-ignore - this.engine.canvas._sizeUpdateFlagManager.addListener(this._onCanvasSizeListener); - } - - private _removeCanvasListener(): void { - // @ts-ignore - this.engine.canvas._sizeUpdateFlagManager.removeListener(this._onCanvasSizeListener); - } - - @ignoreClone - private _onCanvasSizeListener(): void { - const { canvas } = this.engine; - this.entity.transform.setWorldPosition(canvas.width * 0.5, canvas.height * 0.5, 0); - this._adapterSizeInScreenSpace(); - } - - @ignoreClone - private _onReferenceResolutionChanged(): void { - const realRenderMode = this._realRenderMode; - if ( - realRenderMode === CanvasRenderMode.ScreenSpaceOverlay || - realRenderMode === CanvasRenderMode.ScreenSpaceCamera - ) { - this._adapterSizeInScreenSpace(); - } - } - - private _setIsRootCanvas(isRootCanvas: boolean): void { - if (this._isRootCanvas !== isRootCanvas) { - this._isRootCanvas = isRootCanvas; - this._updateCameraObserver(); - this._setRealRenderMode(this._getRealRenderMode()); - if (isRootCanvas) { - this.entity._updateUIHierarchyVersion(UICanvas._hierarchyCounter); - } else { - const { _disorderedElements: disorderedElements } = this; - disorderedElements.forEach((element: IElement) => { - if (element instanceof UICanvas) { - const rootCanvas = Utils.searchRootCanvasInParents(element); - element._setIsRootCanvas(!rootCanvas); - Utils.setRootCanvas(element, rootCanvas); - } else { - Utils.setRootCanvasDirty(this); - Utils.setGroupDirty(element); - } - }); - disorderedElements.length = 0; - disorderedElements.garbageCollection(); - this._orderedRenderers.length = 0; - } - } - } - - private _getCenter(): Vector3 { - if (this._centerDirtyFlag.flag) { - const center = this._center; - const uiTransform = this.entity.transform; - const { pivot, size } = uiTransform; - center.set((0.5 - pivot.x) * size.x, (0.5 - pivot.y) * size.y, 0); - Vector3.transformCoordinate(center, uiTransform.worldMatrix, center); - this._centerDirtyFlag.flag = false; - } - return this._center; - } - - private _getRealRenderMode(): number { - if (this._isRootCanvas) { - const mode = this._renderMode; - if (mode === CanvasRenderMode.ScreenSpaceCamera && !this._renderCamera?.enabled) { - return CanvasRenderMode.ScreenSpaceOverlay; - } else { - return mode; - } - } else { - return CanvasRealRenderMode.None; - } - } - - private _setRealRenderMode(curRealMode: number): void { - const preRealMode = this._realRenderMode; - if (preRealMode !== curRealMode) { - this._realRenderMode = curRealMode; - // @ts-ignore - const componentsManager = this.scene._componentsManager; - switch (preRealMode) { - case CanvasRenderMode.ScreenSpaceOverlay: - this._removeCanvasListener(); - case CanvasRenderMode.ScreenSpaceCamera: - case CanvasRenderMode.WorldSpace: - componentsManager.removeUICanvas(this, preRealMode === CanvasRenderMode.ScreenSpaceOverlay); - break; - default: - break; - } - switch (curRealMode) { - case CanvasRenderMode.ScreenSpaceOverlay: - this._addCanvasListener(); - case CanvasRenderMode.ScreenSpaceCamera: - this._adapterPoseInScreenSpace(); - this._adapterSizeInScreenSpace(); - case CanvasRenderMode.WorldSpace: - componentsManager.addUICanvas(this, curRealMode === CanvasRenderMode.ScreenSpaceOverlay); - break; - default: - break; - } - } - } - - private _isSameOrChildEntity(cameraEntity: Entity): boolean { - const canvasEntity = this.entity; - while (cameraEntity) { - if (cameraEntity === canvasEntity) return true; - cameraEntity = cameraEntity.parent; - } - return false; - } -} - -/** - * @remarks Extends `CanvasRenderMode`. - */ -enum CanvasRealRenderMode { - None = 4 -} - -/** - * @remarks Extends `EntityModifyFlags`. - */ -export enum EntityUIModifyFlags { - CanvasEnableInScene = 0x4, - GroupEnableInScene = 0x8 -} - -export enum RootCanvasModifyFlags { - None = 0x0, - ReferenceResolutionPerUnit = 0x1, - All = 0x1 -} diff --git a/packages/ui/src/component/UIGroup.ts b/packages/ui/src/component/UIGroup.ts deleted file mode 100644 index 98b55d9bf..000000000 --- a/packages/ui/src/component/UIGroup.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { Component, DisorderedArray, Entity, EntityModifyFlags, assignmentClone, ignoreClone } from "@galacean/engine"; -import { Utils } from "../Utils"; -import { IGroupAble } from "../interface/IGroupAble"; -import { EntityUIModifyFlags, UICanvas } from "./UICanvas"; - -export class UIGroup extends Component implements IGroupAble { - /** @internal */ - @ignoreClone - _indexInGroup: number = -1; - /** @internal */ - @ignoreClone - _indexInRootCanvas: number = -1; - /** @internal */ - @ignoreClone - _group: UIGroup; - /** @internal */ - @ignoreClone - _rootCanvas: UICanvas; - /** @internal */ - @ignoreClone - _disorderedElements: DisorderedArray = new DisorderedArray(); - - /** @internal */ - @ignoreClone - _globalAlpha = 1; - /** @internal */ - @ignoreClone - _globalInteractive = true; - - @assignmentClone - private _alpha = 1; - @assignmentClone - private _interactive = true; - @assignmentClone - private _ignoreParentGroup = false; - - /** @internal */ - @ignoreClone - _rootCanvasListeningEntities: Entity[] = []; - /** @internal */ - @ignoreClone - _groupListeningEntities: Entity[] = []; - /** @internal */ - @ignoreClone - _isRootCanvasDirty: boolean = false; - /** @internal */ - @ignoreClone - _isGroupDirty: boolean = false; - /** @internal */ - @ignoreClone - _groupDirtyFlags: number = GroupModifyFlags.None; - - /** - * Whether to ignore the parent group. - * @remarks If this parameter set to `true`, - * all settings of the parent group will be ignored. - */ - get ignoreParentGroup(): boolean { - return this._ignoreParentGroup; - } - - set ignoreParentGroup(value: boolean) { - if (this._ignoreParentGroup !== value) { - this._ignoreParentGroup = value; - this._onGroupModify(GroupModifyFlags.All); - } - } - - /** - * Whether the group is interactive. - */ - get interactive(): boolean { - return this._interactive; - } - - set interactive(value: boolean) { - if (this._interactive !== value) { - this._interactive = value; - this._onGroupModify(GroupModifyFlags.GlobalInteractive); - } - } - - /** - * The alpha value of the group. - */ - get alpha(): number { - return this._alpha; - } - - set alpha(value: number) { - value = Math.max(0, Math.min(value, 1)); - if (this._alpha !== value) { - this._alpha = value; - this._onGroupModify(GroupModifyFlags.GlobalAlpha); - } - } - - /** - * @internal - */ - _getGlobalAlpha(): number { - if (this._isContainDirtyFlag(GroupModifyFlags.GlobalAlpha)) { - if (this._ignoreParentGroup) { - this._globalAlpha = this._alpha; - } else { - const parentGroup = this._getGroup(); - this._globalAlpha = this._alpha * (parentGroup ? parentGroup._getGlobalAlpha() : 1); - } - this._setDirtyFlagFalse(GroupModifyFlags.GlobalAlpha); - } - return this._globalAlpha; - } - - /** - * @internal - */ - _getGlobalInteractive(): boolean { - if (this._isContainDirtyFlag(GroupModifyFlags.GlobalInteractive)) { - if (this._ignoreParentGroup) { - this._globalInteractive = this._interactive; - } else { - const parentGroup = this._getGroup(); - this._globalInteractive = this._interactive && (!parentGroup || parentGroup._getGlobalInteractive()); - } - this._setDirtyFlagFalse(GroupModifyFlags.GlobalInteractive); - } - return this._globalInteractive; - } - - constructor(entity: Entity) { - super(entity); - this._rootCanvasListener = this._rootCanvasListener.bind(this); - this._groupListener = this._groupListener.bind(this); - } - - // @ts-ignore - override _onEnableInScene(): void { - Utils.setRootCanvasDirty(this); - Utils.setGroupDirty(this); - // @ts-ignore - this.entity._dispatchModify(EntityUIModifyFlags.GroupEnableInScene); - } - - // @ts-ignore - override _onDisableInScene(): void { - Utils.cleanRootCanvas(this); - Utils.cleanGroup(this); - const disorderedElements = this._disorderedElements; - disorderedElements.forEach((element: IGroupAble) => { - Utils.setGroupDirty(element); - }); - disorderedElements.length = 0; - disorderedElements.garbageCollection(); - this._isRootCanvasDirty = this._isGroupDirty = false; - } - - /** - * @internal - */ - _getRootCanvas(): UICanvas { - this._isRootCanvasDirty && Utils.setRootCanvas(this, Utils.searchRootCanvasInParents(this)); - return this._rootCanvas; - } - - /** - * @internal - */ - _getGroup(): UIGroup { - this._isGroupDirty && Utils.setGroup(this, Utils.searchGroupInParents(this)); - return this._group; - } - - /** - * @internal - */ - @ignoreClone - _groupListener(flag: number): void { - if (flag === EntityModifyFlags.Parent || flag === EntityUIModifyFlags.GroupEnableInScene) { - Utils.setGroupDirty(this); - } - } - - /** - * @internal - */ - @ignoreClone - _rootCanvasListener(flag: number): void { - if (flag === EntityModifyFlags.Parent || flag === EntityUIModifyFlags.CanvasEnableInScene) { - Utils.setRootCanvasDirty(this); - Utils.setGroupDirty(this); - } - } - - /** - * @internal - */ - _onGroupModify(flags: GroupModifyFlags, isPass: boolean = false): void { - if (isPass && this._ignoreParentGroup) return; - if (this._isContainDirtyFlags(flags)) return; - this._setDirtyFlagTrue(flags); - this._disorderedElements.forEach((element) => { - element._onGroupModify(flags, true); - }); - } - - private _isContainDirtyFlags(targetDirtyFlags: number): boolean { - return (this._groupDirtyFlags & targetDirtyFlags) === targetDirtyFlags; - } - - private _isContainDirtyFlag(type: number): boolean { - return (this._groupDirtyFlags & type) != 0; - } - - private _setDirtyFlagTrue(type: number) { - this._groupDirtyFlags |= type; - } - - private _setDirtyFlagFalse(type: number) { - this._groupDirtyFlags &= ~type; - } -} - -export enum GroupModifyFlags { - None = 0x0, - GlobalAlpha = 0x1, - GlobalInteractive = 0x2, - All = 0x3 -} diff --git a/packages/ui/src/component/UIRenderer.ts b/packages/ui/src/component/UIRenderer.ts deleted file mode 100644 index 285df1d12..000000000 --- a/packages/ui/src/component/UIRenderer.ts +++ /dev/null @@ -1,300 +0,0 @@ -import { - BatchUtils, - Color, - DependentMode, - Entity, - EntityModifyFlags, - Matrix, - Plane, - Ray, - Renderer, - RendererUpdateFlags, - ShaderMacroCollection, - ShaderProperty, - Vector3, - Vector4, - assignmentClone, - deepClone, - dependentComponents, - ignoreClone -} from "@galacean/engine"; -import { Utils } from "../Utils"; -import { UIHitResult } from "../input/UIHitResult"; -import { IGraphics } from "../interface/IGraphics"; -import { EntityUIModifyFlags, UICanvas } from "./UICanvas"; -import { GroupModifyFlags, UIGroup } from "./UIGroup"; -import { UITransform } from "./UITransform"; - -@dependentComponents(UITransform, DependentMode.AutoAdd) -export class UIRenderer extends Renderer implements IGraphics { - /** @internal */ - static _tempVec30: Vector3 = new Vector3(); - /** @internal */ - static _tempVec31: Vector3 = new Vector3(); - /** @internal */ - static _tempMat: Matrix = new Matrix(); - /** @internal */ - static _tempPlane: Plane = new Plane(); - /** @internal */ - static _textureProperty: ShaderProperty = ShaderProperty.getByName("renderer_UITexture"); - - /** - * Custom boundary for raycast detection. - * @remarks this is based on `this.entity.transform`. - */ - @deepClone - raycastPadding: Vector4 = new Vector4(0, 0, 0, 0); - /** @internal */ - @ignoreClone - _rootCanvas: UICanvas; - /** @internal */ - @ignoreClone - _indexInRootCanvas: number = -1; - /** @internal */ - @ignoreClone - _isRootCanvasDirty: boolean = false; - /** @internal */ - @ignoreClone - _rootCanvasListeningEntities: Entity[] = []; - /** @internal */ - @ignoreClone - _group: UIGroup; - /** @internal */ - @ignoreClone - _indexInGroup: number = -1; - /** @internal */ - @ignoreClone - _isGroupDirty: boolean = false; - /** @internal */ - @ignoreClone - _groupListeningEntities: Entity[] = []; - /** @internal */ - @ignoreClone - _subChunk; - - @assignmentClone - private _raycastEnabled: boolean = true; - @deepClone - protected _color: Color = new Color(1, 1, 1, 1); - - /** - * Rendering color for the ui renderer. - */ - get color(): Color { - return this._color; - } - - set color(value: Color) { - if (this._color !== value) { - this._color.copyFrom(value); - } - } - - /** - * Whether this renderer be picked up by raycast. - */ - get raycastEnabled(): boolean { - return this._raycastEnabled; - } - - set raycastEnabled(value: boolean) { - this._raycastEnabled = value; - } - - /** - * @internal - */ - constructor(entity: Entity) { - super(entity); - this._dirtyUpdateFlag = RendererUpdateFlags.WorldVolume | UIRendererUpdateFlags.Color; - this._onColorChanged = this._onColorChanged.bind(this); - //@ts-ignore - this._color._onValueChanged = this._onColorChanged; - this._groupListener = this._groupListener.bind(this); - this._rootCanvasListener = this._rootCanvasListener.bind(this); - } - - // @ts-ignore - override _canBatch(elementA, elementB): boolean { - return BatchUtils.canBatchSprite(elementA, elementB); - } - - // @ts-ignore - override _batch(elementA, elementB?): void { - BatchUtils.batchFor2D(elementA, elementB); - } - - // @ts-ignore - override _updateTransformShaderData(context, onlyMVP: boolean, batched: boolean): void { - // @ts-ignore - super._updateTransformShaderData(context, onlyMVP, true); - } - - // @ts-ignore - override _prepareRender(context): void { - // Update once per frame per renderer, not influenced by batched - if (this._renderFrameCount !== this.engine.time.frameCount) { - this._update(context); - } - - this._render(context); - - // union camera global macro and renderer macro. - ShaderMacroCollection.unionCollection( - context.camera._globalShaderMacro, - // @ts-ignore - this.shaderData._macroCollection, - //@ts-ignore - this._globalShaderMacro - ); - } - - // @ts-ignore - override _onEnableInScene(): void { - // @ts-ignore - this._overrideUpdate && this.scene._componentsManager.addOnUpdateRenderers(this); - this.entity._updateUIHierarchyVersion(UICanvas._hierarchyCounter); - Utils.setRootCanvasDirty(this); - Utils.setGroupDirty(this); - } - - // @ts-ignore - override _onDisableInScene(): void { - // @ts-ignore - this._overrideUpdate && this.scene._componentsManager.removeOnUpdateRenderers(this); - this.entity._updateUIHierarchyVersion(UICanvas._hierarchyCounter); - Utils.cleanRootCanvas(this); - Utils.cleanGroup(this); - } - - /** - * @internal - */ - _getGlobalAlpha(): number { - return this._getGroup()?._getGlobalAlpha() ?? 1; - } - - /** - * @internal - */ - _getRootCanvas(): UICanvas { - this._isRootCanvasDirty && Utils.setRootCanvas(this, Utils.searchRootCanvasInParents(this)); - return this._rootCanvas; - } - - /** - * @internal - */ - _getGroup(): UIGroup { - this._isGroupDirty && Utils.setGroup(this, Utils.searchGroupInParents(this)); - return this._group; - } - - /** - * @internal - */ - @ignoreClone - _groupListener(flag: number): void { - if (flag === EntityModifyFlags.Parent || flag === EntityUIModifyFlags.GroupEnableInScene) { - Utils.setGroupDirty(this); - } - } - - /** - * @internal - */ - @ignoreClone - _rootCanvasListener(flag: number, entity: Entity): void { - switch (flag) { - case EntityModifyFlags.Parent: - Utils.setRootCanvasDirty(this); - Utils.setGroupDirty(this); - case EntityModifyFlags.Child: - entity._updateUIHierarchyVersion(UICanvas._hierarchyCounter); - break; - default: - break; - } - } - - /** - * @internal - */ - _onGroupModify(flags: GroupModifyFlags): void { - if (flags & GroupModifyFlags.GlobalAlpha) { - this._dirtyUpdateFlag |= UIRendererUpdateFlags.Color; - } - } - - @ignoreClone - private _onColorChanged(): void { - this._dirtyUpdateFlag |= UIRendererUpdateFlags.Color; - } - - /** - * @internal - */ - _getChunkManager() { - // @ts-ignore - return this.engine._batcherManager.primitiveChunkManagerUI; - } - - /** - * @internal - */ - _raycast(ray: Ray, out: UIHitResult, distance: number = Number.MAX_SAFE_INTEGER): boolean { - const plane = UIRenderer._tempPlane; - const transform = this._transformEntity.transform; - const normal = plane.normal.copyFrom(transform.worldForward); - plane.distance = -Vector3.dot(normal, transform.worldPosition); - const curDistance = ray.intersectPlane(plane); - if (curDistance >= 0 && curDistance < distance) { - const hitPointWorld = ray.getPoint(curDistance, UIRenderer._tempVec30); - const worldMatrixInv = UIRenderer._tempMat; - Matrix.invert(transform.worldMatrix, worldMatrixInv); - const localPosition = UIRenderer._tempVec31; - Vector3.transformCoordinate(hitPointWorld, worldMatrixInv, localPosition); - if (this._hitTest(localPosition)) { - out.component = this; - out.distance = curDistance; - out.entity = this.entity; - out.normal.copyFrom(normal); - out.point.copyFrom(hitPointWorld); - return true; - } - } - return false; - } - - protected _hitTest(localPosition: Vector3): boolean { - const { x, y } = localPosition; - const uiTransform = this._transformEntity.transform; - const { x: width, y: height } = uiTransform.size; - const { x: pivotX, y: pivotY } = uiTransform.pivot; - const { x: paddingLeft, y: paddingBottom, z: paddingRight, w: paddingTop } = this.raycastPadding; - return ( - x >= -width * pivotX + paddingLeft && - x <= width * (1 - pivotX) - paddingRight && - y >= -height * pivotY + paddingTop && - y <= height * (1 - pivotY) - paddingBottom - ); - } - - protected override _onDestroy(): void { - if (this._subChunk) { - this._getChunkManager().freeSubChunk(this._subChunk); - this._subChunk = null; - } - super._onDestroy(); - //@ts-ignore - this._color._onValueChanged = null; - this._color = null; - } -} - -/** - * @remarks Extends `RendererUpdateFlags`. - */ -export enum UIRendererUpdateFlags { - Color = 0x2 -} diff --git a/packages/ui/src/component/UITransform.ts b/packages/ui/src/component/UITransform.ts deleted file mode 100644 index 699fd5652..000000000 --- a/packages/ui/src/component/UITransform.ts +++ /dev/null @@ -1,446 +0,0 @@ -import { - Entity, - MathUtil, - Rect, - Transform, - TransformModifyFlags, - Vector2, - deepClone, - ignoreClone -} from "@galacean/engine"; -import { HorizontalAlignmentMode } from "../enums/HorizontalAlignmentMode"; -import { VerticalAlignmentMode } from "../enums/VerticalAlignmentMode"; - -/** - * The Transform component exclusive to the UI element. - */ -export class UITransform extends Transform { - @ignoreClone - private _size = new Vector2(100, 100); - @ignoreClone - private _pivot = new Vector2(0.5, 0.5); - @deepClone - private _rect = new Rect(-50, -50, 100, 100); - - private _alignLeft = 0; - private _alignRight = 0; - private _alignCenter = 0; - private _alignTop = 0; - private _alignBottom = 0; - private _alignMiddle = 0; - private _horizontalAlignment = HorizontalAlignmentMode.None; - private _verticalAlignment = VerticalAlignmentMode.None; - - /** - * Width and height of UI element. - */ - get size(): Vector2 { - return this._size; - } - - set size(value: Vector2) { - const { _size: size } = this; - if (size === value) return; - (size.x !== value.x || size.y !== value.y) && size.copyFrom(value); - } - - /** - * Pivot of UI element. - */ - get pivot(): Vector2 { - return this._pivot; - } - - set pivot(value: Vector2) { - const { _pivot: pivot } = this; - if (pivot === value) return; - (pivot.x !== value.x || pivot.y !== value.y) && pivot.copyFrom(value); - } - - /** - * Horizontal alignment mode. - * - * @remarks - * Controls how the element aligns horizontally within its parent: - * - `Left` - Align to parent's left edge - * - `Center` - Align to parent's horizontal center - * - `Right` - Align to parent's right edge - * - `LeftAndRight` - Align to both left and right edges (stretch to fill width) - */ - get horizontalAlignment(): HorizontalAlignmentMode { - return this._horizontalAlignment; - } - - set horizontalAlignment(value: HorizontalAlignmentMode) { - if (this._horizontalAlignment === value) return; - this._horizontalAlignment = value; - switch (value) { - case HorizontalAlignmentMode.Left: - case HorizontalAlignmentMode.Right: - case HorizontalAlignmentMode.Center: - this._onPositionChanged(); - break; - case HorizontalAlignmentMode.LeftAndRight: - this._onPositionChanged(); - this._onSizeChanged(); - break; - default: - break; - } - } - - /** - * Left margin when horizontalAlignment is Left or LeftAndRight. - * - * @remarks - * Only effective when horizontalAlignment includes Left mode. - * Distance from the parent's left edge to the element's left edge. - */ - get alignLeft(): number { - return this._alignLeft; - } - - set alignLeft(value: number) { - if (!Number.isFinite(value)) return; - if (MathUtil.equals(value, this._alignLeft)) return; - this._alignLeft = value; - if (this._horizontalAlignment & HorizontalAlignmentMode.Left) { - this._onPositionChanged(); - this._horizontalAlignment & HorizontalAlignmentMode.Right && this._onSizeChanged(); - } - } - - /** - * Right margin when horizontalAlignment is Right or LeftAndRight. - * - * @remarks - * Only effective when horizontalAlignment includes Right mode. - * Distance from the parent's right edge to the element's right edge. - */ - get alignRight(): number { - return this._alignRight; - } - - set alignRight(value: number) { - if (!Number.isFinite(value)) return; - if (MathUtil.equals(value, this._alignRight)) return; - this._alignRight = value; - if (this._horizontalAlignment & HorizontalAlignmentMode.Right) { - this._onPositionChanged(); - this._horizontalAlignment & HorizontalAlignmentMode.Left && this._onSizeChanged(); - } - } - - /** - * Horizontal center offset when horizontalAlignment is Center. - * - * @remarks - * Only effective when horizontalAlignment is Center mode. - * Positive values move the element to the right, negative values to the left. - */ - get alignCenter(): number { - return this._alignCenter; - } - - set alignCenter(value: number) { - if (!Number.isFinite(value)) return; - if (MathUtil.equals(value, this._alignCenter)) return; - this._alignCenter = value; - this._horizontalAlignment & HorizontalAlignmentMode.Center && this._onPositionChanged(); - } - - /** - * Vertical alignment mode. - * - * @remarks - * Controls how the element aligns vertically within its parent: - * - `Top` - Align to parent's top edge - * - `Middle` - Align to parent's vertical center - * - `Bottom` - Align to parent's bottom edge - * - `TopAndBottom` - Align to both top and bottom edges (stretch to fill height) - */ - get verticalAlignment(): VerticalAlignmentMode { - return this._verticalAlignment; - } - - set verticalAlignment(value: VerticalAlignmentMode) { - if (this._verticalAlignment === value) return; - this._verticalAlignment = value; - switch (value) { - case VerticalAlignmentMode.Top: - case VerticalAlignmentMode.Bottom: - case VerticalAlignmentMode.Middle: - this._onPositionChanged(); - break; - case VerticalAlignmentMode.TopAndBottom: - this._onPositionChanged(); - this._onSizeChanged(); - break; - default: - break; - } - } - - /** - * Top margin when verticalAlignment is Top or TopAndBottom. - * - * @remarks - * Only effective when verticalAlignment includes Top mode. - * Used to offset the element from the parent's top edge. - */ - get alignTop(): number { - return this._alignTop; - } - - set alignTop(value: number) { - if (!Number.isFinite(value)) return; - if (MathUtil.equals(value, this._alignTop)) return; - this._alignTop = value; - if (this._verticalAlignment & VerticalAlignmentMode.Top) { - this._onPositionChanged(); - this._verticalAlignment & VerticalAlignmentMode.Bottom && this._onSizeChanged(); - } - } - - /** - * Bottom inset used in vertical alignment formulas. - */ - get alignBottom(): number { - return this._alignBottom; - } - - set alignBottom(value: number) { - if (!Number.isFinite(value)) return; - if (MathUtil.equals(value, this._alignBottom)) return; - this._alignBottom = value; - if (this._verticalAlignment & VerticalAlignmentMode.Bottom) { - this._onPositionChanged(); - this._verticalAlignment & VerticalAlignmentMode.Top && this._onSizeChanged(); - } - } - - /** - * Vertical middle offset relative to parent's middle. - */ - get alignMiddle(): number { - return this._alignMiddle; - } - - set alignMiddle(value: number) { - if (!Number.isFinite(value)) return; - if (MathUtil.equals(value, this._alignMiddle)) return; - this._alignMiddle = value; - this._verticalAlignment & VerticalAlignmentMode.Middle && this._onPositionChanged(); - } - - /** - * @internal - */ - constructor(entity: Entity) { - super(entity); - this._onSizeChanged = this._onSizeChanged.bind(this); - this._onPivotChanged = this._onPivotChanged.bind(this); - // @ts-ignore - this._size._onValueChanged = this._onSizeChanged; - // @ts-ignore - this._pivot._onValueChanged = this._onPivotChanged; - } - - /** - * @internal - */ - _parentChange(): void { - this._isParentDirty = true; - this._updateWorldFlagWithParentRectChange(TransformModifyFlags.WmWpWeWqWsWus); - } - - // @ts-ignore - override _cloneTo(target: UITransform, srcRoot: Entity, targetRoot: Entity): void { - // @ts-ignore - super._cloneTo(target, srcRoot, targetRoot); - - const { _size: size, _pivot: pivot } = target; - - // @ts-ignore - size._onValueChanged = pivot._onValueChanged = null; - - size.copyFrom(this._size); - pivot.copyFrom(this._pivot); - - // @ts-ignore - size._onValueChanged = target._onSizeChanged; - // @ts-ignore - pivot._onValueChanged = target._onPivotChanged; - } - - protected override _onLocalMatrixChanging(): void { - // `super._onLocalMatrixChanging()` will set `LocalMatrix` dirty flag `false` - // If there is an alignment, `position` and `localMatrix` will be reset again - if (this._horizontalAlignment || this._verticalAlignment) { - this._updatePositionByAlignment(); - this._setDirtyFlagTrue(TransformModifyFlags.LocalMatrix); - } else { - super._onLocalMatrixChanging(); - } - } - - protected override _onWorldMatrixChanging(): void { - // `super._onWorldMatrixChanging()` will set `WorldMatrix` dirty flag `false` - // If there is an alignment, `position` and `worldMatrix` will be reset again(`worldMatrix` dirty flag is already `true`) - !this._horizontalAlignment && !this._verticalAlignment && super._onWorldMatrixChanging(); - } - - @ignoreClone - protected override _onPositionChanged(): void { - (this._horizontalAlignment || this._verticalAlignment) && this._updatePositionByAlignment(); - super._onPositionChanged(); - } - - @ignoreClone - protected override _onWorldPositionChanged(): void { - super._onWorldPositionChanged(); - if (this._horizontalAlignment || this._verticalAlignment) { - this._setDirtyFlagTrue(TransformModifyFlags.WorldPosition); - } - } - - private _updatePositionByAlignment(): void { - const parentRect = (this._getParentTransform() as UITransform)?._rect; - if (parentRect) { - const position = this.position; - // @ts-ignore - position._onValueChanged = null; - const rect = this._rect; - switch (this._horizontalAlignment) { - case HorizontalAlignmentMode.Left: - case HorizontalAlignmentMode.LeftAndRight: - position.x = parentRect.x - rect.x + this._alignLeft; - break; - case HorizontalAlignmentMode.Center: - position.x = parentRect.x + parentRect.width * 0.5 - rect.x - rect.width * 0.5 + this._alignCenter; - break; - case HorizontalAlignmentMode.Right: - position.x = parentRect.x + parentRect.width - rect.x - rect.width - this._alignRight; - break; - default: - break; - } - switch (this._verticalAlignment) { - case VerticalAlignmentMode.Top: - position.y = parentRect.y + parentRect.height - rect.y - rect.height - this._alignTop; - break; - case VerticalAlignmentMode.Middle: - position.y = parentRect.y + parentRect.height * 0.5 - rect.y - rect.height * 0.5 + this._alignMiddle; - break; - case VerticalAlignmentMode.Bottom: - case VerticalAlignmentMode.TopAndBottom: - position.y = parentRect.y - rect.y + this._alignBottom; - break; - default: - break; - } - // @ts-ignore - position._onValueChanged = this._onPositionChanged; - } - } - - private _updateSizeByAlignment(): void { - const parentRect = (this._getParentTransform() as UITransform)?._rect; - if (parentRect) { - const size = this._size; - // @ts-ignore - size._onValueChanged = null; - // The values of size must be greater than 0 - if (this._horizontalAlignment === HorizontalAlignmentMode.LeftAndRight) { - size.x = Math.max(parentRect.width - this._alignLeft - this._alignRight, 0); - } - if (this._verticalAlignment === VerticalAlignmentMode.TopAndBottom) { - size.y = Math.max(parentRect.height - this._alignTop - this._alignBottom, 0); - } - // @ts-ignore - size._onValueChanged = this._onSizeChanged; - } - } - - private _updateRectBySizeAndPivot(): void { - const { size, _pivot: pivot } = this; - const x = -pivot.x * size.x; - const y = -pivot.y * size.y; - this._rect.set(x, y, size.x, size.y); - } - - @ignoreClone - private _onSizeChanged(): void { - if ( - this._horizontalAlignment === HorizontalAlignmentMode.LeftAndRight || - this._verticalAlignment === VerticalAlignmentMode.TopAndBottom - ) { - this._updateSizeByAlignment(); - } - this._updateRectBySizeAndPivot(); - this._updateWorldFlagWithSelfRectChange(); - // @ts-ignore - this._entity._updateFlagManager.dispatch(UITransformModifyFlags.Size); - } - - @ignoreClone - private _onPivotChanged(): void { - this._updateRectBySizeAndPivot(); - this._updateWorldFlagWithSelfRectChange(); - // @ts-ignore - this._entity._updateFlagManager.dispatch(UITransformModifyFlags.Pivot); - } - - private _updateWorldFlagWithSelfRectChange(): void { - let worldFlags = 0; - if (this._horizontalAlignment || this._verticalAlignment) { - this._updatePositionByAlignment(); - this._setDirtyFlagTrue(TransformModifyFlags.LocalMatrix); - worldFlags = TransformModifyFlags.WmWp; - !this._isContainDirtyFlags(worldFlags) && this._worldAssociatedChange(worldFlags); - } - const children = this.entity.children; - for (let i = 0, n = children.length; i < n; i++) { - (children[i].transform as UITransform)?._updateWorldFlagWithParentRectChange?.(worldFlags); - } - } - - private _updateWorldFlagWithParentRectChange(flags: number, parentChange: boolean = true): void { - let selfChange = false; - if (parentChange) { - const { _horizontalAlignment: horizontalAlignment, _verticalAlignment: verticalAlignment } = this; - if (horizontalAlignment || verticalAlignment) { - if ( - horizontalAlignment === HorizontalAlignmentMode.LeftAndRight || - verticalAlignment === VerticalAlignmentMode.TopAndBottom - ) { - this._updateSizeByAlignment(); - this._updateRectBySizeAndPivot(); - selfChange = true; - } - this._updatePositionByAlignment(); - this._setDirtyFlagTrue(TransformModifyFlags.LocalMatrix); - flags |= TransformModifyFlags.WmWp; - } - } - const containDirtyFlags = this._isContainDirtyFlags(flags); - !containDirtyFlags && this._worldAssociatedChange(flags); - if (selfChange || !containDirtyFlags) { - const children = this.entity.children; - for (let i = 0, n = children.length; i < n; i++) { - (children[i].transform as UITransform)?._updateWorldFlagWithParentRectChange?.(flags, selfChange); - } - } - // @ts-ignore - selfChange && this._entity._updateFlagManager.dispatch(UITransformModifyFlags.Size); - } -} - -/** - * @internal - * extends TransformModifyFlags - */ -export enum UITransformModifyFlags { - Size = 0x200, - Pivot = 0x400 -} diff --git a/packages/ui/src/component/advanced/Button.ts b/packages/ui/src/component/advanced/Button.ts deleted file mode 100644 index bc9ef9f22..000000000 --- a/packages/ui/src/component/advanced/Button.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ignoreClone, PointerEventData, SafeLoopArray } from "@galacean/engine"; -import { UIInteractive } from "../interactive/UIInteractive"; - -export class Button extends UIInteractive { - @ignoreClone - private _listeners: SafeLoopArray = new SafeLoopArray(); - - /** - * Add a listening function for click. - * @param listener - The listening function - */ - addClicked(listener: (event: PointerEventData) => void): void { - this._listeners.push({ fn: listener }); - } - - /** - * Remove a listening function of click. - * @param listener - The listening function - */ - removeClicked(listener: (event: PointerEventData) => void): void { - this._listeners.findAndRemove((value) => (value.fn === listener ? (value.destroyed = true) : false)); - } - - override onPointerClick(event: PointerEventData): void { - if (!this._getGlobalInteractive()) return; - const listeners = this._listeners.getLoopArray(); - for (let i = 0, n = listeners.length; i < n; i++) { - const listener = listeners[i]; - !listener.destroyed && listener.fn(event); - } - } - - override onDestroy(): void { - super.onDestroy(); - this._listeners.findAndRemove((value) => (value.destroyed = true)); - } -} - -export interface IUIListener { - fn: (event: PointerEventData) => void; - destroyed?: boolean; -} diff --git a/packages/ui/src/component/advanced/Image.ts b/packages/ui/src/component/advanced/Image.ts deleted file mode 100644 index 404f248a0..000000000 --- a/packages/ui/src/component/advanced/Image.ts +++ /dev/null @@ -1,326 +0,0 @@ -import { - BoundingBox, - Entity, - ISpriteAssembler, - ISpriteRenderer, - MathUtil, - RenderQueueFlags, - RendererUpdateFlags, - SimpleSpriteAssembler, - SlicedSpriteAssembler, - Sprite, - SpriteDrawMode, - SpriteModifyFlags, - SpriteTileMode, - TiledSpriteAssembler, - assignmentClone, - ignoreClone -} from "@galacean/engine"; -import { CanvasRenderMode } from "../../enums/CanvasRenderMode"; -import { RootCanvasModifyFlags } from "../UICanvas"; -import { UIRenderer, UIRendererUpdateFlags } from "../UIRenderer"; -import { UITransform, UITransformModifyFlags } from "../UITransform"; - -/** - * UI element that renders an image. - */ -export class Image extends UIRenderer implements ISpriteRenderer { - @ignoreClone - private _sprite: Sprite = null; - @ignoreClone - private _drawMode: SpriteDrawMode; - @ignoreClone - private _assembler: ISpriteAssembler; - @assignmentClone - private _tileMode: SpriteTileMode = SpriteTileMode.Continuous; - @assignmentClone - private _tiledAdaptiveThreshold: number = 0.5; - - /** - * The draw mode of the image. - */ - get drawMode(): SpriteDrawMode { - return this._drawMode; - } - - set drawMode(value: SpriteDrawMode) { - if (this._drawMode !== value) { - this._drawMode = value; - switch (value) { - case SpriteDrawMode.Simple: - this._assembler = SimpleSpriteAssembler; - break; - case SpriteDrawMode.Sliced: - this._assembler = SlicedSpriteAssembler; - break; - case SpriteDrawMode.Tiled: - this._assembler = TiledSpriteAssembler; - break; - default: - break; - } - this._assembler.resetData(this); - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeUVAndColor; - } - } - - /** - * The tiling mode of the image. (Only works in tiled mode.) - */ - get tileMode(): SpriteTileMode { - return this._tileMode; - } - - set tileMode(value: SpriteTileMode) { - if (this._tileMode !== value) { - this._tileMode = value; - if (this.drawMode === SpriteDrawMode.Tiled) { - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeUVAndColor; - } - } - } - - /** - * Stretch Threshold in Tile Adaptive Mode, specified in normalized. (Only works in tiled adaptive mode.) - */ - get tiledAdaptiveThreshold(): number { - return this._tiledAdaptiveThreshold; - } - - set tiledAdaptiveThreshold(value: number) { - if (value !== this._tiledAdaptiveThreshold) { - value = MathUtil.clamp(value, 0, 1); - this._tiledAdaptiveThreshold = value; - if (this.drawMode === SpriteDrawMode.Tiled) { - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeUVAndColor; - } - } - } - - /** - * The Sprite to render. - */ - get sprite(): Sprite { - return this._sprite; - } - - set sprite(value: Sprite | null) { - const lastSprite = this._sprite; - if (lastSprite !== value) { - if (lastSprite) { - this._addResourceReferCount(lastSprite, -1); - // @ts-ignore - lastSprite._updateFlagManager.removeListener(this._onSpriteChange); - } - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeUVAndColor; - if (value) { - this._addResourceReferCount(value, 1); - // @ts-ignore - value._updateFlagManager.addListener(this._onSpriteChange); - this.shaderData.setTexture(UIRenderer._textureProperty, value.texture); - } else { - this.shaderData.setTexture(UIRenderer._textureProperty, null); - } - this._sprite = value; - } - } - - /** - * @internal - */ - constructor(entity: Entity) { - super(entity); - this.drawMode = SpriteDrawMode.Simple; - this.setMaterial(this._engine._getUIDefaultMaterial()); - this._onSpriteChange = this._onSpriteChange.bind(this); - } - - /** - * @internal - */ - _onRootCanvasModify(flag: RootCanvasModifyFlags): void { - if (flag & RootCanvasModifyFlags.ReferenceResolutionPerUnit) { - const drawMode = this._drawMode; - if (drawMode === SpriteDrawMode.Tiled) { - this._dirtyUpdateFlag |= ImageUpdateFlags.All; - } else if (drawMode === SpriteDrawMode.Sliced) { - this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume; - } - } - } - - /** - * @internal - */ - _cloneTo(target: Image, srcRoot: Entity, targetRoot: Entity): void { - // @ts-ignore - super._cloneTo(target, srcRoot, targetRoot); - target.sprite = this._sprite; - target.drawMode = this._drawMode; - } - - protected override _updateBounds(worldBounds: BoundingBox): void { - const sprite = this._sprite; - const rootCanvas = this._getRootCanvas(); - if (sprite && rootCanvas) { - const transform = this._transformEntity.transform; - const { size } = transform; - this._assembler.updatePositions( - this, - transform.worldMatrix, - size.x, - size.y, - transform.pivot, - false, - false, - rootCanvas.referenceResolutionPerUnit - ); - } else { - const { worldPosition } = this._transformEntity.transform; - worldBounds.min.copyFrom(worldPosition); - worldBounds.max.copyFrom(worldPosition); - } - } - - protected override _render(context): void { - const { _sprite: sprite } = this; - const transform = this._transformEntity.transform; - const { x: width, y: height } = transform.size; - if (!sprite?.texture || !width || !height) { - return; - } - - let material = this.getMaterial(); - if (!material) { - return; - } - // @todo: This question needs to be raised rather than hidden. - if (material.destroyed) { - material = this._engine._getUIDefaultMaterial(); - } - - const alpha = this._getGlobalAlpha(); - if (this._color.a * alpha <= 0) { - return; - } - - let { _dirtyUpdateFlag: dirtyUpdateFlag } = this; - const canvas = this._getRootCanvas(); - // Update position - if (dirtyUpdateFlag & RendererUpdateFlags.WorldVolume) { - this._assembler.updatePositions( - this, - transform.worldMatrix, - width, - height, - transform.pivot, - false, - false, - canvas.referenceResolutionPerUnit - ); - dirtyUpdateFlag &= ~RendererUpdateFlags.WorldVolume; - } - - // Update uv - if (dirtyUpdateFlag & ImageUpdateFlags.UV) { - this._assembler.updateUVs(this); - dirtyUpdateFlag &= ~ImageUpdateFlags.UV; - } - - // Update color - if (dirtyUpdateFlag & UIRendererUpdateFlags.Color) { - this._assembler.updateColor(this, alpha); - dirtyUpdateFlag &= ~UIRendererUpdateFlags.Color; - } - - this._dirtyUpdateFlag = dirtyUpdateFlag; - // Init sub render element. - const { engine } = context.camera; - const subRenderElement = engine._subRenderElementPool.get(); - const subChunk = this._subChunk; - subRenderElement.set(this, material, subChunk.chunk.primitive, subChunk.subMesh, this.sprite.texture, subChunk); - if (canvas._realRenderMode === CanvasRenderMode.ScreenSpaceOverlay) { - subRenderElement.shaderPasses = material.shader.subShaders[0].passes; - subRenderElement.renderQueueFlags = RenderQueueFlags.All; - } - canvas._renderElement.addSubRenderElement(subRenderElement); - } - - @ignoreClone - protected override _onTransformChanged(type: number): void { - if (type & UITransformModifyFlags.Size && this._drawMode === SpriteDrawMode.Tiled) { - this._dirtyUpdateFlag |= ImageUpdateFlags.All; - } - this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume; - } - - protected override _onDestroy(): void { - const sprite = this._sprite; - if (sprite) { - this._addResourceReferCount(sprite, -1); - // @ts-ignore - sprite._updateFlagManager.removeListener(this._onSpriteChange); - this._sprite = null; - } - super._onDestroy(); - } - - @ignoreClone - private _onSpriteChange(type: SpriteModifyFlags): void { - switch (type) { - case SpriteModifyFlags.texture: - this.shaderData.setTexture(UIRenderer._textureProperty, this.sprite.texture); - break; - case SpriteModifyFlags.size: - switch (this._drawMode) { - case SpriteDrawMode.Sliced: - this._dirtyUpdateFlag |= RendererUpdateFlags.WorldVolume; - break; - case SpriteDrawMode.Tiled: - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeUVAndColor; - break; - default: - break; - } - break; - case SpriteModifyFlags.border: - switch (this._drawMode) { - case SpriteDrawMode.Sliced: - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeAndUV; - break; - case SpriteDrawMode.Tiled: - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeUVAndColor; - break; - default: - break; - } - break; - case SpriteModifyFlags.region: - case SpriteModifyFlags.atlasRegionOffset: - this._dirtyUpdateFlag |= ImageUpdateFlags.WorldVolumeAndUV; - break; - case SpriteModifyFlags.atlasRegion: - this._dirtyUpdateFlag |= ImageUpdateFlags.UV; - break; - case SpriteModifyFlags.destroy: - this.sprite = null; - break; - } - } -} - -/** - * @remarks Extends `UIRendererUpdateFlags`. - */ -enum ImageUpdateFlags { - /** UV. */ - UV = 0x4, - /** Automatic Size. */ - AutomaticSize = 0x8, - /** WorldVolume and UV. */ - WorldVolumeAndUV = 0x5, - /** WorldVolume, UV and Color. */ - WorldVolumeUVAndColor = 0x7, - /** All. */ - All = 0xf -} diff --git a/packages/ui/src/component/advanced/Text.ts b/packages/ui/src/component/advanced/Text.ts deleted file mode 100644 index ba4413af6..000000000 --- a/packages/ui/src/component/advanced/Text.ts +++ /dev/null @@ -1,675 +0,0 @@ -import { - BoundingBox, - CharRenderInfo, - Engine, - Entity, - Font, - FontStyle, - ITextRenderer, - OverflowMode, - RenderQueueFlags, - RendererUpdateFlags, - ShaderData, - ShaderDataGroup, - ShaderProperty, - SubFont, - TextHorizontalAlignment, - TextUtils, - TextVerticalAlignment, - Texture2D, - Vector3, - assignmentClone, - ignoreClone -} from "@galacean/engine"; -import { CanvasRenderMode } from "../../enums/CanvasRenderMode"; -import { RootCanvasModifyFlags } from "../UICanvas"; -import { UIRenderer, UIRendererUpdateFlags } from "../UIRenderer"; -import { UITransform, UITransformModifyFlags } from "../UITransform"; - -/** - * UI component used to render text. - */ -export class Text extends UIRenderer implements ITextRenderer { - private static _textTextureProperty = ShaderProperty.getByName("renderElement_TextTexture"); - private static _worldPositions = [new Vector3(), new Vector3(), new Vector3(), new Vector3()]; - private static _charRenderInfos: CharRenderInfo[] = []; - - @ignoreClone - private _textChunks = Array(); - @ignoreClone - private _subFont: SubFont = null; - @assignmentClone - private _text: string = ""; - @ignoreClone - private _localBounds: BoundingBox = new BoundingBox(); - @assignmentClone - private _font: Font = null; - @assignmentClone - private _fontSize: number = 24; - @assignmentClone - private _fontStyle: FontStyle = FontStyle.None; - @assignmentClone - private _lineSpacing: number = 0; - @assignmentClone - private _horizontalAlignment: TextHorizontalAlignment = TextHorizontalAlignment.Center; - @assignmentClone - private _verticalAlignment: TextVerticalAlignment = TextVerticalAlignment.Center; - @assignmentClone - private _enableWrapping: boolean = false; - @assignmentClone - private _overflowMode: OverflowMode = OverflowMode.Overflow; - - /** - * Rendering string for the Text. - */ - get text(): string { - return this._text; - } - - set text(value: string) { - value = value || ""; - if (this._text !== value) { - this._text = value; - this._setDirtyFlagTrue(DirtyFlag.Position); - } - } - - /** - * The font of the Text. - */ - get font(): Font { - return this._font; - } - - set font(value: Font) { - const lastFont = this._font; - if (lastFont !== value) { - lastFont && this._addResourceReferCount(lastFont, -1); - value && this._addResourceReferCount(value, 1); - this._font = value; - this._setDirtyFlagTrue(DirtyFlag.Font); - } - } - - /** - * The font size of the Text. - */ - get fontSize(): number { - return this._fontSize; - } - - set fontSize(value: number) { - if (this._fontSize !== value) { - this._fontSize = value; - this._setDirtyFlagTrue(DirtyFlag.Font); - } - } - - /** - * The style of the font. - */ - get fontStyle(): FontStyle { - return this._fontStyle; - } - - set fontStyle(value: FontStyle) { - if (this.fontStyle !== value) { - this._fontStyle = value; - this._setDirtyFlagTrue(DirtyFlag.Font); - } - } - - /** - * The space between two lines (in pixels). - */ - get lineSpacing(): number { - return this._lineSpacing; - } - - set lineSpacing(value: number) { - if (this._lineSpacing !== value) { - this._lineSpacing = value; - this._setDirtyFlagTrue(DirtyFlag.Position); - } - } - - /** - * The horizontal alignment. - */ - get horizontalAlignment(): TextHorizontalAlignment { - return this._horizontalAlignment; - } - - set horizontalAlignment(value: TextHorizontalAlignment) { - if (this._horizontalAlignment !== value) { - this._horizontalAlignment = value; - this._setDirtyFlagTrue(DirtyFlag.Position); - } - } - - /** - * The vertical alignment. - */ - get verticalAlignment(): TextVerticalAlignment { - return this._verticalAlignment; - } - - set verticalAlignment(value: TextVerticalAlignment) { - if (this._verticalAlignment !== value) { - this._verticalAlignment = value; - this._setDirtyFlagTrue(DirtyFlag.Position); - } - } - - /** - * Whether wrap text to next line when exceeds the width of the container. - */ - get enableWrapping(): boolean { - return this._enableWrapping; - } - - set enableWrapping(value: boolean) { - if (this._enableWrapping !== value) { - this._enableWrapping = value; - this._setDirtyFlagTrue(DirtyFlag.Position); - } - } - - /** - * The overflow mode. - */ - get overflowMode(): OverflowMode { - return this._overflowMode; - } - - set overflowMode(value: OverflowMode) { - if (this._overflowMode !== value) { - this._overflowMode = value; - this._setDirtyFlagTrue(DirtyFlag.Position); - } - } - - /** - * The mask layer the sprite renderer belongs to. - */ - get maskLayer(): number { - return this._maskLayer; - } - - set maskLayer(value: number) { - this._maskLayer = value; - } - - /** - * The bounding volume of the TextRenderer. - */ - override get bounds(): BoundingBox { - if (this._isTextNoVisible()) { - if (this._isContainDirtyFlag(RendererUpdateFlags.WorldVolume)) { - const localBounds = this._localBounds; - localBounds.min.set(0, 0, 0); - localBounds.max.set(0, 0, 0); - this._updateBounds(this._bounds); - this._setDirtyFlagFalse(RendererUpdateFlags.WorldVolume); - } - return this._bounds; - } - this._isContainDirtyFlag(DirtyFlag.SubFont) && this._resetSubFont(); - this._isContainDirtyFlag(DirtyFlag.LocalPositionBounds) && this._updateLocalData(); - this._isContainDirtyFlag(DirtyFlag.WorldPosition) && this._updatePosition(); - this._isContainDirtyFlag(RendererUpdateFlags.WorldVolume) && this._updateBounds(this._bounds); - this._setDirtyFlagFalse(DirtyFlag.Font); - - return this._bounds; - } - - constructor(entity: Entity) { - super(entity); - const { engine } = this; - // @ts-ignore - this.font = engine._textDefaultFont; - this.raycastEnabled = false; - // @ts-ignore - this.setMaterial(engine._basicResources.textDefaultMaterial); - } - - /** - * @internal - */ - protected override _onDestroy(): void { - if (this._font) { - this._addResourceReferCount(this._font, -1); - this._font = null; - } - - super._onDestroy(); - - this._freeTextChunks(); - this._textChunks = null; - - this._subFont && (this._subFont = null); - } - - // @ts-ignore - override _cloneTo(target: Text, srcRoot: Entity, targetRoot: Entity): void { - // @ts-ignore - super._cloneTo(target, srcRoot, targetRoot); - target.font = this._font; - target._subFont = this._subFont; - } - - /** - * @internal - */ - _isContainDirtyFlag(type: number): boolean { - return (this._dirtyUpdateFlag & type) != 0; - } - - /** - * @internal - */ - _setDirtyFlagTrue(type: number): void { - this._dirtyUpdateFlag |= type; - } - - /** - * @internal - */ - _setDirtyFlagFalse(type: number): void { - this._dirtyUpdateFlag &= ~type; - } - - /** - * @internal - */ - _getSubFont(): SubFont { - if (!this._subFont) { - this._resetSubFont(); - } - return this._subFont; - } - - /** - * @internal - */ - _onRootCanvasModify(flag: RootCanvasModifyFlags): void { - if (flag === RootCanvasModifyFlags.ReferenceResolutionPerUnit) { - this._setDirtyFlagTrue(DirtyFlag.LocalPositionBounds); - } - } - - protected override _updateBounds(worldBounds: BoundingBox): void { - const transform = this._transformEntity.transform; - const { x: width, y: height } = transform.size; - const { x: pivotX, y: pivotY } = transform.pivot; - worldBounds.min.set(-width * pivotX, -height * pivotY, 0); - worldBounds.max.set(width * (1 - pivotX), height * (1 - pivotY), 0); - BoundingBox.transform(worldBounds, this._transformEntity.transform.worldMatrix, worldBounds); - } - - protected override _render(context): void { - if (this._isTextNoVisible()) { - return; - } - - if (this._isContainDirtyFlag(DirtyFlag.SubFont)) { - this._resetSubFont(); - this._setDirtyFlagFalse(DirtyFlag.SubFont); - } - - const canvas = this._getRootCanvas(); - if (this._isContainDirtyFlag(DirtyFlag.LocalPositionBounds)) { - this._updateLocalData(); - this._setDirtyFlagTrue(DirtyFlag.LocalPositionBounds); - } - - if (this._isContainDirtyFlag(DirtyFlag.WorldPosition)) { - this._updatePosition(); - this._setDirtyFlagFalse(DirtyFlag.WorldPosition); - } - - if (this._isContainDirtyFlag(UIRendererUpdateFlags.Color)) { - this._updateColor(); - this._setDirtyFlagFalse(UIRendererUpdateFlags.Color); - } - - const engine = context.camera.engine; - const textSubRenderElementPool = engine._textSubRenderElementPool; - const material = this.getMaterial(); - const renderElement = canvas._renderElement; - const textChunks = this._textChunks; - const isOverlay = canvas._realRenderMode === CanvasRenderMode.ScreenSpaceOverlay; - for (let i = 0, n = textChunks.length; i < n; ++i) { - const { subChunk, texture } = textChunks[i]; - const subRenderElement = textSubRenderElementPool.get(); - subRenderElement.set(this, material, subChunk.chunk.primitive, subChunk.subMesh, texture, subChunk); - // @ts-ignore - subRenderElement.shaderData ||= new ShaderData(ShaderDataGroup.RenderElement); - subRenderElement.shaderData.setTexture(Text._textTextureProperty, texture); - if (isOverlay) { - subRenderElement.shaderPasses = material.shader.subShaders[0].passes; - subRenderElement.renderQueueFlags = RenderQueueFlags.All; - } - renderElement.addSubRenderElement(subRenderElement); - } - } - - private _resetSubFont(): void { - const font = this._font; - // @ts-ignore - this._subFont = font._getSubFont(this.fontSize, this.fontStyle); - this._subFont.nativeFontString = TextUtils.getNativeFontString(font.name, this.fontSize, this.fontStyle); - } - - private _updatePosition(): void { - const e = this._transformEntity.transform.worldMatrix.elements; - - // prettier-ignore - const e0 = e[0], e1 = e[1], e2 = e[2], - e4 = e[4], e5 = e[5], e6 = e[6], - e12 = e[12], e13 = e[13], e14 = e[14]; - - const up = UIRenderer._tempVec31.set(e4, e5, e6); - const right = UIRenderer._tempVec30.set(e0, e1, e2); - - const worldPositions = Text._worldPositions; - const [worldPosition0, worldPosition1, worldPosition2, worldPosition3] = worldPositions; - const textChunks = this._textChunks; - for (let i = 0, n = textChunks.length; i < n; ++i) { - const { subChunk, charRenderInfos } = textChunks[i]; - for (let j = 0, m = charRenderInfos.length; j < m; ++j) { - const charRenderInfo = charRenderInfos[j]; - const { localPositions } = charRenderInfo; - const { x: topLeftX, y: topLeftY } = localPositions; - - // Top-Left - worldPosition0.set( - topLeftX * e0 + topLeftY * e4 + e12, - topLeftX * e1 + topLeftY * e5 + e13, - topLeftX * e2 + topLeftY * e6 + e14 - ); - - // Right offset - Vector3.scale(right, localPositions.z - topLeftX, worldPosition1); - // Top-Right - Vector3.add(worldPosition0, worldPosition1, worldPosition1); - // Up offset - Vector3.scale(up, localPositions.w - topLeftY, worldPosition2); - // Bottom-Left - Vector3.add(worldPosition0, worldPosition2, worldPosition3); - // Bottom-Right - Vector3.add(worldPosition1, worldPosition2, worldPosition2); - - const vertices = subChunk.chunk.vertices; - for (let k = 0, o = subChunk.vertexArea.start + charRenderInfo.indexInChunk * 36; k < 4; ++k, o += 9) { - worldPositions[k].copyToArray(vertices, o); - } - } - } - } - - private _updateColor(): void { - const { r, g, b, a } = this._color; - const finalAlpha = a * this._getGlobalAlpha(); - const textChunks = this._textChunks; - for (let i = 0, n = textChunks.length; i < n; ++i) { - const subChunk = textChunks[i].subChunk; - const vertexArea = subChunk.vertexArea; - const vertexCount = vertexArea.size / 9; - const vertices = subChunk.chunk.vertices; - for (let j = 0, o = vertexArea.start + 5; j < vertexCount; ++j, o += 9) { - vertices[o] = r; - vertices[o + 1] = g; - vertices[o + 2] = b; - vertices[o + 3] = finalAlpha; - } - } - } - - private _updateLocalData(): void { - // @ts-ignore - const pixelsPerResolution = Engine._pixelsPerUnit / this._getRootCanvas().referenceResolutionPerUnit; - const { min, max } = this._localBounds; - const charRenderInfos = Text._charRenderInfos; - const charFont = this._getSubFont(); - const { size, pivot } = this._transformEntity.transform; - let rendererWidth = size.x; - let rendererHeight = size.y; - const offsetWidth = rendererWidth * (0.5 - pivot.x); - const offsetHeight = rendererHeight * (0.5 - pivot.y); - const textMetrics = this.enableWrapping - ? TextUtils.measureTextWithWrap( - this, - rendererWidth * pixelsPerResolution, - rendererHeight * pixelsPerResolution, - this._lineSpacing * pixelsPerResolution - ) - : TextUtils.measureTextWithoutWrap( - this, - rendererHeight * pixelsPerResolution, - this._lineSpacing * pixelsPerResolution - ); - const { height, lines, lineWidths, lineHeight, lineMaxSizes } = textMetrics; - // @ts-ignore - const charRenderInfoPool = this.engine._charRenderInfoPool; - const linesLen = lines.length; - let renderElementCount = 0; - - if (linesLen > 0) { - const { horizontalAlignment } = this; - const pixelsPerUnitReciprocal = 1.0 / pixelsPerResolution; - rendererWidth *= pixelsPerResolution; - rendererHeight *= pixelsPerResolution; - const halfRendererWidth = rendererWidth * 0.5; - const halfLineHeight = lineHeight * 0.5; - - let startY = 0; - const topDiff = lineHeight * 0.5 - lineMaxSizes[0].ascent; - const bottomDiff = lineHeight * 0.5 - lineMaxSizes[linesLen - 1].descent - 1; - switch (this.verticalAlignment) { - case TextVerticalAlignment.Top: - startY = rendererHeight * 0.5 - halfLineHeight + topDiff; - break; - case TextVerticalAlignment.Center: - startY = height * 0.5 - halfLineHeight - (bottomDiff - topDiff) * 0.5; - break; - case TextVerticalAlignment.Bottom: - startY = height - rendererHeight * 0.5 - halfLineHeight - bottomDiff; - break; - } - - let firstLine = -1; - let minX = Number.MAX_SAFE_INTEGER; - let minY = Number.MAX_SAFE_INTEGER; - let maxX = Number.MIN_SAFE_INTEGER; - let maxY = Number.MIN_SAFE_INTEGER; - for (let i = 0; i < linesLen; ++i) { - const lineWidth = lineWidths[i]; - if (lineWidth > 0) { - const line = lines[i]; - let startX = 0; - let firstRow = -1; - if (firstLine < 0) { - firstLine = i; - } - switch (horizontalAlignment) { - case TextHorizontalAlignment.Left: - startX = -halfRendererWidth; - break; - case TextHorizontalAlignment.Center: - startX = -lineWidth * 0.5; - break; - case TextHorizontalAlignment.Right: - startX = halfRendererWidth - lineWidth; - break; - } - for (let j = 0, n = line.length; j < n; ++j) { - const char = line[j]; - const charInfo = charFont._getCharInfo(char); - if (charInfo.h > 0) { - firstRow < 0 && (firstRow = j); - const charRenderInfo = (charRenderInfos[renderElementCount++] = charRenderInfoPool.get()); - const { localPositions } = charRenderInfo; - charRenderInfo.texture = charFont._getTextureByIndex(charInfo.index); - charRenderInfo.uvs = charInfo.uvs; - const { w, ascent, descent } = charInfo; - const left = (startX + offsetWidth) * pixelsPerUnitReciprocal; - const right = (startX + w + offsetWidth) * pixelsPerUnitReciprocal; - const top = (startY + ascent + offsetHeight) * pixelsPerUnitReciprocal; - const bottom = (startY - descent + offsetHeight) * pixelsPerUnitReciprocal; - localPositions.set(left, top, right, bottom); - i === firstLine && (maxY = Math.max(maxY, top)); - minY = Math.min(minY, bottom); - j === firstRow && (minX = Math.min(minX, left)); - maxX = Math.max(maxX, right); - } - startX += charInfo.xAdvance + charInfo.offsetX; - } - } - startY -= lineHeight; - } - if (firstLine < 0) { - min.set(0, 0, 0); - max.set(0, 0, 0); - } else { - min.set(minX, minY, 0); - max.set(maxX, maxY, 0); - } - } else { - min.set(0, 0, 0); - max.set(0, 0, 0); - } - - charFont._getLastIndex() > 0 && - charRenderInfos.sort((a, b) => { - return a.texture.instanceId - b.texture.instanceId; - }); - - this._freeTextChunks(); - - if (renderElementCount === 0) { - return; - } - - const textChunks = this._textChunks; - let curTextChunk = new TextChunk(); - textChunks.push(curTextChunk); - - const chunkMaxVertexCount = this._getChunkManager().maxVertexCount; - const curCharRenderInfo = charRenderInfos[0]; - let curTexture = curCharRenderInfo.texture; - curTextChunk.texture = curTexture; - let curCharInfos = curTextChunk.charRenderInfos; - curCharInfos.push(curCharRenderInfo); - - for (let i = 1; i < renderElementCount; ++i) { - const charRenderInfo = charRenderInfos[i]; - const texture = charRenderInfo.texture; - if (curTexture !== texture || curCharInfos.length * 4 + 4 > chunkMaxVertexCount) { - this._buildChunk(curTextChunk, curCharInfos.length); - - curTextChunk = new TextChunk(); - textChunks.push(curTextChunk); - curTexture = texture; - curTextChunk.texture = texture; - curCharInfos = curTextChunk.charRenderInfos; - } - curCharInfos.push(charRenderInfo); - } - const charLength = curCharInfos.length; - if (charLength > 0) { - this._buildChunk(curTextChunk, charLength); - } - charRenderInfos.length = 0; - } - - @ignoreClone - protected override _onTransformChanged(type: number): void { - if (type & UITransformModifyFlags.Size || type & UITransformModifyFlags.Pivot) { - this._dirtyUpdateFlag |= DirtyFlag.LocalPositionBounds; - } - super._onTransformChanged(type); - this._setDirtyFlagTrue(DirtyFlag.WorldPosition); - } - - private _isTextNoVisible(): boolean { - const size = (this._transformEntity.transform).size; - return ( - this._text === "" || - this._fontSize === 0 || - (this.enableWrapping && size.x <= 0) || - (this.overflowMode === OverflowMode.Truncate && size.y <= 0) || - !this._getRootCanvas() - ); - } - - private _buildChunk(textChunk: TextChunk, count: number) { - const { r, g, b, a } = this.color; - const finalAlpha = a * this._getGlobalAlpha(); - const tempIndices = CharRenderInfo.triangles; - const tempIndicesLength = tempIndices.length; - const subChunk = (textChunk.subChunk = this._getChunkManager().allocateSubChunk(count * 4)); - const vertices = subChunk.chunk.vertices; - const indices = (subChunk.indices = []); - const charRenderInfos = textChunk.charRenderInfos; - for (let i = 0, ii = 0, io = 0, vo = subChunk.vertexArea.start + 3; i < count; ++i, io += 4) { - const charRenderInfo = charRenderInfos[i]; - charRenderInfo.indexInChunk = i; - - // Set indices - for (let j = 0; j < tempIndicesLength; ++j) { - indices[ii++] = tempIndices[j] + io; - } - - // Set uv and color for vertices - for (let j = 0; j < 4; ++j, vo += 9) { - const uv = charRenderInfo.uvs[j]; - uv.copyToArray(vertices, vo); - vertices[vo + 2] = r; - vertices[vo + 3] = g; - vertices[vo + 4] = b; - vertices[vo + 5] = finalAlpha; - } - } - - return subChunk; - } - - private _freeTextChunks(): void { - const textChunks = this._textChunks; - // @ts-ignore - const charRenderInfoPool = this.engine._charRenderInfoPool; - const manager = this._getChunkManager(); - for (let i = 0, n = textChunks.length; i < n; ++i) { - const textChunk = textChunks[i]; - const { charRenderInfos } = textChunk; - for (let j = 0, m = charRenderInfos.length; j < m; ++j) { - charRenderInfoPool.return(charRenderInfos[j]); - } - charRenderInfos.length = 0; - manager.freeSubChunk(textChunk.subChunk); - textChunk.subChunk = null; - textChunk.texture = null; - } - textChunks.length = 0; - } -} - -class TextChunk { - charRenderInfos = new Array(); - texture: Texture2D; - subChunk; -} - -/** - * @remarks Extends `UIRendererUpdateFlags`. - */ -enum DirtyFlag { - SubFont = 0x4, - LocalPositionBounds = 0x8, - WorldPosition = 0x10, - - // LocalPositionBounds | WorldPosition | WorldVolume - Position = 0x19, - Font = SubFont | Position -} diff --git a/packages/ui/src/component/index.ts b/packages/ui/src/component/index.ts deleted file mode 100644 index 1f8943126..000000000 --- a/packages/ui/src/component/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export { UICanvas } from "./UICanvas"; -export { UIGroup } from "./UIGroup"; -export { UIRenderer } from "./UIRenderer"; -export { UITransform } from "./UITransform"; -export { Button } from "./advanced/Button"; -export { Image } from "./advanced/Image"; -export { Text } from "./advanced/Text"; -export { ColorTransition } from "./interactive/transition/ColorTransition"; -export { ScaleTransition } from "./interactive/transition/ScaleTransition"; -export { SpriteTransition } from "./interactive/transition/SpriteTransition"; -export { Transition } from "./interactive/transition/Transition"; diff --git a/packages/ui/src/component/interactive/UIInteractive.ts b/packages/ui/src/component/interactive/UIInteractive.ts deleted file mode 100644 index d7c41ea18..000000000 --- a/packages/ui/src/component/interactive/UIInteractive.ts +++ /dev/null @@ -1,302 +0,0 @@ -import { Entity, EntityModifyFlags, Script, assignmentClone, ignoreClone } from "@galacean/engine"; -import { UIGroup } from "../.."; -import { Utils } from "../../Utils"; -import { IGroupAble } from "../../interface/IGroupAble"; -import { EntityUIModifyFlags, UICanvas } from "../UICanvas"; -import { GroupModifyFlags } from "../UIGroup"; -import { Transition } from "./transition/Transition"; - -/** - * Interactive component. - */ -export class UIInteractive extends Script implements IGroupAble { - private static _targetTempPath = new Array(); - - /** @internal */ - @ignoreClone - _rootCanvas: UICanvas; - /** @internal */ - @ignoreClone - _indexInRootCanvas: number = -1; - /** @internal */ - @ignoreClone - _isRootCanvasDirty: boolean = false; - /** @internal */ - @ignoreClone - _rootCanvasListeningEntities: Entity[] = []; - /** @internal */ - @ignoreClone - _group: UIGroup; - /** @internal */ - @ignoreClone - _indexInGroup: number = -1; - /** @internal */ - @ignoreClone - _isGroupDirty: boolean = false; - /** @internal */ - @ignoreClone - _groupListeningEntities: Entity[] = []; - - /** @internal */ - @ignoreClone - _globalInteractive: boolean = false; - /** @internal */ - @ignoreClone - _globalInteractiveDirty: boolean = false; - - @ignoreClone - protected _transitions: Transition[] = []; - @assignmentClone - protected _interactive: boolean = true; - @ignoreClone - protected _state: InteractiveState = InteractiveState.Normal; - - /** @todo Multi-touch points are not considered yet. */ - @ignoreClone - private _isPointerInside: boolean = false; - @ignoreClone - private _isPointerDragging: boolean = false; - - /** - * The transitions of this interactive. - */ - get transitions(): Readonly { - return this._transitions; - } - - /** - * Whether the interactive is enabled. - */ - get interactive() { - return this._interactive; - } - - set interactive(value: boolean) { - if (this._interactive !== value) { - this._interactive = value; - this._globalInteractiveDirty = true; - } - } - - /** - * @internal - */ - constructor(entity: Entity) { - super(entity); - this._groupListener = this._groupListener.bind(this); - this._rootCanvasListener = this._rootCanvasListener.bind(this); - } - - /** - * Add transition on this interactive. - * @param transition - The transition - */ - addTransition(transition: Transition): void { - const interactive = transition._interactive; - if (interactive !== this) { - interactive?.removeTransition(transition); - this._transitions.push(transition); - transition._interactive = this; - transition._setState(this._state, true); - } - } - - /** - * Remove a transition. - * @param shape - The transition. - */ - removeTransition(transition: Transition): void { - const transitions = this._transitions; - const lastOneIndex = transitions.length - 1; - for (let i = lastOneIndex; i >= 0; i--) { - if (transitions[i] === transition) { - i !== lastOneIndex && (transitions[i] = transitions[lastOneIndex]); - transitions.length = lastOneIndex; - transition._interactive = null; - break; - } - } - } - - /** - * Remove all transitions. - */ - clearTransitions(): void { - const transitions = this._transitions; - for (let i = 0, n = transitions.length; i < n; i++) { - transitions[i]._interactive = null; - } - transitions.length = 0; - } - - override onUpdate(deltaTime: number): void { - if (this._getGlobalInteractive()) { - const transitions = this._transitions; - for (let i = 0, n = transitions.length; i < n; i++) { - transitions[i]._onUpdate(deltaTime); - } - } - } - - override onPointerBeginDrag(): void { - this._isPointerDragging = true; - this._updateState(false); - } - - override onPointerEndDrag(): void { - this._isPointerDragging = false; - this._updateState(false); - } - - override onPointerEnter(): void { - this._isPointerInside = true; - this._updateState(false); - } - - override onPointerExit(): void { - this._isPointerInside = false; - this._updateState(false); - } - - override onDestroy(): void { - super.onDestroy(); - const transitions = this._transitions; - for (let i = transitions.length - 1; i >= 0; i--) { - transitions[i].destroy(); - } - } - - // @ts-ignore - override _cloneTo(target: UIInteractive, srcRoot: Entity, targetRoot: Entity): void { - const transitions = this._transitions; - for (let i = 0, n = transitions.length; i < n; i++) { - const srcTransition = transitions[i]; - const dstTransition = new (transitions[i].constructor as new () => Transition)(); - dstTransition.normal = srcTransition.normal; - dstTransition.pressed = srcTransition.pressed; - dstTransition.hover = srcTransition.hover; - dstTransition.disabled = srcTransition.disabled; - const transitionTarget = srcTransition.target; - if (transitionTarget) { - const paths = UIInteractive._targetTempPath; - // @ts-ignore - const success = Entity._getEntityHierarchyPath(srcRoot, transitionTarget.entity, paths); - dstTransition.target = success - ? // @ts-ignore - Entity._getEntityByHierarchyPath(targetRoot, paths).getComponent(transitionTarget.constructor) - : transitionTarget; - } - target.addTransition(dstTransition); - } - } - - /** - * @internal - */ - _getRootCanvas(): UICanvas { - this._isRootCanvasDirty && Utils.setRootCanvas(this, Utils.searchRootCanvasInParents(this)); - return this._rootCanvas; - } - - /** - * @internal - */ - _getGroup(): UIGroup { - this._isGroupDirty && Utils.setGroup(this, Utils.searchGroupInParents(this)); - return this._group; - } - - // @ts-ignore - override _onEnableInScene(): void { - // @ts-ignore - super._onEnableInScene(); - Utils.setRootCanvasDirty(this); - Utils.setGroupDirty(this); - this._updateState(true); - } - - // @ts-ignore - override _onDisableInScene(): void { - // @ts-ignore - super._onDisableInScene(); - Utils.cleanRootCanvas(this); - Utils.cleanGroup(this); - this._isPointerInside = this._isPointerDragging = false; - } - - /** - * @internal - */ - @ignoreClone - _groupListener(flag: number): void { - if (flag === EntityModifyFlags.Parent || flag === EntityUIModifyFlags.GroupEnableInScene) { - Utils.setGroupDirty(this); - } - } - - /** - * @internal - */ - @ignoreClone - _rootCanvasListener(flag: number): void { - if (flag === EntityModifyFlags.Parent || flag === EntityUIModifyFlags.CanvasEnableInScene) { - Utils.setRootCanvasDirty(this); - Utils.setGroupDirty(this); - } - } - - /** - * @internal - */ - @ignoreClone - _onGroupModify(flags: GroupModifyFlags): void { - if (flags & GroupModifyFlags.GlobalInteractive) { - this._globalInteractiveDirty = true; - } - } - - /** - * @internal - */ - _getGlobalInteractive(): boolean { - if (this._globalInteractiveDirty) { - const group = this._getGroup(); - const globalInteractive = this._interactive && (!group || group._getGlobalInteractive()); - if (this._globalInteractive !== globalInteractive) { - this._globalInteractive = globalInteractive; - this._updateState(true); - } - this._globalInteractiveDirty = false; - } - return this._globalInteractive; - } - - private _updateState(instant: boolean): void { - const state = this._getInteractiveState(); - if (this._state !== state) { - this._state = state; - const transitions = this._transitions; - for (let i = 0, n = transitions.length; i < n; i++) { - transitions[i]._setState(state, instant); - } - } - } - - private _getInteractiveState(): InteractiveState { - if (!this._getGlobalInteractive()) { - return InteractiveState.Disable; - } - if (this._isPointerDragging) { - return InteractiveState.Pressed; - } else { - return this._isPointerInside ? InteractiveState.Hover : InteractiveState.Normal; - } - } -} - -export enum InteractiveState { - Normal, - Pressed, - Hover, - Disable -} diff --git a/packages/ui/src/component/interactive/transition/ColorTransition.ts b/packages/ui/src/component/interactive/transition/ColorTransition.ts deleted file mode 100644 index d32a02d26..000000000 --- a/packages/ui/src/component/interactive/transition/ColorTransition.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Color } from "@galacean/engine"; -import { UIRenderer } from "../../UIRenderer"; -import { InteractiveState } from "../UIInteractive"; -import { Transition } from "./Transition"; - -/** - * Color transition. - */ -export class ColorTransition extends Transition { - private _color: Color = new Color(); - constructor() { - super(); - this._normal = new Color(1, 1, 1, 1); - this._hover = new Color(0.9130986517934192, 0.9130986517934192, 0.9130986517934192, 1); - this._pressed = new Color(0.5775804404296506, 0.5775804404296506, 0.5775804404296506, 1); - this._disabled = new Color(0.5775804404296506, 0.5775804404296506, 0.5775804404296506, 1); - this._duration = 0.1; - this._currentValue = new Color(); - - this._onNormalValueChanged = this._onNormalValueChanged.bind(this); - this._onHoverValueChanged = this._onHoverValueChanged.bind(this); - this._onPressedValueChanged = this._onPressedValueChanged.bind(this); - this._onDisabledValueChanged = this._onDisabledValueChanged.bind(this); - - // @ts-ignore - this._normal._onValueChanged = this._onNormalValueChanged; - // @ts-ignore - this._hover._onValueChanged = this._onHoverValueChanged; - // @ts-ignore - this._pressed._onValueChanged = this._onPressedValueChanged; - // @ts-ignore - this._disabled._onValueChanged = this._onDisabledValueChanged; - } - - private _onNormalValueChanged(): void { - if (this._finalState === InteractiveState.Normal) { - this._finalValue = this._normal; - this._updateValue(); - } - } - - private _onHoverValueChanged(): void { - if (this._finalState === InteractiveState.Hover) { - this._finalValue = this._hover; - this._updateValue(); - } - } - - private _onPressedValueChanged(): void { - if (this._finalState === InteractiveState.Pressed) { - this._finalValue = this._pressed; - this._updateValue(); - } - } - - private _onDisabledValueChanged(): void { - if (this._finalState === InteractiveState.Disable) { - this._finalValue = this._disabled; - this._updateValue(); - } - } - - protected _getTargetValueCopy(): Color { - const color = this._color; - color.copyFrom(this._target?.color || this._normal); - return color; - } - - protected override _updateCurrentValue(srcValue: Color, destValue: Color, weight: number): void { - if (weight >= 1) { - this._currentValue.copyFrom(destValue); - } else { - Color.lerp(srcValue, destValue, weight, this._currentValue); - } - } - - protected override _applyValue(value: Color): void { - this._target.color = value; - } -} diff --git a/packages/ui/src/component/interactive/transition/ScaleTransition.ts b/packages/ui/src/component/interactive/transition/ScaleTransition.ts deleted file mode 100644 index d805e8ed1..000000000 --- a/packages/ui/src/component/interactive/transition/ScaleTransition.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { UIRenderer } from "../../UIRenderer"; -import { Transition } from "./Transition"; - -/** - * Scale transition. - */ -export class ScaleTransition extends Transition { - constructor() { - super(); - this._normal = 1; - this._hover = 1; - this._pressed = 1.2; - this._disabled = 1; - this._duration = 0.1; - } - - protected _getTargetValueCopy(): number { - return this._target?.entity.transform.scale.x || this._normal; - } - - protected override _updateCurrentValue(srcValue: number, destValue: number, weight: number): void { - this._currentValue = weight >= 1 ? destValue : (destValue - srcValue) * weight + srcValue; - } - - protected override _applyValue(value: number): void { - this._target.entity.transform.setScale(value, value, value); - } -} diff --git a/packages/ui/src/component/interactive/transition/SpriteTransition.ts b/packages/ui/src/component/interactive/transition/SpriteTransition.ts deleted file mode 100644 index 4a20c1bc1..000000000 --- a/packages/ui/src/component/interactive/transition/SpriteTransition.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Sprite } from "@galacean/engine"; -import { Image } from "../../advanced/Image"; -import { Transition } from "./Transition"; - -/** - * Sprite transition. - */ -export class SpriteTransition extends Transition { - /** - * @internal - */ - override destroy(): void { - super.destroy(); - if (this._normal) { - // @ts-ignore - this._normal._addReferCount(-1); - this._normal = null; - } - if (this._hover) { - // @ts-ignore - this._hover._addReferCount(-1); - this._hover = null; - } - if (this._pressed) { - // @ts-ignore - this._pressed._addReferCount(-1); - this._pressed = null; - } - if (this._disabled) { - // @ts-ignore - this._disabled._addReferCount(-1); - this._disabled = null; - } - this._initialValue = this._currentValue = this._finalValue = null; - this._target = null; - } - - protected _getTargetValueCopy(): Sprite { - return this._target?.sprite; - } - - protected override _updateCurrentValue(srcValue: Sprite, destValue: Sprite, weight: number): void { - this._currentValue = weight >= 1 ? destValue : srcValue; - } - - protected override _applyValue(value: Sprite): void { - this._target.sprite = value; - } -} diff --git a/packages/ui/src/component/interactive/transition/Transition.ts b/packages/ui/src/component/interactive/transition/Transition.ts deleted file mode 100644 index 5dd461e61..000000000 --- a/packages/ui/src/component/interactive/transition/Transition.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { Color, ReferResource, Sprite } from "@galacean/engine"; -import { UIRenderer } from "../../UIRenderer"; -import { InteractiveState, UIInteractive } from "../UIInteractive"; - -/** - * The transition behavior of UIInteractive. - */ -export abstract class Transition< - T extends TransitionValueType = TransitionValueType, - K extends UIRenderer = UIRenderer -> { - /** @internal */ - _interactive: UIInteractive; - - protected _target: K; - protected _normal: T; - protected _pressed: T; - protected _hover: T; - protected _disabled: T; - protected _duration: number = 0; - protected _countDown: number = 0; - protected _initialValue: T; - protected _finalValue: T; - protected _currentValue: T; - protected _finalState: InteractiveState = InteractiveState.Normal; - - /** - * The normal state of the transition. - */ - get normal(): T { - return this._normal; - } - - set normal(value: T) { - const preNormal = this._normal; - if (preNormal !== value) { - this._normal = value; - this._onStateValueDirty(InteractiveState.Normal, preNormal, value); - } - } - - /** - * The pressed state of the transition. - */ - get pressed(): T { - return this._pressed; - } - - set pressed(value: T) { - const prePressed = this._pressed; - if (prePressed !== value) { - this._pressed = value; - this._onStateValueDirty(InteractiveState.Pressed, prePressed, value); - } - } - - /** - * The hover state of the transition. - */ - get hover(): T { - return this._hover; - } - - set hover(value: T) { - const preHover = this._hover; - if (preHover !== value) { - this._hover = value; - this._onStateValueDirty(InteractiveState.Hover, preHover, value); - } - } - - /** - * The disabled state of the transition. - */ - get disabled(): T { - return this._disabled; - } - - set disabled(value: T) { - const preDisabled = this._disabled; - if (preDisabled !== value) { - this._disabled = value; - this._onStateValueDirty(InteractiveState.Disable, preDisabled, value); - } - } - - /** - * The target of the transition. - */ - get target(): K { - return this._target; - } - - set target(value: K) { - if (this._target !== value) { - this._target = value; - value?.enabled && this._applyValue(this._currentValue); - } - } - - /** - * The duration of the transition. - */ - get duration(): number { - return this._duration; - } - - set duration(value: number) { - if (value < 0) value = 0; - const preDuration = this._duration; - if (preDuration !== value) { - this._duration = value; - if (this._countDown > 0) { - this._countDown = value * (1 - this._countDown / preDuration); - this._updateValue(); - } - } - } - - destroy(): void { - this._interactive?.removeTransition(this); - this._target = null; - } - - /** - * @internal - */ - _setState(state: InteractiveState, instant: boolean) { - this._finalState = state; - const value = this._getValueByState(state); - if (instant) { - this._countDown = 0; - this._initialValue = this._finalValue = value; - } else { - this._countDown = this._duration; - this._initialValue = this._getTargetValueCopy(); - this._finalValue = value; - } - this._updateValue(); - } - - /** - * @internal - */ - _onUpdate(delta: number): void { - if (this._countDown > 0) { - this._countDown -= delta; - this._updateValue(); - } - } - - protected abstract _getTargetValueCopy(): T; - protected abstract _updateCurrentValue(srcValue: T, destValue: T, weight: number): void; - protected abstract _applyValue(value: T): void; - - protected _onStateValueDirty(state: InteractiveState, preValue: T, curValue: T): void { - // @ts-ignore - preValue instanceof ReferResource && preValue._addReferCount(-1); - // @ts-ignore - curValue instanceof ReferResource && curValue._addReferCount(1); - if (this._finalState === state) { - this._finalValue = curValue; - this._updateValue(); - } - } - - protected _updateValue() { - const weight = this._duration ? 1 - this._countDown / this._duration : 1; - this._updateCurrentValue(this._initialValue, this._finalValue, weight); - this._target?.enabled && this._applyValue(this._currentValue); - } - - private _getValueByState(state: InteractiveState): T { - switch (state) { - case InteractiveState.Normal: - return this.normal; - case InteractiveState.Pressed: - return this.pressed; - case InteractiveState.Hover: - return this.hover; - case InteractiveState.Disable: - return this.disabled; - } - } -} - -export type TransitionValueType = number | Sprite | Color; diff --git a/packages/ui/src/enums/CanvasRenderMode.ts b/packages/ui/src/enums/CanvasRenderMode.ts deleted file mode 100644 index 4379d355d..000000000 --- a/packages/ui/src/enums/CanvasRenderMode.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Render mode for ui canvas. - */ -export enum CanvasRenderMode { - /** - * The UI canvas will be rendered directly onto the screen and adapted to screen space, - * overlaying other rendering elements in the same scene. - * @remarks if the `engine.canvas` size change, the UI canvas will automatically adapt. - */ - ScreenSpaceOverlay = 0, - /** - * The UI canvas is placed at a specified distance in front of the camera and adapted to screen space, - * with all objects rendered by the camera. - * @remarks if the camera's properties or the `engine.canvas` size change, the UI canvas will automatically adapt. - * @remarks if set `ScreenSpaceCamera` but no corresponding camera is assigned, the actual rendering mode defaults to `ScreenSpaceOverlay`. - */ - ScreenSpaceCamera = 1, - /** - * The UI canvas is placed in the 3D world space and rendered by every camera in the same scene. - */ - WorldSpace = 2 -} diff --git a/packages/ui/src/enums/HorizontalAlignmentMode.ts b/packages/ui/src/enums/HorizontalAlignmentMode.ts deleted file mode 100644 index ba86ff0cc..000000000 --- a/packages/ui/src/enums/HorizontalAlignmentMode.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** Horizontal alignment mode. */ -export enum HorizontalAlignmentMode { - /** No horizontal alignment. */ - None = 0, - /** Left-aligned, `alignLeft` drives `position.x`. */ - Left = 0x1, - /** Right-aligned, `alignRight` drives `position.x`. */ - Right = 0x2, - /** Horizontal stretch, `alignLeft` and `alignRight` drive `position.x` and `size.x`. */ - LeftAndRight = 0x3, - /** Center-aligned, `alignCenter` drives `position.x`. */ - Center = 0x4 -} diff --git a/packages/ui/src/enums/ResolutionAdaptationMode.ts b/packages/ui/src/enums/ResolutionAdaptationMode.ts deleted file mode 100644 index c54771e22..000000000 --- a/packages/ui/src/enums/ResolutionAdaptationMode.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Resolution adaptation mode. - * @remarks Only effective in screen space. - */ -export enum ResolutionAdaptationMode { - /** Adapt based on width.(`referenceResolution.x`) */ - WidthAdaptation, - /** Adapt based on height.(`referenceResolution.y`) */ - HeightAdaptation, - /** Adapt based on both width and height.(`referenceResolution`) */ - BothAdaptation, - /** Adapt to the side with a larger ratio. */ - ExpandAdaptation, - /** Adapt to the side with smaller ratio. */ - ShrinkAdaptation -} diff --git a/packages/ui/src/enums/VerticalAlignmentMode.ts b/packages/ui/src/enums/VerticalAlignmentMode.ts deleted file mode 100644 index 77a9af597..000000000 --- a/packages/ui/src/enums/VerticalAlignmentMode.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** Vertical alignment mode. */ -export enum VerticalAlignmentMode { - /** No vertical alignment. */ - None = 0, - /** Top-aligned, `alignTop` drives `position.y`. */ - Top = 0x1, - /** Bottom-aligned, `alignBottom` drives `position.y`. */ - Bottom = 0x2, - /** Vertical stretch, `alignTop` and `alignBottom` drive `position.y` and `size.y`. */ - TopAndBottom = 0x3, - /** Middle-aligned, `alignMiddle` drives `position.y`. */ - Middle = 0x4 -} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts deleted file mode 100644 index 305d5446a..000000000 --- a/packages/ui/src/index.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { - BlendFactor, - BlendOperation, - CullMode, - Engine, - Entity, - Font, - IClass, - Loader, - Material, - PipelineStage, - ReflectionParser, - RenderQueueType, - Shader, - ShaderPass -} from "@galacean/engine"; -import * as GUIComponent from "./component"; -import uiDefaultFs from "./shader/uiDefault.fs.glsl"; -import uiDefaultVs from "./shader/uiDefault.vs.glsl"; -export * from "./component"; -export { CanvasRenderMode } from "./enums/CanvasRenderMode"; -export { ResolutionAdaptationMode } from "./enums/ResolutionAdaptationMode"; -export { UIPointerEventEmitter } from "./input/UIPointerEventEmitter"; -export { HorizontalAlignmentMode } from "./enums/HorizontalAlignmentMode"; -export { VerticalAlignmentMode } from "./enums/VerticalAlignmentMode"; - -export class EngineExtension { - _uiDefaultMaterial: Material; - _getUIDefaultMaterial(): Material { - if (!this._uiDefaultMaterial) { - const shader = _getOrCreateUIShader(); - // @ts-ignore - const material = new Material(this, shader); - const renderState = material.renderState; - const target = renderState.blendState.targetBlendState; - target.enabled = true; - target.sourceColorBlendFactor = BlendFactor.SourceAlpha; - target.destinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha; - target.sourceAlphaBlendFactor = BlendFactor.One; - target.destinationAlphaBlendFactor = BlendFactor.OneMinusSourceAlpha; - target.colorBlendOperation = target.alphaBlendOperation = BlendOperation.Add; - renderState.depthState.writeEnabled = false; - renderState.rasterState.cullMode = CullMode.Off; - renderState.renderQueueType = RenderQueueType.Transparent; - material.isGCIgnored = true; - this._uiDefaultMaterial = material; - } - return this._uiDefaultMaterial; - } -} - -export class EntityExtension { - _uiHierarchyVersion = 0; - _updateUIHierarchyVersion(version: number): void { - if (this._uiHierarchyVersion !== version) { - this._uiHierarchyVersion = version; - // @ts-ignore - this.parent?._updateUIHierarchyVersion(version); - } - } -} - -declare module "@galacean/engine" { - interface Engine { - // @internal - _uiDefaultMaterial: Material; - // @internal - _getUIDefaultMaterial(): Material; - } - interface Entity { - // @internal - _uiHierarchyVersion: number; - // @internal - _updateUIHierarchyVersion(version: number): void; - } -} - -function ApplyMixins(derivedCtor: any, baseCtors: any[]): void { - baseCtors.forEach((baseCtor) => { - Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { - Object.defineProperty( - derivedCtor.prototype, - name, - Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null) - ); - }); - }); -} - -ApplyMixins(Engine, [EngineExtension]); -ApplyMixins(Entity, [EntityExtension]); - -ReflectionParser.registerCustomParseComponent("Text", async (instance: any, item: Omit) => { - const { props } = item; - if (!props.font) { - // @ts-ignore - instance.font = Font.createFromOS(instance.engine, props.fontFamily || "Arial"); - } - return instance; -}); - -/** - * Register GUI components for the editor. - */ -export function registerGUI() { - for (let key in GUIComponent) { - Loader.registerClass(key, GUIComponent[key]); - } - _getOrCreateUIShader(); -} - -function _getOrCreateUIShader(): Shader { - let shader = Shader.find("ui"); - if (!shader) { - shader = Shader.create("ui", [ - new ShaderPass("Forward", uiDefaultVs, uiDefaultFs, { - pipelineStage: PipelineStage.Forward - }) - ]); - } - return shader; -} diff --git a/packages/ui/src/input/UIHitResult.ts b/packages/ui/src/input/UIHitResult.ts deleted file mode 100644 index dc55dad04..000000000 --- a/packages/ui/src/input/UIHitResult.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Entity, Vector3 } from "@galacean/engine"; -import { UIRenderer } from "../component/UIRenderer"; - -/** - * @internal - */ -export class UIHitResult { - entity: Entity = null; - distance: number = 0; - point: Vector3 = new Vector3(); - normal: Vector3 = new Vector3(); - component: UIRenderer = null; -} diff --git a/packages/ui/src/input/UIPointerEventEmitter.ts b/packages/ui/src/input/UIPointerEventEmitter.ts deleted file mode 100644 index 936e28ff4..000000000 --- a/packages/ui/src/input/UIPointerEventEmitter.ts +++ /dev/null @@ -1,266 +0,0 @@ -import { - CameraClearFlags, - DisorderedArray, - Entity, - Pointer, - PointerEventData, - PointerEventEmitter, - Scene, - registerPointerEventEmitter -} from "@galacean/engine"; -import { UICanvas } from ".."; -import { UIRenderer } from "../component/UIRenderer"; -import { UIHitResult } from "./UIHitResult"; - -/** - * @internal - */ -@registerPointerEventEmitter() -export class UIPointerEventEmitter extends PointerEventEmitter { - private static _MAX_PATH_DEPTH = 2048; - private static _tempSet: Set = new Set(); - private static _path: Entity[] = []; - private static _tempArray0: Entity[] = []; - private static _tempArray1: Entity[] = []; - - private _enteredPath: Entity[] = []; - private _pressedPath: Entity[] = []; - private _draggedPath: Entity[] = []; - - _init(): void { - this._hitResult = new UIHitResult(); - } - - override processRaycast(scenes: readonly Scene[], pointer: Pointer): void { - const { _tempRay: ray } = PointerEventEmitter; - const hitResult = this._hitResult; - const { position } = pointer; - const { x, y } = position; - for (let i = scenes.length - 1; i >= 0; i--) { - const scene = scenes[i]; - if (!scene.isActive || scene.destroyed) continue; - // @ts-ignore - const componentsManager = scene._componentsManager; - // Overlay Canvas - let canvasElements: DisorderedArray = componentsManager._overlayCanvases; - // Screen to world ( Assume that world units have a one-to-one relationship with pixel units ) - ray.origin.set(position.x, scene.engine.canvas.height - position.y, 1); - ray.direction.set(0, 0, -1); - for (let j = canvasElements.length - 1; j >= 0; j--) { - if (canvasElements.get(j)._raycast(ray, hitResult)) { - this._updateRaycast((hitResult).component, pointer); - return; - } - } - - const cameras = componentsManager._activeCameras; - for (let j = cameras.length - 1; j >= 0; j--) { - const camera = cameras.get(j); - if (camera.renderTarget) continue; - const { pixelViewport } = camera; - if ( - x < pixelViewport.x || - y < pixelViewport.y || - x > pixelViewport.x + pixelViewport.width || - y > pixelViewport.y + pixelViewport.height - ) { - continue; - } - camera.screenPointToRay(pointer.position, ray); - - // Other canvases - const isOrthographic = camera.isOrthographic; - const { worldPosition: cameraPosition, worldForward: cameraForward } = camera.entity.transform; - // Sort by rendering order - canvasElements = componentsManager._canvases; - for (let k = 0, n = canvasElements.length; k < n; k++) { - canvasElements.get(k)._updateSortDistance(isOrthographic, cameraPosition, cameraForward); - } - canvasElements.sort((a, b) => a.sortOrder - b.sortOrder || a._sortDistance - b._sortDistance); - for (let k = 0, n = canvasElements.length; k < n; k++) { - canvasElements.get(k)._canvasIndex = k; - } - const farClipPlane = camera.farClipPlane; - // Post-rendering first detection - for (let k = 0, n = canvasElements.length; k < n; k++) { - const canvas = canvasElements.get(k); - if (!canvas._canRender(camera)) continue; - if (canvas._raycast(ray, hitResult, farClipPlane)) { - this._updateRaycast((hitResult).component, pointer); - return; - } - } - if (camera.clearFlags & CameraClearFlags.Color) { - this._updateRaycast(null); - return; - } - } - this._updateRaycast(null); - } - } - - override processDrag(pointer: Pointer): void { - const draggedPath = this._draggedPath; - if (draggedPath.length > 0) { - this._bubble(draggedPath, pointer, this._fireDrag); - } - } - - override processDown(pointer: Pointer): void { - const enteredPath = this._enteredPath; - const pressedPath = this._pressedPath; - const draggedPath = this._draggedPath; - const length = (draggedPath.length = pressedPath.length = enteredPath.length); - if (length > 0) { - for (let i = 0; i < length; i++) { - pressedPath[i] = draggedPath[i] = enteredPath[i]; - } - this._bubble(pressedPath, pointer, this._fireDown); - this._bubble(draggedPath, pointer, this._fireBeginDrag); - } - } - - override processUp(pointer: Pointer): void { - const enteredPath = this._enteredPath; - const pressedPath = this._pressedPath; - if (enteredPath.length > 0) { - this._bubble(enteredPath, pointer, this._fireUp); - if (pressedPath.length > 0) { - const common = UIPointerEventEmitter._tempArray0; - if (this._findCommonInPath(enteredPath, pressedPath, common)) { - const eventData = this._createEventData(pointer); - for (let i = 0, n = common.length; i < n; i++) { - this._fireClick(common[i], eventData); - } - common.length = 0; - } - } - } - - pressedPath.length = 0; - - const draggedPath = this._draggedPath; - if (draggedPath.length > 0) { - this._bubble(draggedPath, pointer, this._fireEndDrag); - draggedPath.length = 0; - } - - if (enteredPath.length > 0) { - this._bubble(enteredPath, pointer, this._fireDrop); - } - } - - override processLeave(pointer: Pointer): void { - const enteredPath = this._enteredPath; - if (enteredPath.length > 0) { - this._bubble(enteredPath, pointer, this._fireExit); - enteredPath.length = 0; - } - - const draggedPath = this._draggedPath; - if (draggedPath.length > 0) { - this._bubble(draggedPath, pointer, this._fireEndDrag); - draggedPath.length = 0; - } - - this._pressedPath.length = 0; - } - - override dispose(): void { - this._enteredPath.length = this._pressedPath.length = this._draggedPath.length = 0; - } - - private _updateRaycast(element: UIRenderer, pointer: Pointer = null): void { - const enteredPath = this._enteredPath; - const curPath = this._composedPath(element, UIPointerEventEmitter._path); - const add = UIPointerEventEmitter._tempArray0; - const del = UIPointerEventEmitter._tempArray1; - if (this._findDiffInPath(enteredPath, curPath, add, del)) { - const eventData = this._createEventData(pointer); - for (let i = 0, n = add.length; i < n; i++) { - this._fireEnter(add[i], eventData); - } - for (let i = 0, n = del.length; i < n; i++) { - this._fireExit(del[i], eventData); - } - - const length = (enteredPath.length = curPath.length); - for (let i = 0; i < length; i++) { - enteredPath[i] = curPath[i]; - } - add.length = del.length = 0; - } - curPath.length = 0; - } - - private _composedPath(element: UIRenderer, path: Entity[]): Entity[] { - if (!element) { - path.length = 0; - return path; - } - let entity = (path[0] = element.entity); - let i = 1; - const rootEntity = element._getRootCanvas().entity; - for (; i < UIPointerEventEmitter._MAX_PATH_DEPTH && !!entity && entity !== rootEntity; i++) { - entity = path[i] = entity.parent; - } - path.length = i; - return path; - } - - private _findCommonInPath(prePath: Entity[], curPath: Entity[], common: Entity[]): boolean { - const idSet = UIPointerEventEmitter._tempSet; - idSet.clear(); - for (let i = 0, n = prePath.length; i < n; i++) { - idSet.add(prePath[i].instanceId); - } - let hasCommon = false; - for (let i = 0, n = curPath.length; i < n; i++) { - const entity = curPath[i]; - if (idSet.has(entity.instanceId)) { - common.push(entity); - hasCommon = true; - } - } - return hasCommon; - } - - private _findDiffInPath(prePath: Entity[], curPath: Entity[], add: Entity[], del: Entity[]): boolean { - const idSet = UIPointerEventEmitter._tempSet; - idSet.clear(); - let changed = false; - for (let i = 0, n = prePath.length; i < n; i++) { - idSet.add(prePath[i].instanceId); - } - for (let i = 0, n = curPath.length; i < n; i++) { - const entity = curPath[i]; - if (!idSet.has(entity.instanceId)) { - add.push(entity); - changed = true; - } - } - idSet.clear(); - for (let i = 0, n = curPath.length; i < n; i++) { - idSet.add(curPath[i].instanceId); - } - for (let i = 0, n = prePath.length; i < n; i++) { - const entity = prePath[i]; - if (!idSet.has(entity.instanceId)) { - del.push(entity); - changed = true; - } - } - return changed; - } - - private _bubble(path: Entity[], pointer: Pointer, fireEvent: FireEvent): void { - const length = path.length; - if (length <= 0) return; - const eventData = this._createEventData(pointer); - for (let i = 0; i < length; i++) { - fireEvent(path[i], eventData); - } - } -} - -type FireEvent = (entity: Entity, eventData: PointerEventData) => void; diff --git a/packages/ui/src/interface/IElement.ts b/packages/ui/src/interface/IElement.ts deleted file mode 100644 index 2e85507cc..000000000 --- a/packages/ui/src/interface/IElement.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Entity } from "@galacean/engine"; -import { UICanvas } from ".."; -import { RootCanvasModifyFlags } from "../component/UICanvas"; - -export interface IElement { - entity: Entity; - _rootCanvas: UICanvas; - _indexInRootCanvas: number; - _rootCanvasListeningEntities: Entity[]; - _isRootCanvasDirty: boolean; - - _getRootCanvas(): UICanvas; - _rootCanvasListener: (flag: number, param?: any) => void; - _onRootCanvasModify?(flag: RootCanvasModifyFlags): void; -} diff --git a/packages/ui/src/interface/IGraphics.ts b/packages/ui/src/interface/IGraphics.ts deleted file mode 100644 index 8bdeda2a0..000000000 --- a/packages/ui/src/interface/IGraphics.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Ray, Vector4 } from "@galacean/engine"; -import { UIHitResult } from "../input/UIHitResult"; -import { IGroupAble } from "./IGroupAble"; - -export interface IGraphics extends IGroupAble { - raycastEnabled: boolean; - raycastPadding: Vector4; - - _raycast(ray: Ray, out: UIHitResult, distance: number): boolean; -} diff --git a/packages/ui/src/interface/IGroupAble.ts b/packages/ui/src/interface/IGroupAble.ts deleted file mode 100644 index 0e6bfd292..000000000 --- a/packages/ui/src/interface/IGroupAble.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Entity } from "@galacean/engine"; -import { GroupModifyFlags, UIGroup } from "../component/UIGroup"; -import { IElement } from "./IElement"; - -export interface IGroupAble extends IElement { - _group: UIGroup; - _indexInGroup: number; - _groupListeningEntities: Entity[]; - _isGroupDirty: boolean; - - _globalAlpha?: number; - _globalInteractive?: boolean; - - _getGroup(): UIGroup; - _onGroupModify(flag: GroupModifyFlags, isPass?: boolean): void; - _groupListener(flag: number): void; -} diff --git a/packages/ui/src/shader/global.d.ts b/packages/ui/src/shader/global.d.ts deleted file mode 100644 index d0abf1234..000000000 --- a/packages/ui/src/shader/global.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare module "*.glsl" { - const value: string; - export default value; -} - -declare module "*.gs" { - const value: string; - export default value; -} diff --git a/packages/ui/src/shader/uiDefault.fs.glsl b/packages/ui/src/shader/uiDefault.fs.glsl deleted file mode 100644 index e4028405d..000000000 --- a/packages/ui/src/shader/uiDefault.fs.glsl +++ /dev/null @@ -1,14 +0,0 @@ -#include -uniform sampler2D renderer_UITexture; - -varying vec2 v_uv; -varying vec4 v_color; - -void main() { - vec4 baseColor = texture2DSRGB(renderer_UITexture, v_uv); - vec4 finalColor = baseColor * v_color; - #ifdef ENGINE_SHOULD_SRGB_CORRECT - finalColor = outputSRGBCorrection(finalColor); - #endif - gl_FragColor = finalColor; -} \ No newline at end of file diff --git a/packages/ui/src/shader/uiDefault.vs.glsl b/packages/ui/src/shader/uiDefault.vs.glsl deleted file mode 100644 index 2a6b45be4..000000000 --- a/packages/ui/src/shader/uiDefault.vs.glsl +++ /dev/null @@ -1,15 +0,0 @@ -uniform mat4 renderer_MVPMat; - -attribute vec3 POSITION; -attribute vec2 TEXCOORD_0; -attribute vec4 COLOR_0; - -varying vec2 v_uv; -varying vec4 v_color; - -void main() { - gl_Position = renderer_MVPMat * vec4(POSITION, 1.0); - - v_uv = TEXCOORD_0; - v_color = COLOR_0; -} diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json deleted file mode 100644 index 588b0055c..000000000 --- a/packages/ui/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "target": "esnext", - "declaration": true, - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "experimentalDecorators": true, - "declarationDir": "types", - "emitDeclarationOnly": true, - "noImplicitOverride": true, - "sourceMap": true, - "incremental": false, - "skipLibCheck": true, - "stripInternal": true - }, - "include": ["src/**/*"] -} diff --git a/packages/xr-webxr/README.md b/packages/xr-webxr/README.md deleted file mode 100644 index 4cf3b5cff..000000000 --- a/packages/xr-webxr/README.md +++ /dev/null @@ -1,42 +0,0 @@ -## Installation - -`@galacean/engine-xr-webxr` is one of the implementation backends of xr. If your XR application interface is WebXR standard, please introduce this package. - -To install, use: - -```sh -npm install @galacean/engine-xr-webxr -``` - -This will allow you to import engine entirely using: - -```javascript -import { WebXRDevice } from "@galacean/engine-xr-webxr"; -import { XRHitTest, XRSessionMode } from "@galacean/engine-xr"; -``` - -## Usage - -```typescript -import { WebXRDevice } from "@galacean/engine-xr-webxr"; -import { XRHitTest, XRSessionMode } from "@galacean/engine-xr"; - -// Create engine by passing in the HTMLCanvasElement -WebGLEngine.create({ - canvas: "canvas", - xrDevice: new WebXRDevice(), -}).then((engine) => { - // Users need to actively click the button to enter XR - XRButton.onClick = function () { - this.engine.xrManager.enterXR(XRSessionMode.AR).then( - () => { - console.log("Enter AR"); - }, - (error) => { - console.log("Not supported AR", error); - } - ); - }; -}); -...... -``` diff --git a/packages/xr-webxr/package.json b/packages/xr-webxr/package.json deleted file mode 100644 index a0d1edd3e..000000000 --- a/packages/xr-webxr/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "@galacean/engine-xr-webxr", - "version": "0.0.0-experimental-backup.4", - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org" - }, - "repository": { - "url": "https://github.com/galacean/engine" - }, - "license": "MIT", - "main": "dist/main.js", - "module": "dist/module.js", - "debug": "src/index.ts", - "browser": "dist/browser.js", - "types": "types/index.d.ts", - "scripts": { - "b:types": "tsc" - }, - "umd": { - "name": "Galacean.WebXR", - "globals": { - "@galacean/engine": "Galacean" - } - }, - "files": [ - "dist/**/*", - "libs/**/*", - "types/**/*" - ], - "dependencies": { - "@galacean/engine-xr": "workspace:*" - }, - "devDependencies": { - "@galacean/engine-design": "workspace:*", - "@galacean/engine-math": "workspace:*" - }, - "peerDependencies": {} -} diff --git a/packages/xr-webxr/src/Util.ts b/packages/xr-webxr/src/Util.ts deleted file mode 100644 index bcb0d0ad9..000000000 --- a/packages/xr-webxr/src/Util.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { XRTrackedInputDevice } from "@galacean/engine-xr"; - -export function parseXRMode(mode: number): XRSessionMode | null { - switch (mode) { - case 1: - return "immersive-ar"; - case 2: - return "immersive-vr"; - default: - return null; - } -} - -export function getInputSource(inputSource: XRInputSource): XRTrackedInputDevice { - let type: number; - switch (inputSource.targetRayMode) { - case "gaze": - break; - case "screen": - return XRTrackedInputDevice.Controller; - case "tracked-pointer": - if (inputSource.hand) { - switch (inputSource.handedness) { - case "left": - return XRTrackedInputDevice.LeftHand; - case "right": - return XRTrackedInputDevice.RightHand; - } - } else { - switch (inputSource.handedness) { - case "left": - return XRTrackedInputDevice.LeftController; - case "right": - return XRTrackedInputDevice.RightController; - } - } - break; - default: - break; - } - return type; -} - -export function viewToCamera(type: XREye): XRTrackedInputDevice { - switch (type) { - case "left": - return XRTrackedInputDevice.LeftCamera; - case "right": - return XRTrackedInputDevice.RightCamera; - default: - return XRTrackedInputDevice.Camera; - } -} diff --git a/packages/xr-webxr/src/WebXRDevice.ts b/packages/xr-webxr/src/WebXRDevice.ts deleted file mode 100644 index 1ac64b30b..000000000 --- a/packages/xr-webxr/src/WebXRDevice.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { IHardwareRenderer, IXRDevice } from "@galacean/engine-design"; -import { XRFeatureType, XRSessionMode } from "@galacean/engine-xr"; -import { parseXRMode } from "./Util"; -import { WebXRSession } from "./WebXRSession"; -import { WebXRFeature } from "./feature/WebXRFeature"; - -export class WebXRDevice implements IXRDevice { - /** @internal */ - static _platformFeatureMap: PlatformFeatureConstructor[] = []; - - isSupportedSessionMode(mode: XRSessionMode): Promise { - return new Promise((resolve, reject: (reason: Error) => void) => { - if (!window.isSecureContext) { - reject(new Error("WebXR is available only in secure contexts (HTTPS).")); - return; - } - if (!navigator.xr) { - reject(new Error("WebXR isn't available")); - return; - } - navigator.xr.isSessionSupported(parseXRMode(mode)).then((isSupported: boolean) => { - isSupported ? resolve() : reject(new Error("The current context doesn't support WebXR.")); - }); - }); - } - - isSupportedFeature(type: XRFeatureType): boolean { - switch (type) { - case XRFeatureType.HitTest: - case XRFeatureType.PlaneTracking: - return typeof XRPlane !== "undefined"; - case XRFeatureType.AnchorTracking: - return typeof XRAnchor !== "undefined"; - case XRFeatureType.ImageTracking: - // @ts-ignore - return typeof XRImageTrackingResult !== "undefined"; - } - } - - createPlatformFeature(type: XRFeatureType, ...args: any[]): WebXRFeature { - const platformFeatureConstructor = WebXRDevice._platformFeatureMap[type]; - return platformFeatureConstructor ? new platformFeatureConstructor(...args) : null; - } - - requestSession(rhi: IHardwareRenderer, mode: XRSessionMode, platformFeatures: WebXRFeature[]): Promise { - return new Promise((resolve, reject) => { - const sessionMode = parseXRMode(mode); - const options: XRSessionInit = { requiredFeatures: ["local"], optionalFeatures: [] }; - const promiseArr = []; - for (let i = 0, n = platformFeatures.length; i < n; i++) { - const promise = platformFeatures[i]._assembleOptions(options); - promise && promiseArr.push(promise); - } - Promise.all(promiseArr).then(() => { - navigator.xr.requestSession(sessionMode, options).then((session) => { - const { gl } = rhi; - const attributes = gl.getContextAttributes(); - if (!attributes) { - reject(Error("GetContextAttributes Error!")); - } - gl.makeXRCompatible().then(() => { - const scaleFactor = XRWebGLLayer.getNativeFramebufferScaleFactor(session); - let layer: XRWebGLLayer; - if (session.renderState.layers === undefined || !!!rhi.isWebGL2) { - const layerInit = { - antialias: session.renderState.layers === undefined ? attributes.antialias : true, - alpha: true, - depth: attributes.depth, - stencil: attributes.stencil, - framebufferScaleFactor: scaleFactor - }; - layer = new XRWebGLLayer(session, gl, layerInit); - session.updateRenderState({ - baseLayer: layer - }); - } else { - layer = new XRWebGLLayer(session, gl); - session.updateRenderState({ - layers: [layer] - }); - } - session.requestReferenceSpace("local").then((referenceSpace: XRReferenceSpace) => { - resolve(new WebXRSession(session, layer, referenceSpace)); - }, reject); - }, reject); - }, reject); - }, reject); - }); - } -} - -type PlatformFeatureConstructor = new (...args: any[]) => WebXRFeature; -export function registerXRPlatformFeature(type: XRFeatureType) { - return (platformFeatureConstructor: PlatformFeatureConstructor) => { - WebXRDevice._platformFeatureMap[type] = platformFeatureConstructor; - }; -} diff --git a/packages/xr-webxr/src/WebXRFrame.ts b/packages/xr-webxr/src/WebXRFrame.ts deleted file mode 100644 index d6e7ce6c8..000000000 --- a/packages/xr-webxr/src/WebXRFrame.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { IXRCamera, IXRController, IXRFrame, IXRInput } from "@galacean/engine-design"; -import { Vector3 } from "@galacean/engine-math"; -import { XRTrackedInputDevice, XRTrackingState } from "@galacean/engine-xr"; -import { getInputSource, viewToCamera } from "./Util"; -import { WebXRSession } from "./WebXRSession"; - -export class WebXRFrame implements IXRFrame { - /** @internal */ - _platformFrame: XRFrame; - private _session: WebXRSession; - - updateInputs(inputs: IXRInput[]): void { - if (!this._platformFrame) return; - this._updateController(inputs); - this._updateCamera(inputs); - } - - private _updateController(inputs: IXRInput[]) { - const { _platformFrame: frame } = this; - const { _platformSession: session, _platformReferenceSpace: referenceSpace } = this._session; - const { inputSources } = session; - for (let i = 0, n = inputSources.length; i < n; i++) { - const inputSource = inputSources[i]; - const type = getInputSource(inputSource); - const input = inputs[type]; - switch (inputSource.targetRayMode) { - case "screen": - case "tracked-pointer": - const { gripSpace, targetRaySpace } = inputSource; - if (gripSpace) { - const { transform, emulatedPosition } = frame.getPose(gripSpace, referenceSpace); - if (transform) { - const { gripPose } = input; - gripPose.matrix.copyFromArray(transform.matrix); - gripPose.position.copyFrom(transform.position); - gripPose.rotation.copyFrom(transform.orientation); - } - input.trackingState = emulatedPosition ? XRTrackingState.TrackingLost : XRTrackingState.Tracking; - } - if (targetRaySpace) { - const { transform, emulatedPosition } = frame.getPose(targetRaySpace, referenceSpace); - if (transform) { - const { targetRayPose } = input; - targetRayPose.matrix.copyFromArray(transform.matrix); - targetRayPose.position.copyFrom(transform.position); - targetRayPose.rotation.copyFrom(transform.orientation); - input.trackingState = emulatedPosition ? XRTrackingState.TrackingLost : XRTrackingState.Tracking; - } - } - break; - case "gaze": - break; - default: - break; - } - } - } - - private _updateCamera(inputs: IXRInput[]) { - const { _platformFrame: frame } = this; - const { - _platformReferenceSpace: referenceSpace, - _platformLayer: layer, - framebufferWidth, - framebufferHeight - } = this._session; - const viewerPose = frame.getViewerPose(referenceSpace); - if (viewerPose) { - let hadUpdateCenterViewer = false; - const { views, emulatedPosition } = viewerPose; - for (let i = 0, n = views.length; i < n; i++) { - const view = views[i]; - const type = viewToCamera(view.eye); - const { transform } = views[i]; - if (type === XRTrackedInputDevice.Camera) { - hadUpdateCenterViewer ||= true; - } - const xrCamera = inputs[type]; - const { pose } = xrCamera; - pose.matrix.copyFromArray(transform.matrix); - pose.position.copyFrom(transform.position); - pose.rotation.copyFrom(transform.orientation); - xrCamera.projectionMatrix.copyFromArray(view.projectionMatrix); - xrCamera.trackingState = emulatedPosition ? XRTrackingState.TrackingLost : XRTrackingState.Tracking; - const xrViewport = layer.getViewport(view); - const width = xrViewport.width / framebufferWidth; - const height = xrViewport.height / framebufferHeight; - const x = xrViewport.x / framebufferWidth; - const y = 1 - xrViewport.y / framebufferHeight - height; - xrCamera.viewport.set(x, y, width, height); - } - - if (!hadUpdateCenterViewer) { - const leftCameraDevice = inputs[XRTrackedInputDevice.LeftCamera]; - const rightCameraDevice = inputs[XRTrackedInputDevice.RightCamera]; - const cameraDevice = inputs[XRTrackedInputDevice.Camera]; - const { pose: leftCameraPose } = leftCameraDevice; - const { pose: rightCameraPose } = rightCameraDevice; - const { pose: cameraPose } = cameraDevice; - cameraPose.rotation.copyFrom(leftCameraPose.rotation); - const { position, matrix } = cameraPose; - Vector3.add(leftCameraPose.position, rightCameraPose.position, position); - position.scale(0.5); - matrix.copyFrom(leftCameraPose.matrix); - const { elements } = matrix; - elements[12] = position.x; - elements[13] = position.y; - elements[14] = position.z; - cameraDevice.projectionMatrix.copyFrom(leftCameraDevice.projectionMatrix); - cameraDevice.trackingState = emulatedPosition ? XRTrackingState.TrackingLost : XRTrackingState.Tracking; - cameraDevice.viewport = - leftCameraDevice.viewport.width && leftCameraDevice.viewport.height - ? leftCameraDevice.viewport - : rightCameraDevice.viewport; - } - } - } - - constructor(session: WebXRSession) { - this._session = session; - } -} diff --git a/packages/xr-webxr/src/WebXRSession.ts b/packages/xr-webxr/src/WebXRSession.ts deleted file mode 100644 index a35fecb02..000000000 --- a/packages/xr-webxr/src/WebXRSession.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { IXRInputEvent, IXRSession } from "@galacean/engine-design"; -import { XRInputEventType, XRTargetRayMode, XRTrackedInputDevice } from "@galacean/engine-xr"; -import { getInputSource } from "./Util"; -import { WebXRFrame } from "./WebXRFrame"; - -export class WebXRSession implements IXRSession { - requestAnimationFrame: (callback: FrameRequestCallback) => number; - cancelAnimationFrame: (id: number) => void; - /** @internal */ - _onSessionExitCallBack: () => void; - - /** @internal */ - _platformSession: XRSession; - /** @internal */ - _platformLayer: XRWebGLLayer; - /** @internal */ - _platformReferenceSpace: XRReferenceSpace; - - private _frame: WebXRFrame; - private _events: IXRInputEvent[] = []; - private _screenPointers: XRInputSource[] = []; - private _inputEventTypeMap: Record = { - selectstart: XRInputEventType.SelectStart, - select: XRInputEventType.Select, - selectend: XRInputEventType.SelectEnd, - squeezestart: XRInputEventType.SqueezeStart, - squeeze: XRInputEventType.Squeeze, - squeezeend: XRInputEventType.SqueezeEnd - }; - private _targetRayModeMap: Record = { - gaze: XRTargetRayMode.Gaze, - "tracked-pointer": XRTargetRayMode.TrackedPointer, - screen: XRTargetRayMode.Screen - }; - - get frame(): WebXRFrame { - return this._frame; - } - - get framebuffer(): WebGLFramebuffer { - return this._platformLayer.framebuffer; - } - - get framebufferWidth(): number { - return this._platformLayer.framebufferWidth; - } - - get framebufferHeight(): number { - return this._platformLayer.framebufferHeight; - } - - get frameRate(): number { - return this._platformSession.frameRate; - } - - get supportedFrameRates(): Float32Array { - return this._platformSession.supportedFrameRates; - } - - get events(): IXRInputEvent[] { - const { _events: events } = this; - // Select event does not dispatch the move event, so we need to simulate dispatching the move here. - const { _screenPointers: screenPointers } = this; - for (let i = 0; i < screenPointers.length; i++) { - const inputSource = screenPointers[i]; - if (!inputSource) continue; - const { axes } = inputSource.gamepad; - const event = { - type: XRInputEventType.Select, - targetRayMode: XRTargetRayMode.Screen, - input: XRTrackedInputDevice.Controller, - id: i, - x: axes[0], - y: axes[1] - }; - events.push(event); - } - return events; - } - - constructor(session: XRSession, layer: XRWebGLLayer, referenceSpace: XRReferenceSpace) { - this._frame = new WebXRFrame(this); - this._platformSession = session; - this._platformLayer = layer; - this._platformReferenceSpace = referenceSpace; - const xrRequestAnimationFrame = session.requestAnimationFrame.bind(session); - const onFrame = function (time: number, frame: XRFrame, callback: FrameRequestCallback) { - this._frame._platformFrame = frame; - callback(time); - }.bind(this); - this.requestAnimationFrame = (callback: FrameRequestCallback) => { - return xrRequestAnimationFrame((time: number, frame: XRFrame) => { - onFrame(time, frame, callback); - }); - }; - this.cancelAnimationFrame = session.cancelAnimationFrame.bind(session); - this._onSessionEvent = this._onSessionEvent.bind(this); - this._onSessionExit = this._onSessionExit.bind(this); - } - - getFixedFoveation(): number { - return this._platformLayer.fixedFoveation; - } - - setFixedFoveation(value: number) { - this._platformLayer.fixedFoveation = value; - } - - start(): void {} - - stop(): void { - this._frame._platformFrame = null; - } - - end(): Promise { - this._frame._platformFrame = null; - return this._platformSession.end(); - } - - setSessionExitCallBack(onSessionExitCallBack: () => void): void { - this._onSessionExitCallBack = onSessionExitCallBack; - } - - addEventListener(): void { - const { _onSessionEvent: onSessionEvent, _platformSession: session } = this; - session.addEventListener("select", onSessionEvent); - session.addEventListener("selectstart", onSessionEvent); - session.addEventListener("selectend", onSessionEvent); - session.addEventListener("squeeze", onSessionEvent); - session.addEventListener("squeezestart", onSessionEvent); - session.addEventListener("squeezeend", onSessionEvent); - session.addEventListener("end", this._onSessionExit); - } - - removeEventListener(): void { - const { _onSessionEvent: onSessionEvent, _platformSession: session } = this; - session.removeEventListener("select", onSessionEvent); - session.removeEventListener("selectstart", onSessionEvent); - session.removeEventListener("selectend", onSessionEvent); - session.removeEventListener("squeeze", onSessionEvent); - session.removeEventListener("squeezestart", onSessionEvent); - session.removeEventListener("squeezeend", onSessionEvent); - session.removeEventListener("end", this._onSessionExit); - this._events.length = 0; - } - - resetEvents(): void { - this._events.length = 0; - } - - private _onSessionExit(): void { - if (this._onSessionExitCallBack) { - this._onSessionExitCallBack(); - this._onSessionExitCallBack = null; - } - } - - private _onSessionEvent(inputSourceEvent: XRInputSourceEvent): void { - const { inputSource } = inputSourceEvent; - const event: IXRInputEvent = { - type: this._inputEventTypeMap[inputSourceEvent.type], - input: getInputSource(inputSource), - targetRayMode: this._targetRayModeMap[inputSource.targetRayMode] - }; - if (event.targetRayMode === XRTargetRayMode.Screen) { - const { _screenPointers: screenPointers } = this; - const { axes } = inputSource.gamepad; - event.x = axes[0]; - event.y = axes[1]; - switch (event.type) { - case XRInputEventType.SelectStart: - let idx = -1; - let emptyIdx = -1; - for (let i = screenPointers.length - 1; i >= 0; i--) { - const pointer = screenPointers[i]; - if (pointer === inputSource) { - idx = i; - break; - } - if (!pointer) { - emptyIdx = i; - } - } - if (idx === -1) { - if (emptyIdx === -1) { - idx = screenPointers.push(inputSource) - 1; - } else { - idx = emptyIdx; - screenPointers[emptyIdx] = inputSource; - } - } - event.id = idx; - break; - case XRInputEventType.SelectEnd: - for (let i = screenPointers.length - 1; i >= 0; i--) { - if (screenPointers[i] === inputSource) { - screenPointers[i] = null; - event.id = i; - } - } - break; - default: - break; - } - } - this._events.push(event); - } -} diff --git a/packages/xr-webxr/src/feature/WebXRAnchorTracking.ts b/packages/xr-webxr/src/feature/WebXRAnchorTracking.ts deleted file mode 100644 index 96a472edf..000000000 --- a/packages/xr-webxr/src/feature/WebXRAnchorTracking.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { IXRRequestAnchor, IXRTracked } from "@galacean/engine-design"; -import { XRFeatureType, XRRequestTrackingState, XRTrackingState } from "@galacean/engine-xr"; -import { registerXRPlatformFeature } from "../WebXRDevice"; -import { WebXRFrame } from "../WebXRFrame"; -import { WebXRSession } from "../WebXRSession"; -import { WebXRTrackableFeature } from "./WebXRTrackableFeature"; -/** - * WebXR implementation of XRPlatformAnchorTracking. - */ -@registerXRPlatformFeature(XRFeatureType.AnchorTracking) -export class WebXRAnchorTracking extends WebXRTrackableFeature { - checkAvailable(session: WebXRSession, frame: WebXRFrame, requestTrackings: IWebXRRequestTrackingAnchor[]): boolean { - if (!frame._platformFrame) return false; - for (let i = 0, n = requestTrackings.length; i < n; i++) { - const requestTracking = requestTrackings[i]; - if (requestTracking.state === XRRequestTrackingState.None) { - this._addAnchor(session, frame, requestTracking); - } - } - return true; - } - - getTrackedResult(session: WebXRSession, frame: WebXRFrame, requestTrackings: IWebXRRequestTrackingAnchor[]): void { - const { _platformReferenceSpace: platformReferenceSpace } = session; - const { _platformFrame: platformFrame } = frame; - const { trackedAnchors } = platformFrame; - for (let i = 0, n = requestTrackings.length; i < n; i++) { - const requestTracking = requestTrackings[i]; - if (requestTracking.state !== XRRequestTrackingState.Resolved) continue; - const tracked = requestTracking.tracked[0]; - if (trackedAnchors.has(requestTracking.xrAnchor)) { - const emulated = this._updateTrackedAnchor(platformFrame, platformReferenceSpace, requestTracking); - if (emulated) { - if (tracked.state === XRTrackingState.Tracking) { - tracked.state = XRTrackingState.TrackingLost; - } - } else { - tracked.state = XRTrackingState.Tracking; - } - } else { - tracked.state = XRTrackingState.NotTracking; - } - } - } - - override get canModifyRequestTrackingAfterInit(): boolean { - return true; - } - - override onDelRequestTracking(requestTracking: IWebXRRequestTrackingAnchor): void { - switch (requestTracking.state) { - case XRRequestTrackingState.Submitted: - requestTracking.state = XRRequestTrackingState.WaitingDestroy; - break; - case XRRequestTrackingState.Resolved: - requestTracking.xrAnchor.delete(); - requestTracking.state = XRRequestTrackingState.Destroyed; - break; - default: - requestTracking.state = XRRequestTrackingState.Destroyed; - break; - } - } - - /** - * @internal - */ - _assembleOptions(options: XRSessionInit): void { - options.optionalFeatures.push("anchors"); - } - - private _addAnchor(session: WebXRSession, frame: WebXRFrame, requestTracking: IWebXRRequestTrackingAnchor): void { - if (!session || !frame) { - return; - } - requestTracking.state = XRRequestTrackingState.Submitted; - const { position, rotation } = requestTracking; - const { _platformFrame: platformFrame } = frame; - const { _platformReferenceSpace: platformReferenceSpace } = session; - platformFrame - .createAnchor( - new XRRigidTransform( - { x: position.x, y: position.y, z: position.z }, - { x: rotation.x, y: rotation.y, z: rotation.z, w: rotation.w } - ), - platformReferenceSpace - ) - .then( - (xrAnchor) => { - if (requestTracking.state === XRRequestTrackingState.WaitingDestroy) { - xrAnchor.delete(); - requestTracking.state = XRRequestTrackingState.Destroyed; - } else { - requestTracking.xrAnchor = xrAnchor; - requestTracking.state = XRRequestTrackingState.Resolved; - } - }, - () => { - if (requestTracking.state === XRRequestTrackingState.WaitingDestroy) { - requestTracking.state = XRRequestTrackingState.Destroyed; - } else { - requestTracking.state = XRRequestTrackingState.Rejected; - } - } - ); - } - - private _updateTrackedAnchor(frame: XRFrame, space: XRSpace, requestTracking: IWebXRRequestTrackingAnchor): boolean { - const { xrAnchor } = requestTracking; - const xrPose = frame.getPose(xrAnchor.anchorSpace, space); - const { transform } = xrPose; - const { pose } = requestTracking.tracked[0]; - pose.matrix.copyFromArray(transform.matrix); - pose.rotation.copyFrom(transform.orientation); - pose.position.copyFrom(transform.position); - return xrPose.emulatedPosition; - } -} - -interface IWebXRRequestTrackingAnchor extends IXRRequestAnchor { - xrAnchor: XRAnchor; -} diff --git a/packages/xr-webxr/src/feature/WebXRFeature.ts b/packages/xr-webxr/src/feature/WebXRFeature.ts deleted file mode 100644 index 1693bae1f..000000000 --- a/packages/xr-webxr/src/feature/WebXRFeature.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { IXRPlatformFeature } from "@galacean/engine-design"; - -/** - * @internal - */ -export abstract class WebXRFeature implements IXRPlatformFeature { - /** @internal */ - abstract _assembleOptions(options: XRSessionInit): Promise | void; -} diff --git a/packages/xr-webxr/src/feature/WebXRImageTracking.ts b/packages/xr-webxr/src/feature/WebXRImageTracking.ts deleted file mode 100644 index 89e744820..000000000 --- a/packages/xr-webxr/src/feature/WebXRImageTracking.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { IXRReferenceImage, IXRRequestImage, IXRTrackedImage } from "@galacean/engine-design"; -import { XRFeatureType, XRRequestTrackingState, XRTrackingState } from "@galacean/engine-xr"; -import { registerXRPlatformFeature } from "../WebXRDevice"; -import { WebXRFrame } from "../WebXRFrame"; -import { WebXRSession } from "../WebXRSession"; -import { WebXRTrackableFeature } from "./WebXRTrackableFeature"; - -/** - * WebXR implementation of XRPlatformImageTracking. - * Note: each tracked image can appear at most once in the tracking results. - * If multiple copies of the same image exist in the user’s environment, - * the device can choose an arbitrary instance to report a pose, - * and this choice can change for future XRFrames. - */ -@registerXRPlatformFeature(XRFeatureType.ImageTracking) -export class WebXRImageTracking extends WebXRTrackableFeature { - private _images: IXRReferenceImage[]; - private _trackingScoreStatus: ImageTrackingScoreStatus = ImageTrackingScoreStatus.NotReceived; - private _tempIdx: number = 0; - private _tempArr: number[] = []; - - constructor(images: IXRReferenceImage[]) { - super(); - this._images = images; - } - - checkAvailable(session: WebXRSession, frame: WebXRFrame, requestTrackings: IXRRequestImage[]): boolean { - if (!frame._platformFrame) return false; - switch (this._trackingScoreStatus) { - case ImageTrackingScoreStatus.NotReceived: - this._requestTrackingScore(session, requestTrackings); - return false; - case ImageTrackingScoreStatus.Waiting: - return false; - } - return true; - } - - getTrackedResult( - session: WebXRSession, - frame: WebXRFrame, - requestTrackings: IXRRequestImage[], - generateTracked: () => IXRTrackedImage - ): void { - const { _platformReferenceSpace: platformReferenceSpace } = session; - const { _platformFrame: platformFrame } = frame; - const { _tempArr: tempArr } = this; - const idx = ++this._tempIdx; - // @ts-ignore - const trackingResults = platformFrame.getImageTrackingResults(); - for (let i = 0, n = trackingResults.length; i < n; i++) { - const trackingResult = trackingResults[i]; - const { index } = trackingResult; - const requestTrackingImage = requestTrackings[index]; - if (requestTrackingImage) { - let tracked = requestTrackingImage.tracked[0]; - if (!tracked) { - tracked = requestTrackingImage.tracked[0] = generateTracked(); - tracked.referenceImage = requestTrackingImage.image; - } - if (trackingResult.trackingState === "tracked") { - this._updateTrackedImage(platformFrame, platformReferenceSpace, tracked, trackingResult); - tracked.state = XRTrackingState.Tracking; - } else { - tracked.state = XRTrackingState.TrackingLost; - } - tempArr[index] = idx; - } else { - console.warn("Images can not find " + index); - } - } - - for (let i = 0, n = requestTrackings.length; i < n; i++) { - if (tempArr[i] < idx) requestTrackings[i].tracked[0].state = XRTrackingState.NotTracking; - } - } - - override onAddRequestTracking(requestTracking: IXRRequestImage): void { - requestTracking.state = XRRequestTrackingState.Submitted; - } - - /** - * @internal - */ - _assembleOptions(options: XRSessionInit): Promise | void { - options.optionalFeatures.push("image-tracking"); - const { _images: images } = this; - const promiseArr: Promise[] = []; - if (images) { - for (let i = 0, n = images.length; i < n; i++) { - const referenceImage = images[i]; - const { imageSource } = images[i]; - if (!imageSource) { - return Promise.reject(new Error("referenceImage[" + referenceImage.name + "].src is null")); - } else { - promiseArr.push(createImageBitmap(imageSource)); - } - } - return new Promise((resolve, reject) => { - // @ts-ignore - const trackedImages = (options.trackedImages = []); - Promise.all(promiseArr).then((bitmaps: ImageBitmap[]) => { - for (let i = 0, n = bitmaps.length; i < n; i++) { - trackedImages.push({ - image: bitmaps[i], - widthInMeters: images[i].physicalWidth - }); - } - resolve(); - }, reject); - }); - } else { - return Promise.reject(new Error("Images.length is 0")); - } - } - - private _requestTrackingScore(session: WebXRSession, requestTrackings: IXRRequestImage[]): void { - this._trackingScoreStatus = ImageTrackingScoreStatus.Waiting; - session._platformSession - // @ts-ignore - .getTrackedImageScores() - .then((trackingScores: ("untrackable" | "trackable")[]) => { - if (trackingScores) { - for (let i = 0, n = trackingScores.length; i < n; i++) { - const trackingScore = trackingScores[i]; - const requestTracking = requestTrackings[i]; - if (trackingScore === "trackable") { - this._trackingScoreStatus = ImageTrackingScoreStatus.Received; - requestTracking.state = XRRequestTrackingState.Resolved; - } else { - requestTracking.state = XRRequestTrackingState.Rejected; - console.warn(requestTracking.image.name, " unTrackable"); - } - } - } - }); - } - - private _updateTrackedImage(frame: XRFrame, space: XRSpace, trackedImage: IXRTrackedImage, trackingResult: any) { - const { pose } = trackedImage; - const { transform } = frame.getPose(trackingResult.imageSpace, space); - pose.matrix.copyFromArray(transform.matrix); - pose.rotation.copyFrom(transform.orientation); - pose.position.copyFrom(transform.position); - trackedImage.measuredPhysicalWidth = trackingResult.measuredWidthInMeters; - } -} - -enum ImageTrackingScoreStatus { - NotReceived, - Waiting, - Received -} diff --git a/packages/xr-webxr/src/feature/WebXRPlaneTracking.ts b/packages/xr-webxr/src/feature/WebXRPlaneTracking.ts deleted file mode 100644 index d40844a38..000000000 --- a/packages/xr-webxr/src/feature/WebXRPlaneTracking.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { IXRRequestPlane, IXRTrackedPlane } from "@galacean/engine-design"; -import { Vector3 } from "@galacean/engine-math"; -import { XRFeatureType, XRPlaneMode, XRRequestTrackingState, XRTrackingState } from "@galacean/engine-xr"; -import { registerXRPlatformFeature } from "../WebXRDevice"; -import { WebXRFrame } from "../WebXRFrame"; -import { WebXRSession } from "../WebXRSession"; -import { WebXRTrackableFeature } from "./WebXRTrackableFeature"; - -/** - * WebXR implementation of XRPlatformPlaneTracking. - */ -@registerXRPlatformFeature(XRFeatureType.PlaneTracking) -export class WebXRPlaneTracking extends WebXRTrackableFeature { - private _lastDetectedPlanes: XRPlaneSet; - - constructor(detectedMode: number) { - super(); - if (detectedMode !== XRPlaneMode.EveryThing) { - console.warn("WebXR only support XRPlaneMode.EveryThing"); - } - } - - checkAvailable(session: WebXRSession, frame: WebXRFrame, requestTrackings: IXRRequestPlane[]): boolean { - return !!frame._platformFrame; - } - - getTrackedResult( - session: WebXRSession, - frame: WebXRFrame, - requestTrackings: IXRRequestPlane[], - generateTracked: () => IWebXRTrackedPlane - ): void { - const { _platformReferenceSpace: platformReferenceSpace } = session; - const { _platformFrame: platformFrame } = frame; - // @ts-ignore - const detectedPlanes: XRPlaneSet = platformFrame.detectedPlanes || platformFrame.worldInformation?.detectedPlanes; - const tracked = requestTrackings[0].tracked; - for (let i = 0, n = tracked.length; i < n; i++) { - const trackedPlane = tracked[i]; - if (detectedPlanes.has(trackedPlane.xrPlane)) { - trackedPlane.state = XRTrackingState.Tracking; - this._updatePlane(platformFrame, platformReferenceSpace, trackedPlane); - } else { - trackedPlane.state = XRTrackingState.NotTracking; - } - } - - const { _lastDetectedPlanes: lastDetectedPlanes } = this; - detectedPlanes.forEach((xrPlane) => { - if (!lastDetectedPlanes?.has(xrPlane)) { - const plane = generateTracked(); - plane.xrPlane = xrPlane; - plane.lastChangedTime = -1; - this._updatePlane(platformFrame, platformReferenceSpace, plane); - tracked.push(plane); - } - }); - this._lastDetectedPlanes = detectedPlanes; - } - - override onAddRequestTracking(requestTracking: IXRRequestPlane): void { - requestTracking.state = XRRequestTrackingState.Resolved; - } - - /** - * @internal - */ - _assembleOptions(options: XRSessionInit): void { - options.optionalFeatures.push("plane-detection"); - } - - private _updatePlane(frame: XRFrame, space: XRSpace, trackedPlane: IWebXRTrackedPlane): void { - const { pose, polygon, xrPlane } = trackedPlane; - const planePose = frame.getPose(xrPlane.planeSpace, space); - if (!planePose) return; - const { transform, emulatedPosition } = planePose; - trackedPlane.state = emulatedPosition ? XRTrackingState.TrackingLost : XRTrackingState.Tracking; - trackedPlane.planeMode = xrPlane.orientation === "horizontal" ? XRPlaneMode.Horizontal : XRPlaneMode.Vertical; - if (trackedPlane.lastChangedTime < xrPlane.lastChangedTime) { - trackedPlane.lastChangedTime = xrPlane.lastChangedTime; - trackedPlane.attributesDirty = true; - const { polygon: oriPolygon } = xrPlane; - for (let i = 0, n = (polygon.length = oriPolygon.length); i < n; i++) { - (polygon[i] ||= new Vector3()).copyFrom(oriPolygon[i]); - } - } else { - trackedPlane.attributesDirty = false; - } - pose.rotation.copyFrom(transform.orientation); - pose.position.copyFrom(transform.position); - pose.matrix.copyFromArray(transform.matrix); - pose.inverseMatrix.copyFromArray(transform.inverse.matrix); - } -} - -interface IWebXRTrackedPlane extends IXRTrackedPlane { - xrPlane?: XRPlane; - lastChangedTime?: number; -} diff --git a/packages/xr-webxr/src/feature/WebXRTrackableFeature.ts b/packages/xr-webxr/src/feature/WebXRTrackableFeature.ts deleted file mode 100644 index f7a7136aa..000000000 --- a/packages/xr-webxr/src/feature/WebXRTrackableFeature.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { IXRRequestTracking, IXRTrackablePlatformFeature, IXRTracked } from "@galacean/engine-design"; -import { XRRequestTrackingState } from "@galacean/engine-xr"; -import { WebXRFrame } from "../WebXRFrame"; -import { WebXRSession } from "../WebXRSession"; -import { WebXRFeature } from "./WebXRFeature"; - -/** - * @internal - */ -export abstract class WebXRTrackableFeature> - extends WebXRFeature - implements IXRTrackablePlatformFeature -{ - get canModifyRequestTrackingAfterInit(): boolean { - return false; - } - - abstract getTrackedResult( - session: WebXRSession, - frame: WebXRFrame, - requestTrackings: K[], - generateTracked: () => T - ): void; - - abstract checkAvailable(session: WebXRSession, frame: WebXRFrame, requestTrackings: K[]): boolean; - - onAddRequestTracking(requestTracking: K): void {} - - onDelRequestTracking(requestTracking: K): void { - requestTracking.state = XRRequestTrackingState.Destroyed; - } -} diff --git a/packages/xr-webxr/src/index.ts b/packages/xr-webxr/src/index.ts deleted file mode 100644 index ca4710042..000000000 --- a/packages/xr-webxr/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import "./feature/WebXRAnchorTracking"; -import "./feature/WebXRImageTracking"; -import "./feature/WebXRPlaneTracking"; - -export { WebXRDevice } from "./WebXRDevice"; diff --git a/packages/xr-webxr/tsconfig.json b/packages/xr-webxr/tsconfig.json deleted file mode 100644 index 588b0055c..000000000 --- a/packages/xr-webxr/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "target": "esnext", - "declaration": true, - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "experimentalDecorators": true, - "declarationDir": "types", - "emitDeclarationOnly": true, - "noImplicitOverride": true, - "sourceMap": true, - "incremental": false, - "skipLibCheck": true, - "stripInternal": true - }, - "include": ["src/**/*"] -} diff --git a/packages/xr/README.md b/packages/xr/README.md deleted file mode 100644 index 85d2a478e..000000000 --- a/packages/xr/README.md +++ /dev/null @@ -1,42 +0,0 @@ -## Installation - -`@galacean/engine-xr` is the implementation layer of XRManager and is a necessary package for developing XR applications. - -To install, use: - -```sh -npm install @galacean/engine-xr -``` - -This will allow you to import engine entirely using: - -```javascript -import { WebXRDevice } from "@galacean/engine-xr-webxr"; -import { XRHitTest, XRSessionMode } from "@galacean/engine-xr"; -``` - -## Usage - -```typescript -import { WebXRDevice } from "@galacean/engine-xr-webxr"; -import { XRHitTest, XRSessionMode } from "@galacean/engine-xr"; - -// Create engine by passing in the HTMLCanvasElement -WebGLEngine.create({ - canvas: "canvas", - xrDevice: new WebXRDevice(), -}).then((engine) => { - // Users need to actively click the button to enter XR - XRButton.onClick = function () { - this.engine.xrManager.enterXR(XRSessionMode.AR).then( - () => { - console.log("Enter AR"); - }, - (error) => { - console.log("Not supported AR", error); - } - ); - }; -}); -...... -``` diff --git a/packages/xr/package.json b/packages/xr/package.json deleted file mode 100644 index 7dc62b83c..000000000 --- a/packages/xr/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@galacean/engine-xr", - "version": "0.0.0-experimental-backup.4", - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org" - }, - "repository": { - "url": "https://github.com/galacean/engine.git" - }, - "license": "MIT", - "main": "dist/main.js", - "module": "dist/module.js", - "debug": "src/index.ts", - "browser": "dist/browser.js", - "types": "types/index.d.ts", - "scripts": { - "b:types": "tsc" - }, - "umd": { - "name": "Galacean.XR", - "globals": { - "@galacean/engine": "Galacean" - } - }, - "files": [ - "dist/**/*", - "libs/**/*", - "types/**/*" - ], - "devDependencies": { - "@galacean/engine-design": "workspace:*", - "@galacean/engine": "workspace:*" - }, - "peerDependencies": { - "@galacean/engine": "workspace:*" - } -} diff --git a/packages/xr/src/XRManagerExtended.ts b/packages/xr/src/XRManagerExtended.ts deleted file mode 100644 index b8488b041..000000000 --- a/packages/xr/src/XRManagerExtended.ts +++ /dev/null @@ -1,320 +0,0 @@ -import { CameraClearFlags, CameraType, Engine, Entity, XRManager } from "@galacean/engine"; -import { IXRDevice } from "@galacean/engine-design"; -import { XRFeature } from "./feature/XRFeature"; -import { XRFeatureType } from "./feature/XRFeatureType"; -import { XRCameraManager } from "./feature/camera/XRCameraManager"; -import { XRInputManager } from "./input/XRInputManager"; -import { XRSessionManager } from "./session/XRSessionManager"; -import { XRSessionMode } from "./session/XRSessionMode"; -import { XRSessionState } from "./session/XRSessionState"; -/** - * @internal - */ -export class XRManagerExtended extends XRManager { - /** @internal */ - static _featureMap: Map, XRFeatureType> = new Map(); - - override inputManager: XRInputManager; - override sessionManager: XRSessionManager; - override cameraManager: XRCameraManager; - - /** @internal */ - _platformDevice: IXRDevice; - - private _features: XRFeature[]; - private _origin: Entity; - - override get features(): XRFeature[] { - return this._features; - } - - override get origin(): Entity { - return this._origin; - } - - override set origin(value: Entity) { - if (this.sessionManager._platformSession) { - throw new Error("Cannot set origin when the session is initialized."); - } - this._origin = value; - } - - override isSupportedFeature(feature: TFeatureConstructor): boolean { - return this._platformDevice.isSupportedFeature(XRManagerExtended._featureMap.get(feature)); - } - - override addFeature XRFeature>( - type: T, - ...args: TFeatureConstructorArguments - ): InstanceType | null { - if (this.sessionManager._platformSession) { - throw new Error("Cannot add feature when the session is initialized."); - } - if (!this._platformDevice.isSupportedFeature(XRManagerExtended._featureMap.get(type))) { - throw new Error("The feature is not supported"); - } - const { features } = this; - for (let i = 0, n = features.length; i < n; i++) { - if (features[i] instanceof type) throw new Error("The feature has been added"); - } - const feature = new type(this, ...args) as InstanceType; - features.push(feature); - return feature; - } - - override getFeature(type: TFeatureConstructor): T | null { - const { features } = this; - for (let i = 0, n = features.length; i < n; i++) { - const feature = features[i]; - if (feature instanceof type) { - return feature; - } - } - } - - override enterXR(sessionMode: XRSessionMode, autoRun: boolean = true): Promise { - const { sessionManager } = this; - if (sessionManager._platformSession) { - throw new Error("Please exit XR immersive mode first."); - } - if (!this._origin) { - throw new Error("Please set origin before enter XR."); - } - return new Promise((resolve, reject) => { - // 1. Check if this xr mode is supported - sessionManager.isSupportedMode(sessionMode).then(() => { - sessionManager._setState(XRSessionState.Initializing); - // 2. Initialize session - sessionManager._initialize(sessionMode, this.features).then(() => { - autoRun && sessionManager.run(); - resolve(); - }, reject); - }, reject); - }); - } - - override exitXR(): Promise { - return new Promise((resolve, reject) => { - this.sessionManager._exit().then(() => { - resolve(); - }, reject); - }); - } - - override _initialize(engine: Engine, xrDevice: IXRDevice): void { - this._features = []; - this._platformDevice = xrDevice; - this.sessionManager = new XRSessionManager(this, engine); - this.inputManager = new XRInputManager(this, engine); - this.cameraManager = new XRCameraManager(this); - } - - override _update(): void { - const { sessionManager } = this; - if (sessionManager.state !== XRSessionState.Running) return; - sessionManager._onUpdate(); - this.inputManager._onUpdate(); - this.cameraManager._onUpdate(); - const { features } = this; - for (let i = 0, n = features.length; i < n; i++) { - const feature = features[i]; - feature.enabled && feature._onUpdate(); - } - } - - override _destroy(): void { - if (this.sessionManager._platformSession) { - this.exitXR().then(() => { - this.sessionManager._onDestroy(); - this.inputManager._onDestroy(); - this.cameraManager._onDestroy(); - }); - } else { - this.sessionManager._onDestroy(); - this.inputManager._onDestroy(); - this.cameraManager._onDestroy(); - } - } - - override _getRequestAnimationFrame(): (callback: FrameRequestCallback) => number { - return this.sessionManager._getRequestAnimationFrame(); - } - - override _getCancelAnimationFrame(): (id: number) => void { - return this.sessionManager._getCancelAnimationFrame(); - } - - override _getCameraIgnoreClearFlags(type: CameraType): CameraClearFlags { - return this.cameraManager._getIgnoreClearFlags(type); - } - - /** - * @internal - */ - _onSessionStop(): void { - const { features } = this; - for (let i = 0, n = features.length; i < n; i++) { - const feature = features[i]; - feature.enabled && feature._onSessionStop(); - } - } - - /** - * @internal - */ - _onSessionInit(): void { - const { features } = this; - for (let i = 0, n = features.length; i < n; i++) { - const feature = features[i]; - feature.enabled && feature._onSessionInit(); - } - } - - /** - * @internal - */ - _onSessionStart(): void { - this.cameraManager._onSessionStart(); - const { features } = this; - for (let i = 0, n = features.length; i < n; i++) { - const feature = features[i]; - feature.enabled && feature._onSessionStart(); - } - } - - /** - * @internal - */ - _onSessionExit(): void { - this.cameraManager._onSessionExit(); - const { features } = this; - for (let i = 0, n = features.length; i < n; i++) { - const feature = features[i]; - feature.enabled && feature._onSessionExit(); - feature._onDestroy(); - } - features.length = 0; - } -} - -/** - * @internal - */ -export function registerXRFeature(type: XRFeatureType): (feature: TFeatureConstructor) => void { - return (feature: TFeatureConstructor) => { - XRManagerExtended._featureMap.set(feature, type); - }; -} - -export interface IXRListener { - fn: (...args: any[]) => any; - destroyed?: boolean; -} - -type TFeatureConstructor = new (xrManager: XRManagerExtended, ...args: any[]) => T; - -type TFeatureConstructorArguments XRFeature> = - T extends new (xrManager: XRManagerExtended, ...args: infer P) => XRFeature ? P : never; - -declare module "@galacean/engine" { - interface XRManager { - /** Input manager for XR. */ - inputManager: XRInputManager; - /** Session manager for XR. */ - sessionManager: XRSessionManager; - /** Camera manager for XR. */ - cameraManager: XRCameraManager; - - /** Initialized features. */ - get features(): XRFeature[]; - - /** - * The current origin of XR space. - * @remarks The connection point between the virtual world and the real world ( XR Space ) - */ - get origin(): Entity; - set origin(value: Entity); - - /** - * Check if the specified feature is supported. - * @param type - The type of the feature - * @returns If the feature is supported - */ - isSupportedFeature(feature: TFeatureConstructor): boolean; - - /** - * Add feature based on the xr feature type. - * @param type - The type of the feature - * @param args - The constructor params of the feature - * @returns The feature which has been added - */ - addFeature XRFeature>( - type: T, - ...args: TFeatureConstructorArguments - ): InstanceType | null; - - /** - * Get feature which match the type. - * @param type - The type of the feature - * @returns The feature which match type - */ - getFeature(type: TFeatureConstructor): T | null; - /** - * Enter XR immersive mode, when you call this method, it will initialize and display the XR virtual world. - * @param sessionMode - The mode of the session - * @param autoRun - Whether to automatically run the session, when `autoRun` is set to true, xr will start working immediately after initialization. Otherwise, you need to call `sessionManager.run` later to work. - * @returns A promise that resolves if the XR virtual world is entered, otherwise rejects - */ - enterXR(sessionMode: XRSessionMode, autoRun?: boolean): Promise; - /** - * Exit XR immersive mode, when you call this method, it will destroy the XR virtual world. - * @returns A promise that resolves if the XR virtual world is destroyed, otherwise rejects - */ - exitXR(): Promise; - - /** - * @internal - */ - _initialize(engine: Engine, xrDevice: IXRDevice): void; - - /** - * @internal - */ - _getRequestAnimationFrame(): (callback: FrameRequestCallback) => number; - - /** - * @internal - */ - _getCancelAnimationFrame(): (id: number) => void; - - /** - * @internal - */ - _getCameraIgnoreClearFlags(type: CameraType): CameraClearFlags; - - /** - * @internal - */ - _update(): void; - - /** - * @internal - */ - _destroy(): void; - } -} - -// 实现混入的函数 -function ApplyMixins(derivedCtor: any, baseCtors: any[]): void { - baseCtors.forEach((baseCtor) => { - Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { - Object.defineProperty( - derivedCtor.prototype, - name, - Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null) - ); - }); - }); -} - -ApplyMixins(XRManager, [XRManagerExtended]); diff --git a/packages/xr/src/XRPose.ts b/packages/xr/src/XRPose.ts deleted file mode 100644 index 22d66fcbc..000000000 --- a/packages/xr/src/XRPose.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Matrix, Quaternion, Vector3 } from "@galacean/engine"; -import { IXRPose } from "@galacean/engine-design"; - -/** - * Data for describing pose in the XR space. - */ -export class XRPose implements IXRPose { - /** The position of the pose in XR space. */ - position: Vector3 = new Vector3(); - /** The rotation of the pose in XR space. */ - rotation: Quaternion = new Quaternion(); - /** The matrix of the pose in XR space. */ - matrix: Matrix = new Matrix(); - /** The inverse matrix of the pose in XR space. */ - inverseMatrix: Matrix = new Matrix(); -} diff --git a/packages/xr/src/feature/XRFeature.ts b/packages/xr/src/feature/XRFeature.ts deleted file mode 100644 index defe21307..000000000 --- a/packages/xr/src/feature/XRFeature.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { IXRPlatformFeature } from "@galacean/engine-design"; -import { XRManagerExtended } from "../XRManagerExtended"; -import { XRFeatureType } from "./XRFeatureType"; - -/** - * The base class of XR feature manager. - */ -export abstract class XRFeature { - /** @internal */ - _platformFeature: T; - protected _enabled: boolean = true; - - /** - * Returns whether the feature is enabled. - */ - get enabled(): boolean { - return this._enabled; - } - - set enabled(value: boolean) { - if (this.enabled !== value) { - this._enabled = value; - value ? this._onEnable() : this._onDisable(); - } - } - - /** - * @internal - */ - constructor( - protected _xrManager: XRManagerExtended, - protected _type: XRFeatureType, - ...args: any[] - ) { - this._platformFeature = _xrManager._platformDevice.createPlatformFeature(_type, ...args); - this._onEnable(); - } - - /** - * @internal - */ - _onEnable(): void {} - - /** - * @internal - */ - _onDisable(): void {} - - /** - * @internal - */ - _onUpdate(): void {} - - /** - * @internal - */ - _onSessionInit(): void {} - - /** - * @internal - */ - _onSessionStart(): void {} - - /** - * @internal - */ - _onSessionStop(): void {} - - /** - * @internal - */ - _onSessionExit(): void {} - - /** - * @internal - */ - _onDestroy(): void {} -} diff --git a/packages/xr/src/feature/XRFeatureType.ts b/packages/xr/src/feature/XRFeatureType.ts deleted file mode 100644 index d920313c7..000000000 --- a/packages/xr/src/feature/XRFeatureType.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum XRFeatureType { - AnchorTracking, - ImageTracking, - PlaneTracking, - HitTest -} diff --git a/packages/xr/src/feature/camera/XRCameraManager.ts b/packages/xr/src/feature/camera/XRCameraManager.ts deleted file mode 100644 index 6050dd464..000000000 --- a/packages/xr/src/feature/camera/XRCameraManager.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { Camera, CameraClearFlags, CameraType, Matrix } from "@galacean/engine"; -import { XRManagerExtended } from "../../XRManagerExtended"; -import { XRCamera } from "../../input/XRCamera"; -import { XRTrackedInputDevice } from "../../input/XRTrackedInputDevice"; -import { XRSessionState } from "../../session/XRSessionState"; - -/** - * The manager of XR camera. - */ -export class XRCameraManager { - /** - * The fixed foveation of the camera. - */ - get fixedFoveation(): number { - const { _platformSession: platformSession } = this._xrManager.sessionManager; - if (platformSession) { - return platformSession.getFixedFoveation(); - } else { - throw new Error("XR session is not available."); - } - } - - set fixedFoveation(value: number) { - const { _platformSession: platformSession } = this._xrManager.sessionManager; - if (platformSession) { - platformSession.setFixedFoveation(value); - } else { - throw new Error("XR session is not available."); - } - } - - /** - * @internal - */ - constructor(private _xrManager: XRManagerExtended) {} - - /** - * Attach the camera to the specified input type(Camera, LeftCamera or RightCamera). - * The camera entity need to be moved to the XROrigin entity. - * @param type - The input type - * @param camera - The camera to be attached - */ - attachCamera( - type: XRTrackedInputDevice.Camera | XRTrackedInputDevice.LeftCamera | XRTrackedInputDevice.RightCamera, - camera: Camera - ): void { - const xrCamera = this._xrManager.inputManager.getTrackedDevice(type); - const preCamera = xrCamera._camera; - if (preCamera !== camera) { - // @ts-ignore - preCamera && (preCamera._cameraType = CameraType.Normal); - switch (type) { - case XRTrackedInputDevice.Camera: - // @ts-ignore - camera._cameraType = CameraType.XRCenterCamera; - break; - case XRTrackedInputDevice.LeftCamera: - // @ts-ignore - camera._cameraType = CameraType.XRLeftCamera; - break; - case XRTrackedInputDevice.RightCamera: - // @ts-ignore - camera._cameraType = CameraType.XRRightCamera; - break; - default: - break; - } - xrCamera._camera = camera; - } - } - - /** - * Detach the camera from the specified input type. - * @param type - The input type - * @returns The camera that was detached - */ - detachCamera( - type: XRTrackedInputDevice.Camera | XRTrackedInputDevice.LeftCamera | XRTrackedInputDevice.RightCamera - ): Camera { - const xrCamera = this._xrManager.inputManager.getTrackedDevice(type); - const preCamera = xrCamera._camera; - // @ts-ignore - preCamera && (preCamera._cameraType = CameraType.Normal); - xrCamera._camera = null; - return preCamera; - } - - /** - * @internal - */ - _onSessionStart(): void {} - - /** - * @internal - */ - _onUpdate(): void { - const cameras = this._xrManager.inputManager._cameras; - const platformSession = this._xrManager.sessionManager._platformSession; - for (let i = 0, n = cameras.length; i < n; i++) { - const cameraDevice = cameras[i]; - const { _camera: camera } = cameraDevice; - if (!camera) continue; - // sync position and rotation - const { transform } = camera.entity; - const { pose } = cameraDevice; - transform.position = pose.position; - transform.rotationQuaternion = pose.rotation; - // sync viewport - const { viewport } = camera; - const { x, y, width, height } = cameraDevice.viewport; - if (!(x === viewport.x && y === viewport.y && width === viewport.z && height === viewport.w)) { - camera.viewport = viewport.set(x, y, width, height); - } - // sync project matrix - if (!Matrix.equals(camera.projectionMatrix, cameraDevice.projectionMatrix)) { - camera.projectionMatrix = cameraDevice.projectionMatrix; - } - // sync pixel viewport (only when rendering to XR main framebuffer) - if (!camera.renderTarget) { - // @ts-ignore - camera._adjustPixelViewport(platformSession.framebufferWidth, platformSession.framebufferHeight); - } - } - } - - /** - * @internal - */ - _onSessionExit(): void { - const cameras = this._xrManager.inputManager._cameras; - for (let i = 0, n = cameras.length; i < n; i++) { - // @ts-ignore - cameras[i]._camera?._updatePixelViewport(); - } - } - - /** - * @internal - */ - _getIgnoreClearFlags(cameraType: CameraType): CameraClearFlags { - if (cameraType === CameraType.XRCenterCamera) { - if (this._xrManager.sessionManager.state === XRSessionState.Running) { - return CameraClearFlags.Color; - } else { - return CameraClearFlags.None; - } - } else { - return CameraClearFlags.None; - } - } - - /** - * @internal - */ - _onDestroy(): void {} -} diff --git a/packages/xr/src/feature/hitTest/TrackableType.ts b/packages/xr/src/feature/hitTest/TrackableType.ts deleted file mode 100644 index f3ccfd12e..000000000 --- a/packages/xr/src/feature/hitTest/TrackableType.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Enum for the types of hit test that can be performed. - * Note: currently only supports plane. - */ -export enum TrackableType { - /** Tracked plane. */ - Plane = 0x1, - /** All tracked objects. */ - All = 0x1 -} diff --git a/packages/xr/src/feature/hitTest/XRHitResult.ts b/packages/xr/src/feature/hitTest/XRHitResult.ts deleted file mode 100644 index 17e154b61..000000000 --- a/packages/xr/src/feature/hitTest/XRHitResult.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { IXRTracked } from "@galacean/engine-design"; -import { TrackableType } from "./TrackableType"; -import { Vector3 } from "@galacean/engine"; - -/** - * XR hit result. - * It is the detection result returned by using XR HitTest feature. - */ -export class XRHitResult { - /** The position of the hit point. */ - point: Vector3 = new Vector3(); - /** The normal of the hit point. */ - normal: Vector3 = new Vector3(); - /** The distance from the origin of the ray to the hit point. */ - distance: number; - /** The hit tracked object, such as IXRTrackedPlane. */ - trackedObject: IXRTracked; - /** The type of tracked object detected, such as TrackableType.Plane */ - trackableType: TrackableType; -} diff --git a/packages/xr/src/feature/hitTest/XRHitTest.ts b/packages/xr/src/feature/hitTest/XRHitTest.ts deleted file mode 100644 index 369f793b6..000000000 --- a/packages/xr/src/feature/hitTest/XRHitTest.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { Plane, Ray, Vector2, Vector3 } from "@galacean/engine"; -import { IXRTrackedPlane } from "@galacean/engine-design"; -import { XRManagerExtended, registerXRFeature } from "../../XRManagerExtended"; -import { XRCamera } from "../../input/XRCamera"; -import { XRTrackedInputDevice } from "../../input/XRTrackedInputDevice"; -import { XRSessionMode } from "../../session/XRSessionMode"; -import { XRFeature } from "../XRFeature"; -import { XRFeatureType } from "../XRFeatureType"; -import { XRPlaneTracking } from "../trackable/plane/XRPlaneTracking"; -import { TrackableType } from "./TrackableType"; -import { XRHitResult } from "./XRHitResult"; - -/** - * The manager of XR hit test. - */ -@registerXRFeature(XRFeatureType.HitTest) -export class XRHitTest extends XRFeature { - private _tempRay: Ray = new Ray(); - private _tempPlane: Plane = new Plane(); - private _tempVec2: Vector2 = new Vector2(); - private _tempVec30: Vector3 = new Vector3(); - private _tempVec31: Vector3 = new Vector3(); - private _tempVec32: Vector3 = new Vector3(); - private _tempVec33: Vector3 = new Vector3(); - private _tempVec34: Vector3 = new Vector3(); - private _tempVec35: Vector3 = new Vector3(); - - /** - * @param xrManager - The xr manager - */ - constructor(xrManager: XRManagerExtended) { - super(xrManager, XRFeatureType.HitTest); - } - - /** - * Hit test. - * @param ray - The ray to test - * @param type - The type of hit test - * @returns The hit result - */ - hitTest(ray: Ray, type: TrackableType): XRHitResult[] { - const result = []; - if (type & TrackableType.Plane) { - this._hitTestPlane(ray, result); - } - return result; - } - - /** - * Screen hit test. - * @param x - The x coordinate of the screen point - * @param y - The y coordinate of the screen point - * @param type - The type of hit test - * @returns The hit result - */ - screenHitTest(x: number, y: number, type: TrackableType): XRHitResult[] { - const { _xrManager: xrManager } = this; - if (xrManager.sessionManager.mode !== XRSessionMode.AR) { - throw new Error("Only AR mode supports using screen ray hit test."); - } - const { _camera: camera } = xrManager.inputManager.getTrackedDevice(XRTrackedInputDevice.Camera); - if (!camera) { - throw new Error("No camera available."); - } - const ray = camera.screenPointToRay(this._tempVec2.set(x, y), this._tempRay); - return this.hitTest(ray, type); - } - - private _hitTestPlane(ray: Ray, result: XRHitResult[]): void { - const planeManager = this._xrManager.getFeature(XRPlaneTracking); - if (!planeManager || !planeManager.enabled) { - throw new Error("The plane estimation function needs to be turned on for plane hit test."); - } - const { _tempPlane: plane, _tempVec30: normal, _tempVec31: hitPoint, _tempVec32: hitPointInPlane } = this; - const { trackedPlanes } = planeManager; - for (let i = 0, n = trackedPlanes.length; i < n; i++) { - const trackedPlane = trackedPlanes[i]; - normal.set(0, 1, 0).transformNormal(trackedPlane.pose.matrix); - plane.normal.copyFrom(normal); - plane.distance = -Vector3.dot(normal, trackedPlane.pose.position); - const distance = ray.intersectPlane(plane); - if (distance >= 0) { - ray.getPoint(distance, hitPoint); - Vector3.transformToVec3(hitPoint, trackedPlane.pose.inverseMatrix, hitPointInPlane); - // Check if the hit position is within the plane boundary. - if (this._checkPointerWithinPlane(hitPointInPlane, trackedPlane)) { - const hitResult = new XRHitResult(); - hitResult.point.copyFrom(hitPoint); - hitResult.normal.copyFrom(normal); - hitResult.distance = distance; - hitResult.trackedObject = trackedPlane; - hitResult.trackableType = TrackableType.Plane; - result.push(hitResult); - } - } - } - } - - private _checkPointerWithinPlane(pointer: Vector3, plane: IXRTrackedPlane): boolean { - const { _tempVec33: preToCur, _tempVec34: preToPointer, _tempVec35: cross } = this; - const { polygon } = plane; - const length = polygon.length; - let prePoint = polygon[length - 1]; - let side = 0; - for (let i = 0; i < length; i++) { - const curPoint = polygon[i]; - Vector3.subtract(curPoint, prePoint, preToCur); - Vector3.subtract(pointer, prePoint, preToPointer); - Vector3.cross(preToCur, preToPointer, cross); - const y = cross.y; - if (side === 0) { - if (y > 0) { - side = 1; - } else if (y < 0) { - side = -1; - } - } else { - if ((y > 0 && side < 0) || (y < 0 && side > 0)) { - return false; - } - } - prePoint = curPoint; - } - return true; - } -} diff --git a/packages/xr/src/feature/trackable/XRRequestTracking.ts b/packages/xr/src/feature/trackable/XRRequestTracking.ts deleted file mode 100644 index 515853ecc..000000000 --- a/packages/xr/src/feature/trackable/XRRequestTracking.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { XRRequestTrackingState } from "./XRRequestTrackingState"; -import { XRTracked } from "./XRTracked"; - -/** - * @internal - */ -export abstract class XRRequestTracking { - /** The status of the current request tracking. */ - state: XRRequestTrackingState = XRRequestTrackingState.None; - /** Tracked instances, make up from the tracking data returned by Session. */ - tracked: T[] = []; -} diff --git a/packages/xr/src/feature/trackable/XRRequestTrackingState.ts b/packages/xr/src/feature/trackable/XRRequestTrackingState.ts deleted file mode 100644 index fc8394dee..000000000 --- a/packages/xr/src/feature/trackable/XRRequestTrackingState.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum XRRequestTrackingState { - None, - Submitted, - Resolved, - Rejected, - Destroyed, - WaitingDestroy -} diff --git a/packages/xr/src/feature/trackable/XRTrackableFeature.ts b/packages/xr/src/feature/trackable/XRTrackableFeature.ts deleted file mode 100644 index ba3abe480..000000000 --- a/packages/xr/src/feature/trackable/XRTrackableFeature.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { SafeLoopArray } from "@galacean/engine"; -import { IXRTrackablePlatformFeature } from "@galacean/engine-design"; -import { IXRListener } from "../../XRManagerExtended"; -import { XRTrackingState } from "../../input/XRTrackingState"; -import { XRFeature } from "../XRFeature"; -import { XRFeatureType } from "../XRFeatureType"; -import { XRRequestTracking } from "./XRRequestTracking"; -import { XRRequestTrackingState } from "./XRRequestTrackingState"; -import { XRTracked } from "./XRTracked"; - -/** - * The base class of XR trackable manager. - */ -export abstract class XRTrackableFeature< - T extends XRTracked = XRTracked, - K extends XRRequestTracking = XRRequestTracking -> extends XRFeature> { - protected static _uuid = 0; - - protected _requestTrackings: K[] = []; - protected _tracked: T[] = []; - protected _added: T[] = []; - protected _updated: T[] = []; - protected _removed: T[] = []; - protected _statusSnapshot: Record = {}; - private _listeners: SafeLoopArray = new SafeLoopArray(); - - /** - * Add a listening function for tracked object changes. - * @param listener - The listening function - */ - addChangedListener(listener: (added: readonly T[], updated: readonly T[], removed: readonly T[]) => void): void { - this._listeners.push({ fn: listener }); - } - - /** - * Remove a listening function of tracked object changes. - * @param listener - The listening function - */ - removeChangedListener(listener: (added: readonly T[], updated: readonly T[], removed: readonly T[]) => void): void { - this._listeners.findAndRemove((value) => (value.fn === listener ? (value.destroyed = true) : false)); - } - - override _onUpdate(): void { - const { _platformSession: platformSession } = this._xrManager.sessionManager; - const { frame: platformFrame } = platformSession; - const { - _platformFeature: platformFeature, - _requestTrackings: requestTrackings, - _statusSnapshot: statusSnapshot, - _tracked: allTracked, - _added: added, - _updated: updated, - _removed: removed - } = this; - if (!platformFrame || !requestTrackings.length) { - return; - } - if (!platformFeature.checkAvailable(platformSession, platformFrame, requestTrackings)) { - return; - } - added.length = updated.length = removed.length = 0; - platformFeature.getTrackedResult(platformSession, platformFrame, requestTrackings, this._generateTracked); - for (let i = 0, n = requestTrackings.length; i < n; i++) { - const requestTracking = requestTrackings[i]; - switch (requestTracking.state) { - case XRRequestTrackingState.Destroyed: - const destroyedTracked = requestTracking.tracked; - for (let j = 0, n = destroyedTracked.length; j < n; j++) { - const tracked = destroyedTracked[j]; - const trackId = tracked.id; - if (statusSnapshot[trackId] === XRTrackingState.Tracking) { - removed.push(tracked); - allTracked.splice(allTracked.indexOf(tracked), 1); - } - statusSnapshot[trackId] = XRTrackingState.NotTracking; - } - break; - case XRRequestTrackingState.Resolved: - const { tracked } = requestTracking; - for (let j = 0, n = tracked.length; j < n; j++) { - const trackedObject = tracked[j]; - const trackId = trackedObject.id; - if (trackedObject.state === XRTrackingState.Tracking) { - if (statusSnapshot[trackId] === XRTrackingState.Tracking) { - updated.push(trackedObject); - } else { - added.push(trackedObject); - statusSnapshot[trackId] = XRTrackingState.Tracking; - allTracked.push(trackedObject); - } - } else { - if (statusSnapshot[trackId] === XRTrackingState.Tracking) { - removed.push(trackedObject); - allTracked.splice(allTracked.indexOf(trackedObject), 1); - } - statusSnapshot[trackId] = trackedObject.state; - } - } - break; - default: - break; - } - } - for (let i = requestTrackings.length - 1; i >= 0; i--) { - requestTrackings[i].state === XRRequestTrackingState.Destroyed && requestTrackings.splice(i, 1); - } - if (added.length > 0 || updated.length > 0 || removed.length > 0) { - const listeners = this._listeners.getLoopArray(); - for (let i = 0, n = listeners.length; i < n; i++) { - const listener = listeners[i]; - !listener.destroyed && listener.fn(added, updated, removed); - } - } - } - - override _onSessionStop(): void { - this._added.length = this._updated.length = this._removed.length = 0; - } - - override _onSessionExit(): void { - // prettier-ignore - this._requestTrackings.length = this._tracked.length = this._added.length = this._updated.length = this._removed.length = 0; - this._listeners.findAndRemove((value) => (value.destroyed = true)); - } - - protected _addRequestTracking(requestTracking: K): void { - const { _platformFeature: platformFeature } = this; - if (this._xrManager.sessionManager._platformSession && !platformFeature.canModifyRequestTrackingAfterInit) { - throw new Error(XRFeatureType[this._type] + " request tracking cannot be modified after initialization."); - } - this._requestTrackings.push(requestTracking); - platformFeature.onAddRequestTracking(requestTracking); - } - - protected _removeRequestTracking(requestTracking: K): void { - const { _platformFeature: platformFeature } = this; - if (this._xrManager.sessionManager._platformSession && !platformFeature.canModifyRequestTrackingAfterInit) { - throw new Error(XRFeatureType[this._type] + " request tracking cannot be modified after initialization."); - } - platformFeature.onDelRequestTracking(requestTracking); - } - - protected _removeAllRequestTrackings(): void { - const { _platformFeature: platformFeature } = this; - if (this._xrManager.sessionManager._platformSession && !platformFeature.canModifyRequestTrackingAfterInit) { - throw new Error(XRFeatureType[this._type] + " request tracking cannot be modified after initialization."); - } - const { _requestTrackings: requestTrackings } = this; - for (let i = 0, n = requestTrackings.length; i < n; i++) { - platformFeature.onDelRequestTracking(requestTrackings[i]); - } - } - - protected abstract _generateTracked(): T; -} diff --git a/packages/xr/src/feature/trackable/XRTracked.ts b/packages/xr/src/feature/trackable/XRTracked.ts deleted file mode 100644 index 6cb70a411..000000000 --- a/packages/xr/src/feature/trackable/XRTracked.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { IXRTracked } from "@galacean/engine-design"; -import { XRPose } from "../../XRPose"; -import { XRTrackingState } from "../../input/XRTrackingState"; - -/** - * The base class of XR tracked object. - */ -export abstract class XRTracked implements IXRTracked { - /** The unique id of the trackable. */ - id: number; - /** The pose of the trackable in XR space. */ - pose: XRPose = new XRPose(); - /** The tracking state of the trackable. */ - state: XRTrackingState = XRTrackingState.NotTracking; -} diff --git a/packages/xr/src/feature/trackable/anchor/XRAnchor.ts b/packages/xr/src/feature/trackable/anchor/XRAnchor.ts deleted file mode 100644 index 6db9d9d46..000000000 --- a/packages/xr/src/feature/trackable/anchor/XRAnchor.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { XRTracked } from "../XRTracked"; - -/** - * The anchor in XR space. - */ -export class XRAnchor extends XRTracked {} diff --git a/packages/xr/src/feature/trackable/anchor/XRAnchorTracking.ts b/packages/xr/src/feature/trackable/anchor/XRAnchorTracking.ts deleted file mode 100644 index b8e14686a..000000000 --- a/packages/xr/src/feature/trackable/anchor/XRAnchorTracking.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Quaternion, Vector3 } from "@galacean/engine"; -import { XRManagerExtended, registerXRFeature } from "../../../XRManagerExtended"; -import { XRFeatureType } from "../../XRFeatureType"; -import { XRTrackableFeature } from "../XRTrackableFeature"; -import { XRAnchor } from "./XRAnchor"; -import { XRRequestAnchor } from "./XRRequestAnchor"; - -/** - * The manager of XR anchor tracking. - */ -@registerXRFeature(XRFeatureType.AnchorTracking) -export class XRAnchorTracking extends XRTrackableFeature { - private _anchors: XRAnchor[] = []; - - /** - * The anchors to tracking. - */ - get trackingAnchors(): readonly XRAnchor[] { - return this._anchors; - } - - /** - * The tracked anchors. - */ - get trackedAnchors(): readonly XRAnchor[] { - return this._tracked; - } - - /** - * @param xrManager - The xr manager - */ - constructor(xrManager: XRManagerExtended) { - super(xrManager, XRFeatureType.AnchorTracking); - } - - /** - * Add a anchor in XR space. - * @param anchor - The anchor to be added - */ - addAnchor(position: Vector3, rotation: Quaternion): XRAnchor { - if (!this._enabled) { - throw new Error("Cannot add an anchor from a disabled anchor manager."); - } - const { _anchors: anchors } = this; - const requestAnchor = new XRRequestAnchor(position, rotation); - const xrAnchor = this._generateTracked(); - requestAnchor.tracked[0] = xrAnchor; - this._addRequestTracking(requestAnchor); - anchors.push(xrAnchor); - return xrAnchor; - } - - /** - * Remove a anchor in XR space. - * @param anchor - The anchor to be removed - */ - removeAnchor(anchor: XRAnchor): void { - if (!this._enabled) { - throw new Error("Cannot remove an anchor from a disabled anchor manager."); - } - const { _requestTrackings: requestTrackings, _anchors: anchors } = this; - for (let i = 0, n = requestTrackings.length; i < n; i++) { - const requestAnchor = requestTrackings[i]; - if (requestAnchor.tracked[0] === anchor) { - this._removeRequestTracking(requestAnchor); - break; - } - } - anchors.splice(anchors.indexOf(anchor), 1); - } - - /** - * Remove all tracking anchors. - */ - clearAnchors(): void { - if (!this._enabled) { - throw new Error("Cannot remove anchors from a disabled anchor manager."); - } - this._removeAllRequestTrackings(); - } - - protected override _generateTracked(): XRAnchor { - const anchor = new XRAnchor(); - anchor.id = XRTrackableFeature._uuid++; - return anchor; - } -} diff --git a/packages/xr/src/feature/trackable/anchor/XRRequestAnchor.ts b/packages/xr/src/feature/trackable/anchor/XRRequestAnchor.ts deleted file mode 100644 index 8e236330e..000000000 --- a/packages/xr/src/feature/trackable/anchor/XRRequestAnchor.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Quaternion, Vector3 } from "@galacean/engine"; -import { IXRRequestAnchor } from "@galacean/engine-design"; -import { XRRequestTracking } from "../XRRequestTracking"; -import { XRAnchor } from "./XRAnchor"; - -/** - * The request anchor in XR space. - */ -export class XRRequestAnchor extends XRRequestTracking implements IXRRequestAnchor { - /** - * @param position - Requests the position of the anchor to be added - * @param rotation - Requests the rotation of the anchor to be added - */ - constructor( - public position: Vector3, - public rotation: Quaternion - ) { - super(); - } -} diff --git a/packages/xr/src/feature/trackable/image/XRImageTracking.ts b/packages/xr/src/feature/trackable/image/XRImageTracking.ts deleted file mode 100644 index 27ed6595f..000000000 --- a/packages/xr/src/feature/trackable/image/XRImageTracking.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { XRManagerExtended, registerXRFeature } from "../../../XRManagerExtended"; -import { XRFeatureType } from "../../XRFeatureType"; -import { XRTrackableFeature } from "../XRTrackableFeature"; -import { XRReferenceImage } from "./XRReferenceImage"; -import { XRRequestImage } from "./XRRequestImage"; -import { XRTrackedImage } from "./XRTrackedImage"; - -/** - * The manager of XR image tracking. - */ -@registerXRFeature(XRFeatureType.ImageTracking) -export class XRImageTracking extends XRTrackableFeature { - private _trackingImages: XRReferenceImage[]; - /** - * The image to tracking. - */ - get trackingImages(): readonly XRReferenceImage[] { - return this._trackingImages; - } - - /** - * The tracked images. - */ - get trackedImages(): readonly XRTrackedImage[] { - return this._tracked; - } - - /** - * @param xrManager - The xr manager - * @param trackingImages - The images to be tracked - */ - constructor(xrManager: XRManagerExtended, trackingImages: XRReferenceImage[]) { - super(xrManager, XRFeatureType.ImageTracking, trackingImages); - this._trackingImages = trackingImages; - const imageLength = trackingImages ? trackingImages.length : 0; - if (imageLength > 0) { - for (let i = 0, n = trackingImages.length; i < n; i++) { - this._addRequestTracking(new XRRequestImage(trackingImages[i])); - } - } else { - console.warn("No image to be tracked."); - } - } - - protected override _generateTracked(): XRTrackedImage { - const image = new XRTrackedImage(); - image.id = XRTrackableFeature._uuid++; - return image; - } -} diff --git a/packages/xr/src/feature/trackable/image/XRReferenceImage.ts b/packages/xr/src/feature/trackable/image/XRReferenceImage.ts deleted file mode 100644 index 036187d29..000000000 --- a/packages/xr/src/feature/trackable/image/XRReferenceImage.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { IXRReferenceImage } from "@galacean/engine-design"; - -/** - * A reference image is an image to look for in the physical environment. - */ -export class XRReferenceImage implements IXRReferenceImage { - /** - * Create a reference image. - * @param name - The name of the image to be tracked - * @param imageSource - The image to be tracked - * @param physicalWidth - The expected physical width measurement for the real-world image being tracked in meters - */ - constructor( - public name: string, - public imageSource: ImageBitmapSource, - public physicalWidth: number - ) {} -} diff --git a/packages/xr/src/feature/trackable/image/XRRequestImage.ts b/packages/xr/src/feature/trackable/image/XRRequestImage.ts deleted file mode 100644 index 01c3b374b..000000000 --- a/packages/xr/src/feature/trackable/image/XRRequestImage.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { IXRRequestImage } from "@galacean/engine-design"; -import { XRRequestTracking } from "../XRRequestTracking"; -import { XRReferenceImage } from "./XRReferenceImage"; -import { XRTrackedImage } from "./XRTrackedImage"; - -/** - * The request image in XR space. - */ -export class XRRequestImage extends XRRequestTracking implements IXRRequestImage { - /** - * @param image - The image to be tracked - */ - constructor(public image: XRReferenceImage) { - super(); - } -} diff --git a/packages/xr/src/feature/trackable/image/XRTrackedImage.ts b/packages/xr/src/feature/trackable/image/XRTrackedImage.ts deleted file mode 100644 index 11c91d1ba..000000000 --- a/packages/xr/src/feature/trackable/image/XRTrackedImage.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IXRTrackedImage } from "@galacean/engine-design"; -import { XRTracked } from "../XRTracked"; -import { XRReferenceImage } from "./XRReferenceImage"; - -/** - * A tracked image in XR space. - */ -export class XRTrackedImage extends XRTracked implements IXRTrackedImage { - /** The reference image which was used to detect this image in the environment. */ - referenceImage: XRReferenceImage; - /** The width of the image in meters in the physical world. */ - measuredPhysicalWidth: number; -} diff --git a/packages/xr/src/feature/trackable/plane/XRPlaneMode.ts b/packages/xr/src/feature/trackable/plane/XRPlaneMode.ts deleted file mode 100644 index a59dcef22..000000000 --- a/packages/xr/src/feature/trackable/plane/XRPlaneMode.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Enumerates modes of plane in XR. - */ -export enum XRPlaneMode { - /** None. */ - None = 0, - /** Horizontal */ - Horizontal = 0b1, - /** Vertical */ - Vertical = 0b10, - /** Includes horizontal and vertical. */ - EveryThing = 0b11 -} diff --git a/packages/xr/src/feature/trackable/plane/XRPlaneTracking.ts b/packages/xr/src/feature/trackable/plane/XRPlaneTracking.ts deleted file mode 100644 index d9ea3add9..000000000 --- a/packages/xr/src/feature/trackable/plane/XRPlaneTracking.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { XRManagerExtended, registerXRFeature } from "../../../XRManagerExtended"; -import { XRFeatureType } from "../../XRFeatureType"; -import { XRTrackableFeature } from "../XRTrackableFeature"; -import { XRPlaneMode } from "./XRPlaneMode"; -import { XRRequestPlane } from "./XRRequestPlane"; -import { XRTrackedPlane } from "./XRTrackedPlane"; - -/** - * The manager of plane tracking feature. - */ -@registerXRFeature(XRFeatureType.PlaneTracking) -export class XRPlaneTracking extends XRTrackableFeature { - /** - * The plane detection mode. - */ - get detectionMode(): XRPlaneMode { - return this._requestTrackings[0].detectionMode; - } - - /** - * The tracked planes. - */ - get trackedPlanes(): readonly XRTrackedPlane[] { - return this._tracked; - } - - /** - * @param xrManager - The xr manager - * @param detectionMode - The plane detection mode - */ - constructor(xrManager: XRManagerExtended, detectionMode: XRPlaneMode = XRPlaneMode.EveryThing) { - super(xrManager, XRFeatureType.PlaneTracking, detectionMode); - this._addRequestTracking(new XRRequestPlane(detectionMode)); - } - - protected override _generateTracked(): XRTrackedPlane { - const plane = new XRTrackedPlane(); - plane.id = XRTrackableFeature._uuid++; - return plane; - } -} diff --git a/packages/xr/src/feature/trackable/plane/XRRequestPlane.ts b/packages/xr/src/feature/trackable/plane/XRRequestPlane.ts deleted file mode 100644 index eaf57a795..000000000 --- a/packages/xr/src/feature/trackable/plane/XRRequestPlane.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { IXRRequestPlane } from "@galacean/engine-design"; -import { XRRequestTracking } from "../XRRequestTracking"; -import { XRTrackedPlane } from "./XRTrackedPlane"; - -/** - * The request plane in XR space. - */ -export class XRRequestPlane extends XRRequestTracking implements IXRRequestPlane { - /** - * @param detectionMode - The plane detection mode - */ - constructor(public detectionMode: number) { - super(); - } -} diff --git a/packages/xr/src/feature/trackable/plane/XRTrackedPlane.ts b/packages/xr/src/feature/trackable/plane/XRTrackedPlane.ts deleted file mode 100644 index 9ecb8a193..000000000 --- a/packages/xr/src/feature/trackable/plane/XRTrackedPlane.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Vector3 } from "@galacean/engine"; -import { IXRTrackedPlane } from "@galacean/engine-design"; -import { XRTracked } from "../XRTracked"; -import { XRPlaneMode } from "./XRPlaneMode"; - -/** - * The tracked plane in XR space. - */ -export class XRTrackedPlane extends XRTracked implements IXRTrackedPlane { - /** Whether the detected plane is horizontal or vertical. */ - planeMode: XRPlaneMode; - /** The points that make up this plane. - * Note: These points are in the plane coordinate system, - * and their Y coordinates are all zero. - */ - polygon: Vector3[] = []; - /** - * Whether this frame changes the attributes of the plane. - * Note: Includes `polygon` but no `pose`. - */ - attributesDirty: boolean = false; -} diff --git a/packages/xr/src/index.ts b/packages/xr/src/index.ts deleted file mode 100644 index 15e94bdbd..000000000 --- a/packages/xr/src/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -// xr manager -import "./XRManagerExtended"; -// xr pose -export { XRPose } from "./XRPose"; -// xr feature -export { XRFeature } from "./feature/XRFeature"; -export { XRTrackableFeature } from "./feature/trackable/XRTrackableFeature"; -export { XRTracked } from "./feature/trackable/XRTracked"; -// camera -export { XRCameraManager } from "./feature/camera/XRCameraManager"; -// hitTest -export { TrackableType } from "./feature/hitTest/TrackableType"; -export { XRHitResult } from "./feature/hitTest/XRHitResult"; -export { XRHitTest } from "./feature/hitTest/XRHitTest"; -// anchor tracking -export { XRAnchor } from "./feature/trackable/anchor/XRAnchor"; -export { XRAnchorTracking } from "./feature/trackable/anchor/XRAnchorTracking"; -// image tracking -export { XRImageTracking } from "./feature/trackable/image/XRImageTracking"; -export { XRReferenceImage } from "./feature/trackable/image/XRReferenceImage"; -export { XRTrackedImage } from "./feature/trackable/image/XRTrackedImage"; -// plane Tracking -export { XRPlaneMode } from "./feature/trackable/plane/XRPlaneMode"; -export { XRPlaneTracking } from "./feature/trackable/plane/XRPlaneTracking"; -export { XRTrackedPlane } from "./feature/trackable/plane/XRTrackedPlane"; -// xr input -export { XRCamera } from "./input/XRCamera"; -export { XRController } from "./input/XRController"; -export { XRInputButton } from "./input/XRInputButton"; -export { XRInputManager } from "./input/XRInputManager"; -export { XRTrackedInputDevice } from "./input/XRTrackedInputDevice"; -export { XRTrackingState } from "./input/XRTrackingState"; -// xr session -export { XRSessionManager } from "./session/XRSessionManager"; -export { XRSessionMode } from "./session/XRSessionMode"; -export { XRSessionState } from "./session/XRSessionState"; - -// only use in xr backend -export { XRFeatureType } from "./feature/XRFeatureType"; -export { XRRequestTrackingState } from "./feature/trackable/XRRequestTrackingState"; -export { XRInputEventType } from "./input/XRInputEventType"; -export { XRTargetRayMode } from "./input/XRTargetRayMode"; - -export * from "./loader/XRReferenceImageDecoder"; -export * from "./loader/XRReferenceImageLoader"; diff --git a/packages/xr/src/input/XRCamera.ts b/packages/xr/src/input/XRCamera.ts deleted file mode 100644 index c35262bbb..000000000 --- a/packages/xr/src/input/XRCamera.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { IXRCamera } from "@galacean/engine-design"; -import { Matrix, Rect, Camera } from "@galacean/engine"; -import { XRPose } from "../XRPose"; -import { XRInput } from "./XRInput"; - -/** - * The XR camera. - */ -export class XRCamera extends XRInput implements IXRCamera { - /** The pose of the camera in XR space. */ - pose: XRPose = new XRPose(); - /** The viewport of the camera. */ - viewport: Rect = new Rect(); - /** The projection matrix of the camera. */ - projectionMatrix: Matrix = new Matrix(); - - /** @internal */ - _camera: Camera; -} diff --git a/packages/xr/src/input/XRController.ts b/packages/xr/src/input/XRController.ts deleted file mode 100644 index bdb8b46c5..000000000 --- a/packages/xr/src/input/XRController.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { IXRController } from "@galacean/engine-design"; -import { XRPose } from "../XRPose"; -import { XRInput } from "./XRInput"; -import { XRInputButton } from "./XRInputButton"; - -/** - * The XR controller. - */ -export class XRController extends XRInput implements IXRController { - /** The grip space pose of the controller in XR space. */ - gripPose: XRPose = new XRPose(); - /** The target ray space pose of the controller in XR space. */ - targetRayPose: XRPose = new XRPose(); - /** The currently pressed buttons of this controller. */ - pressedButtons: XRInputButton = XRInputButton.None; - /** Record button lifted. */ - down: XRInputButton = XRInputButton.None; - /** Record button pressed. */ - up: XRInputButton = XRInputButton.None; - - /** - * - * Returns whether the button is pressed. - * @param button - The button to check - * @returns Whether the button is pressed - */ - isButtonDown(button: XRInputButton): boolean { - return (this.down & button) !== 0; - } - - /** - * Returns whether the button is lifted. - * @param button - The button to check - * @returns Whether the button is lifted - */ - isButtonUp(button: XRInputButton): boolean { - return (this.up & button) !== 0; - } - - /** - * Returns whether the button is held down. - * @param button - The button to check - * @returns Whether the button is held down - */ - isButtonHeldDown(button: XRInputButton): boolean { - return (this.pressedButtons & button) !== 0; - } -} diff --git a/packages/xr/src/input/XRInput.ts b/packages/xr/src/input/XRInput.ts deleted file mode 100644 index 856c624b4..000000000 --- a/packages/xr/src/input/XRInput.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IXRInput } from "@galacean/engine-design"; -import { XRTrackedInputDevice } from "./XRTrackedInputDevice"; -import { XRTrackingState } from "./XRTrackingState"; - -export class XRInput implements IXRInput { - /** The tracking state of xr input. */ - trackingState: XRTrackingState = XRTrackingState.NotTracking; - - /** - * @internal - */ - constructor(public type: XRTrackedInputDevice) {} -} diff --git a/packages/xr/src/input/XRInputButton.ts b/packages/xr/src/input/XRInputButton.ts deleted file mode 100644 index ed50c6293..000000000 --- a/packages/xr/src/input/XRInputButton.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Enum for XR input button. - */ -export enum XRInputButton { - /** None */ - None = 0x0, - /** Select */ - Select = 0x1, - /** Select */ - Trigger = 0x1, - /** Squeeze */ - Squeeze = 0x2, - /** TouchPad */ - TouchPad = 0x4, - /** A */ - AButton = 0x8, - /** B */ - BButton = 0x10 -} diff --git a/packages/xr/src/input/XRInputEventType.ts b/packages/xr/src/input/XRInputEventType.ts deleted file mode 100644 index 93b7141c4..000000000 --- a/packages/xr/src/input/XRInputEventType.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum XRInputEventType { - SelectStart, - Select, - SelectEnd, - SqueezeStart, - Squeeze, - SqueezeEnd -} diff --git a/packages/xr/src/input/XRInputManager.ts b/packages/xr/src/input/XRInputManager.ts deleted file mode 100644 index 58d4e25aa..000000000 --- a/packages/xr/src/input/XRInputManager.ts +++ /dev/null @@ -1,215 +0,0 @@ -import { Engine, SafeLoopArray } from "@galacean/engine"; -import { IXRInputEvent } from "@galacean/engine-design"; -import { IXRListener, XRManagerExtended } from "../XRManagerExtended"; -import { XRCamera } from "./XRCamera"; -import { XRController } from "./XRController"; -import { XRInput } from "./XRInput"; -import { XRInputButton } from "./XRInputButton"; -import { XRInputEventType } from "./XRInputEventType"; -import { XRTargetRayMode } from "./XRTargetRayMode"; -import { XRTrackedInputDevice } from "./XRTrackedInputDevice"; -import { XRTrackingState } from "./XRTrackingState"; - -/** - * The manager of XR input. - */ -export class XRInputManager { - /** @internal */ - _cameras: XRCamera[] = []; - /** @internal */ - _controllers: XRController[] = []; - - private _added: XRInput[] = []; - private _removed: XRInput[] = []; - private _trackedDevices: XRInput[] = []; - private _statusSnapshot: XRTrackingState[] = []; - private _listeners: SafeLoopArray = new SafeLoopArray(); - - /** - * @internal - */ - constructor( - private _xrManager: XRManagerExtended, - private _engine: Engine - ) { - const { _trackedDevices: trackedDevices, _controllers: controllers, _cameras: cameras } = this; - for (let i = 0; i < 6; i++) { - switch (i) { - case XRTrackedInputDevice.Camera: - case XRTrackedInputDevice.LeftCamera: - case XRTrackedInputDevice.RightCamera: - cameras.push((trackedDevices[i] = new XRCamera(i))); - break; - case XRTrackedInputDevice.Controller: - case XRTrackedInputDevice.LeftController: - case XRTrackedInputDevice.RightController: - controllers.push((trackedDevices[i] = new XRController(i))); - break; - default: - break; - } - } - this._statusSnapshot.fill(XRTrackingState.NotTracking, 0, trackedDevices.length); - } - - /** - * Returns the tracked device instance. - * @param type - The tracked input device type - * @returns The input instance - */ - getTrackedDevice(type: XRTrackedInputDevice): T { - return this._trackedDevices[type]; - } - - /** - * Add a listener for tracked device changes. - * @param listener - The listener to add - */ - addTrackedDeviceChangedListener(listener: (added: readonly XRInput[], removed: readonly XRInput[]) => void): void { - this._listeners.push({ fn: listener }); - } - - /** - * Remove a listener of tracked device changes. - * @param listener - The listener to remove - */ - removeTrackedDeviceChangedListener(listener: (added: readonly XRInput[], removed: readonly XRInput[]) => void): void { - this._listeners.findAndRemove((value) => (value.fn === listener ? (value.destroyed = true) : false)); - } - - /** - * @internal - */ - _onUpdate(): void { - const { _added: added, _removed: removed, _statusSnapshot: statusSnapshot } = this; - const { _trackedDevices: trackedDevices, _controllers: controllers } = this; - // Reset data - added.length = removed.length = 0; - for (let i = 0, n = controllers.length; i < n; i++) { - const controller = controllers[i]; - controller.down = controller.up = 0; - } - // Handle events and update tracked devices - const { _platformSession: platformSession } = this._xrManager.sessionManager; - const { events: platformEvents } = platformSession; - for (let i = 0, n = platformEvents.length; i < n; i++) { - this._handleEvent(platformEvents[i]); - } - platformSession.resetEvents(); - platformSession.frame.updateInputs(trackedDevices); - for (let i = 0, n = trackedDevices.length; i < n; i++) { - const input = trackedDevices[i]; - if (!input) continue; - const nowState = input.trackingState; - if (statusSnapshot[i] === XRTrackingState.Tracking) { - if (nowState !== XRTrackingState.Tracking) { - removed.push(input); - } - } else { - if (nowState === XRTrackingState.Tracking) { - added.push(input); - } - } - statusSnapshot[i] = nowState; - } - // Dispatch change event - if (added.length > 0 || removed.length > 0) { - const listeners = this._listeners.getLoopArray(); - for (let i = 0, n = listeners.length; i < n; i++) { - const listener = listeners[i]; - !listener.destroyed && listener.fn(added, removed); - } - } - } - - /** - * @internal - */ - _onDestroy(): void { - this._listeners.findAndRemove((value) => (value.destroyed = true)); - } - - private _handleEvent(event: IXRInputEvent): void { - const input = this._trackedDevices[event.input]; - switch (event.targetRayMode) { - case XRTargetRayMode.TrackedPointer: - switch (event.type) { - case XRInputEventType.SelectStart: - input.down |= XRInputButton.Select; - input.pressedButtons |= XRInputButton.Select; - break; - case XRInputEventType.SelectEnd: - input.up |= XRInputButton.Select; - input.pressedButtons &= ~XRInputButton.Select; - break; - case XRInputEventType.SqueezeStart: - input.down |= XRInputButton.Squeeze; - input.pressedButtons |= XRInputButton.Squeeze; - break; - case XRInputEventType.SqueezeEnd: - input.up |= XRInputButton.Squeeze; - input.pressedButtons &= ~XRInputButton.Squeeze; - break; - default: - break; - } - break; - case XRTargetRayMode.Screen: - const { _engine: engine } = this; - // @ts-ignore - const target: EventTarget = engine.inputManager._pointerManager._target; - // @ts-ignore - const canvas = engine.canvas._webCanvas; - const { clientWidth, clientHeight } = canvas; - const clientX = clientWidth * (event.x + 1) * 0.5; - const clientY = clientHeight * (event.y + 1) * 0.5; - // @ts-ignore - switch (event.type) { - case XRInputEventType.SelectStart: - target.dispatchEvent(this._makeUpPointerEvent("pointerdown", event.id, clientX, clientY)); - break; - case XRInputEventType.Select: - target.dispatchEvent(this._makeUpPointerEvent("pointermove", event.id, clientX, clientY)); - break; - case XRInputEventType.SelectEnd: - target.dispatchEvent(this._makeUpPointerEvent("pointerup", event.id, clientX, clientY)); - target.dispatchEvent(this._makeUpPointerEvent("pointerleave", event.id, clientX, clientY)); - break; - default: - break; - } - break; - default: - break; - } - } - - private _makeUpPointerEvent(type: string, pointerId: number, clientX: number, clientY: number): PointerEvent { - const eventInitDict: PointerEventInit = { - pointerId, - clientX, - clientY - }; - switch (type) { - case "pointerdown": - eventInitDict.button = 0; - eventInitDict.buttons = 1; - break; - case "pointermove": - eventInitDict.button = -1; - eventInitDict.buttons = 1; - break; - case "pointerup": - eventInitDict.button = 0; - eventInitDict.buttons = 0; - break; - case "pointerleave": - eventInitDict.button = 0; - eventInitDict.buttons = 0; - break; - default: - break; - } - return new PointerEvent(type, eventInitDict); - } -} diff --git a/packages/xr/src/input/XRTargetRayMode.ts b/packages/xr/src/input/XRTargetRayMode.ts deleted file mode 100644 index d6d2fc1d9..000000000 --- a/packages/xr/src/input/XRTargetRayMode.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum XRTargetRayMode { - Gaze, - TrackedPointer, - Screen -} diff --git a/packages/xr/src/input/XRTrackedInputDevice.ts b/packages/xr/src/input/XRTrackedInputDevice.ts deleted file mode 100644 index 4bf4b3bc9..000000000 --- a/packages/xr/src/input/XRTrackedInputDevice.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Enumerates some input devices that can be tracked.(including status, posture and other information) - */ -export enum XRTrackedInputDevice { - /** Controller */ - Controller, - /** Left controller */ - LeftController, - /** Right controller */ - RightController, - /** Camera */ - Camera, - /** Left camera */ - LeftCamera, - /** Right camera */ - RightCamera, - /** Head */ - LeftHand, - /** Right hand */ - RightHand -} diff --git a/packages/xr/src/input/XRTrackingState.ts b/packages/xr/src/input/XRTrackingState.ts deleted file mode 100644 index 227d42694..000000000 --- a/packages/xr/src/input/XRTrackingState.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Enum for XR tracking state. - */ -export enum XRTrackingState { - /** Not tracking */ - NotTracking, - /** Tracking */ - Tracking, - /** Lost track */ - TrackingLost -} diff --git a/packages/xr/src/loader/XRReferenceImageDecoder.ts b/packages/xr/src/loader/XRReferenceImageDecoder.ts deleted file mode 100644 index e7d394dd2..000000000 --- a/packages/xr/src/loader/XRReferenceImageDecoder.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { AssetPromise, BufferReader, Engine, decoder } from "@galacean/engine"; -import { XRReferenceImage } from "../feature/trackable/image/XRReferenceImage"; - -@decoder("XRReferenceImage") -export class XRReferenceImageDecoder { - static decode(engine: Engine, bufferReader: BufferReader): AssetPromise { - return new AssetPromise((resolve, reject) => { - const physicalWidth = bufferReader.nextFloat32(); - bufferReader.nextUint8(); - const img = new Image(); - img.onload = () => { - resolve(new XRReferenceImage("", img, physicalWidth)); - }; - img.src = URL.createObjectURL(new window.Blob([bufferReader.nextImagesData(1)[0]])); - }); - } -} diff --git a/packages/xr/src/loader/XRReferenceImageLoader.ts b/packages/xr/src/loader/XRReferenceImageLoader.ts deleted file mode 100644 index 847638272..000000000 --- a/packages/xr/src/loader/XRReferenceImageLoader.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { AssetPromise, decode, Loader, LoadItem, resourceLoader, ResourceManager } from "@galacean/engine"; -import { XRReferenceImage } from "../feature/trackable/image/XRReferenceImage"; - -@resourceLoader("XRReferenceImage", []) -export class XRReferenceImageLoader extends Loader { - load(item: LoadItem, resourceManager: ResourceManager): AssetPromise { - return new AssetPromise((resolve, reject) => { - resourceManager - // @ts-ignore - ._request(item.url, { ...item, type: "arraybuffer" }) - .then((data) => { - decode(data, resourceManager.engine).then((referenceImage) => { - resolve(referenceImage); - }); - }) - .catch(reject); - }); - } -} diff --git a/packages/xr/src/session/XRSessionManager.ts b/packages/xr/src/session/XRSessionManager.ts deleted file mode 100644 index f56cbd678..000000000 --- a/packages/xr/src/session/XRSessionManager.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { Engine, SafeLoopArray } from "@galacean/engine"; -import { IHardwareRenderer, IXRSession } from "@galacean/engine-design"; -import { IXRListener, XRManagerExtended } from "../XRManagerExtended"; -import { XRFeature } from "../feature/XRFeature"; -import { XRSessionMode } from "./XRSessionMode"; -import { XRSessionState } from "./XRSessionState"; - -/** - * XRSessionManager manages the life cycle of XR sessions. - */ -export class XRSessionManager { - /** @internal */ - _platformSession: IXRSession; - - private _mode: XRSessionMode = XRSessionMode.None; - private _state: XRSessionState = XRSessionState.None; - private _rhi: IHardwareRenderer; - private _raf: (callback: FrameRequestCallback) => number; - private _caf: (id: number) => void; - private _listeners: SafeLoopArray = new SafeLoopArray(); - - /** - * The current session mode( AR or VR ). - */ - get mode(): XRSessionMode { - return this._mode; - } - - /** - * Return the current session state. - */ - get state(): XRSessionState { - return this._state; - } - - /** - * Return a list of supported frame rates.(only available in-session) - */ - get supportedFrameRate(): Float32Array { - return this._platformSession.supportedFrameRates; - } - - /** - * Return the current frame rate as reported by the device. - */ - get frameRate(): number { - return this._platformSession.frameRate; - } - - /** - * @internal - */ - constructor( - private _xrManager: XRManagerExtended, - private _engine: Engine - ) { - // @ts-ignore - this._rhi = _engine._hardwareRenderer; - this._raf = requestAnimationFrame.bind(window); - this._caf = cancelAnimationFrame.bind(window); - this._onSessionExit = this._onSessionExit.bind(this); - } - - /** - * Check if the specified mode is supported. - * @param mode - The mode to check - * @returns A promise that resolves if the mode is supported, otherwise rejects - */ - isSupportedMode(mode: XRSessionMode): Promise { - return this._xrManager._platformDevice.isSupportedSessionMode(mode); - } - - /** - * Run the session. - */ - run(): void { - const { _platformSession: platformSession, _engine: engine } = this; - if (!platformSession) { - throw new Error("Without session to run."); - } - platformSession.start(); - this._setState(XRSessionState.Running); - this._xrManager._onSessionStart(); - if (!engine.isPaused) { - engine.pause(); - engine.resume(); - } - } - - /** - * Stop the session. - */ - stop(): void { - const { _platformSession: platformSession, _engine: engine, _rhi: rhi } = this; - if (!platformSession) { - throw new Error("Without session to stop."); - } - if (this._state !== XRSessionState.Running) { - throw new Error("Session is not running."); - } - rhi._mainFrameBuffer = null; - rhi._mainFrameWidth = rhi._mainFrameHeight = 0; - platformSession.stop(); - this._setState(XRSessionState.Paused); - this._xrManager._onSessionStop(); - if (!engine.isPaused) { - engine.pause(); - engine.resume(); - } - } - - /** - * Add a listening function for session state changes. - * @param listener - The listening function - */ - addStateChangedListener(listener: (state: XRSessionState) => void): void { - this._listeners.push({ fn: listener }); - } - - /** - * Remove a listening function of session state changes. - * @param listener - The listening function - */ - removeStateChangedListener(listener: (state: XRSessionState) => void): void { - this._listeners.findAndRemove((value) => (value.fn === listener ? (value.destroyed = true) : false)); - } - - /** - * @internal - */ - _setState(value: XRSessionState) { - this._state = value; - const listeners = this._listeners.getLoopArray(); - for (let i = 0, n = listeners.length; i < n; i++) { - const listener = listeners[i]; - !listener.destroyed && listener.fn(value); - } - } - - /** - * @internal - */ - _initialize(mode: XRSessionMode, features: XRFeature[]): Promise { - return new Promise((resolve, reject) => { - const { _xrManager: xrManager } = this; - // Initialize all features - const platformFeatures = []; - for (let i = 0, n = features.length; i < n; i++) { - const { _platformFeature: platformFeature } = features[i]; - platformFeature && platformFeatures.push(platformFeature); - } - xrManager._platformDevice - .requestSession(this._rhi, mode, platformFeatures) - .then((platformSession: IXRSession) => { - this._mode = mode; - this._platformSession = platformSession; - this._setState(XRSessionState.Initialized); - platformSession.setSessionExitCallBack(this._onSessionExit); - platformSession.addEventListener(); - xrManager._onSessionInit(); - resolve(); - }, reject); - }); - } - - /** - * @internal - */ - _onUpdate() { - const { _rhi: rhi, _platformSession: platformSession } = this; - rhi._mainFrameBuffer = platformSession.framebuffer; - rhi._mainFrameWidth = platformSession.framebufferWidth; - rhi._mainFrameHeight = platformSession.framebufferHeight; - } - - /** - * @internal - */ - _getRequestAnimationFrame(): (callback: FrameRequestCallback) => number { - if (this._state === XRSessionState.Running) { - return this._platformSession.requestAnimationFrame; - } else { - return this._raf; - } - } - - /** - * @internal - */ - _getCancelAnimationFrame(): (id: number) => void { - if (this._state === XRSessionState.Running) { - return this._platformSession.cancelAnimationFrame; - } else { - return this._caf; - } - } - - /** - * @internal - */ - _exit(): Promise { - const { _platformSession: platformSession } = this; - if (!platformSession) { - return Promise.reject("Without session to stop."); - } - return platformSession.end(); - } - - private _onSessionExit() { - const { _rhi: rhi, _platformSession: platformSession, _engine: engine } = this; - rhi._mainFrameBuffer = null; - rhi._mainFrameWidth = rhi._mainFrameHeight = 0; - platformSession.removeEventListener(); - this._platformSession = null; - this._setState(XRSessionState.None); - this._xrManager._onSessionExit(); - if (!engine.isPaused) { - engine.pause(); - engine.resume(); - } - } - - /** - * @internal - */ - _onDestroy(): void { - this._listeners.findAndRemove((value) => (value.destroyed = true)); - this._raf = this._caf = null; - } -} diff --git a/packages/xr/src/session/XRSessionMode.ts b/packages/xr/src/session/XRSessionMode.ts deleted file mode 100644 index 791b6efab..000000000 --- a/packages/xr/src/session/XRSessionMode.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * The type of XR session. - */ -export enum XRSessionMode { - None, - AR, - VR -} diff --git a/packages/xr/src/session/XRSessionState.ts b/packages/xr/src/session/XRSessionState.ts deleted file mode 100644 index 7895f09c1..000000000 --- a/packages/xr/src/session/XRSessionState.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * The state of an XRSession. - */ -export enum XRSessionState { - /** Not initialized. */ - None, - /** Initializing session. */ - Initializing, - /** Initialized but not started. */ - Initialized, - /** Running. */ - Running, - /** Paused. */ - Paused -} diff --git a/packages/xr/tsconfig.json b/packages/xr/tsconfig.json deleted file mode 100644 index 588b0055c..000000000 --- a/packages/xr/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "compilerOptions": { - "module": "esnext", - "target": "esnext", - "declaration": true, - "moduleResolution": "node", - "allowSyntheticDefaultImports": true, - "experimentalDecorators": true, - "declarationDir": "types", - "emitDeclarationOnly": true, - "noImplicitOverride": true, - "sourceMap": true, - "incremental": false, - "skipLibCheck": true, - "stripInternal": true - }, - "include": ["src/**/*"] -}