diff --git a/src/experiences/factories/ExperienceBased.factory.ts b/src/experiences/factories/ExperienceBased.factory.ts
index fc9925e..29cb514 100644
--- a/src/experiences/factories/ExperienceBased.factory.ts
+++ b/src/experiences/factories/ExperienceBased.factory.ts
@@ -1,11 +1,16 @@
-//
+import { EventEmitter } from "events";
+
+// BLUEPRINTS
import type { ExperienceFactory } from "./Experience.factory";
// INTERFACES
import type { ExperienceBase } from "@/interfaces/experienceBase";
/** Represent a class that depend on {@link ExperienceFactory}. */
-export abstract class ExperienceBasedFactory implements ExperienceBase {
+export abstract class ExperienceBasedFactory
+ extends EventEmitter
+ implements ExperienceBase
+{
protected abstract readonly _experience: ExperienceFactory;
public abstract construct(): unknown;
diff --git a/src/experiences/pages/Home/Camera.ts b/src/experiences/pages/Home/Camera.ts
index a9ba5b0..541a973 100644
--- a/src/experiences/pages/Home/Camera.ts
+++ b/src/experiences/pages/Home/Camera.ts
@@ -29,7 +29,7 @@ export class Camera implements ExperienceBase {
if (!(this._appCamera?.instance instanceof PerspectiveCamera)) return;
this._appCamera.instance.fov = this.initialCameraFov;
- this._appCamera.instance.far = 50;
+ this._appCamera.instance.far = 500;
this._appCamera.miniCamera?.position.set(10, 8, 30);
if (this._appDebug?.cameraControls) {
diff --git a/src/experiences/pages/Home/Debug.ts b/src/experiences/pages/Home/Debug.ts
index 8a84af9..28cb1e2 100644
--- a/src/experiences/pages/Home/Debug.ts
+++ b/src/experiences/pages/Home/Debug.ts
@@ -1,5 +1,6 @@
import {
BufferGeometry,
+ CameraHelper,
Line,
LineBasicMaterial,
Mesh,
@@ -8,7 +9,7 @@ import {
SphereGeometry,
Vector3,
} from "three";
-import GUI from "lil-gui";
+import GUI from "three/examples/jsm/libs/lil-gui.module.min.js";
// EXPERIENCE
import Experience from ".";
@@ -20,6 +21,7 @@ export default class Debug implements ExperienceBase {
protected readonly _experience = new Experience();
protected readonly _appDebug = this._experience.app.debug;
protected readonly _appCamera = this._experience.app.camera;
+ protected _worldSecondaryCameraHelper?: CameraHelper;
/** Graphic user interface of the experience instance */
protected _gui?: GUI;
@@ -50,15 +52,18 @@ export default class Debug implements ExperienceBase {
if (!this._gui || !this._experience.world) return;
- // this._gui.add(
- // { destruct_experience: () => this._experience?.destruct() },
- // "destruct_experience"
- // );
-
this.cameraLookAtPointIndicator = new Mesh(
new SphereGeometry(0.1, 12, 12),
new MeshBasicMaterial({ color: "#ff0040" })
);
+ this.cameraLookAtPointIndicator.visible = false;
+
+ if (!this._experience.world?.secondaryCamera) return;
+
+ this._worldSecondaryCameraHelper = new CameraHelper(
+ this._experience.world.secondaryCamera
+ );
+ this._experience.app.scene.add(this._worldSecondaryCameraHelper);
this._gui
.add(
@@ -120,17 +125,6 @@ export default class Debug implements ExperienceBase {
)
.name("Toggle auto camera animation");
- this._gui
- .add(
- {
- fn: () => {
- this._experience.world?.nextScene();
- },
- },
- "fn"
- )
- .name("Next Scene");
-
this._experience.app.scene.add(
this._cameraCurvePathLine,
this.cameraLookAtPointIndicator
diff --git a/src/experiences/pages/Home/Loader.ts b/src/experiences/pages/Home/Loader.ts
index 9dfc373..4c4843f 100644
--- a/src/experiences/pages/Home/Loader.ts
+++ b/src/experiences/pages/Home/Loader.ts
@@ -1,4 +1,4 @@
-import { Mesh, MeshBasicMaterial, SRGBColorSpace, Texture } from "three";
+import { MeshBasicMaterial, Texture, SRGBColorSpace } from "three";
import EventEmitter from "events";
// ---
diff --git a/src/experiences/pages/Home/Renderer.ts b/src/experiences/pages/Home/Renderer.ts
index d562bd0..ef69cff 100644
--- a/src/experiences/pages/Home/Renderer.ts
+++ b/src/experiences/pages/Home/Renderer.ts
@@ -1,10 +1,14 @@
import {
ACESFilmicToneMapping,
+ Box3,
+ Matrix4,
+ Mesh,
PCFShadowMap,
+ PerspectiveCamera,
SRGBColorSpace,
Vector3,
+ WebGLRenderTarget,
} from "three";
-import * as CameraUtils from "three/examples/jsm/utils/CameraUtils";
// EXPERIENCE
import HomeExperience from ".";
@@ -14,21 +18,33 @@ import { type ExperienceBase } from "@/interfaces/experienceBase";
export interface PortalAssets {
mesh: THREE.Mesh;
- texture: THREE.WebGLRenderTarget;
- camera: THREE.PerspectiveCamera;
+ meshWebGLTexture: THREE.WebGLRenderTarget;
+ meshCamera: THREE.PerspectiveCamera;
+}
+
+export interface PortalMeshCorners {
+ bottomLeft: Vector3;
+ bottomRight: Vector3;
+ topLeft: Vector3;
+ topRight: Vector3;
}
/** Renderer */
export default class Renderer implements ExperienceBase {
protected readonly _experience = new HomeExperience();
protected readonly _appRenderer = this._experience.app.renderer;
+ protected readonly _appRendererInstance =
+ this._experience.app.renderer.instance;
protected readonly _renderPortalAssets: {
- [callbackName: string]: PortalAssets;
+ [callbackName: string]: {
+ assets: PortalAssets;
+ corners: PortalMeshCorners;
+ };
} = {};
- protected _currentRenderTarget = this._appRenderer.instance.getRenderTarget();
- protected _currentXrEnabled = this._appRenderer.instance.xr.enabled;
+ protected _currentRenderTarget = this._appRendererInstance.getRenderTarget();
+ protected _currentXrEnabled = this._appRendererInstance.xr.enabled;
protected _currentShadowAutoUpdate =
- this._appRenderer.instance.shadowMap.autoUpdate;
+ this._appRendererInstance.shadowMap.autoUpdate;
protected _portalBottomLeftCorner = new Vector3();
protected _portalBottomRightCorner = new Vector3();
protected _portalTopLeftCorner = new Vector3();
@@ -37,21 +53,23 @@ export default class Renderer implements ExperienceBase {
constructor() {}
public construct() {
- this._appRenderer.instance.useLegacyLights = true;
- this._appRenderer.instance.outputColorSpace = SRGBColorSpace;
- this._appRenderer.instance.toneMapping = ACESFilmicToneMapping;
- this._appRenderer.instance.toneMappingExposure = 1;
- this._appRenderer.instance.shadowMap.enabled = false;
- this._appRenderer.instance.shadowMap.type = PCFShadowMap;
- this._appRenderer.instance.setClearColor("#211d20");
- this._appRenderer.instance.setSize(
- this._experience.app.sizes.width,
- this._experience.app.sizes.height
- );
- this._appRenderer.instance.setPixelRatio(
- this._experience.app.sizes.pixelRatio
- );
- this._appRenderer.instance.localClippingEnabled = true;
+ // Configure renderer behaviors
+ ~(() => {
+ this._appRendererInstance.outputColorSpace = SRGBColorSpace;
+ this._appRendererInstance.toneMapping = ACESFilmicToneMapping;
+ this._appRendererInstance.toneMappingExposure = 1;
+ this._appRendererInstance.shadowMap.enabled = false;
+ this._appRendererInstance.shadowMap.type = PCFShadowMap;
+ this._appRendererInstance.setClearColor("#211d20");
+ this._appRendererInstance.setSize(
+ this._experience.app.sizes.width,
+ this._experience.app.sizes.height
+ );
+ this._appRendererInstance.setPixelRatio(
+ this._experience.app.sizes.pixelRatio
+ );
+ this._appRendererInstance.localClippingEnabled = true;
+ })();
~(() => {
this._appRenderer.beforeRenderUpdate = () => {
@@ -60,24 +78,23 @@ export default class Renderer implements ExperienceBase {
Object.keys(this._renderPortalAssets).forEach((key: string) => {
if (this._renderPortalAssets[key]) {
this._currentRenderTarget =
- this._appRenderer.instance.getRenderTarget();
- this._currentXrEnabled = this._appRenderer.instance.xr.enabled;
+ this._appRendererInstance.getRenderTarget();
+ this._currentXrEnabled = this._appRendererInstance.xr.enabled;
this._currentShadowAutoUpdate =
- this._appRenderer.instance.shadowMap.autoUpdate;
- // Avoid camera modification
- this._appRenderer.instance.xr.enabled = false;
- // Avoid re-computing shadows
- this._appRenderer.instance.shadowMap.autoUpdate = false;
+ this._appRendererInstance.shadowMap.autoUpdate;
+ this._appRendererInstance.xr.enabled = false;
+ this._appRendererInstance.shadowMap.autoUpdate = false;
this.renderPortal(
- this._renderPortalAssets[key].mesh,
- this._renderPortalAssets[key].texture,
- this._renderPortalAssets[key].camera
+ this._renderPortalAssets[key].assets.mesh,
+ this._renderPortalAssets[key].assets.meshWebGLTexture,
+ this._renderPortalAssets[key].assets.meshCamera,
+ this._renderPortalAssets[key].corners
);
// restore the original rendering properties
- this._appRenderer.instance.xr.enabled = this._currentXrEnabled;
- this._appRenderer.instance.shadowMap.autoUpdate =
+ this._appRendererInstance.xr.enabled = this._currentXrEnabled;
+ this._appRendererInstance.shadowMap.autoUpdate =
this._currentShadowAutoUpdate;
- this._appRenderer.instance.setRenderTarget(
+ this._appRendererInstance.setRenderTarget(
this._currentRenderTarget
);
}
@@ -92,49 +109,78 @@ export default class Renderer implements ExperienceBase {
}
public renderPortal(
- mesh: THREE.Mesh,
- texture: THREE.WebGLRenderTarget,
- portalCamera: THREE.PerspectiveCamera
+ mesh: Mesh,
+ meshWebGLTexture: WebGLRenderTarget,
+ portalCamera: PerspectiveCamera,
+ corners: PortalMeshCorners
) {
- // set the portal camera position to be reflected about the portal plane
- mesh.worldToLocal(
- this._portalReflectedPosition.copy(
- this._experience.app.camera.instance?.position ?? new Vector3()
+ mesh.localToWorld(
+ this._portalBottomLeftCorner.set(
+ corners.bottomLeft.x,
+ corners.bottomLeft.y,
+ corners.bottomLeft.z
)
);
- this._portalReflectedPosition.x *= -1.0;
- this._portalReflectedPosition.z *= -1.0;
-
- mesh.localToWorld(this._portalReflectedPosition);
- portalCamera.position.copy(this._portalReflectedPosition);
-
- mesh.localToWorld(this._portalBottomLeftCorner.set(50.05, -50.05, 0.0));
- mesh.localToWorld(this._portalBottomRightCorner.set(-50.05, -50.05, 0.0));
- mesh.localToWorld(this._portalTopLeftCorner.set(50.05, 50.05, 0.0));
-
- // set the projection matrix to encompass the portal's frame
- CameraUtils.frameCorners(
- portalCamera,
- this._portalBottomLeftCorner,
- this._portalBottomRightCorner,
- this._portalTopLeftCorner,
- false
+ mesh.localToWorld(
+ this._portalBottomRightCorner.set(
+ corners.bottomRight.x,
+ corners.bottomRight.y,
+ corners.bottomRight.z
+ )
+ );
+ mesh.localToWorld(
+ this._portalTopLeftCorner.set(
+ corners.topLeft.x,
+ corners.topLeft.y,
+ corners.topLeft.z
+ )
);
- // render the portal
- texture.texture.colorSpace = this._appRenderer.instance.outputColorSpace;
-
- this._appRenderer.instance.setRenderTarget(texture);
- this._appRenderer.instance.state.buffers.depth.setMask(true); // making sure the depth buffer is writable so it can be properly cleared, see #18897
- if (this._appRenderer.instance.autoClear === false)
- this._appRenderer.instance.clear();
- mesh.visible = false; // hide this portal from its own rendering
- this._appRenderer.instance.render(this._experience.app.scene, portalCamera);
- mesh.visible = true; // re-enable this portal's visibility for general rendering
+ this._appRendererInstance.setRenderTarget(meshWebGLTexture);
+ this._appRendererInstance.state.buffers.depth.setMask(true);
+ if (this._appRendererInstance.autoClear === false)
+ this._appRendererInstance.clear();
+ mesh.visible = false;
+ this._appRendererInstance.render(this._experience.app.scene, portalCamera);
+ mesh.visible = true;
}
public addPortalMeshAssets(portalName: string, assets: PortalAssets): void {
- this._renderPortalAssets[portalName] = assets;
+ // Calculate width, height
+ const boundingBox = new Box3().setFromObject(assets.mesh);
+ const width = boundingBox.max.x - boundingBox.min.x;
+ const height = boundingBox.max.y - boundingBox.min.y;
+ const halfWidth = width / 2;
+ const halfHeight = height / 2;
+
+ // Define the corners of the plane in local coordinates
+ const corners = [
+ new Vector3(-halfWidth, -halfHeight, 0),
+ new Vector3(halfWidth, -halfHeight, 0),
+ new Vector3(-halfWidth, halfHeight, 0),
+ new Vector3(halfWidth, halfHeight, 0),
+ ];
+
+ // Apply the mesh's position and rotation to the corners
+ const matrix = new Matrix4();
+ matrix.makeRotationFromQuaternion(assets.mesh.quaternion);
+ matrix.setPosition(assets.mesh.position);
+ matrix.compose(
+ assets.mesh.position,
+ assets.mesh.quaternion,
+ assets.mesh.scale
+ );
+ corners.map((corner) => corner.applyMatrix4(matrix));
+
+ this._renderPortalAssets[portalName] = {
+ assets,
+ corners: {
+ bottomLeft: corners[0],
+ bottomRight: corners[1],
+ topLeft: corners[2],
+ topRight: corners[3],
+ },
+ };
}
public removeBeforeUpdateCallback(portalName: string): void {
diff --git a/src/experiences/pages/Home/World/Scene_1.ts b/src/experiences/pages/Home/World/Scene_1.ts
index 3bb267c..2eccc59 100644
--- a/src/experiences/pages/Home/World/Scene_1.ts
+++ b/src/experiences/pages/Home/World/Scene_1.ts
@@ -1,9 +1,14 @@
import {
CatmullRomCurve3,
+ Color,
+ Group,
Material,
Mesh,
MeshBasicMaterial,
+ NoColorSpace,
PerspectiveCamera,
+ PlaneGeometry,
+ RawShaderMaterial,
Vector3,
WebGLRenderTarget,
} from "three";
@@ -15,9 +20,18 @@ import { SceneFactory } from "@/experiences/factories/SceneFactory";
// CONSTANTS
import { GSAP_DEFAULT_INTRO_PROPS } from "@/constants/ANIMATION";
+// SHADERS
+import fragment from "./shaders/scene1/fragment.frag";
+import vertex from "./shaders/scene1/vertex.vert";
+
export default class Scene_1 extends SceneFactory {
protected _renderer = this._experience.renderer;
+ public pcScreenWebglTexture?: WebGLRenderTarget;
+ public pcScreen?: Mesh;
+
+ modelScene2?: Group;
+
constructor() {
try {
super({
@@ -35,7 +49,7 @@ export default class Scene_1 extends SceneFactory {
linkedTextureName: "scene_1_room_baked_texture",
},
{
- childName: "scene_1_room_woods",
+ childName: "scene_1_woods",
linkedTextureName: "scene_1_room_woods_baked_texture",
},
],
@@ -48,34 +62,33 @@ export default class Scene_1 extends SceneFactory {
this.modelScene = this._model?.scene.clone();
if (!this.modelScene) return;
- this.cameraPath.getPointAt(0, this._appCamera.instance.position);
- this._appCamera.instance.position.y += 8;
- this._appCamera.instance.position.x -= 2;
- this._appCamera.instance.position.z += 10;
-
try {
this.modelScene.children.forEach((child) => {
- if (child.name === "scene_1_room_pc_screen")
+ if (child.name === "scene_1_pc_screen")
throw new Error("CHILD_FOUND", { cause: child });
});
} catch (_err) {
if (_err instanceof Error && _err.cause instanceof Mesh) {
- const mesh = _err.cause;
- const camera = new PerspectiveCamera(75, 1.0, 0.1, 500.0);
- const texture = new WebGLRenderTarget(256, 256);
- mesh.material = new MeshBasicMaterial({ map: texture.texture });
-
- this._renderer?.addPortalMeshAssets(Scene_1.name + "_screen_pc", {
- mesh,
- camera,
- texture,
+ const planeGeo = new PlaneGeometry(1.25, 0.6728);
+ this.pcScreenWebglTexture = new WebGLRenderTarget(4096, 4096);
+ this.pcScreen = new Mesh(planeGeo);
+ this.pcScreen.material = new MeshBasicMaterial({
+ map: this.pcScreenWebglTexture.texture,
});
+
+ // TODO:: Correctly setup the portal by passing the texture to the screen it self
+ this.pcScreen.rotateY(Math.PI * 0.271);
+ this.pcScreen.rotateX(Math.PI * -0.03);
+ this.pcScreen.position.z += 0.048;
+ this.pcScreen.position.x -= 0.01;
+ _err.cause.localToWorld(this.pcScreen.position);
+ _err.cause.removeFromParent();
+
+ this.modelScene.add(this.pcScreen);
}
}
this._setModelMaterials();
- this._experience.world?.group?.add(this.modelScene);
-
this.emit("constructed");
}
@@ -89,6 +102,7 @@ export default class Scene_1 extends SceneFactory {
onComplete: () => {
this.modelScene?.clear();
this.modelScene?.removeFromParent();
+ this._renderer?.removeBeforeUpdateCallback(Scene_1.name + "_screen_pc");
this.emit(this.eventListNames.destructed);
},
});
@@ -131,4 +145,38 @@ export default class Scene_1 extends SceneFactory {
public outro(): void {}
public update(): void {}
+
+ protected _setModelMaterials() {
+ const TEXTURES_MESH_BASIC_MATERIALS =
+ this._Loader?.texturesMeshBasicMaterials;
+
+ if (!TEXTURES_MESH_BASIC_MATERIALS) return;
+
+ this.modelScene?.children.forEach((child) => {
+ this._modelChildrenTextures.forEach((item) => {
+ const CHILD_TEXTURE =
+ TEXTURES_MESH_BASIC_MATERIALS[item.linkedTextureName].clone();
+
+ if (
+ child instanceof Mesh &&
+ child.name === item.childName &&
+ CHILD_TEXTURE.map
+ ) {
+ const MAP_TEXTURE = CHILD_TEXTURE.map.clone();
+ MAP_TEXTURE.colorSpace = NoColorSpace;
+
+ ~(child.material = new RawShaderMaterial({
+ uniforms: {
+ uBakedTexture: { value: MAP_TEXTURE },
+ uTime: { value: 0 },
+ uColor: { value: new Color(0x00ff00) },
+ },
+ fragmentShader: fragment,
+ vertexShader: vertex,
+ transparent: true,
+ }));
+ }
+ });
+ });
+ }
}
diff --git a/src/experiences/pages/Home/World/Scene_2.ts b/src/experiences/pages/Home/World/Scene_2.ts
index 3f70670..24e2215 100644
--- a/src/experiences/pages/Home/World/Scene_2.ts
+++ b/src/experiences/pages/Home/World/Scene_2.ts
@@ -19,31 +19,26 @@ export default class Scene_2 extends SceneFactory {
new Vector3(12, 3.7, 12),
new Vector3(0, 5.5, 21),
]),
+ modelName: "scene_1_room",
modelChildrenTextures: [
{
childName: "scene_1_room",
linkedTextureName: "scene_1_room_baked_texture",
},
+ {
+ childName: "scene_1_woods",
+ linkedTextureName: "scene_1_room_woods_baked_texture",
+ },
],
});
} catch (error) {}
}
construct() {
- if (!this._appCamera.instance) return;
-
- const ISOMETRIC_ROOM = this._experience.app.resources.items.scene_1_room as
- | GLTF
- | undefined;
-
- this.cameraPath.getPointAt(0, this._appCamera.instance.position);
- this._appCamera.instance.position.y += 8;
- this._appCamera.instance.position.x -= 2;
- this._appCamera.instance.position.z += 10;
+ this.modelScene = this._model?.scene.clone();
+ if (!this.modelScene) return;
- this.model = ISOMETRIC_ROOM;
- this.modelScene = this.model?.scene.clone();
- this.modelScene && this._experience.world?.group?.add(this.modelScene);
+ this.modelScene.position.set(20, 0, 0);
this._setModelMaterials();
this.emit("constructed");
diff --git a/src/experiences/pages/Home/World/Scene_3.ts b/src/experiences/pages/Home/World/Scene_3.ts
index 31fd225..a86ca9e 100644
--- a/src/experiences/pages/Home/World/Scene_3.ts
+++ b/src/experiences/pages/Home/World/Scene_3.ts
@@ -1,5 +1,4 @@
import { CatmullRomCurve3, PerspectiveCamera, Vector3 } from "three";
-import { type GLTF } from "three/examples/jsm/loaders/GLTFLoader.js";
import GSAP from "gsap";
// EXPERIENCES
@@ -19,31 +18,26 @@ export default class Scene_3 extends SceneFactory {
new Vector3(12, 3.7, 12),
new Vector3(0, 5.5, 21),
]),
+ modelName: "scene_1_room",
modelChildrenTextures: [
{
childName: "scene_1_room",
linkedTextureName: "scene_1_room_baked_texture",
},
+ {
+ childName: "scene_1_woods",
+ linkedTextureName: "scene_1_room_woods_baked_texture",
+ },
],
});
} catch (error) {}
}
construct() {
- if (!this._appCamera.instance) return;
-
- const ISOMETRIC_ROOM = this._experience.app.resources.items.scene_1_room as
- | GLTF
- | undefined;
-
- this.cameraPath.getPointAt(0, this._appCamera.instance.position);
- this._appCamera.instance.position.y += 8;
- this._appCamera.instance.position.x -= 2;
- this._appCamera.instance.position.z += 10;
+ this.modelScene = this._model?.scene.clone();
+ if (!this.modelScene) return;
- this.model = ISOMETRIC_ROOM;
- this.modelScene = this.model?.scene.clone();
- this.modelScene && this._experience.world?.group?.add(this.modelScene);
+ this.modelScene.position.set(18, 0, 0);
this._setModelMaterials();
this.emit("constructed");
diff --git a/src/experiences/pages/Home/World/index.ts b/src/experiences/pages/Home/World/index.ts
index 797b865..7f6c9fc 100644
--- a/src/experiences/pages/Home/World/index.ts
+++ b/src/experiences/pages/Home/World/index.ts
@@ -1,5 +1,4 @@
-import { Group, Mesh, PerspectiveCamera } from "three";
-import EventEmitter from "events";
+import { Group, Mesh, PerspectiveCamera, Vector3 } from "three";
// EXPERIENCE
import Experience from "..";
@@ -7,16 +6,20 @@ import Controls from "./Controls";
import Scene_1 from "./Scene_1";
import Scene_2 from "./Scene_2";
import Scene_3 from "./Scene_3";
-import { SceneFactory } from "@/experiences/factories/SceneFactory";
-// INTERFACES
-import { type ExperienceBase } from "@/interfaces/experienceBase";
+// BLUEPRINTS
+import { ExperienceBasedFactory } from "@/experiences/factories/ExperienceBased.factory";
-export default class World extends EventEmitter implements ExperienceBase {
+export default class World extends ExperienceBasedFactory {
protected readonly _experience = new Experience();
+ protected readonly _appCamera = this._experience.app.camera;
+ protected readonly _renderer = this._experience.renderer;
+ private scene1?: Scene_1;
+ private scene2?: Scene_2;
+ private scene3?: Scene_3;
+ public secondaryCamera?: PerspectiveCamera;
public controls?: Controls;
- public scenes?: SceneFactory[] = [];
public currentSceneIndex?: number;
/** Represent the ThreeJs `Group` containing the experience. */
public group?: Group;
@@ -41,9 +44,10 @@ export default class World extends EventEmitter implements ExperienceBase {
}
});
- this.scenes?.forEach((group) => {
- group.destruct();
- });
+ this.scene1?.destruct();
+ this.scene2?.destruct();
+ this.scene3?.destruct();
+
this._experience.app.scene.remove(this.group);
this.group?.clear();
@@ -52,77 +56,59 @@ export default class World extends EventEmitter implements ExperienceBase {
}
public construct() {
- this._experience.loader?.on("load", () => {
- if (!(this._experience.app.camera.instance instanceof PerspectiveCamera))
- return;
+ if (!(this._experience.app.camera.instance instanceof PerspectiveCamera))
+ return;
+
+ this.group = new Group();
+ this.controls = new Controls();
+
+ this.scene1 = new Scene_1();
+ this.scene2 = new Scene_2();
+ // this.scene3 = new Scene_3();
+
+ this.scene1.construct();
+ this.scene2.construct();
+ // this.scene3.construct();
+
+ this.secondaryCamera = new PerspectiveCamera(
+ (this._appCamera.instance as PerspectiveCamera).fov,
+ (this._appCamera.instance as PerspectiveCamera).aspect,
+ (this._appCamera.instance as PerspectiveCamera).near,
+ (this._appCamera.instance as PerspectiveCamera).far
+ );
+
+ this.secondaryCamera.position.copy(
+ this.scene2.modelScene?.position ?? new Vector3()
+ );
+ this.secondaryCamera.position.set(
+ this.scene2.modelScene?.position.x ?? 0,
+ 8,
+ 30
+ );
+ this.secondaryCamera.lookAt(
+ this.scene2.modelScene?.position ?? new Vector3()
+ );
+
+ if (this.scene1.pcScreen && this.scene1.pcScreenWebglTexture)
+ this._renderer?.addPortalMeshAssets(Scene_1.name + "_pc_screen", {
+ mesh: this.scene1.pcScreen,
+ meshCamera: this.secondaryCamera,
+ meshWebGLTexture: this.scene1.pcScreenWebglTexture,
+ });
- this.group = new Group();
- this.controls = new Controls();
+ this.scene1.modelScene && this.group.add(this.scene1.modelScene);
+ this.scene2.modelScene && this.group.add(this.scene2.modelScene);
- this.scenes?.push(new Scene_1(), new Scene_2(), new Scene_3());
- this._experience.app.scene.add(this.group);
- this.nextScene();
- });
+ this._experience.app.scene.add(this.group);
}
- public nextScene() {
- try {
- if (!this.scenes || !this.scenes.length) return;
-
- const PREV_INDEX = this.currentSceneIndex;
-
- ~(() => {
- if (
- typeof this.currentSceneIndex === "number" &&
- this.currentSceneIndex + 2 <= this.scenes.length
- )
- this.currentSceneIndex += 1;
- else this.currentSceneIndex = 0;
- })();
-
- ~(() => {
- const PrevScene =
- typeof PREV_INDEX === "number" ? this.scenes[PREV_INDEX] : PREV_INDEX;
- const CurrentScene = this.scenes[this.currentSceneIndex];
-
- const constructCurrentScene = () => {
- CurrentScene.construct();
- PrevScene?.off(
- PrevScene.eventListNames.destructed,
- constructCurrentScene
- );
- };
-
- if (PrevScene) {
- PrevScene.on(
- PrevScene.eventListNames.destructed,
- constructCurrentScene
- );
-
- PrevScene.destruct();
- } else constructCurrentScene();
- })();
- } catch (error) {
- // TODO: Add an error handler
- console.error(`🚧 ${World.name}->${this.nextScene.name}`, error);
- }
- }
+ public nextScene() {}
- public prevScene() {
- if (!this.scenes) return;
- if (this.currentSceneIndex === undefined) this.currentSceneIndex = 0;
- }
+ public prevScene() {}
public setScene(index: number) {}
public update() {
this.controls?.update();
-
- // Current Scene update
- // ~(() => {
- // this.currentSceneIndex !== undefined &&
- // this.scenes !== undefined &&
- // this.scenes[this.currentSceneIndex]?.update();
- // })();
}
}
diff --git a/src/experiences/pages/Home/index.ts b/src/experiences/pages/Home/index.ts
index fbf9afe..2031adc 100644
--- a/src/experiences/pages/Home/index.ts
+++ b/src/experiences/pages/Home/index.ts
@@ -59,14 +59,16 @@ export class HomeExperience extends ExperienceFactory {
this.renderer?.construct();
this.ui?.construct();
- this.loader?.construct();
this.camera?.construct();
- this.world?.construct();
- this.debug?.construct();
-
- this.app?.setUpdateCallback(HomeExperience.name, () => this.update());
+ this.loader?.construct();
- this._onConstruct && this._onConstruct();
+ this.loader?.on("load", () => {
+ this.world?.construct();
+ this.world?.on("constructed", () => console.log("Launched here ==>"));
+ this.debug?.construct();
+ this.app?.setUpdateCallback(HomeExperience.name, () => this.update());
+ this._onConstruct && this._onConstruct();
+ });
}
public update() {
diff --git a/src/layouts/default.vue b/src/layouts/default.vue
index cadb01b..0d7b784 100644
--- a/src/layouts/default.vue
+++ b/src/layouts/default.vue
@@ -1,11 +1,11 @@
-
+
-
+
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 33ce6f8..3888422 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -38,7 +38,7 @@ onBeforeUnmount(() => setTimeout(() => endExperience(), 500));
-
+