From b0025212615304962845eba61a448f36f587d6c8 Mon Sep 17 00:00:00 2001 From: Ian Mancini Date: Sun, 13 Dec 2020 15:18:12 -0300 Subject: [PATCH] Add audio and obras with video projections --- packages/client/public/computer.glb | Bin 9888 -> 0 bytes packages/client/public/model/obras/mateo.glb | 4 +- .../client/public/model/obras/proyector.glb | 4 +- .../public/model/obras/proyector_wide.glb | 3 + packages/client/src/3d/ArtworkCollection.tsx | 24 ++--- packages/client/src/3d/Collisions.tsx | 12 ++- packages/client/src/3d/Controls.tsx | 1 - packages/client/src/3d/ObraAudio.tsx | 36 +++++++ packages/client/src/3d/Phantom.tsx | 1 - packages/client/src/3d/Player.tsx | 2 +- packages/client/src/3d/models/Computer.tsx | 13 +-- packages/client/src/3d/models/Entrance.tsx | 2 +- packages/client/src/3d/models/Human.tsx | 3 +- .../client/src/3d/models/obras/Daniela.tsx | 14 +++ .../client/src/3d/models/obras/DiegoGuido.tsx | 14 +++ .../client/src/3d/models/obras/Gaston.tsx | 8 ++ packages/client/src/3d/models/obras/Pedro.tsx | 14 +++ .../client/src/3d/models/obras/Proyector.tsx | 91 ++++++++++++++---- .../src/3d/models/obras/Proyector_wide.tsx | 36 +++++++ .../client/src/components/MenuOverlay.tsx | 1 - 20 files changed, 228 insertions(+), 55 deletions(-) delete mode 100644 packages/client/public/computer.glb create mode 100644 packages/client/public/model/obras/proyector_wide.glb create mode 100644 packages/client/src/3d/ObraAudio.tsx create mode 100644 packages/client/src/3d/models/obras/Daniela.tsx create mode 100644 packages/client/src/3d/models/obras/DiegoGuido.tsx create mode 100644 packages/client/src/3d/models/obras/Pedro.tsx create mode 100644 packages/client/src/3d/models/obras/Proyector_wide.tsx diff --git a/packages/client/public/computer.glb b/packages/client/public/computer.glb deleted file mode 100644 index e7a90614fa870e935135fa91558e0a2a69e72728..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9888 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, + , // , null, // Juan cruz null, // Lucia cordoba null, // Camila - , + , null, // Lucia Novello - , - , + , + , null, // Edu - , - , - , - null, //, - null, //, + , + , + , + , + , ] function ArtworkCollection(props: JSX.IntrinsicElements['group']) { diff --git a/packages/client/src/3d/Collisions.tsx b/packages/client/src/3d/Collisions.tsx index 791b477..fdd24f2 100644 --- a/packages/client/src/3d/Collisions.tsx +++ b/packages/client/src/3d/Collisions.tsx @@ -6,14 +6,14 @@ import ParkCollisions from './models/Park_collisions' import StreetCollisions from './models/Street_collisions' import MuseumCollisions from './models/Museum_collisions' import EntranceCollsions from './models/Entrance_collisions' -import { Mesh, MeshBasicMaterial } from 'three' +import { Mesh } from 'three' const Model = forwardRef( (props: JSX.IntrinsicElements['group'], ref: ForwardedRef) => { - const material = new MeshBasicMaterial({ - wireframe: true, - color: 0xffff00, - }) + // const material = new MeshBasicMaterial({ + // wireframe: true, + // color: 0xffff00, + // }) return ( @@ -26,4 +26,6 @@ const Model = forwardRef( }, ) +Model.displayName = 'collisions' + export default Model diff --git a/packages/client/src/3d/Controls.tsx b/packages/client/src/3d/Controls.tsx index 54c454c..8b7a306 100644 --- a/packages/client/src/3d/Controls.tsx +++ b/packages/client/src/3d/Controls.tsx @@ -14,7 +14,6 @@ const Controls: React.FC = () => { const onLock = () => setPointerLockStatus(true) const onUnlock = () => { setPointerLockStatus(false) - console.log('unlock') } ref.current.addEventListener?.('lock', onLock) diff --git a/packages/client/src/3d/ObraAudio.tsx b/packages/client/src/3d/ObraAudio.tsx new file mode 100644 index 0000000..1613a66 --- /dev/null +++ b/packages/client/src/3d/ObraAudio.tsx @@ -0,0 +1,36 @@ +import React, { useEffect, useRef } from 'react' +import { PositionalAudio, Box } from '@react-three/drei' +import { PositionalAudio as PositionalAudioImpl } from 'three' +import useStore from '../store' + +type Props = JSX.IntrinsicElements['positionalAudio'] & { + url: string + distance?: number + loop?: boolean +} + +const ObraAudio: React.FC = ({ position, url, loop = true, ...props }) => { + const pointerLocked = useStore((state) => state.pointerLocked) + const audioRef = useRef() + + useEffect(() => { + if (audioRef.current) { + if (!pointerLocked && audioRef.current.isPlaying) { + audioRef.current.pause() + } else if (pointerLocked && !audioRef.current.isPlaying) { + audioRef.current.play() + } + + audioRef.current.setDirectionalCone(35, 60, 0.1) + audioRef.current.setRefDistance(0.5) + } + }, [audioRef.current, pointerLocked]) + + return ( + + + + ) +} + +export default ObraAudio diff --git a/packages/client/src/3d/Phantom.tsx b/packages/client/src/3d/Phantom.tsx index 7413e0d..4e2ee59 100644 --- a/packages/client/src/3d/Phantom.tsx +++ b/packages/client/src/3d/Phantom.tsx @@ -1,6 +1,5 @@ // @ts-nocheck import React, { useEffect, useRef } from 'react' -import { Vector3, Euler } from 'three' import Human from './models/Human' import api, { Transform } from '../store' diff --git a/packages/client/src/3d/Player.tsx b/packages/client/src/3d/Player.tsx index 721af78..47bfe0f 100644 --- a/packages/client/src/3d/Player.tsx +++ b/packages/client/src/3d/Player.tsx @@ -144,7 +144,7 @@ const Player = () => { const socketEmitTransformInterval = setInterval(() => { if (socket && groupRef.current && camera) { const cameraRotation = camera.quaternion.toArray() - const [x, y, z] = direction.current.toArray() + const [x, , z] = direction.current.toArray() let anim = animations.idle diff --git a/packages/client/src/3d/models/Computer.tsx b/packages/client/src/3d/models/Computer.tsx index 7fa8e9f..fdb379f 100644 --- a/packages/client/src/3d/models/Computer.tsx +++ b/packages/client/src/3d/models/Computer.tsx @@ -29,7 +29,6 @@ type ComputerProps = { export default function Model(props: ComputerProps & JSX.IntrinsicElements['group']) { const pointerLockControls = useStore((state) => state.pointerLockControls) - const setPointerLockStatus = useStore((state) => state.setPointerLockStatus) const setModalObra = useStore((state) => state.setModalObra) const group = useRef() @@ -54,15 +53,17 @@ export default function Model(props: ComputerProps & JSX.IntrinsicElements['grou ref={group} {...props} dispose={null} - onPointerOver={(e) => { + onPointerOver={() => { setCurrentMaterial(true) }} onPointerOut={() => setCurrentMaterial(false)} onClick={() => { - setModalObra(props.obraId) - setTimeout(() => { - pointerLockControls.unlock() - }, 500) + if (pointerLockControls) { + setModalObra(props.obraId) + setTimeout(() => { + pointerLockControls.unlock?.() + }, 500) + } }} > diff --git a/packages/client/src/3d/models/Entrance.tsx b/packages/client/src/3d/models/Entrance.tsx index 4ef93e3..bf631fd 100644 --- a/packages/client/src/3d/models/Entrance.tsx +++ b/packages/client/src/3d/models/Entrance.tsx @@ -27,7 +27,7 @@ type GLTFResult = GLTF & { export default function Model(props: JSX.IntrinsicElements['group']) { const group = useRef() - const { scene, materials } = useGLTF('/model/entrance.glb') as GLTFResult + const { scene } = useGLTF('/model/entrance.glb') as GLTFResult return ( diff --git a/packages/client/src/3d/models/Human.tsx b/packages/client/src/3d/models/Human.tsx index 4010191..3e0b2f0 100644 --- a/packages/client/src/3d/models/Human.tsx +++ b/packages/client/src/3d/models/Human.tsx @@ -14,8 +14,7 @@ import { FrontSide } from 'three/src/constants' import { HEIGHT } from '../Player' -import api, { State, Transform } from '../../store' -import { Color } from 'three/src/math/Color' +import api, { Transform } from '../../store' import { MeshNormalMaterial } from 'three/src/materials/MeshNormalMaterial' import { Object3D } from 'three/src/core/Object3D' import { SkinnedMesh } from 'three/src/objects/SkinnedMesh' diff --git a/packages/client/src/3d/models/obras/Daniela.tsx b/packages/client/src/3d/models/obras/Daniela.tsx new file mode 100644 index 0000000..fc4d0ca --- /dev/null +++ b/packages/client/src/3d/models/obras/Daniela.tsx @@ -0,0 +1,14 @@ +import * as THREE from 'three' +import Proyector from './Proyector' +import React, { useRef } from 'react' +import ObraAudio from '../../ObraAudio' + +export default function Model(props: JSX.IntrinsicElements['group']) { + const group = useRef() + return ( + + + + + ) +} diff --git a/packages/client/src/3d/models/obras/DiegoGuido.tsx b/packages/client/src/3d/models/obras/DiegoGuido.tsx new file mode 100644 index 0000000..6a427d7 --- /dev/null +++ b/packages/client/src/3d/models/obras/DiegoGuido.tsx @@ -0,0 +1,14 @@ +import * as THREE from 'three' +import Proyector from './Proyector' +import React, { useRef } from 'react' +import ObraAudio from '../../ObraAudio' + +export default function Model(props: JSX.IntrinsicElements['group']) { + const group = useRef() + return ( + + + + + ) +} diff --git a/packages/client/src/3d/models/obras/Gaston.tsx b/packages/client/src/3d/models/obras/Gaston.tsx index 81c8a16..1758280 100644 --- a/packages/client/src/3d/models/obras/Gaston.tsx +++ b/packages/client/src/3d/models/obras/Gaston.tsx @@ -5,6 +5,7 @@ Auto-generated by: https://github.com/pmndrs/gltfjsx import * as THREE from 'three' import React, { useRef } from 'react' import { useGLTF } from '@react-three/drei/useGLTF' +import ObraAudio from '../../ObraAudio' import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader' @@ -23,6 +24,13 @@ export default function Model(props: JSX.IntrinsicElements['group']) { return ( + + ) } diff --git a/packages/client/src/3d/models/obras/Pedro.tsx b/packages/client/src/3d/models/obras/Pedro.tsx new file mode 100644 index 0000000..42d666a --- /dev/null +++ b/packages/client/src/3d/models/obras/Pedro.tsx @@ -0,0 +1,14 @@ +import * as THREE from 'three' +import Proyector from './Proyector' +import React, { useRef } from 'react' +import ObraAudio from '../../ObraAudio' + +export default function Model(props: JSX.IntrinsicElements['group']) { + const group = useRef() + return ( + + + + + ) +} diff --git a/packages/client/src/3d/models/obras/Proyector.tsx b/packages/client/src/3d/models/obras/Proyector.tsx index 0974ab6..bc73e20 100644 --- a/packages/client/src/3d/models/obras/Proyector.tsx +++ b/packages/client/src/3d/models/obras/Proyector.tsx @@ -3,40 +3,89 @@ Auto-generated by: https://github.com/pmndrs/gltfjsx */ import * as THREE from 'three' -import React, { useRef } from 'react' +import React, { useRef, useEffect } from 'react' import { useGLTF } from '@react-three/drei/useGLTF' - +import { + Mesh, + Color, + MeshBasicMaterial, + MeshStandardMaterial, + VideoTexture, + DoubleSide, +} from 'three' import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader' type GLTFResult = GLTF & { nodes: { - Cube013: THREE.Mesh - ['Cube.013_1']: THREE.Mesh - ['Cube.013_2']: THREE.Mesh + Cube013: Mesh + ['Cube.013_1']: Mesh + ['Cube.013_2']: Mesh + Cube001: THREE.Mesh + ['Cube.001_1']: THREE.Mesh + ['Cube.001_2']: THREE.Mesh } materials: { - ['VrHeadset cuerpo.002']: THREE.MeshStandardMaterial - ['light.001']: THREE.MeshStandardMaterial - ['projection.001']: THREE.MeshStandardMaterial + plastic: MeshStandardMaterial + projection_light: MeshStandardMaterial + projection: MeshStandardMaterial } } -export default function Model(props: JSX.IntrinsicElements['group']) { +export default function Model( + props: JSX.IntrinsicElements['group'] & { videoSrc: string; wide?: boolean }, +) { + const { nodes, materials } = useGLTF( + `/model/obras/proyector${props.wide ? '_wide' : ''}.glb`, + ) as GLTFResult const group = useRef() - const { nodes, materials } = useGLTF('/model/obras/proyector.glb') as GLTFResult + const videoRef = useRef(document.createElement('video')) + const projectionMaterial = useRef( + new MeshBasicMaterial({ color: new Color('white') }), + ) + const videoTexture = useRef() + + useEffect(() => { + if (videoRef.current && projectionMaterial) { + videoRef.current.src = props.videoSrc + videoRef.current.load() + videoRef.current.loop = true + videoRef.current.muted = true + videoRef.current.autoplay = true + videoRef.current.play() + + videoTexture.current = new VideoTexture(videoRef.current) + projectionMaterial.current.map = videoTexture.current + projectionMaterial.current.needsUpdate = true + } + }, [videoRef.current, projectionMaterial.current]) + return ( - - - - - + {!props.wide ? ( + <> + + + + + ) : ( + <> + + + + + )} ) } diff --git a/packages/client/src/3d/models/obras/Proyector_wide.tsx b/packages/client/src/3d/models/obras/Proyector_wide.tsx new file mode 100644 index 0000000..a2b8531 --- /dev/null +++ b/packages/client/src/3d/models/obras/Proyector_wide.tsx @@ -0,0 +1,36 @@ +/* +Auto-generated by: https://github.com/pmndrs/gltfjsx +*/ + +import * as THREE from 'three' +import React, { useRef } from 'react' +import { useGLTF } from '@react-three/drei/useGLTF' + +import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader' + +type GLTFResult = GLTF & { + nodes: { + Cube001: THREE.Mesh + ['Cube.001_1']: THREE.Mesh + ['Cube.001_2']: THREE.Mesh + } + materials: { + plastic: THREE.MeshStandardMaterial + projection_light: THREE.MeshStandardMaterial + projection: THREE.MeshStandardMaterial + } +} + +export default function Model(props: JSX.IntrinsicElements['group']) { + const group = useRef() + const { nodes, materials } = useGLTF('/proyector_wide.glb') as GLTFResult + return ( + + + + + + ) +} + +useGLTF.preload('/proyector_wide.glb') diff --git a/packages/client/src/components/MenuOverlay.tsx b/packages/client/src/components/MenuOverlay.tsx index a5007f3..09e28c7 100644 --- a/packages/client/src/components/MenuOverlay.tsx +++ b/packages/client/src/components/MenuOverlay.tsx @@ -46,7 +46,6 @@ const MenuOverlay: React.FC = () => { pointerLockControls.lock?.() } } - console.log(modalObra) return ( <>