feat(nds): improve 3d model and texture display
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { useLoop, useTresContext } from "@tresjs/core";
|
||||
import * as THREE from "three";
|
||||
import gsap from "gsap";
|
||||
import { LOGICAL_WIDTH, LOGICAL_HEIGHT } from "~/utils/screen";
|
||||
|
||||
const INTRO_ANIMATION = {
|
||||
MODEL_SPIN_DURATION: 3,
|
||||
@@ -26,25 +27,25 @@ const props = defineProps<{
|
||||
const { assets } = useAssets();
|
||||
const app = useAppStore();
|
||||
|
||||
const model = assets.nintendoDs.scene.clone(true);
|
||||
const model = assets.nitendoDs.model.clone(true);
|
||||
|
||||
let topScreenTexture: THREE.CanvasTexture | null = null;
|
||||
let bottomScreenTexture: THREE.CanvasTexture | null = null;
|
||||
|
||||
/// meshes ///
|
||||
// screens
|
||||
const TOP_SCREEN = "Object_9";
|
||||
const BOTTOM_SCREEN = "Object_28";
|
||||
const LID = "Object_8";
|
||||
const TOP_SCREEN = "top_screen";
|
||||
const BOTTOM_SCREEN = "bottom_screen";
|
||||
const LID = "lid";
|
||||
|
||||
// buttons
|
||||
const CROSS_BUTTON = "Object_21";
|
||||
const X_BUTTON = "Object_6";
|
||||
const A_BUTTON = "Object_32";
|
||||
const Y_BUTTON = "Object_4";
|
||||
const B_BUTTON = "Object_30";
|
||||
const SELECT_BUTTON = "Object_17";
|
||||
const START_BUTTON = "Object_11";
|
||||
const CROSS_BUTTON = "button_pad";
|
||||
const X_BUTTON = "button_x";
|
||||
const A_BUTTON = "button_a";
|
||||
const Y_BUTTON = "button_y";
|
||||
const B_BUTTON = "button_b";
|
||||
const SELECT_BUTTON = "button_select";
|
||||
const START_BUTTON = "button_start";
|
||||
|
||||
const meshes = new Map<string, THREE.Mesh>();
|
||||
|
||||
@@ -163,21 +164,25 @@ watch(
|
||||
() => {
|
||||
if (!props.topScreenCanvas || !props.bottomScreenCanvas) return;
|
||||
|
||||
topScreenTexture = new THREE.CanvasTexture(props.topScreenCanvas);
|
||||
topScreenTexture.minFilter = THREE.NearestFilter;
|
||||
topScreenTexture.magFilter = THREE.NearestFilter;
|
||||
topScreenTexture.colorSpace = THREE.SRGBColorSpace;
|
||||
topScreenTexture.flipY = false;
|
||||
topScreenTexture.repeat.set(1, 1024 / 404);
|
||||
topScreenTexture.offset.set(0, -4 / 1024);
|
||||
const webglRenderer = renderer.instance;
|
||||
if (!(webglRenderer instanceof THREE.WebGLRenderer)) return;
|
||||
|
||||
bottomScreenTexture = new THREE.CanvasTexture(props.bottomScreenCanvas);
|
||||
bottomScreenTexture.minFilter = THREE.NearestFilter;
|
||||
bottomScreenTexture.magFilter = THREE.NearestFilter;
|
||||
bottomScreenTexture.colorSpace = THREE.SRGBColorSpace;
|
||||
bottomScreenTexture.flipY = false;
|
||||
bottomScreenTexture.repeat.set(1, 1024 / 532);
|
||||
bottomScreenTexture.offset.set(0, -1024 / 532 + 1);
|
||||
const createScreenTexture = (
|
||||
canvas: HTMLCanvasElement,
|
||||
): THREE.CanvasTexture => {
|
||||
const texture = new THREE.CanvasTexture(canvas);
|
||||
texture.minFilter = THREE.LinearFilter;
|
||||
texture.magFilter = THREE.LinearFilter;
|
||||
texture.colorSpace = THREE.SRGBColorSpace;
|
||||
texture.wrapS = THREE.RepeatWrapping;
|
||||
texture.repeat.x = -1;
|
||||
texture.anisotropy = webglRenderer.capabilities.getMaxAnisotropy();
|
||||
texture.generateMipmaps = false;
|
||||
return texture;
|
||||
};
|
||||
|
||||
topScreenTexture = createScreenTexture(props.topScreenCanvas);
|
||||
bottomScreenTexture = createScreenTexture(props.bottomScreenCanvas);
|
||||
|
||||
requireMesh(TOP_SCREEN).material = new THREE.MeshStandardMaterial({
|
||||
map: topScreenTexture,
|
||||
@@ -314,7 +319,6 @@ const handleClick = (event: MouseEvent) => {
|
||||
switch (intersection.object.name) {
|
||||
case TOP_SCREEN:
|
||||
case BOTTOM_SCREEN: {
|
||||
console.log(intersection);
|
||||
const canvas =
|
||||
intersection.object.name === TOP_SCREEN
|
||||
? props.topScreenCanvas
|
||||
@@ -322,22 +326,16 @@ const handleClick = (event: MouseEvent) => {
|
||||
|
||||
if (!canvas) break;
|
||||
|
||||
const x = Math.floor(intersection.uv.x * 256);
|
||||
let y: number;
|
||||
|
||||
if (intersection.object.name === TOP_SCREEN) {
|
||||
y = Math.floor(intersection.uv.y * (1024 / 404) * 192);
|
||||
} else {
|
||||
y = Math.floor(192 - (1 - intersection.uv.y) * (1024 / 532) * 192);
|
||||
}
|
||||
const logicalX = (1 - intersection.uv.x) * LOGICAL_WIDTH;
|
||||
const logicalY = (1 - intersection.uv.y) * LOGICAL_HEIGHT;
|
||||
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
canvas.dispatchEvent(
|
||||
new MouseEvent("click", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: (x / 256) * rect.width + rect.left,
|
||||
clientY: (y / 192) * rect.height + rect.top,
|
||||
clientX: (logicalX / LOGICAL_WIDTH) * rect.width + rect.left,
|
||||
clientY: (logicalY / LOGICAL_HEIGHT) * rect.height + rect.top,
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user