From aefe01860e070fa852165f1fead4deb03470ceda Mon Sep 17 00:00:00 2001 From: Vasyl Kazakov Date: Wed, 27 May 2026 12:19:17 +0300 Subject: [PATCH] impot models and set camera --- src/controllers/CameraC.ts | 14 ++++++- src/controllers/TestSceneC.ts | 72 +++++++++++++++++++++++++---------- src/controllers/ThreeC.ts | 40 ++++++++++++++++++- 3 files changed, 103 insertions(+), 23 deletions(-) diff --git a/src/controllers/CameraC.ts b/src/controllers/CameraC.ts index 80096da..77644de 100644 --- a/src/controllers/CameraC.ts +++ b/src/controllers/CameraC.ts @@ -1,5 +1,5 @@ import { CameraC_internal, Helper, Template } from "@24tools/playable_template"; -import { PerspectiveCamera } from "three"; +import { PerspectiveCamera, Vector3 } from "three"; export class CameraC extends CameraC_internal { static setCamera(portraitOrientation: boolean) { @@ -23,4 +23,16 @@ export class CameraC extends CameraC_internal { } } } + + static setTopDownCamera() { + if (this.camera !== null) { + this.camera.position.set(20, 10, -5); + this.camera.rotation.set(-5 * Math.PI / 12, 0, 0); + this.camera.lookAt(new Vector3(0, 0, 0)); + if (this.camera instanceof PerspectiveCamera) { + this.camera.fov = 55; + this.camera.updateProjectionMatrix(); + } + } + } } diff --git a/src/controllers/TestSceneC.ts b/src/controllers/TestSceneC.ts index d91db27..62bfbc5 100644 --- a/src/controllers/TestSceneC.ts +++ b/src/controllers/TestSceneC.ts @@ -1,42 +1,72 @@ -import { BoxGeometry, Mesh, MeshStandardMaterial, Vector3 } from "three"; +import { DirectionalLight, Object3D, Vector3, Mesh, Material } from "three"; import { ThreeC } from "./ThreeC"; -import { InputC, JoystickC } from "@24tools/playable_template"; +import { CameraC } from "./CameraC"; +import { InputC, UpdateController } from "@24tools/playable_template"; export class TestSceneC { + private static character: Object3D | null = null; + static init() { - this.createPrimitive(); + this.loadMapModel(); + this.loadCharacter(); // example of using InputC events InputC.onTouchDown.addDelegate((event) => { console.log("onMouseDown", event); }); - // if you have update in your controller - // UpdateController.Instance.onUpdate.addDelegate(() => { - // this.update(); - // }); + // Update loop to follow character with camera + UpdateController.Instance.onUpdate.addDelegate(() => { + this.updateCameraFollow(); + }); } - private static createPrimitive() { - const geometry = new BoxGeometry(1, 1, 1); - const material = new MeshStandardMaterial({ color: 0xcc0000 }); - const cube = new Mesh(geometry, material); + private static loadMapModel() { + const mapObject = ThreeC.getObject("map"); + if (!mapObject) { + console.warn("Map model resource not found: map"); + return; + } - const geometryPlane = new BoxGeometry(5, 0.1, 7); - const materialPlane = new MeshStandardMaterial({ color: 0xaaaaaa }); - const plane = new Mesh(geometryPlane, materialPlane); + mapObject.position.set(0, 0, 0); + + ThreeC.setShadowsStateForChildren(mapObject, true, true); + ThreeC.addToScene(mapObject); + } + - let planePosition = plane.position.clone(); + private static updateCameraFollow() { + if (!this.character || !CameraC.camera) return; - ThreeC.setShadowsStateForChildren(cube, true, false); + // Position camera at 75 degree angle from horizontal, slightly to the side + const charPos = this.character.position; + const angle = 70 * (Math.PI / 180); // 75 degrees + const distance = 10; + const sideOffset = 5; // offset to the left side - ThreeC.setShadowsStateForChildren(plane, false, true); + // Calculate vertical and horizontal distances based on 75 degree angle + const verticalDistance = distance * Math.sin(angle); + const horizontalDistance = distance * Math.cos(angle); - plane.position.copy( - new Vector3(planePosition.x, planePosition.y - 0.5, planePosition.z - 1.5) + CameraC.camera.position.set( + charPos.x + sideOffset, + charPos.y + verticalDistance, + charPos.z + horizontalDistance ); + CameraC.camera.lookAt(charPos.x, charPos.y + 1, charPos.z); + } - ThreeC.addToScene(cube); - ThreeC.addToScene(plane); + private static loadCharacter() { + const charObject = ThreeC.getObject("character"); + if (!charObject) { + console.warn("Character model resource not found: character"); + return; + } + + // Place character near the map center; adjust Y for ground offset + charObject.position.copy(new Vector3(0, 0, 32)); + this.character = charObject; + ThreeC.setShadowsStateForChildren(charObject, true, true); + ThreeC.addToScene(charObject); } } diff --git a/src/controllers/ThreeC.ts b/src/controllers/ThreeC.ts index 4dfd974..87b8428 100644 --- a/src/controllers/ThreeC.ts +++ b/src/controllers/ThreeC.ts @@ -1,6 +1,6 @@ import { ColorFormat } from "@24tools/ads_common"; import { ThreeC_internal, Template } from "@24tools/playable_template"; -import { AmbientLight, DirectionalLight } from "three"; +import { AmbientLight, DirectionalLight, HemisphereLight } from "three"; import { Color } from "three/src/math/Color"; export class ThreeC extends ThreeC_internal { @@ -65,4 +65,42 @@ export class ThreeC extends ThreeC_internal { dirLight.shadow.camera.near = 0.5; dirLight.shadow.camera.far = 200; } + + // static setupTopDownLighting() { + // let dirLight = this.defaultDirectionalLight; + + // if (!dirLight) { + // this.defaultDirectionalLight = new DirectionalLight(0xffffff, 2.5); + // dirLight = this.defaultDirectionalLight; + // } + + // // Позиціонуємо світло для топ-даун виду і додаємо в сцену + // dirLight.position.set(15, 20, -15); + // dirLight.intensity = 3.0; + // dirLight.target.position.set(0, 0, 0); + // dirLight.castShadow = true; + + // const d = 25; + // dirLight.shadow.camera.left = -d; + // dirLight.shadow.camera.right = d; + // dirLight.shadow.camera.top = d; + // dirLight.shadow.camera.bottom = -d; + // dirLight.shadow.mapSize.width = 2048; + // dirLight.shadow.mapSize.height = 2048; + // dirLight.shadow.camera.near = 0.5; + // dirLight.shadow.camera.far = 200; + + // this.addToScene(dirLight); + + // // Ensure ambient light exists and is stronger for top-down + // if (!this.defaultAmbientLight) { + // this.defaultAmbientLight = new AmbientLight(0xffffff, 1.5); + // } + // this.defaultAmbientLight.intensity = 1.6; + // this.addToScene(this.defaultAmbientLight); + + // // Add a soft hemisphere light to fill shadows + // const hemi = new HemisphereLight(0xffffbb, 0x080820, 0.6); + // this.addToScene(hemi); + // } }