├── .DS_Store ├── .firebaserc ├── .gitignore ├── LICENSE ├── README.md ├── blender └── particle-sample.blend.zip ├── docs ├── blender-particlewonder.png ├── blender-with-effectnode.png ├── discovery.png ├── fallingnoodles.png ├── landing.png └── simulation.png ├── firebase.json ├── firebase.rules.json ├── next.config.js ├── package.json ├── pages ├── .DS_Store ├── _app.js ├── api │ ├── .DS_Store │ ├── hello.js │ └── starlink.js ├── index.js ├── lab │ └── index.js ├── place │ └── [placeID].js ├── system │ └── index.js └── user │ └── index.js ├── postcss.config.js ├── public ├── .DS_Store ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── chibi │ ├── actions │ │ ├── contorls │ │ │ ├── .DS_Store │ │ │ ├── idle-breathing.fbx │ │ │ ├── idle-happy.fbx │ │ │ ├── idle-sad.fbx │ │ │ ├── running-in-place-fast.fbx │ │ │ └── running-in-place-relax.fbx │ │ ├── dances │ │ │ ├── arms-hip-hop.fbx │ │ │ ├── dancing.fbx │ │ │ ├── gangnam-style.fbx │ │ │ ├── hand-wave.fbx │ │ │ ├── hip-hop-breakdance.fbx │ │ │ ├── hip-hop.fbx │ │ │ ├── hokey-pokey.fbx │ │ │ ├── locking.fbx │ │ │ ├── northern-soul.fbx │ │ │ ├── salsa.fbx │ │ │ ├── samba-dancing.fbx │ │ │ ├── silly.fbx │ │ │ ├── swing.fbx │ │ │ └── wave.fbx │ │ ├── emojis │ │ │ ├── cheering.fbx │ │ │ ├── clapping.fbx │ │ │ ├── excited.fbx │ │ │ ├── pointing-gesture.fbx │ │ │ ├── pointing.fbx │ │ │ ├── praying.fbx │ │ │ ├── rallying.fbx │ │ │ ├── singing.fbx │ │ │ ├── victory-2.fbx │ │ │ ├── victory-3.fbx │ │ │ ├── victory-4.fbx │ │ │ ├── victory.fbx │ │ │ ├── waving.fbx │ │ │ └── ymca-dance.fbx │ │ └── pose │ │ │ ├── laying-1.fbx │ │ │ ├── laying-2.fbx │ │ │ ├── laying-3.fbx │ │ │ └── laying-4.fbx │ └── avatar │ │ └── ChibiBase-rigged.fbx ├── church │ └── dove-v2.glb ├── cubemap │ ├── .DS_Store │ └── sky-grass │ │ ├── nx.png │ │ ├── ny.png │ │ ├── nz.png │ │ ├── px.png │ │ ├── py.png │ │ └── pz.png ├── draco-glbs │ ├── gltf │ │ ├── draco_decoder.js │ │ ├── draco_decoder.wasm │ │ ├── draco_encoder.js │ │ └── draco_wasm_wrapper.js │ └── mac-draco.glb ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── font │ ├── Cronos-Pro-Light_12448.ttf │ └── trivial │ │ ├── Trivial-Bold.otf │ │ ├── Trivial-ExtraLight.otf │ │ ├── Trivial-Heavy.otf │ │ ├── Trivial-Light.otf │ │ ├── Trivial-Regular.otf │ │ ├── Trivial-Thin.otf │ │ └── Trivial-UltraLight.otf ├── hdr │ ├── nightwilderness.png │ └── spaichingen_hill_1k.hdr ├── image │ ├── sky.png │ ├── social-icons │ │ ├── .DS_Store │ │ ├── ig.png │ │ ├── tiktok.png │ │ ├── web.png │ │ └── youtube.png │ └── thankyou-jesus.png ├── img │ ├── cms-demo.png │ └── dream-code.png ├── map │ ├── .DS_Store │ ├── camset │ │ ├── .DS_Store │ │ └── cam-set.glb │ ├── heavenly-platforms │ │ └── heavenly-platforms.glb │ ├── journey-with-dear-God │ │ └── journey.glb │ ├── orchid-sing │ │ └── orchid-sing.glb │ ├── skycity │ │ └── church-sky-city.glb │ ├── space-walk-001.glb │ ├── spaewalk │ │ ├── .DS_Store │ │ └── space-walk-v003.glb │ └── stage │ │ └── stage.glb ├── me.png ├── objects │ ├── .DS_Store │ ├── bubble-gun │ │ └── bubble-gun.glb │ ├── butterfly │ │ └── butterfly.glb │ ├── card │ │ └── card-oobe.glb │ ├── honey │ │ └── .DS_Store │ ├── hud │ │ └── HUD.glb │ └── spaceship-05 │ │ └── spaceship-05.glb ├── particles │ ├── .DS_Store │ └── old │ │ ├── atv.glb │ │ ├── atv2.glb │ │ ├── flower-organism.glb │ │ └── noodlehat.glb ├── preview │ ├── church-thumb.png │ ├── sing-thumb.png │ └── spaceship-thumb.png ├── rpm │ ├── .DS_Store │ ├── rpm-actions-locomotion │ │ ├── hip-hop-dancing.fbx │ │ ├── quick-formal-bow.fbx │ │ ├── running.fbx │ │ ├── standing-foot.fbx │ │ ├── standing-greeting.fbx │ │ ├── standing-texting.fbx │ │ ├── standing-time.fbx │ │ ├── standing.fbx │ │ ├── swim-float.fbx │ │ ├── swim-forward.fbx │ │ └── waving-gesture.fbx │ ├── rpm-actions-look │ │ ├── look-forward.fbx │ │ ├── look-ground.fbx │ │ ├── look-hand.fbx │ │ ├── look-lift.fbx │ │ ├── look-pick-2.fbx │ │ ├── look-pick.fbx │ │ └── look-point.fbx │ ├── rpm-actions │ │ ├── backflip.fbx │ │ ├── bow-quick-formal.fbx │ │ ├── cheer.fbx │ │ ├── dance-hiphop.fbx │ │ ├── excited.fbx │ │ ├── greetings.fbx │ │ ├── guesture-pointer-2.fbx │ │ ├── guesture-pointer.fbx │ │ ├── gun-shoot.fbx │ │ ├── hand-forward.fbx │ │ ├── happy-hand.fbx │ │ ├── happy-idle.fbx │ │ ├── hi-wave-both-hands.fbx │ │ ├── mma-idle.fbx │ │ ├── mma-kick-2.fbx │ │ ├── mma-kick.fbx │ │ ├── mma-warmup.fbx │ │ ├── silly-dance.fbx │ │ └── spin-in-place.fbx │ ├── rpm-avatar │ │ └── white-armor.glb │ └── rpm-pose │ │ ├── standing-waiting.fbx │ │ └── standing.fbx ├── song │ └── hallelujah.mp3 ├── texture │ └── portalAlpahMap.png └── ui-imgs │ └── pexels-rodnae-productions-7563568.jpg ├── styles ├── Home.module.css └── globals.css ├── tailwind.config.js └── vfx ├── admin ├── gates │ ├── SystemGate.js │ └── UserGate.js ├── system-admin │ └── dashboard.js └── ui │ ├── GlassBlock.js │ ├── LoginUI.js │ ├── MenuBlock.js │ ├── Navbar.js │ └── WelcomeBack.js ├── canvas ├── Controls │ ├── FirstCamControls.js │ ├── SkyViewControls.js │ ├── SongFlyControls.js │ ├── StoryFlyControls.js │ ├── WalkerFollowerControls.js │ └── old │ │ └── WalkerFollowerControls.js ├── MapAddons │ └── PathWay.js ├── PlayerCollider │ └── PlayerCollider.js ├── PlayerDisplay │ └── PlayerDisplay.js ├── PostProcessing │ ├── FXAAfrag.js │ ├── ShaderBloomer.js │ └── SimpleBloomer.js ├── Preload │ └── Preload.js ├── StarSky │ ├── StarSky.js │ └── StarSkyDots.js └── Starter │ └── Starter.js ├── classes ├── ColliderClient.js ├── ColliderManager.js └── Mini.js ├── editor ├── AssetWindow │ └── AssetWindow.js ├── CanvasPreview │ └── CanvasPreview.js ├── CanvasWork │ └── CanvasWork.js ├── FloatingWindow │ └── FloatingWindow.js ├── GravityLab │ └── GravityLab.js ├── Lab │ └── Lab.js ├── Loading │ └── Loading.js ├── LowBar │ └── LowBar.js └── TopBar │ └── TopBar.js ├── explore ├── Explore.js ├── ForceGraphR3F.js └── Prototyper.js ├── firebase ├── firebaseConfig.js └── firelib.js ├── game └── Portals │ ├── FlyTeleport.js │ └── MapPortal.js ├── places ├── .DS_Store ├── Fashion │ ├── Assets.js │ ├── Fashion.js │ ├── FunSim.js │ ├── InteractionUI.js │ └── PositionSimulation.js ├── Spirit │ ├── AnimationPlayer.js │ ├── CameraFlow.js │ ├── FieldCompute.js │ ├── FieldRendering.js │ ├── Floor.js │ ├── ForceShield.js │ ├── GeoSpirit.js │ ├── JustBloom.js │ ├── Lighting.js │ ├── LoadingInCam.js │ ├── ProgressControls.js │ ├── SpaceWrap.js │ ├── Spirit.js │ └── Stage2.js ├── church │ ├── Assets.js │ └── SkyCityChurch.js ├── common │ └── CommonAssets.js ├── fly │ ├── Assets.js │ ├── Fly.js │ └── TrackO3D.js ├── index.js ├── journey │ ├── Assets.js │ └── Journey.js ├── magnet │ ├── Assets.js │ └── Magnet.js ├── simulation │ ├── Assets.js │ ├── FunSim.js │ ├── InteractionUI.js │ ├── PositionSimulation.js │ └── SimPage.js ├── sing │ ├── Assets.js │ ├── Butterflyer.js │ └── Sing.js └── spaceship │ ├── Assets.js │ └── SpaceStation.js ├── store ├── Now.js └── Place.js └── utils ├── get-id.js ├── make-now.js ├── make-shallow-store.js ├── use-auto-event.js ├── use-compute-env-map.js ├── use-env-light.js └── use-mini-engine.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/.DS_Store -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "effectnode" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | yarn.lock 4 | .vercel 5 | .env -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 WONG LOK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EffectNode Metaverse - a Boilerplate for You 2 | 3 | ![SkyCity Church](https://github.com/wonglok/effectnode-metaverse/raw/master/docs/landing.png) 4 | 5 | Effect Node METAVERSE is a open source boilerplate project for helping everyone own their own metaverse. 6 | 7 | The Vision for Effect Node Metaverse is that everyone should be able to own a piece of the whole metaverse cake over the internet. LokLok, the sole inventor of EffectNode, wants to embrace the hyperlink in the internet because it’s the fundamental of the internet that is letting users flow to different information with a breeze. 8 | 9 | 3D Content on the web has always been a high price / high cost for anyone who wants to own a piece of the metaverse cake. And by sharing the starter boilerplate, it made the metaverse open and to prevent a single ownership of the technology. 10 | 11 | We all don’t really like having to pay a royalty fee to every creation that we yearn to make. 12 | 13 | --- 14 | 15 | 16 | # Update!! - 2022-05-26 17 | 18 | ## Telly Awards 2022 19 | ![Bronze_Trophy_Large](https://user-images.githubusercontent.com/4082826/170433686-cd9138c4-f11f-47e0-96fd-ed660a2ed233.png) 20 | ![Silver_Trophy_Large](https://user-images.githubusercontent.com/4082826/170433703-3dfc0b29-b5bb-4104-b2ab-73e4cc8f8120.png) 21 | 22 | https://www.tellyawards.com/winners/2022/immersive-mixed-reality/general-social-responsibility/effectnode-metaverse-opensource-template/269020/ 23 | 24 | https://www.tellyawards.com/winners/2022/immersive-mixed-reality/craft-metaverse/effectnode-metaverse-opensource-template/275332/ 25 | 26 | 27 | # Update!! - 2022-04-05 28 | 29 | ## Webbys Awards 2022 30 | 31 | ![webbys](https://user-images.githubusercontent.com/4082826/161773205-7c79fad8-31f2-4136-8c56-0c57bda43cde.png) 32 | 33 | https://vote.webbyawards.com/PublicVoting#/2022/apps-and-software/app-features/experimental-innovation 34 | 35 | --- 36 | 37 | 38 | # Update!! - 2022-02-16 39 | 40 | ## Anthem Awards Bronze 41 | 42 | ![Anthem-bronze-winner-announ-share-square-2 (1)](https://user-images.githubusercontent.com/4082826/154196891-7af02d39-ad58-4160-8e57-1643af5934f3.png) 43 | 44 | https://www.anthemawards.com/winners/list/entry/#responsible-technology/product-innovation-or-service-categories-for-profit/effectnode-metaverse-opensource-boilerplate/1972/25455/337622 45 | 46 | ---- 47 | 48 | ## VFX on 3D Web 49 | 50 | ![Simulation](https://github.com/wonglok/effectnode-metaverse/raw/master/docs/simulation.png) 51 | 52 | [Simulation of Noodles](https://metaverse.effectnode.com/place/simulation) 53 | 54 | Effet Node is an on-going group of projects made by Lok Lok. 55 | 56 | Open Source Custom Graphics Pipeline with Custom Shaders in web computer graphics is extremely rare in the market and is costly to many. And that is what effectnode is made for - to provide good and high quality code to people who wants to create 3D Content. 57 | 58 | Effect Node has evolved throughout the years to improve the developer experience on building custom visual effects. 59 | 60 | - 2014 Particle Simulation Animation with Raw WebGL APIs 61 | - 2017 Shader Node (before effect node) - won $300K HKD Grant 62 | - 2019 Effect Node - Webbys Nomination 63 | - 2019 Effect Node - Webbys Judgeship 64 | - 2021 Effect Node Cloud - Webbys Honoree 65 | 66 | The sole inventor of Effect Node, Lok Lok, wants to share many of his expertise in webgl engineering, through this open source boilerplate 67 | 68 | --- 69 | 70 | ## Falling Noodles 71 | 72 | [Demo Noodle Map](https://metaverse.effectnode.com/place/magnet) 73 | 74 | ![Falling Noodles with Avatar](https://github.com/wonglok/effectnode-metaverse/raw/master/docs/fallingnoodles.png) 75 | 76 | ## Blender Workflow with Effectnode 77 | 78 | [Blender Motion to EffectNode](https://metaverse.effectnode.com/place/fly) 79 | 80 | [Blender File](https://github.com/wonglok/effectnode-metaverse/tree/master/blender) 81 | 82 | ![Blender with EffectNode](https://github.com/wonglok/effectnode-metaverse/raw/master/docs/blender-with-effectnode.png) 83 | 84 | ![Blender export motion](https://github.com/wonglok/effectnode-metaverse/raw/master/docs/blender-particlewonder.png) 85 | 86 | ## Crawling on METAVERSE made Possible 87 | 88 | [StarLink API](https://metaverse.effectnode.com/api/starlink) 89 | 90 | ![Discovery](https://github.com/wonglok/effectnode-metaverse/raw/master/docs/discovery.png) 91 | 92 | MIT LICENSED 93 | 94 | Copyright 2021 WONGLOK 95 | 96 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 97 | 98 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 99 | 100 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 101 | -------------------------------------------------------------------------------- /blender/particle-sample.blend.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/blender/particle-sample.blend.zip -------------------------------------------------------------------------------- /docs/blender-particlewonder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/docs/blender-particlewonder.png -------------------------------------------------------------------------------- /docs/blender-with-effectnode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/docs/blender-with-effectnode.png -------------------------------------------------------------------------------- /docs/discovery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/docs/discovery.png -------------------------------------------------------------------------------- /docs/fallingnoodles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/docs/fallingnoodles.png -------------------------------------------------------------------------------- /docs/landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/docs/landing.png -------------------------------------------------------------------------------- /docs/simulation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/docs/simulation.png -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /firebase.rules.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | ".read": false, 4 | ".write": false, 5 | "profiles": { 6 | "$owner_id": { 7 | ".read": "true", 8 | ".write": "auth != null && $owner_id === auth.uid || auth != null && root.child('admin').hasChild(auth.uid)" 9 | } 10 | }, 11 | "rooms": { 12 | "$roomID": { 13 | "$owner_id": { 14 | ".read": "true", 15 | ".write": "auth != null && $owner_id === auth.uid || auth != null && root.child('admin').hasChild(auth.uid)" 16 | } 17 | } 18 | }, 19 | "online": { 20 | "$roomID": { 21 | ".read": "true", 22 | "$owner_id": { 23 | ".read": "true", 24 | ".write": "auth != null && $owner_id === auth.uid || auth != null && root.child('admin').hasChild(auth.uid)" 25 | } 26 | } 27 | }, 28 | "usernames": { 29 | "$username": { 30 | ".write": "!data.exists() && auth!= null && newData.val() == auth.uid" 31 | } 32 | }, 33 | "slug": { 34 | ".read": true, 35 | "$slugID": { 36 | ".write": "(!data.exists() || data.child('author').val() == auth.uid) && (newData.child('author').val() == auth.uid || !newData.exists())" 37 | } 38 | }, 39 | "assets": { 40 | ".read": true, 41 | "$assetID": { 42 | ".write": "root.child('admins/'+auth.uid).exists()" 43 | } 44 | }, 45 | "card-private-info": { 46 | ".read": "root.child('admins/'+auth.uid).exists()", 47 | ".write": "root.child('admins/'+auth.uid).exists()" 48 | }, 49 | // 50 | "card-public-meta": { 51 | "$cardID": { 52 | ".read": "root.child('admins/'+auth.uid).exists()", 53 | ".write": "root.child('admins/'+auth.uid).exists()" 54 | } 55 | }, 56 | "card-activation-info": { 57 | "$cardID": { 58 | ".read": true, 59 | ".write": "root.child('admins/'+auth.uid).exists()" 60 | } 61 | }, 62 | "card-stroy-draft": { 63 | "$cardID": { 64 | ".read": true, 65 | ".write": "root.child('card-activation-info').child($cardID).child('uid').exists() && auth != null && root.child('card-activation-info').child($cardID).child('uid').val() == auth.uid" 66 | } 67 | }, 68 | "card-stroy-info": { 69 | "$cardID": { 70 | ".read": true, 71 | ".write": "root.child('card-activation-info').child($cardID).child('uid').exists() && auth != null && root.child('card-activation-info').child($cardID).child('uid').val() == auth.uid" 72 | } 73 | }, 74 | "card-avatar-info": { 75 | "$cardID": { 76 | ".read": true, 77 | ".write": "root.child('card-activation-info').child($cardID).child('uid').exists() && auth != null && root.child('card-activation-info').child($cardID).child('uid').val() == auth.uid" 78 | } 79 | }, 80 | "card-room-info": { 81 | "$cardID": { 82 | ".read": true, 83 | ".write": "root.child('card-activation-info').child($cardID).child('uid').exists() && auth != null && root.child('card-activation-info').child($cardID).child('uid').val() == auth.uid" 84 | } 85 | }, 86 | "card-meta-info": { 87 | "$cardID": { 88 | ".read": true, 89 | ".write": "root.child('admins/'+auth.uid).exists()" 90 | } 91 | }, 92 | "test-admin": { 93 | ".read": "root.child('admins/'+auth.uid).exists()", 94 | ".write": "root.child('admins/'+auth.uid).exists()" 95 | }, 96 | "test-user": { 97 | ".read": "auth !== null && auth.provider === 'google'", 98 | ".write": "auth !== null && auth.provider === 'google'" 99 | }, 100 | "profile": { 101 | "$owner_user_id": { 102 | "canvas": { 103 | ".read": "auth !== null", 104 | "$canvasID": { 105 | ".write": "auth !== null && auth.uid === $owner_user_id", 106 | "shareACL": { 107 | ".write": "auth !== null && auth.uid === $owner_user_id", 108 | }, 109 | "ownerACL": { 110 | ".write": "auth !== null && auth.uid === $owner_user_id", 111 | } 112 | }, 113 | }, 114 | "layout": { 115 | ".read": "auth !== null", 116 | "$canvasID": { 117 | ".write": "auth !== null && auth.uid === $owner_user_id", 118 | "shareACL": { 119 | ".write": "auth !== null && auth.uid === $owner_user_id", 120 | }, 121 | "ownerACL": { 122 | ".write": "auth !== null && auth.uid === $owner_user_id", 123 | } 124 | }, 125 | } 126 | }, 127 | }, 128 | "canvas": { 129 | "$canvasID": { 130 | ".read": true, 131 | "$ownerID": { 132 | ".read": true, 133 | ".write": "auth !== null && auth.uid === $ownerID || auth !== null && root.child('profile').child($ownerID).child('canvas').child($canvasID).child('shareACL').hasChild(auth.uid)" 134 | } 135 | } 136 | }, 137 | "layout": { 138 | "$layoutID": { 139 | ".read": true, 140 | "$ownerID": { 141 | ".read": true, 142 | ".write": "auth !== null && auth.uid === $ownerID || auth !== null && root.child('profile').child($ownerID).child('layout').child($layoutID).child('shareACL').hasChild(auth.uid)" 143 | } 144 | } 145 | } 146 | } 147 | } -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | // 2 | // 3 | // 4 | // const withTM = require("next-transpile-modules")([ 5 | // // 6 | // // 7 | // // 8 | 9 | // "three-forcegraph", 10 | // "d3-quadtree", 11 | // "d3-force-3d", 12 | // "d3-array", 13 | // "d3-scale", 14 | // "d3-scale-chromatic", 15 | // "d3-dispatch", 16 | // "d3-timer", 17 | // "internmap", 18 | // "d3-interpolate", 19 | // "d3-color", 20 | // "d3-format", 21 | // "d3-time", 22 | // "d3-timer", 23 | // "d3-time-format", 24 | // "d3-scale", 25 | // "d3-octree", 26 | // "d3-binarytree", 27 | // ]); 28 | 29 | module.exports = { 30 | // Webpack 5 is enabled by default 31 | // You can still use webpack 4 while upgrading to the latest version of Next.js by adding the "webpack5: false" flag 32 | webpack5: true, 33 | }; 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "PORT=3001 next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lt": "ngrok http 3000 --subdomain wonglok --region ap" 10 | }, 11 | "dependencies": { 12 | "@react-three/drei": "^7.3.1", 13 | "@react-three/fiber": "^7.0.6", 14 | "@use-gesture/react": "^10.1.3", 15 | "animejs": "^3.2.1", 16 | "canvas-multiline-text": "^1.0.3", 17 | "canvas-txt": "^3.0.0", 18 | "cors": "^2.8.5", 19 | "d3-force-3d": "^3.0.2", 20 | "daisyui": "^1.14.0", 21 | "detect-gpu": "^3.1.11", 22 | "effectnode": "^1.5.3", 23 | "effectnode-3dworld": "^0.0.20", 24 | "effectnode-cms": "1.0.6", 25 | "firebase": "^8.9.0", 26 | "firebase-admin": "^9.11.1", 27 | "firebaseui": "^4.8.1", 28 | "fontfaceobserver": "^2.1.0", 29 | "localforage": "^1.10.0", 30 | "md5": "^2.3.0", 31 | "next": "^12.0.3", 32 | "nipplejs": "^0.9.0", 33 | "react": "17.0.1", 34 | "react-dom": "17.0.1", 35 | "react-router-dom": "^5.2.1", 36 | "recursive-readdir": "^2.2.2", 37 | "slugify": "^1.6.0", 38 | "three": "^0.131.1", 39 | "three-forcegraph": "^1.39.1", 40 | "three-mesh-bvh": "^0.4.2", 41 | "url-hash": "^1.0.2" 42 | }, 43 | "license": "MIT", 44 | "devDependencies": { 45 | "autoprefixer": "^10.3.1", 46 | "file-loader": "^6.2.0", 47 | "next-transpile-modules": "^8.0.0", 48 | "postcss": "^8.3.6", 49 | "tailwindcss": "^2.2.7" 50 | } 51 | } -------------------------------------------------------------------------------- /pages/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/pages/.DS_Store -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import "tailwindcss/tailwind.css"; 2 | import "../styles/globals.css"; 3 | 4 | // 5 | export default function MyApp({ Component, pageProps }) { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /pages/api/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/pages/api/.DS_Store -------------------------------------------------------------------------------- /pages/api/hello.js: -------------------------------------------------------------------------------- 1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction 2 | 3 | export default (req, res) => { 4 | // Open Chrome DevTools to step through the debugger! 5 | // debugger; 6 | res.status(200).json({ discovery: [] }); 7 | }; 8 | -------------------------------------------------------------------------------- /pages/api/starlink.js: -------------------------------------------------------------------------------- 1 | import { getDiscoveryData } from "../../vfx/places"; 2 | import Cors from "cors"; 3 | 4 | // Initializing the cors middleware 5 | const cors = Cors({ 6 | origin: (origin, callback) => { 7 | callback(null, [origin]); 8 | }, 9 | }); 10 | 11 | // Helper method to wait for a middleware to execute before continuing 12 | // And to throw an error when an error happens in a middleware 13 | function runMiddleware(req, res, fn) { 14 | return new Promise((resolve, reject) => { 15 | fn(req, res, (result) => { 16 | if (result instanceof Error) { 17 | return reject(result); 18 | } 19 | 20 | return resolve(result); 21 | }); 22 | }); 23 | } 24 | 25 | async function handler(req, res) { 26 | // Run the middleware 27 | await runMiddleware(req, res, cors); 28 | 29 | res.json(await getDiscoveryData({ origin: req.query.domain })); 30 | } 31 | 32 | export default handler; 33 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import router from "next/router"; 2 | import { useEffect } from "react"; 3 | 4 | export default function Home() { 5 | useEffect(() => { 6 | if (process.env.NODE_ENV === "development") { 7 | router.push(`/place/church`); 8 | } else { 9 | if (window.location.href.indexOf("thankyou.church/") !== -1) { 10 | router.push(`/place/church`); 11 | } else if (window.location.href.indexOf("loving.place/") !== -1) { 12 | router.push(`/place/spaceship`); 13 | } else { 14 | router.push(`/place/church`); 15 | } 16 | } 17 | }, []); 18 | return
; 19 | } 20 | -------------------------------------------------------------------------------- /pages/lab/index.js: -------------------------------------------------------------------------------- 1 | import GravityLab from "../../vfx/editor/GravityLab/GravityLab"; 2 | 3 | export default GravityLab; 4 | -------------------------------------------------------------------------------- /pages/place/[placeID].js: -------------------------------------------------------------------------------- 1 | // import { useEffect, useState } from "react"; 2 | import { getPages } from "../../vfx/places"; 3 | 4 | export async function getServerSideProps(context) { 5 | let placeID = context?.query?.placeID || null; 6 | 7 | if (!placeID) { 8 | return { 9 | redirect: { 10 | destination: "/", 11 | permanent: false, 12 | }, 13 | }; 14 | } 15 | 16 | return { 17 | props: { 18 | placeID, 19 | }, 20 | }; 21 | } 22 | 23 | export default function PlacePage({ placeID }) { 24 | return ; 25 | } 26 | 27 | function PageRouter({ placeID }) { 28 | let MyPage = () =>
Not found
; 29 | 30 | let res = getPages().find((e) => e.placeID === placeID); 31 | if (res) { 32 | MyPage = res.compo; 33 | } 34 | 35 | return ; 36 | } 37 | -------------------------------------------------------------------------------- /pages/system/index.js: -------------------------------------------------------------------------------- 1 | import { SystemGate } from "../../vfx/admin/gates/SystemGate"; 2 | import { Dashboard } from "../../vfx/admin/system-admin/dashboard"; 3 | 4 | export default function Page() { 5 | return ( 6 | 7 | 8 | 9 | ); 10 | } 11 | 12 | // 13 | 14 | // 15 | 16 | // 17 | 18 | // 19 | -------------------------------------------------------------------------------- /pages/user/index.js: -------------------------------------------------------------------------------- 1 | import { UserGate } from "../../vfx/admin/gates/UserGate"; 2 | 3 | export default function Page() { 4 | return User pages; 5 | } 6 | 7 | // 8 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/.DS_Store -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/chibi/actions/contorls/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/contorls/.DS_Store -------------------------------------------------------------------------------- /public/chibi/actions/contorls/idle-breathing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/contorls/idle-breathing.fbx -------------------------------------------------------------------------------- /public/chibi/actions/contorls/idle-happy.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/contorls/idle-happy.fbx -------------------------------------------------------------------------------- /public/chibi/actions/contorls/idle-sad.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/contorls/idle-sad.fbx -------------------------------------------------------------------------------- /public/chibi/actions/contorls/running-in-place-fast.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/contorls/running-in-place-fast.fbx -------------------------------------------------------------------------------- /public/chibi/actions/contorls/running-in-place-relax.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/contorls/running-in-place-relax.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/arms-hip-hop.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/arms-hip-hop.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/dancing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/dancing.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/gangnam-style.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/gangnam-style.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/hand-wave.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/hand-wave.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/hip-hop-breakdance.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/hip-hop-breakdance.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/hip-hop.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/hip-hop.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/hokey-pokey.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/hokey-pokey.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/locking.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/locking.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/northern-soul.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/northern-soul.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/salsa.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/salsa.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/samba-dancing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/samba-dancing.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/silly.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/silly.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/swing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/swing.fbx -------------------------------------------------------------------------------- /public/chibi/actions/dances/wave.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/dances/wave.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/cheering.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/cheering.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/clapping.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/clapping.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/excited.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/excited.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/pointing-gesture.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/pointing-gesture.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/pointing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/pointing.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/praying.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/praying.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/rallying.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/rallying.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/singing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/singing.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/victory-2.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/victory-2.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/victory-3.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/victory-3.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/victory-4.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/victory-4.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/victory.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/victory.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/waving.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/waving.fbx -------------------------------------------------------------------------------- /public/chibi/actions/emojis/ymca-dance.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/emojis/ymca-dance.fbx -------------------------------------------------------------------------------- /public/chibi/actions/pose/laying-1.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/pose/laying-1.fbx -------------------------------------------------------------------------------- /public/chibi/actions/pose/laying-2.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/pose/laying-2.fbx -------------------------------------------------------------------------------- /public/chibi/actions/pose/laying-3.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/pose/laying-3.fbx -------------------------------------------------------------------------------- /public/chibi/actions/pose/laying-4.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/actions/pose/laying-4.fbx -------------------------------------------------------------------------------- /public/chibi/avatar/ChibiBase-rigged.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/chibi/avatar/ChibiBase-rigged.fbx -------------------------------------------------------------------------------- /public/church/dove-v2.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/church/dove-v2.glb -------------------------------------------------------------------------------- /public/cubemap/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/cubemap/.DS_Store -------------------------------------------------------------------------------- /public/cubemap/sky-grass/nx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/cubemap/sky-grass/nx.png -------------------------------------------------------------------------------- /public/cubemap/sky-grass/ny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/cubemap/sky-grass/ny.png -------------------------------------------------------------------------------- /public/cubemap/sky-grass/nz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/cubemap/sky-grass/nz.png -------------------------------------------------------------------------------- /public/cubemap/sky-grass/px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/cubemap/sky-grass/px.png -------------------------------------------------------------------------------- /public/cubemap/sky-grass/py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/cubemap/sky-grass/py.png -------------------------------------------------------------------------------- /public/cubemap/sky-grass/pz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/cubemap/sky-grass/pz.png -------------------------------------------------------------------------------- /public/draco-glbs/gltf/draco_decoder.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/draco-glbs/gltf/draco_decoder.wasm -------------------------------------------------------------------------------- /public/draco-glbs/mac-draco.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/draco-glbs/mac-draco.glb -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/favicon.ico -------------------------------------------------------------------------------- /public/font/Cronos-Pro-Light_12448.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/Cronos-Pro-Light_12448.ttf -------------------------------------------------------------------------------- /public/font/trivial/Trivial-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/trivial/Trivial-Bold.otf -------------------------------------------------------------------------------- /public/font/trivial/Trivial-ExtraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/trivial/Trivial-ExtraLight.otf -------------------------------------------------------------------------------- /public/font/trivial/Trivial-Heavy.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/trivial/Trivial-Heavy.otf -------------------------------------------------------------------------------- /public/font/trivial/Trivial-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/trivial/Trivial-Light.otf -------------------------------------------------------------------------------- /public/font/trivial/Trivial-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/trivial/Trivial-Regular.otf -------------------------------------------------------------------------------- /public/font/trivial/Trivial-Thin.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/trivial/Trivial-Thin.otf -------------------------------------------------------------------------------- /public/font/trivial/Trivial-UltraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/font/trivial/Trivial-UltraLight.otf -------------------------------------------------------------------------------- /public/hdr/nightwilderness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/hdr/nightwilderness.png -------------------------------------------------------------------------------- /public/hdr/spaichingen_hill_1k.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/hdr/spaichingen_hill_1k.hdr -------------------------------------------------------------------------------- /public/image/sky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/image/sky.png -------------------------------------------------------------------------------- /public/image/social-icons/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/image/social-icons/.DS_Store -------------------------------------------------------------------------------- /public/image/social-icons/ig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/image/social-icons/ig.png -------------------------------------------------------------------------------- /public/image/social-icons/tiktok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/image/social-icons/tiktok.png -------------------------------------------------------------------------------- /public/image/social-icons/web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/image/social-icons/web.png -------------------------------------------------------------------------------- /public/image/social-icons/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/image/social-icons/youtube.png -------------------------------------------------------------------------------- /public/image/thankyou-jesus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/image/thankyou-jesus.png -------------------------------------------------------------------------------- /public/img/cms-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/img/cms-demo.png -------------------------------------------------------------------------------- /public/img/dream-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/img/dream-code.png -------------------------------------------------------------------------------- /public/map/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/.DS_Store -------------------------------------------------------------------------------- /public/map/camset/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/camset/.DS_Store -------------------------------------------------------------------------------- /public/map/camset/cam-set.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/camset/cam-set.glb -------------------------------------------------------------------------------- /public/map/heavenly-platforms/heavenly-platforms.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/heavenly-platforms/heavenly-platforms.glb -------------------------------------------------------------------------------- /public/map/journey-with-dear-God/journey.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/journey-with-dear-God/journey.glb -------------------------------------------------------------------------------- /public/map/orchid-sing/orchid-sing.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/orchid-sing/orchid-sing.glb -------------------------------------------------------------------------------- /public/map/skycity/church-sky-city.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/skycity/church-sky-city.glb -------------------------------------------------------------------------------- /public/map/space-walk-001.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/space-walk-001.glb -------------------------------------------------------------------------------- /public/map/spaewalk/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/spaewalk/.DS_Store -------------------------------------------------------------------------------- /public/map/spaewalk/space-walk-v003.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/spaewalk/space-walk-v003.glb -------------------------------------------------------------------------------- /public/map/stage/stage.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/map/stage/stage.glb -------------------------------------------------------------------------------- /public/me.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/me.png -------------------------------------------------------------------------------- /public/objects/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/objects/.DS_Store -------------------------------------------------------------------------------- /public/objects/bubble-gun/bubble-gun.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/objects/bubble-gun/bubble-gun.glb -------------------------------------------------------------------------------- /public/objects/butterfly/butterfly.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/objects/butterfly/butterfly.glb -------------------------------------------------------------------------------- /public/objects/card/card-oobe.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/objects/card/card-oobe.glb -------------------------------------------------------------------------------- /public/objects/honey/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/objects/honey/.DS_Store -------------------------------------------------------------------------------- /public/objects/hud/HUD.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/objects/hud/HUD.glb -------------------------------------------------------------------------------- /public/objects/spaceship-05/spaceship-05.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/objects/spaceship-05/spaceship-05.glb -------------------------------------------------------------------------------- /public/particles/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/particles/.DS_Store -------------------------------------------------------------------------------- /public/particles/old/atv.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/particles/old/atv.glb -------------------------------------------------------------------------------- /public/particles/old/atv2.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/particles/old/atv2.glb -------------------------------------------------------------------------------- /public/particles/old/flower-organism.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/particles/old/flower-organism.glb -------------------------------------------------------------------------------- /public/particles/old/noodlehat.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/particles/old/noodlehat.glb -------------------------------------------------------------------------------- /public/preview/church-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/preview/church-thumb.png -------------------------------------------------------------------------------- /public/preview/sing-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/preview/sing-thumb.png -------------------------------------------------------------------------------- /public/preview/spaceship-thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/preview/spaceship-thumb.png -------------------------------------------------------------------------------- /public/rpm/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/.DS_Store -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/hip-hop-dancing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/hip-hop-dancing.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/quick-formal-bow.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/quick-formal-bow.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/running.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/running.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/standing-foot.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/standing-foot.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/standing-greeting.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/standing-greeting.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/standing-texting.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/standing-texting.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/standing-time.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/standing-time.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/standing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/standing.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/swim-float.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/swim-float.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/swim-forward.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/swim-forward.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-locomotion/waving-gesture.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-locomotion/waving-gesture.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-look/look-forward.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-look/look-forward.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-look/look-ground.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-look/look-ground.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-look/look-hand.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-look/look-hand.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-look/look-lift.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-look/look-lift.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-look/look-pick-2.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-look/look-pick-2.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-look/look-pick.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-look/look-pick.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions-look/look-point.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions-look/look-point.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/backflip.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/backflip.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/bow-quick-formal.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/bow-quick-formal.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/cheer.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/cheer.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/dance-hiphop.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/dance-hiphop.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/excited.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/excited.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/greetings.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/greetings.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/guesture-pointer-2.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/guesture-pointer-2.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/guesture-pointer.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/guesture-pointer.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/gun-shoot.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/gun-shoot.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/hand-forward.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/hand-forward.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/happy-hand.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/happy-hand.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/happy-idle.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/happy-idle.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/hi-wave-both-hands.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/hi-wave-both-hands.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/mma-idle.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/mma-idle.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/mma-kick-2.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/mma-kick-2.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/mma-kick.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/mma-kick.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/mma-warmup.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/mma-warmup.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/silly-dance.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/silly-dance.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-actions/spin-in-place.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-actions/spin-in-place.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-avatar/white-armor.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-avatar/white-armor.glb -------------------------------------------------------------------------------- /public/rpm/rpm-pose/standing-waiting.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-pose/standing-waiting.fbx -------------------------------------------------------------------------------- /public/rpm/rpm-pose/standing.fbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/rpm/rpm-pose/standing.fbx -------------------------------------------------------------------------------- /public/song/hallelujah.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/song/hallelujah.mp3 -------------------------------------------------------------------------------- /public/texture/portalAlpahMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/texture/portalAlpahMap.png -------------------------------------------------------------------------------- /public/ui-imgs/pexels-rodnae-productions-7563568.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/public/ui-imgs/pexels-rodnae-productions-7563568.jpg -------------------------------------------------------------------------------- /styles/Home.module.css: -------------------------------------------------------------------------------- 1 | /* .container { 2 | min-height: 100vh; 3 | padding: 0 0.5rem; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | 10 | .main { 11 | padding: 5rem 0; 12 | flex: 1; 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: center; 16 | align-items: center; 17 | } 18 | 19 | .footer { 20 | width: 100%; 21 | height: 100px; 22 | border-top: 1px solid #eaeaea; 23 | display: flex; 24 | justify-content: center; 25 | align-items: center; 26 | } 27 | 28 | .footer img { 29 | margin-left: 0.5rem; 30 | } 31 | 32 | .footer a { 33 | display: flex; 34 | justify-content: center; 35 | align-items: center; 36 | } 37 | 38 | .title a { 39 | color: #0070f3; 40 | text-decoration: none; 41 | } 42 | 43 | .title a:hover, 44 | .title a:focus, 45 | .title a:active { 46 | text-decoration: underline; 47 | } 48 | 49 | .title { 50 | margin: 0; 51 | line-height: 1.15; 52 | font-size: 4rem; 53 | } 54 | 55 | .title, 56 | .description { 57 | text-align: center; 58 | } 59 | 60 | .description { 61 | line-height: 1.5; 62 | font-size: 1.5rem; 63 | } 64 | 65 | .code { 66 | background: #fafafa; 67 | border-radius: 5px; 68 | padding: 0.75rem; 69 | font-size: 1.1rem; 70 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, 71 | Bitstream Vera Sans Mono, Courier New, monospace; 72 | } 73 | 74 | .grid { 75 | display: flex; 76 | align-items: center; 77 | justify-content: center; 78 | flex-wrap: wrap; 79 | max-width: 800px; 80 | margin-top: 3rem; 81 | } 82 | 83 | .card { 84 | margin: 1rem; 85 | flex-basis: 45%; 86 | padding: 1.5rem; 87 | text-align: left; 88 | color: inherit; 89 | text-decoration: none; 90 | border: 1px solid #eaeaea; 91 | border-radius: 10px; 92 | transition: color 0.15s ease, border-color 0.15s ease; 93 | } 94 | 95 | .card:hover, 96 | .card:focus, 97 | .card:active { 98 | color: #0070f3; 99 | border-color: #0070f3; 100 | } 101 | 102 | .card h3 { 103 | margin: 0 0 1rem 0; 104 | font-size: 1.5rem; 105 | } 106 | 107 | .card p { 108 | margin: 0; 109 | font-size: 1.25rem; 110 | line-height: 1.5; 111 | } 112 | 113 | .logo { 114 | height: 1em; 115 | } 116 | 117 | @media (max-width: 600px) { 118 | .grid { 119 | width: 100%; 120 | flex-direction: column; 121 | } 122 | } */ 123 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body, 3 | #__next, 4 | .full { 5 | width: 100%; 6 | height: 100%; 7 | padding: 0; 8 | margin: 0; 9 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 10 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 11 | } 12 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: ["./*/**/*.{js,ts,jsx,tsx}"], 3 | darkMode: false, // or 'media' or 'class' 4 | theme: { 5 | extend: {}, 6 | }, 7 | variants: { 8 | extend: {}, 9 | }, 10 | plugins: [ 11 | // 12 | // require("daisyui"), 13 | ], 14 | 15 | // daisyui: { 16 | // styled: true, 17 | // themes: false, 18 | // rtl: false, 19 | // }, 20 | }; 21 | -------------------------------------------------------------------------------- /vfx/admin/gates/SystemGate.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { testAdminRights } from "../../firebase/firelib"; 3 | import { LoginUI } from "../ui/LoginUI"; 4 | 5 | export function SystemGate({ children }) { 6 | let [ok, setOK] = useState("loading"); 7 | 8 | let test = () => { 9 | setOK("loading"); 10 | testAdminRights().then( 11 | () => { 12 | setOK("ok"); 13 | }, 14 | () => { 15 | setOK("fail"); 16 | } 17 | ); 18 | }; 19 | useEffect(() => { 20 | test(); 21 | }, []); 22 | 23 | // 24 | // 25 | // 26 | return ( 27 | <> 28 | {ok === "loading" && ( 29 |
30 |
31 |
32 |
33 | 37 | Security Check 38 | 39 |
40 | 41 |
42 | {/* */} 43 |
44 | Checking Access Rights... 45 |
46 |
47 |
48 | 49 |
50 | 54 |
55 |
56 |
57 | )} 58 | {ok === "fail" && ( 59 |
60 |
61 |
62 |
63 | 67 | Security Check 68 | 69 |
70 | 71 |
72 | {/* */} 73 |
74 |
No Access Rights...
75 |
76 | { 78 | test(); 79 | }} 80 | onFail={() => { 81 | setOK("fail"); 82 | }} 83 | > 84 |
85 |
86 |
87 |
88 | 89 |
90 | 94 |
95 |
96 |
97 | )} 98 | {ok === "ok" && children} 99 | 100 | ); 101 | } 102 | 103 | // 104 | 105 | // 106 | 107 | // 108 | 109 | // 110 | -------------------------------------------------------------------------------- /vfx/admin/gates/UserGate.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { testUserRights } from "../../firebase/firelib"; 3 | import { LoginUI } from "../ui/LoginUI"; 4 | 5 | export function UserGate({ children }) { 6 | let [ok, setOK] = useState("loading"); 7 | 8 | let test = () => { 9 | setOK("loading"); 10 | testUserRights().then( 11 | () => { 12 | setOK("ok"); 13 | }, 14 | () => { 15 | setOK("fail"); 16 | } 17 | ); 18 | }; 19 | useEffect(() => { 20 | test(); 21 | }, []); 22 | 23 | // 24 | // 25 | return ( 26 | <> 27 | {ok === "loading" && ( 28 |
29 |
30 |
31 |
32 | 36 | Security Check 37 | 38 |
39 | 40 |
41 | {/* */} 42 |
43 | Checking Access Rights... 44 |
45 |
46 |
47 | 48 |
49 | 53 |
54 |
55 |
56 | )} 57 | 58 | {ok === "fail" && ( 59 |
60 |
61 |
62 |
63 | 67 | Security Check 68 | 69 |
70 | 71 |
72 | {/* */} 73 |
74 |
No Access Rights...
75 |
76 | { 78 | test(); 79 | }} 80 | onFail={() => { 81 | setOK("fail"); 82 | }} 83 | > 84 |
85 |
86 |
87 |
88 | 89 |
90 | 94 |
95 |
96 |
97 | )} 98 | 99 | {ok === "ok" && children} 100 | 101 | ); 102 | } 103 | 104 | // 105 | 106 | // 107 | 108 | // 109 | 110 | // 111 | -------------------------------------------------------------------------------- /vfx/admin/system-admin/dashboard.js: -------------------------------------------------------------------------------- 1 | import { MenuBlock } from "../ui/MenuBlock"; 2 | import { NavBar } from "../ui/Navbar"; 3 | import { GlassBlock } from "../ui/GlassBlock"; 4 | 5 | export function Dashboard() { 6 | return ( 7 |
8 | 9 |
10 |
11 | {/* */} 12 | 13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /vfx/admin/ui/GlassBlock.js: -------------------------------------------------------------------------------- 1 | export function GlassBlock() { 2 | return ( 3 |
9 |
10 |
11 | 15 |
16 |
17 |

Glass

18 |

19 | Rerum reiciendis beatae tenetur excepturi aut pariatur est eos. Sit 20 | sit necessitatibus veritatis sed molestiae voluptates incidunt iure 21 | sapiente. 22 |

23 |
24 | 25 |
26 |
27 |
28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /vfx/admin/ui/LoginUI.js: -------------------------------------------------------------------------------- 1 | import { loginGoogle } from "../../firebase/firelib"; 2 | 3 | export function LoginUI({ onDone, onFail }) { 4 | // 5 | return ( 6 |
7 |
Please Login...
8 | 17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /vfx/admin/ui/MenuBlock.js: -------------------------------------------------------------------------------- 1 | export function MenuBlock() { 2 | return ( 3 |
4 | 5 |
6 | ); 7 | } 8 | 9 | function CardManagement() { 10 | return ( 11 | 41 | ); 42 | } 43 | 44 | function InfoIcon() { 45 | return ( 46 | 52 | 58 | 59 | ); 60 | } 61 | 62 | function FolderIcon() { 63 | return ( 64 | 70 | {/* */} 71 | 77 | {/* */} 78 | 79 | ); 80 | } 81 | -------------------------------------------------------------------------------- /vfx/admin/ui/Navbar.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | 3 | export function NavBar() { 4 | let applyTheme = (v) => { 5 | document.querySelector("html").setAttribute("data-theme", v); 6 | }; 7 | let setTheme = (v) => { 8 | localStorage.setItem("theme-daisy", v); 9 | applyTheme(v); 10 | }; 11 | 12 | useEffect(() => { 13 | let str = localStorage.getItem("theme-daisy"); 14 | if (str) { 15 | applyTheme(str); 16 | } 17 | return () => { 18 | // 19 | }; 20 | }, []); 21 | 22 | let themes = [ 23 | "light", 24 | "dark", 25 | "cupcake", 26 | "bumblebee", 27 | "emerald", 28 | "corporate", 29 | "synthwave", 30 | "retro", 31 | "cyberpunk", 32 | "valentine", 33 | "halloween", 34 | "garden", 35 | "forest", 36 | "aqua", 37 | "lofi", 38 | "pastel", 39 | "fantasy", 40 | "wireframe", 41 | "black", 42 | "luxury", 43 | "dracula", 44 | ]; 45 | 46 | return ( 47 |
48 |
49 | Admin Panel 50 |
51 |
52 |
53 | Home 54 | {/* Portfolio 55 | About 56 | Contact */} 57 |
58 |
59 |
60 | {/*
61 |
62 | Themes 63 |
64 |
    68 | {themes.map((e) => { 69 | return ( 70 |
  • 71 | { 74 | setTheme(e); 75 | }} 76 | > 77 | {e} 78 | 79 |
  • 80 | ); 81 | })} 82 |
83 |
*/} 84 |
85 |
86 | ); 87 | } 88 | -------------------------------------------------------------------------------- /vfx/admin/ui/WelcomeBack.js: -------------------------------------------------------------------------------- 1 | export function WelcomeBack() { 2 | return ( 3 |
4 | 8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /vfx/canvas/Controls/FirstCamControls.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree } from "@react-three/fiber"; 2 | import { useEffect, useRef } from "react"; 3 | import { Camera, Vector3 } from "three"; 4 | import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; 5 | import { Now } from "../../store/Now"; 6 | import { useAutoEvent } from "../../utils/use-auto-event"; 7 | 8 | export function FirstCamControls({ Now, envMap, higherCamera = 1.3 }) { 9 | // 10 | let { get } = useThree(); 11 | 12 | // useFrame(({ camera }) => { 13 | // camera.position.x = Now.avatarAt.x; 14 | // camera.position.y = Now.avatarAt.y + higherCamera; 15 | // camera.position.z = Now.avatarAt.z; 16 | // }); 17 | 18 | return ( 19 | 20 | {/* */} 21 | {/* */} 22 | {/* */} 23 | 24 | 25 | { 27 | get().camera.rotation.copy(camera.rotation); 28 | }} 29 | > 30 | 31 | ); 32 | } 33 | 34 | function DragOrbit({ onRotation }) { 35 | let { get } = useThree(); 36 | 37 | let ref = useRef({ works() {} }); 38 | 39 | useEffect(() => { 40 | // 41 | let cam = new Camera(); 42 | cam.position.z = 10; 43 | let orbit = new OrbitControls(cam, get().gl.domElement); 44 | orbit.enableDamping = true; 45 | orbit.dampingFactor = 0.93; 46 | ref.current.works = () => { 47 | // 48 | orbit.update(); 49 | onRotation({ camera: cam }); 50 | }; 51 | // onRotation 52 | }, []); 53 | 54 | useFrame(() => { 55 | ref.current.works(); 56 | }); 57 | 58 | return ; 59 | } 60 | 61 | function Keyboard({ camera }) { 62 | // 63 | useAutoEvent("keydown", (ev) => { 64 | // console.log(ev.key); 65 | 66 | if (ev.key === "w") { 67 | Now.keyW = true; 68 | } 69 | if (ev.key === "a") { 70 | Now.keyA = true; 71 | } 72 | if (ev.key === "s") { 73 | Now.keyS = true; 74 | } 75 | if (ev.key === "d") { 76 | Now.keyD = true; 77 | } 78 | }); 79 | 80 | useAutoEvent("keyup", (ev) => { 81 | // console.log(ev.key); 82 | 83 | if (ev.key === "w") { 84 | Now.keyW = false; 85 | } 86 | if (ev.key === "a") { 87 | Now.keyA = false; 88 | } 89 | if (ev.key === "s") { 90 | Now.keyS = false; 91 | } 92 | if (ev.key === "d") { 93 | Now.keyD = false; 94 | } 95 | }); 96 | 97 | let scaler = 1; 98 | let keyBoardForward = new Vector3(); 99 | useFrame(({ camera }) => { 100 | if (Now.keyW) { 101 | keyBoardForward.set(0, 0, -1); 102 | keyBoardForward.applyEuler(camera.rotation); 103 | keyBoardForward.y = 0.0; 104 | 105 | keyBoardForward.normalize().multiplyScalar(scaler); 106 | camera.position.add(keyBoardForward); 107 | } else if (Now.keyA) { 108 | keyBoardForward.set(-1, 0, 0); 109 | keyBoardForward.applyEuler(camera.rotation); 110 | keyBoardForward.y = 0.0; 111 | keyBoardForward.normalize().multiplyScalar(scaler); 112 | 113 | camera.position.add(keyBoardForward); 114 | } else if (Now.keyS) { 115 | keyBoardForward.set(0, 0, 1); 116 | keyBoardForward.applyEuler(camera.rotation); 117 | keyBoardForward.y = 0.0; 118 | keyBoardForward.normalize().multiplyScalar(scaler); 119 | 120 | camera.position.add(keyBoardForward); 121 | } else if (Now.keyD) { 122 | keyBoardForward.set(1, 0, 0); 123 | keyBoardForward.applyEuler(camera.rotation); 124 | keyBoardForward.y = 0.0; 125 | keyBoardForward.normalize().multiplyScalar(scaler); 126 | 127 | camera.position.add(keyBoardForward); 128 | } 129 | 130 | camera.position.y = 1.5; 131 | 132 | if (camera.position.distanceTo(Now.goingTo) >= 3) { 133 | Now.goingTo.lerp(camera.position, 0.05); 134 | } 135 | }); 136 | 137 | return null; 138 | } 139 | -------------------------------------------------------------------------------- /vfx/canvas/Controls/SkyViewControls.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree } from "@react-three/fiber"; 2 | import { useEffect, useMemo, useRef } from "react"; 3 | import { MapControls } from "three/examples/jsm/controls/OrbitControls"; 4 | import { useAutoEvent } from "../../utils/use-auto-event"; 5 | import { usePinch, useWheel } from "@use-gesture/react"; 6 | import { MathUtils } from "three"; 7 | export function SkyViewControls({ colliderMesh, Now }) { 8 | let { get } = useThree(); 9 | 10 | let orbit = useMemo(() => { 11 | // Now.goingTo.set( 12 | // Now.startAt.x, 13 | // Now.startAt.y, 14 | // Now.startAt.z 15 | // ); 16 | 17 | // Now.avatarAt.set( 18 | // Now.startAt.x, 19 | // Now.startAt.y, 20 | // Now.startAt.z 21 | // ); 22 | 23 | let orbit = new MapControls(get().camera, get().gl.domElement); 24 | orbit.screenSpacePanning = true; 25 | orbit.enableRotate = false; 26 | orbit.enableZoom = false; 27 | 28 | // orbit.zoomSpeed = 0.1; 29 | orbit.object.position.x = Now.startAt.x + 0; 30 | orbit.object.position.y = Now.startAt.y + 10; 31 | orbit.object.position.z = Now.startAt.z + 10; 32 | 33 | orbit.object.lookAt(Now.startAt); 34 | orbit.target.copy(Now.startAt); 35 | 36 | orbit.object.fov = 35; 37 | orbit.object.updateProjectionMatrix(); 38 | 39 | return orbit; 40 | }, [get().camera]); 41 | 42 | let zoom = useRef(1); 43 | useWheel( 44 | (st) => { 45 | st.event.preventDefault(); 46 | 47 | let delta = -st.delta[0] / 10; 48 | 49 | zoom.current += delta; 50 | 51 | if (zoom.current <= 0.1) { 52 | zoom.current -= delta; 53 | } 54 | if (zoom.current >= 4) { 55 | zoom.current -= delta; 56 | } 57 | }, 58 | { 59 | target: get().gl.domElement, 60 | eventOptions: { 61 | passive: false, 62 | }, 63 | } 64 | ); 65 | 66 | usePinch( 67 | (st) => { 68 | zoom.current = 1 / st.offset[0]; 69 | 70 | if (zoom.current <= 0.1) { 71 | zoom.current = 0.1; 72 | } 73 | if (zoom.current >= 4) { 74 | zoom.current = 4; 75 | } 76 | 77 | Now.goingTo.copy(Now.avatarAt); 78 | Now.isDown = false; 79 | }, 80 | { 81 | target: get().gl.domElement, 82 | } 83 | ); 84 | 85 | let zoomInter = useRef(zoom.current); 86 | useFrame(() => { 87 | zoomInter.current = MathUtils.lerp(zoomInter.current, zoom.current, 0.05); 88 | orbit.object.position.set( 89 | // 90 | Now.avatarAt.x, 91 | Now.avatarAt.y + Math.pow(30, 1) * Math.pow(zoomInter.current, 1), 92 | Now.avatarAt.z + Math.pow(30, 1) * Math.pow(zoomInter.current, 1 / 2) 93 | ); 94 | 95 | orbit.target.copy(Now.avatarAt); 96 | orbit.update(); 97 | orbit.object.lookAt(Now.avatarAt.x, Now.avatarAt.y - 1.3, Now.avatarAt.z); 98 | // orbit.object.position.copy(Now.avatarAtDelta); 99 | }); 100 | 101 | useEffect(() => { 102 | return () => { 103 | orbit.dispose(); 104 | }; 105 | }, [orbit]); 106 | 107 | let castSync = ({ detect = false }) => { 108 | // 109 | const { raycaster, mouse, camera, scene } = get(); 110 | 111 | raycaster.setFromCamera(mouse, camera); 112 | 113 | // let hit = colliderMesh.geometry.boundsTree.raycastFirst( 114 | // colliderMesh, 115 | // raycaster, 116 | // raycaster.ray 117 | // ); 118 | 119 | let res = raycaster.intersectObject(scene, true); 120 | 121 | let hit = false; 122 | if (res && res[0]) { 123 | hit = res[0]; 124 | } 125 | 126 | if (hit) { 127 | // console.log(hit?.object); 128 | if (detect && hit?.object?.userData?.node) { 129 | window.dispatchEvent( 130 | new CustomEvent("metaverse-click-mesh", { 131 | detail: hit?.object, 132 | }) 133 | ); 134 | return; 135 | } 136 | 137 | Now.goingTo.copy(hit.point); 138 | console.log(hit.point.toArray().map((e) => Number(e.toFixed(2)))); 139 | } 140 | }; 141 | 142 | // 143 | // 144 | 145 | Now.isDown = false; 146 | let moved = 0; 147 | useAutoEvent( 148 | "pointerdown", 149 | () => { 150 | Now.isDown = true; 151 | castSync({}); 152 | moved = 0; 153 | }, 154 | { passive: false }, 155 | get().gl.domElement 156 | ); 157 | useAutoEvent( 158 | "pointermove", 159 | () => { 160 | moved++; 161 | }, 162 | { passive: false }, 163 | get().gl.domElement 164 | ); 165 | 166 | useAutoEvent( 167 | "pointerup", 168 | () => { 169 | Now.isDown = false; 170 | castSync({ detect: moved <= 20 }); 171 | moved = 0; 172 | }, 173 | { passive: false }, 174 | get().gl.domElement 175 | ); 176 | 177 | // useAutoEvent( 178 | // "mousedown", 179 | // () => { 180 | // Now.isDown = true; 181 | // castSync(); 182 | // }, 183 | // { passive: false }, 184 | // get().gl.domElement 185 | // ); 186 | 187 | // useAutoEvent( 188 | // "mouseup", 189 | // () => { 190 | // Now.isDown = false; 191 | // castSync(); 192 | // }, 193 | // { passive: false }, 194 | // get().gl.domElement 195 | // ); 196 | 197 | // useAutoEvent( 198 | // "touchstart", 199 | // () => { 200 | // Now.isDown = true; 201 | // castSync(); 202 | // }, 203 | // { passive: false }, 204 | // get().gl.domElement 205 | // ); 206 | 207 | // useAutoEvent( 208 | // "touchend", 209 | // () => { 210 | // Now.isDown = false; 211 | // castSync(); 212 | // }, 213 | // { passive: false }, 214 | // get().gl.domElement 215 | // ); 216 | 217 | useFrame(() => { 218 | if (Now.isDown) { 219 | castSync({}); 220 | } 221 | }); 222 | 223 | return ; 224 | } 225 | -------------------------------------------------------------------------------- /vfx/canvas/Controls/StoryFlyControls.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree, createPortal } from "@react-three/fiber"; 2 | import { useEffect, useMemo, useRef } from "react"; 3 | import { CatmullRomCurve3, MathUtils, Object3D, Vector3 } from "three"; 4 | import { useDrag, useWheel } from "@use-gesture/react"; 5 | import { Now } from "../../store/Now"; 6 | import { useAutoEvent } from "../../utils/use-auto-event"; 7 | // import { createPortal } from "react-dom"; 8 | export function StoryFlyControls({ 9 | floor, 10 | overallSpeed = 1, 11 | cameraHeight = 1.5, 12 | loop = true, 13 | }) { 14 | let { get } = useThree(); 15 | // 16 | 17 | let nameList = []; 18 | floor.traverse((it) => { 19 | if (it.name.indexOf("walk") === 0) { 20 | nameList.push(it.name); 21 | } 22 | }); 23 | 24 | let pts = nameList.map((e) => { 25 | let obj = floor.getObjectByName(e) || new Object3D(); 26 | return obj.position; 27 | }); 28 | 29 | let roll = useMemo(() => { 30 | if (pts.length === 0) { 31 | return false; 32 | } 33 | return new CatmullRomCurve3(pts, loop, "catmullrom", 0.8); 34 | }, [pts, loop]); 35 | 36 | console.log(pts); 37 | 38 | let progress = useRef(0); 39 | 40 | let speed = 0.003; 41 | get().gl.domElement.style.touchAction = "none"; 42 | 43 | // 44 | useDrag( 45 | (state) => { 46 | state.event.preventDefault(); 47 | 48 | let change = state.movement[1] || 0; 49 | let delta = change / 120; 50 | 51 | if (delta >= speed) { 52 | delta = speed; 53 | } 54 | if (delta <= -speed) { 55 | delta = -speed; 56 | } 57 | 58 | progress.current += delta * overallSpeed; 59 | }, 60 | { 61 | target: get().gl.domElement, 62 | eventOptions: { 63 | passive: false, 64 | }, 65 | } 66 | ); 67 | 68 | useWheel( 69 | (state) => { 70 | state.event.preventDefault(); 71 | 72 | let change = state.delta[1] || 0; 73 | let delta = change / 100; 74 | 75 | if (delta >= speed) { 76 | delta = speed; 77 | } 78 | 79 | if (delta <= -speed) { 80 | delta = -speed; 81 | } 82 | 83 | progress.current += delta * overallSpeed; 84 | }, 85 | { 86 | target: get().gl.domElement, 87 | eventOptions: { 88 | passive: false, 89 | }, 90 | } 91 | ); 92 | 93 | useAutoEvent("touchstart", (ev) => { 94 | ev.preventDefault(); 95 | }); 96 | useAutoEvent("touchmove", (ev) => { 97 | ev.preventDefault(); 98 | }); 99 | useAutoEvent("touchend", (ev) => { 100 | ev.preventDefault(); 101 | }); 102 | 103 | // let lv = progress.current; 104 | let at = new Vector3(); 105 | let at2 = new Vector3(); 106 | 107 | // 108 | let lv = 0; 109 | useFrame(({ camera, scene }) => { 110 | progress.current = progress.current % 1; 111 | progress.current = Math.abs(progress.current); 112 | 113 | lv = MathUtils.lerp(lv, progress.current, 0.3); 114 | // lv = MathUtils.lerp(lv, progress.current, 0.18); 115 | if (!roll) { 116 | return; 117 | } 118 | 119 | // if (lv <= 0) { 120 | // lv = 0; 121 | // } 122 | 123 | roll.getPoint(lv, at); 124 | roll.getPoint(lv + 0.03, at2); 125 | 126 | camera.position.copy(at); 127 | camera.lookAt(at2.x, at2.y, at2.z); 128 | }); 129 | 130 | useEffect(() => { 131 | get().scene.add(get().camera); 132 | return () => { 133 | get().scene.remove(get().camera); 134 | }; 135 | }, []); 136 | 137 | return ( 138 | 139 | {createPortal( 140 | 141 | 142 | 146 | , 147 | get().camera 148 | )} 149 | 150 | {/* */} 151 | {/* */} 152 | 153 | ); 154 | } 155 | -------------------------------------------------------------------------------- /vfx/canvas/Controls/WalkerFollowerControls.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree, createPortal } from "@react-three/fiber"; 2 | import { useEffect, useMemo, useRef } from "react"; 3 | import { CatmullRomCurve3, MathUtils, Object3D, Vector3 } from "three"; 4 | import { useDrag, useWheel } from "@use-gesture/react"; 5 | import { Now } from "../../store/Now"; 6 | import { useAutoEvent } from "../../utils/use-auto-event"; 7 | // import { createPortal } from "react-dom"; 8 | export function WalkerFollowerControls({ 9 | floor, 10 | overallSpeed = 1, 11 | cameraHeight = 1.5, 12 | loop = true, 13 | }) { 14 | let { get } = useThree(); 15 | // 16 | 17 | let nameList = []; 18 | floor.traverse((it) => { 19 | if (it.name.indexOf("walk") === 0) { 20 | nameList.push(it.name); 21 | } 22 | }); 23 | 24 | let pts = nameList.map((e) => { 25 | let obj = floor.getObjectByName(e) || new Object3D(); 26 | return obj.position; 27 | }); 28 | 29 | let roll = useMemo(() => { 30 | if (pts.length === 0) { 31 | return false; 32 | } 33 | return new CatmullRomCurve3(pts, loop, "catmullrom", 0.8); 34 | return new CatmullRomCurve3(pts, loop, "catmullrom", 0.8); 35 | }, [pts]); 36 | 37 | console.log(pts); 38 | 39 | let progress = useRef(0); 40 | 41 | let speed = 0.003; 42 | get().gl.domElement.style.touchAction = "none"; 43 | 44 | // 45 | useDrag( 46 | (state) => { 47 | state.event.preventDefault(); 48 | 49 | let change = state.movement[1] || 0; 50 | let delta = change / 120; 51 | 52 | if (delta >= speed) { 53 | delta = speed; 54 | } 55 | if (delta <= -speed) { 56 | delta = -speed; 57 | } 58 | 59 | progress.current += delta * overallSpeed; 60 | }, 61 | { 62 | target: get().gl.domElement, 63 | eventOptions: { 64 | passive: false, 65 | }, 66 | } 67 | ); 68 | 69 | useWheel( 70 | (state) => { 71 | state.event.preventDefault(); 72 | 73 | let change = state.delta[1] || 0; 74 | let delta = change / 100; 75 | 76 | if (delta >= speed * 0.4) { 77 | delta = speed * 0.4; 78 | } 79 | 80 | if (delta <= -speed * 0.4) { 81 | delta = -speed * 0.4; 82 | } 83 | 84 | progress.current += delta * overallSpeed; 85 | }, 86 | { 87 | target: get().gl.domElement, 88 | eventOptions: { 89 | passive: false, 90 | }, 91 | } 92 | ); 93 | 94 | useAutoEvent("touchstart", (ev) => { 95 | ev.preventDefault(); 96 | }); 97 | useAutoEvent("touchmove", (ev) => { 98 | ev.preventDefault(); 99 | }); 100 | useAutoEvent("touchend", (ev) => { 101 | ev.preventDefault(); 102 | }); 103 | 104 | let lv = progress.current; 105 | let at = new Vector3(); 106 | let back = new Vector3(); 107 | let back2 = new Vector3(); 108 | let headWP = new Vector3(); 109 | let camWD = new Vector3(); 110 | 111 | // 112 | useFrame(({ camera, scene }) => { 113 | lv = MathUtils.lerp(lv, progress.current, 0.18); 114 | if (!roll) { 115 | return; 116 | } 117 | roll.getPoint(lv + 0.001, at); 118 | roll.getPoint(lv + -0.0, back); 119 | roll.getPoint(lv + -0.001, back2); 120 | 121 | Now.goingTo.copy(at); 122 | camera.position.copy(back2); 123 | camera.position.y = 1.5; 124 | camera.lookAt(back.x, 1.5, back.z); 125 | 126 | let head = scene.getObjectByName("Head"); 127 | if (head) { 128 | head.getWorldPosition(headWP); 129 | camera.getWorldDirection(camWD); 130 | 131 | camera.position.lerp(Now.avatarAt, 0.1); 132 | 133 | camWD.normalize().multiplyScalar(2); 134 | camWD.y = 0; 135 | 136 | camera.position.copy(back2); 137 | camera.position.sub(camWD); 138 | 139 | camera.position.y = 1.5; 140 | camera.lookAt(at.x, 1.5, at.z); 141 | } 142 | }); 143 | 144 | useEffect(() => { 145 | get().scene.add(get().camera); 146 | return () => { 147 | get().scene.remove(get().camera); 148 | }; 149 | }, []); 150 | 151 | return ( 152 | 153 | {createPortal( 154 | 155 | 156 | 160 | , 161 | get().camera 162 | )} 163 | 164 | {/* */} 165 | {/* */} 166 | 167 | ); 168 | } 169 | -------------------------------------------------------------------------------- /vfx/canvas/Controls/old/WalkerFollowerControls.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree, createPortal } from "@react-three/fiber"; 2 | import { useEffect, useMemo, useRef } from "react"; 3 | import { CatmullRomCurve3, MathUtils, Vector3 } from "three"; 4 | import { useDrag, useWheel } from "@use-gesture/react"; 5 | import { Now } from "../../store/Now"; 6 | import { useAutoEvent } from "../../utils/use-auto-event"; 7 | // import { createPortal } from "react-dom"; 8 | export function WalkerFollowerControls({ floor, cameraHeight = 1.5 }) { 9 | let { get } = useThree(); 10 | // 11 | 12 | let nameList = []; 13 | floor.traverse((it) => { 14 | if (it.name.indexOf("walk") === 0) { 15 | nameList.push(it.name); 16 | } 17 | }); 18 | 19 | let pts = nameList.map((e) => { 20 | return floor.getObjectByName(e).position; 21 | }); 22 | 23 | let roll = useMemo(() => { 24 | return new CatmullRomCurve3(pts, true, "catmullrom", 1.0); 25 | }, [pts]); 26 | 27 | let progress = useRef(0); 28 | 29 | let speed = 0.003; 30 | 31 | // 32 | useDrag( 33 | (state) => { 34 | state.event.preventDefault(); 35 | 36 | let change = state.movement[1] || 0; 37 | let delta = change / 200; 38 | 39 | if (delta >= speed) { 40 | delta = speed; 41 | } 42 | if (delta <= -speed) { 43 | delta = -speed; 44 | } 45 | 46 | progress.current += delta * 0.3; 47 | }, 48 | { 49 | target: get().gl.domElement, 50 | eventOptions: { 51 | passive: false, 52 | }, 53 | } 54 | ); 55 | 56 | useWheel( 57 | (state) => { 58 | state.event.preventDefault(); 59 | 60 | let change = state.delta[1] || 0; 61 | let delta = change / 100; 62 | 63 | if (delta >= speed * 0.2) { 64 | delta = speed * 0.2; 65 | } 66 | 67 | if (delta <= -speed * 0.2) { 68 | delta = -speed * 0.2; 69 | } 70 | 71 | progress.current += delta; 72 | }, 73 | { 74 | target: get().gl.domElement, 75 | eventOptions: { 76 | passive: false, 77 | }, 78 | } 79 | ); 80 | 81 | useAutoEvent("touchstart", (ev) => { 82 | ev.preventDefault(); 83 | }); 84 | useAutoEvent("touchmove", (ev) => { 85 | ev.preventDefault(); 86 | }); 87 | useAutoEvent("touchend", (ev) => { 88 | ev.preventDefault(); 89 | }); 90 | 91 | let lv = progress.current; 92 | let at = new Vector3(); 93 | let back = new Vector3(); 94 | let back2 = new Vector3(); 95 | let headWP = new Vector3(); 96 | let camWD = new Vector3(); 97 | useFrame(({ camera, scene }) => { 98 | lv = MathUtils.lerp(lv, progress.current, 0.1); 99 | 100 | roll.getPoint(lv + 0.01, at); 101 | roll.getPoint(lv + -0.0, back); 102 | roll.getPoint(lv + -0.01, back2); 103 | 104 | Now.goingTo.copy(at); 105 | camera.position.copy(back2); 106 | camera.lookAt(back); 107 | 108 | let head = scene.getObjectByName("Head"); 109 | if (head) { 110 | head.getWorldPosition(headWP); 111 | camera.getWorldDirection(camWD); 112 | 113 | camera.position.lerp(Now.avatarAt, 0.1); 114 | 115 | camWD.normalize().multiplyScalar(2); 116 | camWD.y = 0; 117 | 118 | camera.position.copy(back2); 119 | camera.position.sub(camWD); 120 | 121 | camera.position.y = 1.5; 122 | camera.lookAt(Now.avatarAt.x, 1.5, Now.avatarAt.z); 123 | } 124 | }); 125 | 126 | useEffect(() => { 127 | get().scene.add(get().camera); 128 | return () => { 129 | get().scene.remove(get().camera); 130 | }; 131 | }, []); 132 | 133 | return ( 134 | 135 | {createPortal( 136 | 137 | 138 | 142 | , 143 | get().camera 144 | )} 145 | 146 | {/* */} 147 | {/* */} 148 | 149 | ); 150 | } 151 | -------------------------------------------------------------------------------- /vfx/canvas/MapAddons/PathWay.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useMemo, useRef } from "react"; 2 | import { CatmullRomCurve3, Color, Vector3 } from "three"; 3 | import { Line2 } from "three/examples/jsm/lines/Line2"; 4 | import { LineMaterial } from "three/examples/jsm/lines/LineMaterial"; 5 | import { LineSegmentsGeometry } from "three/examples/jsm/lines/LineSegmentsGeometry"; 6 | import { LineGeometry } from "three/examples/jsm/lines/LineGeometry"; 7 | import { useFrame, useThree } from "@react-three/fiber"; 8 | export function PathWay({ floor, loop = true }) { 9 | let nameList = []; 10 | floor.traverse((it) => { 11 | if (it.name.indexOf("walk") === 0) { 12 | nameList.push(it.name); 13 | } 14 | }); 15 | 16 | let pts = nameList.map((e) => { 17 | let obj = floor.getObjectByName(e) || new Object3D(); 18 | return obj.position; 19 | }); 20 | 21 | let roll = useMemo(() => { 22 | if (pts.length === 0) { 23 | return false; 24 | } 25 | return new CatmullRomCurve3(pts, loop, "catmullrom", 0.8); 26 | }, [pts, loop]); 27 | 28 | const lineMat = useMemo(() => { 29 | const material = new LineMaterial({ 30 | transparent: true, 31 | color: new Color("#00ffff"), 32 | linewidth: 0.0015 * 3, 33 | opacity: 0.8, 34 | dashed: true, 35 | vertexColors: true, 36 | }); 37 | 38 | return material; 39 | }, []); 40 | 41 | let works = useRef({}); 42 | 43 | let mesh = useMemo(() => { 44 | let lineGeo = getGeo({ roll }); 45 | 46 | const mesh = new Line2(lineGeo, lineMat); 47 | mesh.computeLineDistances(); 48 | 49 | mesh.userData.enableBloom = true; 50 | 51 | return mesh; 52 | }, []); 53 | 54 | useEffect(() => { 55 | let lineGeo = getGeo({ roll }); 56 | mesh.geometry = lineGeo; 57 | 58 | // 59 | }, [roll]); 60 | 61 | useFrame(() => { 62 | Object.values(works.current).forEach((w) => w()); 63 | }); 64 | 65 | return ( 66 | 67 | 68 | 69 | ); 70 | } 71 | 72 | export const getGeo = ({ roll, dotted = false }) => { 73 | const curvePts = roll; 74 | 75 | let lineGeo = new LineGeometry(); 76 | if (dotted) { 77 | lineGeo = new LineSegmentsGeometry(); 78 | } 79 | let colors = []; 80 | let pos = []; 81 | let count = 500; 82 | let temp = new Vector3(); 83 | 84 | let colorA = new Color(); 85 | let colorB = new Color("#0000ff"); 86 | 87 | // color1: { value: new Color("#01187C") }, 88 | // color2: { value: new Color("#BE56FF") }, 89 | 90 | for (let i = 0; i < count; i++) { 91 | curvePts.getPoint((i / count) % 1, temp); 92 | if (isNaN(temp.x)) { 93 | temp.x = 0.0; 94 | } 95 | if (isNaN(temp.y)) { 96 | temp.y = 0.0; 97 | } 98 | if (isNaN(temp.z)) { 99 | temp.z = 0.0; 100 | } 101 | 102 | // pos.push(temp.x, temp.y, temp.z); 103 | pos.push(temp.x, 0.15, temp.z); 104 | colorA.setStyle("#ffffff"); 105 | colorA.lerp(colorB, i / count); 106 | 107 | // 108 | colorA.offsetHSL(0, 0.5, 0.0); 109 | colors.push(colorA.r, colorA.g, colorA.b); 110 | } 111 | 112 | lineGeo.setColors(colors); 113 | 114 | lineGeo.setPositions(pos); 115 | return lineGeo; 116 | }; 117 | -------------------------------------------------------------------------------- /vfx/canvas/PlayerCollider/PlayerCollider.js: -------------------------------------------------------------------------------- 1 | import { useFrame } from "@react-three/fiber"; 2 | import { useMemo } from "react"; 3 | import { ColliderClient } from "../../classes/ColliderClient"; 4 | 5 | export function PlayerCollider({ colliderMesh, Now }) { 6 | let npc = useMemo(() => { 7 | return new ColliderClient({ 8 | collider: colliderMesh, 9 | startAt: Now.startAt, 10 | Now, 11 | }); 12 | }, []); 13 | 14 | useFrame(() => { 15 | npc.onSimulate(); 16 | }); 17 | 18 | return ; 19 | } 20 | -------------------------------------------------------------------------------- /vfx/canvas/Preload/Preload.js: -------------------------------------------------------------------------------- 1 | import localforage from "localforage"; 2 | import { useEffect, useState } from "react"; 3 | import { FileLoader } from "three"; 4 | 5 | const Disk = localforage.createInstance({ 6 | name: "assets-disk", 7 | }); 8 | 9 | let toBlobURL = (array) => { 10 | return URL.createObjectURL( 11 | new Blob([array], { type: "application/octet-stream" }) 12 | ); 13 | }; 14 | 15 | export function Preload({ Assets, children }) { 16 | let [show, setShow] = useState(false); 17 | 18 | useEffect(() => { 19 | let doneProm = Assets.filter((e) => e.preload).map((asset) => { 20 | if (asset.offline) { 21 | return new Promise((resolve) => { 22 | Disk.getItem(asset.rawurl).then((arrayBuffer) => { 23 | if (arrayBuffer) { 24 | asset.cacheURL = toBlobURL(arrayBuffer); 25 | resolve(); 26 | } else { 27 | let loader = new FileLoader(); 28 | loader.setResponseType("arraybuffer"); 29 | loader.load( 30 | asset.rawurl, 31 | (arrayBuffer) => { 32 | Disk.setItem(asset.rawurl, arrayBuffer); 33 | 34 | asset.cacheURL = toBlobURL(arrayBuffer); 35 | 36 | resolve(); 37 | }, 38 | () => {}, 39 | () => { 40 | resolve(); 41 | } 42 | ); 43 | } 44 | }); 45 | }); 46 | } else { 47 | return new Promise((resolve) => { 48 | let loader = new FileLoader(); 49 | loader.setResponseType("arraybuffer"); 50 | loader.load( 51 | asset.rawurl, 52 | (arrayBuffer) => { 53 | asset.cacheURL = toBlobURL(arrayBuffer); 54 | resolve(); 55 | }, 56 | () => {}, 57 | () => { 58 | resolve(); 59 | } 60 | ); 61 | }); 62 | } 63 | }); 64 | Promise.all(doneProm).then(() => { 65 | setShow(true); 66 | }); 67 | }, []); 68 | 69 | return {show && children}; 70 | } 71 | -------------------------------------------------------------------------------- /vfx/canvas/Starter/Starter.js: -------------------------------------------------------------------------------- 1 | import { Canvas } from "@react-three/fiber"; 2 | import { sRGBEncoding } from "three"; 3 | 4 | export function Starter({ children, reducedMaxDPI = 3 }) { 5 | return ( 6 | { 10 | // state.gl.toneMapping = ReinhardToneMapping; 11 | state.gl.outputEncoding = sRGBEncoding; 12 | state.gl.physicallyCorrectLights = true; 13 | }} 14 | style={{ width: "100%", height: "100%" }} 15 | > 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /vfx/classes/ColliderManager.js: -------------------------------------------------------------------------------- 1 | import { Mesh, MeshBasicMaterial, Raycaster, Vector2 } from "three"; 2 | import { BufferGeometryUtils } from "three/examples/jsm/utils/BufferGeometryUtils"; 3 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 4 | import { MeshBVH } from "three-mesh-bvh"; 5 | 6 | export class ColliderManager { 7 | constructor({ floor, scene }) { 8 | this.floor = floor; 9 | this.raycaster = new Raycaster(); 10 | this.scene = scene; 11 | 12 | const collider = this.makeCollider(); 13 | this.collider = collider; 14 | this.preview = collider; 15 | } 16 | 17 | makeCollider() { 18 | const { scene, floor } = this; 19 | 20 | const environment = SkeletonUtils.clone(floor); 21 | 22 | const geometries = []; 23 | 24 | environment.updateMatrixWorld(); 25 | environment.traverse((c) => { 26 | if (c.geometry && !c.userData.skipFloor) { 27 | const cloned = c.geometry.clone(); 28 | 29 | cloned.applyMatrix4(c.matrixWorld); 30 | 31 | for (const key in cloned.attributes) { 32 | if (key === "position" || key === "index") { 33 | } else { 34 | cloned.deleteAttribute(key); 35 | } 36 | } 37 | 38 | geometries.push(cloned); 39 | } 40 | }); 41 | 42 | scene.traverse((it) => { 43 | if ( 44 | it && 45 | it.geometry && 46 | it.userData && 47 | it.userData.isFloor && 48 | it.material.userData.isFloor 49 | ) { 50 | const cloned = it.geometry.clone(); 51 | it.updateMatrixWorld(); 52 | 53 | cloned.applyMatrix4(it.matrixWorld); 54 | for (const key in cloned.attributes) { 55 | if (key !== "position") { 56 | cloned.deleteAttribute(key); 57 | } 58 | } 59 | geometries.push(cloned); 60 | } 61 | }); 62 | 63 | const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries( 64 | geometries, 65 | false 66 | ); 67 | 68 | mergedGeometry.boundsTree = new MeshBVH(mergedGeometry); 69 | 70 | const collider = new Mesh( 71 | mergedGeometry, 72 | new MeshBasicMaterial({ color: 0xff0000 }) 73 | ); 74 | collider.userData.skipFloor = 1; 75 | collider.material.wireframe = true; 76 | collider.material.opacity = 1; 77 | collider.material.transparent = true; 78 | collider.updateMatrixWorld(); 79 | 80 | return collider; 81 | } 82 | 83 | static queryHover({ scene }) { 84 | const source = []; 85 | 86 | scene.traverse((it) => { 87 | if ( 88 | it.geometry && 89 | it.userData && 90 | !it?.material?.userData?.discard && 91 | (it?.userData?.isHoverable || 92 | it?.material?.userData?.isFloor || 93 | it?.userData?.isFloor || 94 | it?.userData?.hint || 95 | it?.userData?.website) && 96 | typeof it?.userData?.skipFloor === "undefined" 97 | ) { 98 | source.push(it); 99 | } 100 | }); 101 | 102 | return source; 103 | } 104 | 105 | // 106 | scanCenter({ camera, scene, center = new Vector2(0, 0) }) { 107 | // this.center = new Vector2(0, 0); 108 | 109 | const { raycaster, collider } = this; 110 | 111 | raycaster.setFromCamera(center, camera); 112 | 113 | // let hit = collider.geometry.boundsTree.raycastFirst( 114 | // collider, 115 | // raycaster, 116 | // raycaster.ray 117 | // ); 118 | 119 | const result = []; 120 | 121 | let source = Collider.queryHover({ scene }); 122 | 123 | raycaster.intersectObjects(source, false, result); 124 | const hit = result[0]; 125 | 126 | if (hit) { 127 | return hit; 128 | } else { 129 | return false; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /vfx/classes/Mini.js: -------------------------------------------------------------------------------- 1 | export class Mini { 2 | constructor({ parent = false }) { 3 | this.parent = parent; 4 | this.resource = new Map(); 5 | this.get = (k) => { 6 | return new Promise((resolve) => { 7 | let ttt = 0; 8 | ttt = setInterval(() => { 9 | if (this.parent) { 10 | if (this.resource.has(k) || this.parent.resource.has(k)) { 11 | clearInterval(ttt); 12 | resolve(this.resource.get(k) || this.parent.resource.get(k)); 13 | } 14 | } else { 15 | if (this.resource.has(k)) { 16 | clearInterval(ttt); 17 | resolve(this.resource.get(k)); 18 | } 19 | } 20 | }); 21 | }); 22 | }; 23 | this.set = (k, v) => { 24 | this.resource.set(k, v); 25 | }; 26 | this.name = "ENMini"; 27 | 28 | let isAborted = false; 29 | this.tasks = []; 30 | this.resizeTasks = []; 31 | this.cleanTasks = []; 32 | this.onLoop = (fnc, num = 0) => { 33 | if (num >= 0) { 34 | this.tasks.push(fnc); 35 | } else { 36 | this.tasks.unshift(fnc); 37 | } 38 | }; 39 | 40 | this.onResize = (fnc) => { 41 | fnc(); 42 | this.resizeTasks.push(fnc); 43 | }; 44 | 45 | this.onClean = (func) => { 46 | this.cleanTasks.push(func); 47 | }; 48 | 49 | let intv = 0; 50 | const internalResize = () => { 51 | clearTimeout(intv); 52 | intv = setTimeout(() => { 53 | this.resizeTasks.forEach((e) => e()); 54 | }, 16.8888); 55 | }; 56 | 57 | window.addEventListener("resize", () => { 58 | internalResize(); 59 | }); 60 | 61 | let isPaused = false; 62 | this.toggle = () => { 63 | isPaused = !isPaused; 64 | }; 65 | this.pause = () => { 66 | isPaused = true; 67 | }; 68 | this.play = () => { 69 | isPaused = false; 70 | }; 71 | 72 | this.clean = () => { 73 | isAborted = true; 74 | try { 75 | this.cleanTasks.forEach((e) => e()); 76 | } catch (e) { 77 | console.error(e); 78 | } 79 | }; 80 | 81 | this.lastTime = window.performance.now(); 82 | this.work = () => { 83 | this.timeNow = window.performance.now(); 84 | if (isAborted) { 85 | return { 86 | name: this.name, 87 | duration: 0, 88 | }; 89 | } 90 | if (isPaused) { 91 | return { 92 | name: this.name, 93 | duration: 0, 94 | }; 95 | } 96 | const start = window.performance.now(); 97 | try { 98 | let t = this.timeNow; 99 | const lt = this.lastTime; 100 | let dt = t - lt; 101 | this.lastTime = t; 102 | dt = dt / 1000; 103 | t = t / 1000; 104 | if (dt >= 100) { 105 | dt = 100; 106 | } 107 | 108 | this.tasks.forEach((e) => e(t, dt)); 109 | } catch (e) { 110 | console.error(e); 111 | } 112 | const end = window.performance.now(); 113 | const duration = end - start; 114 | 115 | return { 116 | name: this.name, 117 | duration, 118 | }; 119 | }; 120 | 121 | this.ready = new Proxy( 122 | {}, 123 | { 124 | get: (obj, key) => { 125 | return this.get(key); 126 | }, 127 | } 128 | ); 129 | this.now = new Proxy( 130 | {}, 131 | { 132 | get: (obj, key) => { 133 | if (this.parent) { 134 | return this.resource.get(key) || this.parent.resource.get(key); 135 | } else { 136 | return this.resource.get(key); 137 | } 138 | }, 139 | } 140 | ); 141 | } 142 | } 143 | 144 | // let mini = new Mini({ name: "base", domElement: ref.current, window }); 145 | // 146 | 147 | // 148 | // 149 | // 150 | -------------------------------------------------------------------------------- /vfx/editor/AssetWindow/AssetWindow.js: -------------------------------------------------------------------------------- 1 | export default function AssetWindow() { 2 | return ( 3 |
4 | 123 5 | {/* */} 6 | {/* */} 7 | {/* */} 8 | {/* */} 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /vfx/editor/CanvasPreview/CanvasPreview.js: -------------------------------------------------------------------------------- 1 | import { Canvas, useThree, useFrame } from "@react-three/fiber"; 2 | import { Suspense, useEffect } from "react"; 3 | import Loading from "../Loading/Loading"; 4 | 5 | export default function CanvasPreview() { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | function Content() { 14 | return ( 15 | 16 | }> 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | } 24 | 25 | function Camdemo() { 26 | let { get } = useThree(); 27 | 28 | useEffect(() => { 29 | let py = 1.56; 30 | let pz = 3; 31 | get().camera.position.y = py; 32 | get().camera.position.z = pz; 33 | get().camera.lookAt(0, py, pz); 34 | 35 | // 36 | // 37 | }, []); 38 | 39 | useFrame(({ camera }) => { 40 | // 41 | // 42 | }); 43 | 44 | // 45 | return null; 46 | } 47 | -------------------------------------------------------------------------------- /vfx/editor/CanvasWork/CanvasWork.js: -------------------------------------------------------------------------------- 1 | import { Canvas, useThree } from "@react-three/fiber"; 2 | import { Suspense, useEffect } from "react"; 3 | import Loading from "../Loading/Loading"; 4 | 5 | export default function CanvasWork() { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | } 12 | 13 | function Content() { 14 | return ( 15 | 16 | }> 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | } 24 | 25 | function Camdemo() { 26 | let { get } = useThree(); 27 | 28 | useEffect(() => { 29 | get().camera.position.y = 5; 30 | get().camera.position.z = 5; 31 | get().camera.lookAt(0, 0, 0); 32 | }, []); 33 | return null; 34 | } 35 | -------------------------------------------------------------------------------- /vfx/editor/FloatingWindow/FloatingWindow.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from "react"; 2 | import { useDrag } from "@use-gesture/react"; 3 | import { applyAutoEvent } from "../../utils/use-auto-event"; 4 | 5 | export default function FloatingWindow(props) { 6 | let [init, setInit] = useState(false); 7 | 8 | useEffect(() => { 9 | setInit(props.config().win); 10 | 11 | let clean = applyAutoEvent(window, "resize", () => { 12 | let { win, onResetResize } = props.config(); 13 | 14 | if (onResetResize) { 15 | setInit(win); 16 | } 17 | }); 18 | return () => { 19 | clean(); 20 | }; 21 | }, [props.config]); 22 | 23 | return ( 24 | (init && ( 25 | 26 | {props.children} 27 | 28 | )) || 29 | null 30 | ); 31 | } 32 | 33 | function FloatingWindowInternal({ title = "win title", children, init = [] }) { 34 | let st = useRef({ ax: 0, ay: 0 }); 35 | let ref = useRef(); 36 | 37 | useEffect(() => { 38 | st.current.ax = init[0]; 39 | st.current.ay = init[1]; 40 | 41 | ref.current.style.transform = `translate3d(${st.current.ax}px, ${st.current.ay}px, 0px)`; 42 | }, [init]); 43 | // Set the drag hook and define component movement based on gesture data. 44 | const bind = useDrag(({ down, delta: [dx, dy], movement: [mx, my] }) => { 45 | st.current.ax += dx; 46 | st.current.ay += dy; 47 | ref.current.style.transform = `translate3d(${st.current.ax}px, ${st.current.ay}px, 0px)`; 48 | }); 49 | 50 | // Bind it to a component. 51 | return ( 52 |
53 |
58 | {title} 59 |
60 |
68 | {children} 69 |
70 |
71 | ); 72 | } 73 | -------------------------------------------------------------------------------- /vfx/editor/GravityLab/GravityLab.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from "react"; 2 | import LowBar from "../LowBar/LowBar"; 3 | import TopBar from "../TopBar/TopBar"; 4 | import CanvasWork from "../CanvasWork/CanvasWork"; 5 | import CanvasPreview from "../CanvasPreview/CanvasPreview"; 6 | import { useDrag } from "@use-gesture/react"; 7 | import { Vector2 } from "three"; 8 | import FloatingWindow from "../FloatingWindow/FloatingWindow"; 9 | import { Lab } from "../Lab/Lab"; 10 | import AssetWindow from "../AssetWindow/AssetWindow"; 11 | 12 | export default function GravityLab() { 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | } 21 | 22 | function OnlyDesktop({ children }) { 23 | return ( 24 |
25 |
26 |
27 | Please use lab editor on a computer screen 28 |
29 |
30 |
{children}
31 |
32 | ); 33 | } 34 | 35 | function TopMiddleBottom({ children }) { 36 | return ( 37 | <> 38 |
39 |
40 | 41 |
42 |
43 | {children} 44 | {/* */} 45 |
46 |
47 | 48 |
49 |
50 | 51 | ); 52 | } 53 | 54 | function FloatingLayout() { 55 | Lab.makeKeyReactive("tabs"); 56 | return ( 57 |
58 |
59 | 60 |
61 | 62 | { 65 | return { 66 | win: [window.innerWidth - 414 - 30, 30, 414, 896], 67 | onResetResize: true, 68 | }; 69 | }} 70 | > 71 | 72 | 73 | 74 | 75 | 76 | { 79 | return { 80 | win: [30, 30, 414, 896], 81 | onResetResize: false, 82 | }; 83 | }} 84 | > 85 | 86 | 87 | 88 |
89 | ); 90 | } 91 | 92 | function SelfSwitch({ self, others = [], children }) { 93 | Lab.makeKeyReactive(self); 94 | 95 | useEffect(() => { 96 | // 97 | others = others.filter((ot) => self !== ot); 98 | if (others.length > 0) { 99 | if (Lab[self] === true) { 100 | others.forEach((kn) => { 101 | Lab[kn] = false; 102 | }); 103 | } 104 | } 105 | }, [others]); 106 | 107 | return (Lab[self] && children) || null; 108 | } 109 | -------------------------------------------------------------------------------- /vfx/editor/Lab/Lab.js: -------------------------------------------------------------------------------- 1 | import { 2 | makeShallowStore, 3 | ShallowStoreMethods, 4 | } from "../../utils/make-shallow-store"; 5 | 6 | let getInternal = () => { 7 | let data = { 8 | currentTab: "tabCanvas", 9 | tabs: ["tabCanvas"], 10 | keyW: false, 11 | keyA: false, 12 | keyS: false, 13 | keyD: false, 14 | keyU: false, 15 | keyD: false, 16 | keyL: false, 17 | keyR: false, 18 | 19 | winPreview: true, 20 | winAsset: false, 21 | }; 22 | 23 | /** @returns {data} */ 24 | return data; 25 | }; 26 | 27 | let TypeOfStore = { 28 | ...getInternal(), 29 | ...ShallowStoreMethods, 30 | }; 31 | 32 | /** @returns {TypeOfStore} */ 33 | const makeStore = () => { 34 | return makeShallowStore(getInternal()); 35 | }; 36 | 37 | /** @type {TypeOfStore} */ 38 | const Lab = makeStore(); 39 | 40 | export { Lab }; 41 | -------------------------------------------------------------------------------- /vfx/editor/Loading/Loading.js: -------------------------------------------------------------------------------- 1 | import { useProgress } from "@react-three/drei"; 2 | import { createPortal, useThree } from "@react-three/fiber"; 3 | import { useEffect, useMemo } from "react"; 4 | import { Object3D } from "three"; 5 | 6 | export default function Loading() { 7 | let { get } = useThree(); 8 | let { loaded, total } = useProgress(); 9 | 10 | // let o3d = useMemo(() => { 11 | // return new Object3D(); 12 | // }, []); 13 | 14 | useEffect(() => { 15 | // o3d.children.forEach((k) => { 16 | // o3d.remove(k); 17 | // }); 18 | 19 | return () => { 20 | // 21 | // 22 | }; 23 | }); 24 | 25 | return ( 26 | 27 | {createPortal( 28 | 29 | {/* */} 30 | {/* */} 31 | {/* */} 32 | {/* */} 33 | {/* */} 34 | 35 | {loaded} Loaded / {total} Items to be loaded 36 | 37 | , 38 | get().camera 39 | )} 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /vfx/editor/LowBar/LowBar.js: -------------------------------------------------------------------------------- 1 | import { Lab } from "../Lab/Lab"; 2 | 3 | export default function LowBar() { 4 | Lab.makeKeyReactive("winPreview"); 5 | Lab.makeKeyReactive("winAsset"); 6 | // 7 | // 8 | 9 | // 10 | return ( 11 |
12 |
13 |
{ 18 | Lab.winPreview = !Lab.winPreview; 19 | }} 20 | > 21 | Preview Window: {Lab.winPreview ? "ON" : "OFF"} 22 |
23 | 24 |
{ 29 | Lab.winAsset = !Lab.winAsset; 30 | }} 31 | > 32 | Asset Window: {Lab.winAsset ? "ON" : "OFF"} 33 |
34 |
35 |
Made at Than you Jesus Church
36 |
37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /vfx/editor/TopBar/TopBar.js: -------------------------------------------------------------------------------- 1 | export default function TopBar() { 2 | // 3 | // 4 | return ( 5 |
6 |
EffectNode
7 |
File
8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /vfx/explore/Explore.js: -------------------------------------------------------------------------------- 1 | import { Canvas, createPortal, useFrame, useThree } from "@react-three/fiber"; 2 | import { useEffect, useMemo, useRef, useState } from "react"; 3 | import { Object3D } from "three"; 4 | import { ForceGraphR3F } from "./ForceGraphR3F"; 5 | import { Prototyper } from "./Prototyper"; 6 | // import ThreeGraph from ""; 7 | 8 | export function Explore() { 9 | return ( 10 |
11 | {/* */} 12 | {/* */} 13 | {/* */} 14 | {/* */} 15 | {/* */} 16 | 17 | 18 | 19 | 20 |
21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /vfx/explore/Prototyper.js: -------------------------------------------------------------------------------- 1 | import { OrbitControls } from "@react-three/drei"; 2 | import { useThree } from "@react-three/fiber"; 3 | import { useEffect } from "react"; 4 | import { Color, sRGBEncoding } from "three"; 5 | 6 | export function Prototyper() { 7 | let { get } = useThree(); 8 | 9 | useEffect(() => { 10 | get().gl.physicallyCorrectLights = true; 11 | get().gl.outputEncoding = sRGBEncoding; 12 | get().scene.background = new Color("#333"); 13 | get().camera.position.z = 100; 14 | }, []); 15 | 16 | return ( 17 | 18 | 19 | 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /vfx/firebase/firebaseConfig.js: -------------------------------------------------------------------------------- 1 | export const firebaseConfig = { 2 | apiKey: "AIzaSyB-tfIbfq6okbv1tYReo585t_r4zFvf-rI", 3 | authDomain: "effectnode.firebaseapp.com", 4 | databaseURL: "https://effectnode-metaverse.firebaseio.com/", 5 | projectId: "effectnode", 6 | storageBucket: "effectnode.appspot.com", 7 | messagingSenderId: "316567530740", 8 | appId: "1:316567530740:web:99544cc907524fe65242a1", 9 | measurementId: "G-7N3BQDZR4G", 10 | }; 11 | 12 | // export const firebaseConfig = { 13 | // apiKey: "AIzaSyC7x57s-6fZIknaQ40QC3_6PRYwJ5KgTRo", 14 | // authDomain: "my3dworld-club.firebaseapp.com", 15 | // databaseURL: 16 | // "https://my3dworld-club-default-rtdb.asia-southeast1.firebasedatabase.app", 17 | // projectId: "my3dworld-club", 18 | // storageBucket: "my3dworld-club.appspot.com", 19 | // messagingSenderId: "612670919698", 20 | // appId: "1:612670919698:web:ce90eca2dc99117cd3f4cb", 21 | // measurementId: "G-V8TEN2M81F", 22 | // }; 23 | 24 | // export var firebaseConfig = { 25 | // apiKey: "AIzaSyDaRJW-X2darZMyXN-khxiW18-htb1dx1Q", 26 | // authDomain: "sharing-jesus-academy.firebaseapp.com", 27 | // databaseURL: "https://sharing-jesus-academy-default-rtdb.firebaseio.com", 28 | // projectId: "sharing-jesus-academy", 29 | // storageBucket: "sharing-jesus-academy.appspot.com", 30 | // messagingSenderId: "157597634307", 31 | // appId: "1:157597634307:web:925ac0bd0e54cc5ae2e336", 32 | // measurementId: "G-56SELQX9BJ", 33 | // }; 34 | -------------------------------------------------------------------------------- /vfx/firebase/firelib.js: -------------------------------------------------------------------------------- 1 | import firebase from "firebase/app"; 2 | import "firebase/auth"; 3 | import "firebase/database"; 4 | import "firebase/analytics"; 5 | import { firebaseConfig } from "./firebaseConfig"; 6 | let initMap = new Map(); 7 | 8 | export function getFirebase() { 9 | if (!initMap.has("app") && firebase.apps.length === 0) { 10 | initMap.set("app", true); 11 | firebase.initializeApp(firebaseConfig); 12 | firebase.analytics(); 13 | } 14 | 15 | if (!initMap.has("setup-listen-login")) { 16 | initMap.set("setup-listen-login", true); 17 | firebase.auth().onAuthStateChanged((user) => { 18 | if (user) { 19 | // User is signed in, see docs for a list of available properties 20 | // https://firebase.google.com/docs/reference/js/firebase.User 21 | initMap.set("user", user); 22 | // ... 23 | } else { 24 | // User is signed out 25 | // ... 26 | initMap.delete("user"); 27 | } 28 | }); 29 | } 30 | return firebase; 31 | } 32 | 33 | /** 34 | * 35 | * @returns @type firebaseui.auth.AuthUI 36 | */ 37 | export function getUI() { 38 | let firebase = getFirebase(); 39 | if (!initMap.has("ui")) { 40 | let firebaseui = require("firebaseui"); 41 | var fireUI = new firebaseui.auth.AuthUI(firebase.auth()); 42 | initMap.set("ui", fireUI); 43 | } 44 | 45 | /** @type firebaseui.auth.AuthUI */ 46 | return initMap.get("ui"); 47 | } 48 | 49 | export function testAdminRights() { 50 | return getFirebase().database().ref(`/test-admin`).set(Math.random()); 51 | } 52 | 53 | export function testUserRights() { 54 | return getMe().then((user) => { 55 | return getFirebase() 56 | .database() 57 | .ref(`/test-user/${user.uid}`) 58 | .set(Math.random()); 59 | }); 60 | } 61 | 62 | export function getMe() { 63 | getFirebase(); 64 | return new Promise((resolve, reject) => { 65 | firebase.auth().onAuthStateChanged((user) => { 66 | if (user) { 67 | // User is signed in, see docs for a list of available properties 68 | // https://firebase.google.com/docs/reference/js/firebase.User 69 | // var uid = user.uid; 70 | resolve(user); 71 | // ... 72 | } else { 73 | // User is signed out 74 | // ... 75 | reject(); 76 | } 77 | }); 78 | }); 79 | } 80 | 81 | export function logout() { 82 | getFirebase(); 83 | return firebase.auth().signOut(); 84 | } 85 | 86 | // export function loginRedirectGoogle() { 87 | // setup(); 88 | // var provider = new firebase.auth.GoogleAuthProvider(); 89 | 90 | // firebase.auth().signInWithRedirect(provider); 91 | // } 92 | 93 | export function loginRedirectGoogle() { 94 | getFirebase(); 95 | var provider = new firebase.auth.GoogleAuthProvider(); 96 | 97 | return firebase.auth().signInWithRedirect(provider); 98 | } 99 | 100 | export function loginGoogle() { 101 | getFirebase(); 102 | var provider = new firebase.auth.GoogleAuthProvider(); 103 | return new Promise((resolve, reject) => { 104 | // provider.addScope('https://www.googleapis.com/auth/contacts.readonly'); 105 | // firebase.auth().signInWithRedirect(provider); 106 | firebase 107 | .auth() 108 | .signInWithPopup(provider) 109 | .then((result) => { 110 | /** @type {firebase.auth.OAuthCredential} */ 111 | var credential = result.credential; 112 | 113 | // This gives you a Google Access Token. You can use it to access the Google API. 114 | var token = credential.accessToken; 115 | // The signed-in user info. 116 | var user = result.user; 117 | 118 | // ... 119 | resolve({ user }); 120 | }) 121 | .catch((error) => { 122 | // Handle Errors here. 123 | var errorCode = error.code; 124 | var errorMessage = error.message; 125 | // The email of the user's account used. 126 | var email = error.email; 127 | // The firebase.auth.AuthCredential type that was used. 128 | var credential = error.credential; 129 | // ... 130 | 131 | console.log(error); 132 | reject(error); 133 | 134 | // firebase.auth().signInWithRedirect(provider) 135 | }); 136 | }); 137 | } 138 | 139 | export const onReady = () => { 140 | getFirebase(); 141 | return new Promise((resolve) => { 142 | let tt = setInterval(() => { 143 | if (initMap.has("user")) { 144 | clearInterval(tt); 145 | resolve({ 146 | firebase, 147 | user: initMap.get("user"), 148 | fire: firebase, 149 | db: firebase.database(), 150 | logout: () => { 151 | return firebase.auth().signOut(); 152 | }, 153 | }); 154 | } 155 | }); 156 | }); 157 | }; 158 | 159 | export const PreviewGameCards = { 160 | WongTaiSin: "_szjcl6vco_jdplughmk_wx8y8wqzf", 161 | }; 162 | 163 | export function onTapCard({ cardID, isActivated }) { 164 | if (process.env.NODE_ENV === "production") { 165 | if (cardID === PreviewGameCards.WongTaiSin) { 166 | getFirebase().analytics().logEvent("card_open_store", { 167 | name: "Wong Tai Sin Box Store", 168 | isActivated, 169 | cardID: cardID, 170 | }); 171 | } 172 | 173 | getFirebase().analytics().logEvent("card_open_general", { 174 | name: "Activating General", 175 | isActivated, 176 | cardID: cardID, 177 | }); 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /vfx/game/Portals/FlyTeleport.js: -------------------------------------------------------------------------------- 1 | import { Text, useTexture } from "@react-three/drei"; 2 | import { useFrame, useThree, createPortal } from "@react-three/fiber"; 3 | import router from "next/router"; 4 | import { useRef } from "react"; 5 | import { DoubleSide, Vector3 } from "three"; 6 | import { Now } from "../../store/Now"; 7 | // 8 | import { CommonAssets } from "../../places/common/CommonAssets"; 9 | export function FlyTeleport({ floor, envMap, title = "", start, dest }) { 10 | let { scene } = useThree(); 11 | 12 | let alphaMap = useTexture(CommonAssets.portalAlphaMap.url); 13 | alphaMap.flipY = true; 14 | // 15 | let destination = floor.getObjectByName(dest); 16 | if (!destination) { 17 | throw new Error(`start ${start} dest: ${dest}`); 18 | } 19 | let startingPoint = floor.getObjectByName(start); 20 | if (!startingPoint) { 21 | throw new Error(`start ${start} dest: ${dest}`); 22 | } 23 | 24 | let ref = useRef(); 25 | let text = useRef(); 26 | let wp = new Vector3(); 27 | useFrame(() => { 28 | if (ref.current) { 29 | ref.current.getWorldPosition(wp); 30 | wp.y = Now.avatarAt.y; 31 | if (Now.avatarAt.distanceTo(wp) <= 3.5) { 32 | destination.getWorldPosition(Now.avatarFlyTo); 33 | } else { 34 | } 35 | } 36 | }); 37 | 38 | useFrame(({ camera }) => { 39 | if (text.current) { 40 | text.current.lookAt(camera.position); 41 | } 42 | }); 43 | 44 | useFrame(() => { 45 | if (ref.current.position) { 46 | startingPoint.getWorldPosition(ref.current.position); 47 | } 48 | }); 49 | 50 | return createPortal( 51 | { 56 | // Now.avatarFlyTo.fromArray([-0.69, -1.35, 0.28]); 57 | // }} 58 | userData={{ 59 | // onClick: () => { 60 | // Now.avatarFlyTo.fromArray([-0.69, -1.35, 0.28]); 61 | // }, 62 | hint: title, 63 | }} 64 | > 65 | 80 | {title} 81 | 82 | 85 | {/* */} 86 | 96 | , 97 | scene 98 | ); 99 | } 100 | -------------------------------------------------------------------------------- /vfx/game/Portals/MapPortal.js: -------------------------------------------------------------------------------- 1 | import { Text } from "@react-three/drei"; 2 | import router from "next/router"; 3 | 4 | // 5 | export function MapPortal({ envMap, title = "Church", page, preloadGLB }) { 6 | return ( 7 | { 9 | router.push(page); 10 | }} 11 | onPointerEnter={(ev) => { 12 | ev.object.userData.forceBloom = true; 13 | router.prefetch(page); 14 | 15 | if (preloadGLB) { 16 | fetch(preloadGLB); 17 | } 18 | }} 19 | onPointerLeave={(ev) => { 20 | ev.object.userData.forceBloom = false; 21 | }} 22 | userData={{ 23 | onClick: () => { 24 | router.push(page); 25 | }, 26 | hint: title, 27 | }} 28 | > 29 | 43 | {title} 44 | 45 | 46 | 52 | 53 | ); 54 | } 55 | -------------------------------------------------------------------------------- /vfx/places/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wonglok/effectnode-metaverse/fe7d8b0e5f44e6174811a75f7303ffc2c9331676/vfx/places/.DS_Store -------------------------------------------------------------------------------- /vfx/places/Fashion/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/orchid-sing/orchid-sing.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | butterfly: { 12 | slug: "butterfly", 13 | type: "glb", 14 | rawurl: "/objects/butterfly/butterfly.glb", 15 | cacheURL: false, 16 | preload: false, 17 | }, 18 | ...CommonAssets, 19 | }; 20 | 21 | processAQ({ AQ }); 22 | 23 | export const Assets = Object.values(AQ); 24 | 25 | // 26 | -------------------------------------------------------------------------------- /vfx/places/Fashion/InteractionUI.js: -------------------------------------------------------------------------------- 1 | import { 2 | PlaneBufferGeometry, 3 | MeshBasicMaterial, 4 | Mesh, 5 | Vector3, 6 | // AdditiveBlending, 7 | } from "three"; 8 | 9 | export class InteractionUI { 10 | static fixTouchScreen({ target }) { 11 | let onEvent = (target, event, h) => { 12 | target.addEventListener(event, h, { passive: false }); 13 | return () => { 14 | target.removeEventListener(event, h); 15 | }; 16 | }; 17 | 18 | let cleanTouchStart = onEvent(target, "touchstart", (ev) => { 19 | ev.preventDefault(); 20 | }); 21 | 22 | let cleanTouchMove = onEvent(target, "toucmove", (ev) => { 23 | ev.preventDefault(); 24 | }); 25 | 26 | return () => { 27 | cleanTouchStart(); 28 | cleanTouchMove(); 29 | }; 30 | } 31 | 32 | static async hoverPlane({ mini }) { 33 | let raycaster = await mini.ready.raycaster; 34 | let mouse = await mini.ready.mouse; 35 | let camera = await mini.ready.camera; 36 | let scene = await mini.ready.scene; 37 | let viewport = await mini.ready.viewport; 38 | 39 | let geoPlane = new PlaneBufferGeometry( 40 | 3.0 * viewport.width, 41 | 3.0 * viewport.height, 42 | 2, 43 | 2 44 | ); 45 | 46 | let matPlane = new MeshBasicMaterial({ 47 | transparent: true, 48 | opacity: 0.25, 49 | color: 0xbababa, 50 | }); 51 | 52 | let planeMesh = new Mesh(geoPlane, matPlane); 53 | planeMesh.position.z = -camera.position.z / 2; 54 | 55 | mini.onResize(() => { 56 | let viewport = mini.now.viewport; 57 | let geoPlane = new PlaneBufferGeometry( 58 | 3.0 * viewport.width, 59 | 3.0 * viewport.height, 60 | 2, 61 | 2 62 | ); 63 | planeMesh.geometry = geoPlane; 64 | }); 65 | 66 | // scene.add(planeMesh); 67 | // mini.onClean(() => { 68 | // scene.remove(planeMesh); 69 | // }); 70 | 71 | let temppos = new Vector3(0, 0, 0); 72 | mini.onLoop(() => { 73 | planeMesh.lookAt(camera.position); 74 | raycaster.setFromCamera(mouse, camera); 75 | let res = raycaster.intersectObject(planeMesh); 76 | if (res && res[0]) { 77 | temppos.copy(res[0].point); 78 | } 79 | }); 80 | 81 | return temppos; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /vfx/places/Spirit/AnimationPlayer.js: -------------------------------------------------------------------------------- 1 | import { useAnimations } from "@react-three/drei"; 2 | import { useFrame } from "@react-three/fiber"; 3 | import { useEffect } from "react"; 4 | 5 | export function AllAnimationPlayer({ animations, scene, prog }) { 6 | const { actions, mixer, names } = useAnimations(animations, scene); 7 | 8 | // Storybook Knobs 9 | 10 | useFrame((st, dt) => { 11 | if (prog && prog.current) { 12 | mixer.setTime(prog.current); 13 | } else { 14 | mixer.update(dt); 15 | } 16 | }); 17 | useEffect(() => { 18 | names.forEach((kn) => { 19 | actions[kn].reset(); 20 | actions[kn].repetitions = Infinity; 21 | actions[kn].play(); 22 | }); 23 | }, []); 24 | 25 | // useEffect(() => { 26 | // actions[selectedAction]?.reset().fadeIn(blendDuration).play(); 27 | // return () => { 28 | // actions[selectedAction]?.fadeOut(blendDuration); 29 | // }; 30 | // }, [actions, selectedAction, blendDuration]); 31 | 32 | return null; 33 | } 34 | -------------------------------------------------------------------------------- /vfx/places/Spirit/CameraFlow.js: -------------------------------------------------------------------------------- 1 | import { useGLTF } from "@react-three/drei"; 2 | import { useFrame, useThree } from "@react-three/fiber"; 3 | import { useEffect, useMemo, useRef } from "react"; 4 | import { AnimationMixer, Object3D } from "three"; 5 | 6 | export function CameraFlow({ prog }) { 7 | let gltf = useGLTF(`/map/blockout/cam/blockout_cam.glb`); 8 | 9 | let { get } = useThree(); 10 | 11 | let duration = Math.max(...gltf.animations.map((e) => e.duration)); 12 | 13 | // console.log(duration); 14 | 15 | useFrame(() => { 16 | let max = duration - 0.00025; 17 | if (prog.current >= max) { 18 | prog.current = max; 19 | } 20 | 21 | if (prog.current <= 0.00025) { 22 | prog.current = 0.00025; 23 | } 24 | 25 | mixer.setTime(prog.current); 26 | }); 27 | 28 | let mixer = useMemo(() => { 29 | return new AnimationMixer(gltf.scene); 30 | }, [gltf]); 31 | 32 | useEffect(() => { 33 | get().gl.autoClear = false; 34 | get().camera.name = "SceneControls"; 35 | get().camera.near = 0.5; 36 | get().camera.far = 2000; 37 | get().camera.fov = 35; 38 | if (window.innerWidth <= 500) { 39 | get().camera.fov = 60; 40 | } 41 | get().camera.updateProjectionMatrix(); 42 | gltf.animations.forEach((c) => { 43 | let action = mixer.clipAction(c); 44 | action.reset(); 45 | // action.repetitions = 1; 46 | // action.setLoop(LoopOnce); 47 | // action.clampWhenFinished = true; 48 | action.play(); 49 | }); 50 | }, []); 51 | 52 | let sync = useRef(() => {}); 53 | useFrame(() => { 54 | sync.current(); 55 | }); 56 | useEffect(() => { 57 | let o3d = new Object3D(); 58 | gltf.scene.traverse(console.log); 59 | 60 | let yas = gltf.scene.getObjectByName(`ORIGINAL_COPY_CameraLetsGo`); 61 | yas.add(o3d); 62 | 63 | let cam = get().camera; 64 | cam.rotation.set(0, 0, 0, "XYZ"); 65 | cam.position.set(0, 0, 0); 66 | o3d.add(cam); 67 | o3d.rotation.x = -0.5 * Math.PI; 68 | 69 | // let wQ = new Quaternion(); 70 | // let wP = new Vector3(); 71 | // sync.current = () => { 72 | // o3d.updateMatrixWorld(); 73 | // o3d.getWorldPosition(wP); 74 | // o3d.getWorldQuaternion(wQ); 75 | 76 | // get().camera.position.lerp(wP, 0.5); 77 | // get().camera.quaternion.slerp(wQ, 0.5); 78 | // }; 79 | 80 | // let ptl = new PointLight(0xffffff, 0.3, 50, 2); 81 | // get().camera.add(ptl); 82 | 83 | return () => { 84 | sync.current = () => {}; 85 | // get().camera.remove(ptl); 86 | }; 87 | }, []); 88 | 89 | useEffect(() => { 90 | get().gl.domElement.style.touchAction = "none"; 91 | get().gl.domElement.parentElement.style.touchAction = "none"; 92 | }, []); 93 | 94 | return ( 95 | 96 | 97 | 98 | ); 99 | } 100 | -------------------------------------------------------------------------------- /vfx/places/Spirit/Floor.js: -------------------------------------------------------------------------------- 1 | import { useGLTF } from "@react-three/drei"; 2 | import { useFrame } from "@react-three/fiber"; 3 | import { useEffect, useRef } from "react"; 4 | import { Color, ShaderMaterial } from "three"; 5 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 6 | 7 | export function Floor() { 8 | let gltf = useGLTF(`/map/blockout/map-without-stage2/map-no-stage-2-v1.glb`); 9 | let moutner = useRef(); 10 | let render = useRef(() => {}); 11 | useFrame(() => { 12 | render.current(); 13 | }); 14 | useEffect(() => { 15 | if (moutner.current) { 16 | // 17 | moutner.current.children.forEach((l) => { 18 | moutner.current.remove(l); 19 | }); 20 | // 21 | let o3d = moutner.current; 22 | 23 | let floor = SkeletonUtils.clone(gltf.scene); 24 | 25 | o3d.add(floor); 26 | 27 | let Plane002_2 = floor.getObjectByName("Plane002_2"); 28 | Plane002_2.material = getRainbowMat(); 29 | 30 | render.current = () => {}; 31 | 32 | return () => { 33 | render.current = () => {}; 34 | }; 35 | } 36 | }, []); 37 | return ( 38 | 39 | 40 | {/* */} 41 | {/* */} 42 | {/* */} 43 | 44 | ); 45 | } 46 | 47 | function getRainbowMat() { 48 | return new ShaderMaterial({ 49 | uniforms: { 50 | colorA: { 51 | value: new Color("#f0f"), 52 | }, 53 | colorB: { 54 | value: new Color("#0ff"), 55 | }, 56 | }, 57 | vertexShader: ` 58 | 59 | varying vec2 vUv; 60 | void main (void) { 61 | vUv = uv; 62 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 63 | } 64 | `, 65 | 66 | fragmentShader: ` 67 | 68 | varying vec2 vUv; 69 | uniform vec3 colorA; 70 | uniform vec3 colorB; 71 | void main (void) { 72 | 73 | 74 | gl_FragColor = vec4(mix(colorA.rgb, colorB.rgb, (vUv.x + vUv.y) / 2.0), 1.0); 75 | } 76 | `, 77 | }); 78 | } 79 | -------------------------------------------------------------------------------- /vfx/places/Spirit/JustBloom.js: -------------------------------------------------------------------------------- 1 | import { Html, useGLTF } from "@react-three/drei"; 2 | import { createPortal, useFrame, useThree } from "@react-three/fiber"; 3 | import { Suspense, useEffect, useMemo, useRef, useState } from "react"; 4 | 5 | import { DirectionalLight, Vector2 } from "three"; 6 | import { EffectComposer, RenderPass, UnrealBloomPass } from "three-stdlib"; 7 | 8 | export function JustBloom() { 9 | let { get } = useThree(); 10 | let [bloomer, setBloomer] = useState(false); 11 | let [reoad, setReload] = useState(false); 12 | // 13 | let render = useRef(() => {}); 14 | useEffect(() => { 15 | let camera = get().camera; 16 | let renderer = get().gl; 17 | let effectComposer = new EffectComposer(renderer); 18 | let renderPass = new RenderPass(get().scene, camera); 19 | renderPass.renderToScreen = false; 20 | effectComposer.renderToScreen = true; 21 | 22 | effectComposer.addPass(renderPass); 23 | let size = new Vector2(window.innerWidth, window.innerHeight); 24 | 25 | let bloomPass = new UnrealBloomPass(size, 3.3, 0.6, 0.0); 26 | effectComposer.addPass(bloomPass); 27 | 28 | window.addEventListener("resize", () => { 29 | renderer.getSize(size); 30 | 31 | bloomPass.setSize(size.width, size.height); 32 | }); 33 | 34 | bloomPass.renderToScreen = true; 35 | // 36 | render.current = () => { 37 | effectComposer.render(); 38 | }; 39 | 40 | setBloomer(bloomPass); 41 | // let dirLight = new DirectionalLight(0xffffff, 10); 42 | // dirLight.position.y = 10; 43 | 44 | // window.addEventListener("magnet", ({ detail: { type, percentage } }) => { 45 | // // 46 | // bloomPass.strength = (percentage + 0.1) * 3.0; 47 | // // dirLight.intensity = (percentage + 0.1) * 300.0; 48 | // // dirLight. 49 | // }); 50 | }, []); 51 | 52 | useFrame(({}) => { 53 | render.current(); 54 | }, 10000); 55 | 56 | return ( 57 | 58 | {/* { 61 | return [size.width / 2, size.height / 2]; 62 | }} 63 | > 64 |
65 |
66 | { 74 | bloomer.strength = value; 75 | setReload(Math.random()); 76 | }} 77 | /> 78 | {bloomer.strength} 79 |
80 |
81 | { 89 | bloomer.radius = value; 90 | setReload(Math.random()); 91 | }} 92 | /> 93 | {bloomer.radius} 94 |
95 | 96 |
97 | { 105 | bloomer.threshold = value; 106 | setReload(Math.random()); 107 | }} 108 | /> 109 | {bloomer.threshold} 110 |
111 |
112 | */} 113 | {/* */} 114 | {/* */} 115 | {/* */} 116 | {/* */} 117 |
118 | ); 119 | } 120 | -------------------------------------------------------------------------------- /vfx/places/Spirit/Lighting.js: -------------------------------------------------------------------------------- 1 | import { useTexture } from "@react-three/drei"; 2 | import { useThree } from "@react-three/fiber"; 3 | import { Suspense, useEffect } from "react"; 4 | import { 5 | CineonToneMapping, 6 | Color, 7 | EquirectangularReflectionMapping, 8 | sRGBEncoding, 9 | } from "three"; 10 | 11 | export function Lighting() { 12 | let { get } = useThree(); 13 | 14 | useEffect(() => { 15 | get().scene.background = new Color("#000000"); 16 | get().gl.toneMapping = CineonToneMapping; 17 | get().gl.toneMappingExposure = 1; 18 | get().gl.physicallyCorrectLights = true; 19 | // 20 | }, []); 21 | return ( 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | } 29 | 30 | function Load() { 31 | let { get } = useThree(); 32 | 33 | let wilderness = useTexture(`/hdr/nightwilderness.png`); 34 | useEffect(() => { 35 | wilderness.encoding = sRGBEncoding; 36 | wilderness.mapping = EquirectangularReflectionMapping; 37 | 38 | get().scene.environment = wilderness; 39 | // 40 | }, []); 41 | return ; 42 | } 43 | -------------------------------------------------------------------------------- /vfx/places/Spirit/LoadingInCam.js: -------------------------------------------------------------------------------- 1 | import { Text, useProgress } from "@react-three/drei"; 2 | import { createPortal, useThree } from "@react-three/fiber"; 3 | export function LoadingInCam() { 4 | let { get } = useThree(); 5 | let { total, active, loaded } = useProgress(); 6 | return ( 7 | 8 | {createPortal( 9 | 10 | { 11 | 16 | {loaded} / {total} Loaded 17 | 18 | } 19 | , 20 | get().camera 21 | )} 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /vfx/places/Spirit/ProgressControls.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree } from "@react-three/fiber"; 2 | import { useEffect, useRef } from "react"; 3 | import { useWheel, useDrag } from "@use-gesture/react"; 4 | import { Vector3 } from "three"; 5 | import { Now } from "../../store/Now"; 6 | export function ProgressControls({ children }) { 7 | let { get } = useThree(); 8 | 9 | let prog = useRef(0); 10 | let vel = useRef(0); 11 | 12 | useWheel( 13 | (st) => { 14 | st.event.preventDefault(); 15 | vel.current = -st.event.deltaY / 50; 16 | }, 17 | { 18 | target: get().gl.domElement.parentElement, 19 | eventOptions: { passive: false }, 20 | } 21 | ); 22 | 23 | useDrag( 24 | (st) => { 25 | // st.event.preventDefault(); 26 | 27 | vel.current = -st.delta[1] / 40; 28 | }, 29 | { 30 | target: get().gl.domElement, 31 | // eventOptions: { passive: false }, 32 | } 33 | ); 34 | 35 | useEffect(() => { 36 | get().gl.domElement.parentElement.style.touchAction = "none"; 37 | get().gl.domElement.style.touchAction = "none"; 38 | }); 39 | 40 | useFrame((st, dt) => { 41 | let velocity = (vel.current / 1000) * 50; 42 | 43 | prog.current += velocity * 1.5; 44 | 45 | if (Now.autoPlayScroll) { 46 | prog.current += dt / 10.0; 47 | } else { 48 | } 49 | 50 | vel.current *= 0.98; 51 | }); 52 | 53 | // 54 | 55 | return {children({ prog })}; 56 | } 57 | -------------------------------------------------------------------------------- /vfx/places/Spirit/SpaceWrap.js: -------------------------------------------------------------------------------- 1 | import { useFrame } from "@react-three/fiber"; 2 | import { Vector3 } from "three"; 3 | 4 | export function SpaceWrap() { 5 | // 6 | let tl = new Vector3(); 7 | let velocity = new Vector3(); 8 | useFrame((st, dt) => { 9 | st.camera.getWorldPosition(velocity); 10 | let vv = velocity.sub(tl).length(); 11 | if (vv <= 0) { 12 | vv = 0; 13 | } 14 | if (vv >= 1) { 15 | vv = 1; 16 | } 17 | st.camera.getWorldPosition(tl); 18 | 19 | st.camera.fov = MathUtils.lerp(st.camera.fov, 50 + vv * 130, 0.1); 20 | st.camera.updateProjectionMatrix(); 21 | }); 22 | 23 | return null; 24 | } 25 | -------------------------------------------------------------------------------- /vfx/places/Spirit/Spirit.js: -------------------------------------------------------------------------------- 1 | import { Suspense, useEffect } from "react"; 2 | import { Starter } from "../../canvas/Starter/Starter"; 3 | import { CameraFlow } from "./CameraFlow"; 4 | import { Floor } from "./Floor"; 5 | import { JustBloom } from "./JustBloom"; 6 | import { Lighting } from "./Lighting"; 7 | import { ProgressControls } from "./ProgressControls"; 8 | import { Stage2 } from "./Stage2"; 9 | import { StarSky } from "../../canvas/StarSky/StarSky"; 10 | import { LoadingInCam } from "./LoadingInCam.js"; 11 | import { GeoSpirit } from "./GeoSpirit"; 12 | import { useThree } from "@react-three/fiber"; 13 | import { OrbitControls as DOR } from "@react-three/drei"; 14 | // 15 | 16 | export default function Spirit() { 17 | return ( 18 | <> 19 | 20 | {/* */} 21 | {/* */} 22 | {/* */} 23 | 24 | 25 | 26 | 27 | 28 | 29 | {/* */} 30 | {/* */} 31 | {/* */} 32 | {/* 33 | {({ prog }) => { 34 | // 35 | return ( 36 | 37 | 38 | 39 | 40 | ); 41 | }} 42 | */} 43 | 44 | 45 | 46 | 47 | {/* */} 48 | 49 | 50 | 51 | {/*
oh my dear....
*/} 52 | 53 | ); 54 | } 55 | 56 | function Cam() { 57 | let { get } = useThree(); 58 | useEffect(() => { 59 | // 60 | // 61 | get().camera.position.y = 1; 62 | }, []); 63 | return null; 64 | } 65 | 66 | // 67 | // 68 | // 69 | // 70 | 71 | // 72 | // 73 | // 74 | 75 | // 76 | // 77 | // 78 | // 79 | -------------------------------------------------------------------------------- /vfx/places/Spirit/Stage2.js: -------------------------------------------------------------------------------- 1 | import { useAnimations, useGLTF } from "@react-three/drei"; 2 | import { useFrame } from "@react-three/fiber"; 3 | import { useEffect, useRef } from "react"; 4 | import { 5 | Color, 6 | CubeCamera, 7 | CubeRefractionMapping, 8 | DoubleSide, 9 | LinearEncoding, 10 | ShaderMaterial, 11 | TextureLoader, 12 | WebGLCubeRenderTarget, 13 | } from "three"; 14 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 15 | import { ForceShield } from "./ForceShield"; 16 | import { useThree } from "@react-three/fiber"; 17 | 18 | export function Stage2() { 19 | let gltf = useGLTF(`/map/blockout/stage2/stage2-v1.glb`); 20 | let moutner = useRef(); 21 | let render = useRef(() => {}); 22 | useFrame((st, dt) => { 23 | render.current(st, dt); 24 | }); 25 | // 26 | // 27 | useEffect(() => { 28 | if (moutner.current) { 29 | // 30 | moutner.current.children.forEach((l) => { 31 | moutner.current.remove(l); 32 | }); 33 | 34 | let o3d = moutner.current; 35 | 36 | let floor = SkeletonUtils.clone(gltf.scene); 37 | 38 | o3d.add(floor); 39 | 40 | let crtt = new WebGLCubeRenderTarget(256); 41 | crtt.texture.mapping = CubeRefractionMapping; 42 | let cubeCam = new CubeCamera(0.3, 1000, crtt); 43 | // get().scene.environment = cubeCam.texture; 44 | 45 | let honey = floor.getObjectByName("HoneyCome"); 46 | 47 | honey.scale.multiplyScalar(3); 48 | 49 | let force = new ForceShield({ 50 | // 51 | // 52 | }); 53 | honey.material = force.shield; 54 | force.uniforms.tCube.value = crtt.texture; 55 | // 56 | 57 | render.current = (st, dt) => { 58 | // 59 | force.time += dt; 60 | honey.visible = false; 61 | cubeCam.position.copy(honey.position); 62 | 63 | // console.log(honey.position); 64 | 65 | cubeCam.update(st.gl, st.scene); 66 | honey.visible = true; 67 | 68 | // debug 69 | honey.visible = false; 70 | }; 71 | 72 | return () => { 73 | render.current = (st, dt) => { 74 | // 75 | }; 76 | }; 77 | } 78 | }, []); 79 | return ( 80 | 81 | 82 | 83 | {/* */} 87 | {/* */} 88 | {/* */} 89 | {/* */} 90 | {/* */} 91 | 92 | ); 93 | } 94 | 95 | // function AnimationController({ animations, scene }) { 96 | // const { actions } = useAnimations(animations, scene); 97 | 98 | // // Storybook Knobs 99 | // const actionOptions = Object.keys(actions); 100 | // const selectedAction = actionOptions[0]; 101 | // const blendDuration = 2; 102 | 103 | // useEffect(() => { 104 | // actions[selectedAction]?.reset().fadeIn(blendDuration).play(); 105 | // return () => { 106 | // actions[selectedAction]?.fadeOut(blendDuration); 107 | // }; 108 | // }, [actions, selectedAction, blendDuration]); 109 | 110 | // return null; 111 | // } 112 | 113 | // function getRainbowMat({ works }) { 114 | // let dudv = new TextureLoader().load(`/texture/waterdudv.jpg`, (t) => { 115 | // // 116 | // // 117 | // t.encoding = LinearEncoding; 118 | 119 | // // 120 | // }); 121 | // let uniforms = { 122 | // colorA: { 123 | // value: new Color("#f0f"), 124 | // }, 125 | // colorB: { 126 | // value: new Color("#0ff"), 127 | // }, 128 | // dudv: { 129 | // value: dudv, 130 | // }, 131 | // }; 132 | 133 | // // 134 | // works.push((st, dt) => { 135 | // // 136 | // }); 137 | 138 | // return new ShaderMaterial({ 139 | // uniforms, 140 | // side: DoubleSide, 141 | 142 | // // 143 | // vertexShader: ` 144 | // varying vec2 vUv; 145 | // void main (void) { 146 | // vUv = uv; 147 | // gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); 148 | // } 149 | // `, 150 | // // 151 | 152 | // // 153 | // fragmentShader: ` 154 | // varying vec2 vUv; 155 | // uniform vec3 colorA; 156 | // uniform vec3 colorB; 157 | // void main (void) { 158 | 159 | // gl_FragColor = vec4(mix(colorA.rgb, colorB.rgb, (vUv.x - vUv.y) / 2.0), 1.0); 160 | // } 161 | // `, 162 | // // 163 | // }); 164 | // } 165 | -------------------------------------------------------------------------------- /vfx/places/church/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/heavenly-platforms/heavenly-platforms.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | ...CommonAssets, 12 | }; 13 | 14 | processAQ({ AQ }); 15 | 16 | export const Assets = Object.values(AQ); 17 | -------------------------------------------------------------------------------- /vfx/places/church/SkyCityChurch.js: -------------------------------------------------------------------------------- 1 | import { useGLTF } from "@react-three/drei"; 2 | import { createPortal, useFrame, useThree } from "@react-three/fiber"; 3 | import { Suspense, useEffect, useMemo } from "react"; 4 | import { Preload } from "../../canvas/Preload/Preload"; 5 | import { Starter } from "../../canvas/Starter/Starter"; 6 | import { Assets, AQ } from "./Assets"; 7 | import { Color, Object3D } from "three"; 8 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 9 | import { ColliderManager } from "../../classes/ColliderManager"; 10 | import { PlayerCollider } from "../../canvas/PlayerCollider/PlayerCollider"; 11 | import { Now } from "../../store/Now"; 12 | import { SkyViewControls } from "../../canvas/Controls/SkyViewControls"; 13 | import { PlayerDisplay } from "../../canvas/PlayerDisplay/PlayerDisplay"; 14 | // import { SimpleBloomer } from "../../canvas/PostProcessing/SimpleBloomer"; 15 | import { StarSky } from "../../canvas/StarSky/StarSky"; 16 | import { useEnvLight } from "../../utils/use-env-light"; 17 | import { FlyTeleport } from "../../game/Portals/FlyTeleport"; 18 | import { ShaderBloomer } from "../../canvas/PostProcessing/ShaderBloomer"; 19 | import { ForceGraphR3F } from "../../explore/ForceGraphR3F"; 20 | 21 | export default function SkyCityChurch() { 22 | return ( 23 |
24 | 25 | 26 | 27 | {/* */} 28 | {/* */} 29 | 30 | 31 | 32 | 33 |
34 | ); 35 | } 36 | 37 | function BG() { 38 | let { get } = useThree(); 39 | useEffect(() => { 40 | let orig = get().scene.background; 41 | 42 | get().scene.background = new Color("#457bcd"); 43 | 44 | return () => { 45 | get().scene.background = orig; 46 | }; 47 | }); 48 | return null; 49 | } 50 | 51 | function MapLoader() { 52 | return ( 53 | 54 | 55 | 56 | 57 | 58 | ); 59 | } 60 | 61 | function MapContent() { 62 | let { get } = useThree(); 63 | let gltf = useGLTF(AQ.floorMap.url); 64 | let { envMap } = useEnvLight(); 65 | 66 | let floor = useMemo(() => { 67 | let floor = SkeletonUtils.clone(gltf.scene); 68 | floor.rotation.y = Math.PI * 0.5; 69 | 70 | let startAt = floor.getObjectByName("startAt"); 71 | if (startAt) { 72 | startAt.getWorldPosition(Now.startAt); 73 | startAt.getWorldPosition(Now.avatarAt); 74 | startAt.getWorldPosition(Now.goingTo); 75 | Now.goingTo.x += 1.3; 76 | Now.startAt.y += 1.3; 77 | } 78 | return floor; 79 | }, [gltf]); 80 | 81 | let colliderManager = useMemo(() => { 82 | return new ColliderManager({ floor, scene: get().scene }); 83 | }, [floor]); 84 | 85 | let o3d = new Object3D(); 86 | 87 | return ( 88 | 89 | 90 | 91 | {createPortal(, o3d)} 92 | 93 | {createPortal( 94 | 95 | 96 | , 97 | o3d 98 | )} 99 | 100 | {createPortal( 101 | 102 | 103 | , 104 | floor.getObjectByName("startAt") 105 | )} 106 | 107 | 108 | 112 | 113 | 114 | 118 | 119 | {/* */} 120 | {/* */} 121 | 122 | 123 | 124 | ); 125 | } 126 | 127 | function Portals({ floor, envMap }) { 128 | return ( 129 | 130 | 137 | 138 | 145 | 146 | 153 | 154 | 161 | 162 | 169 | 170 | 177 | 178 | ); 179 | } 180 | -------------------------------------------------------------------------------- /vfx/places/common/CommonAssets.js: -------------------------------------------------------------------------------- 1 | export const CommonAssets = { 2 | swimming: { 3 | slug: "swimming", 4 | type: "fbx", 5 | rawurl: `/rpm/rpm-actions-locomotion/swim-forward.fbx`, 6 | cacheURL: false, 7 | preload: false, 8 | }, 9 | 10 | floating: { 11 | slug: "floating", 12 | type: "fbx", 13 | rawurl: `/rpm/rpm-actions-locomotion/swim-float.fbx`, 14 | cacheURL: false, 15 | preload: false, 16 | }, 17 | 18 | running: { 19 | slug: "running", 20 | type: "fbx", 21 | rawurl: `/rpm/rpm-actions-locomotion/running.fbx`, 22 | cacheURL: false, 23 | preload: true, 24 | }, 25 | standing: { 26 | slug: "standing", 27 | type: "fbx", 28 | rawurl: `/rpm/rpm-actions-locomotion/standing.fbx`, 29 | cacheURL: false, 30 | preload: true, 31 | }, 32 | 33 | // 34 | portalAlphaMap: { 35 | slug: "portalAlphaMap", 36 | type: "png", 37 | rawurl: `/texture/portalAlpahMap.png`, 38 | cacheURL: false, 39 | preload: true, 40 | }, 41 | }; 42 | 43 | export const processAQ = ({ AQ }) => { 44 | for (let kn in AQ) { 45 | let obj = AQ[kn]; 46 | if (!obj.url) { 47 | Object.defineProperty(obj, "url", { 48 | get: () => { 49 | if (obj.cacheURL) { 50 | console.log("using blob url", obj.slug); 51 | return obj.cacheURL; 52 | } 53 | return obj.rawurl; 54 | }, 55 | set: (v) => { 56 | obj.url = v; 57 | }, 58 | }); 59 | } 60 | } 61 | }; 62 | 63 | processAQ({ AQ: CommonAssets }); 64 | -------------------------------------------------------------------------------- /vfx/places/fly/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/orchid-sing/orchid-sing.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | butterfly: { 12 | slug: "butterfly", 13 | type: "glb", 14 | rawurl: "/objects/butterfly/butterfly.glb", 15 | cacheURL: false, 16 | preload: false, 17 | }, 18 | ...CommonAssets, 19 | }; 20 | 21 | processAQ({ AQ }); 22 | 23 | export const Assets = Object.values(AQ); 24 | 25 | // 26 | -------------------------------------------------------------------------------- /vfx/places/fly/Fly.js: -------------------------------------------------------------------------------- 1 | import { 2 | useCubeTexture, 3 | useGLTF, 4 | OrbitControls as DOribt, 5 | } from "@react-three/drei"; 6 | import { createPortal, useFrame, useThree } from "@react-three/fiber"; 7 | import { Suspense, useEffect, useMemo, useState } from "react"; 8 | import { Preload } from "../../canvas/Preload/Preload"; 9 | import { Starter } from "../../canvas/Starter/Starter"; 10 | import { Assets, AQ } from "./Assets"; 11 | import { 12 | CatmullRomCurve3, 13 | Object3D, 14 | Vector3, 15 | sRGBEncoding, 16 | Color, 17 | AnimationMixer, 18 | } from "three"; 19 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 20 | import { ColliderManager } from "../../classes/ColliderManager"; 21 | import { Now } from "../../store/Now"; 22 | import { SimpleBloomer } from "../../canvas/PostProcessing/SimpleBloomer"; 23 | import { useEnvLight } from "../../utils/use-env-light"; 24 | import { TrackO3D } from "./TrackO3D"; 25 | // import { PlayerCollider } from "../../canvas/PlayerCollider/PlayerCollider"; 26 | // import { SkyViewControls } from "../../canvas/Controls/SkyViewControls"; 27 | // import { PlayerDisplay } from "../../canvas/PlayerDisplay/PlayerDisplay"; 28 | // import { StarSky } from "../../canvas/StarSky/StarSky"; 29 | // import { useEnvLight } from "../../utils/use-env-light"; 30 | // import { FlyTeleport } from "../../game/Portals/FlyTeleport"; 31 | // import { WalkerFollowerControls } from "../../canvas/Controls/WalkerFollowerControls"; 32 | 33 | // import { SimpleBloomer } from "../../canvas/PostProcessing/SimpleBloomer"; 34 | import { useMiniEngine } from "../../utils/use-mini-engine"; 35 | 36 | export default function Fly() { 37 | return ( 38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {/* */} 47 | 48 | 49 |
50 | ); 51 | } 52 | 53 | function BG({ children }) { 54 | let { get } = useThree(); 55 | 56 | const envMap = useCubeTexture( 57 | ["px.png", "nx.png", "py.png", "ny.png", "pz.png", "nz.png"], 58 | { path: "/cubemap/sky-grass/" } 59 | ); 60 | 61 | useEffect(() => { 62 | let orig = get().scene.background; 63 | // envMap.encoding = sRGBEncoding; 64 | // get().scene.background = envMap; 65 | 66 | get().scene.background = new Color("#000000"); 67 | 68 | return () => { 69 | get().scene.background = orig; 70 | }; 71 | }, []); 72 | return {children}; 73 | } 74 | 75 | function MapLoader() { 76 | return ( 77 | 78 | 79 | 80 | 81 | 82 | 83 | ); 84 | } 85 | 86 | function FlyTracker() { 87 | // 88 | let gltf = useGLTF(`/particles/old/atv2.glb`); 89 | 90 | let actions = []; 91 | let mixer = new AnimationMixer(gltf.scene); 92 | gltf.animations.forEach((clip) => { 93 | let action = mixer.clipAction(clip); 94 | actions.push(action); 95 | action.play(); 96 | }); 97 | 98 | useFrame((st, dt) => { 99 | mixer.update(dt); 100 | }); 101 | 102 | let trackers = []; 103 | let { mini } = useMiniEngine(); 104 | 105 | gltf.scene.traverse((it) => { 106 | if (it.name.indexOf("particle") === 0) { 107 | trackers.push(it); 108 | } 109 | }); 110 | 111 | let sim = useMemo(() => { 112 | return new TrackO3D({ 113 | node: mini, 114 | tailLength: 16, // 512, 1024 115 | howManyTrackers: trackers.length, 116 | }); 117 | }, [trackers, trackers.length]); 118 | 119 | useFrame(() => { 120 | sim.track({ trackers, lerp: 1 }); 121 | }); 122 | // 123 | return ( 124 | 125 | 126 | 127 | ); 128 | } 129 | 130 | // 131 | -------------------------------------------------------------------------------- /vfx/places/index.js: -------------------------------------------------------------------------------- 1 | import dynamic from "next/dynamic"; 2 | import md5 from "md5"; 3 | 4 | export let SiteBaseURL = "https://metaverse.effectnode.com"; 5 | 6 | export let getPages = () => { 7 | return [ 8 | { 9 | placeID: `spaceship`, 10 | slug: `/place/spaceship`, 11 | title: "Spaceship", 12 | thumbnail: `${SiteBaseURL}/preview/spaceship-thumb.png`, 13 | compo: dynamic(() => import("./spaceship/SpaceStation"), { 14 | ssr: false, 15 | }), 16 | }, 17 | { 18 | placeID: `church`, 19 | slug: `/place/church`, 20 | title: "Thank you Church", 21 | thumbnail: `${SiteBaseURL}/preview/church-thumb.png`, 22 | compo: dynamic(() => import("./church/SkyCityChurch"), { 23 | ssr: false, 24 | }), 25 | }, 26 | { 27 | placeID: `sing`, 28 | slug: `/place/sing`, 29 | title: "Thank you Worship", 30 | thumbnail: `${SiteBaseURL}/preview/sing-thumb.png`, 31 | compo: dynamic(() => import("./sing/Sing"), { 32 | ssr: false, 33 | }), 34 | }, 35 | { 36 | placeID: `fly`, 37 | slug: `/place/fly`, 38 | title: "GLB to Lines", 39 | thumbnail: `${SiteBaseURL}/preview/fly-thumb.png`, 40 | compo: dynamic(() => import("./fly/Fly.js"), { 41 | ssr: false, 42 | }), 43 | }, 44 | { 45 | placeID: `simulation`, 46 | slug: `/place/simulation`, 47 | title: "Thank you Jesus - Particle Simulation", 48 | thumbnail: `${SiteBaseURL}/preview/simulation-thumb.png`, 49 | compo: dynamic(() => import("./simulation/SimPage.js"), { 50 | ssr: false, 51 | }), 52 | }, 53 | { 54 | placeID: `magnet`, 55 | slug: `/place/magnet`, 56 | title: "Thank you Jesus - Line Magnet", 57 | thumbnail: `${SiteBaseURL}/preview/simulation-thumb.png`, 58 | compo: dynamic(() => import("./magnet/Magnet.js"), { 59 | ssr: false, 60 | }), 61 | }, 62 | { 63 | placeID: `dove`, 64 | slug: `/place/dove`, 65 | title: "Thank you Jesus - Dove", 66 | thumbnail: `${SiteBaseURL}/preview/simulation-thumb.png`, 67 | compo: dynamic(() => import("./Spirit/Spirit.js"), { 68 | ssr: false, 69 | }), 70 | }, 71 | // { 72 | // placeID: `fashion`, 73 | // slug: `/place/fashion`, 74 | // title: "Fashion", 75 | // thumbnail: `${SiteBaseURL}/preview/simulation-thumb.png`, 76 | // compo: dynamic(() => import("./fashion/Fashion.js"), { 77 | // ssr: false, 78 | // // 79 | // }), 80 | // }, 81 | ]; 82 | }; 83 | 84 | export let getMyFreinds = async () => { 85 | let list = []; 86 | 87 | list.push({ 88 | id: md5(`https://www.loving.place/api/starlink`), 89 | type: "starlink", 90 | title: `Loving Place`, 91 | url: `https://www.loving.place/api/starlink`, 92 | }); 93 | 94 | list.push({ 95 | id: md5(`https://metaverse.thankyou.church/api/starlink`), 96 | type: "starlink", 97 | title: `Metaverse Church`, 98 | url: `https://metaverse.thankyou.church/api/starlink`, 99 | }); 100 | 101 | return list; 102 | }; 103 | 104 | export let getDiscoveryData = async ({ origin = SiteBaseURL }) => { 105 | if (!origin) { 106 | origin = SiteBaseURL; 107 | } 108 | let endpoint = `${origin}/api/starlink`; 109 | let yourselfID = md5(endpoint); 110 | 111 | let yourCore = { 112 | id: yourselfID, 113 | thumbnail: `${origin}/me.png`, 114 | endpoint, 115 | type: "core", 116 | }; 117 | 118 | let friends = await getMyFreinds(); 119 | 120 | const MyMaps = getPages().map((obj) => { 121 | let url = `${origin}${obj.slug}`; 122 | return { 123 | ...obj, 124 | site: origin, 125 | id: md5(url), 126 | url, 127 | type: "map", 128 | }; 129 | }); 130 | 131 | let data = { 132 | id: yourCore.id, 133 | meta: { 134 | schema: "metaverse-starlink", 135 | license: "MIT", 136 | version: "0.0.1", 137 | }, 138 | myself: yourCore, 139 | nodes: [ 140 | // 141 | yourCore, 142 | ...MyMaps, 143 | ], 144 | links: [], 145 | notes: [ 146 | // 147 | "node id is made of md5(url)", 148 | "link id is made of md5(source id + target id)", 149 | ], 150 | friends, 151 | }; 152 | 153 | data.links = MyMaps.map((obj) => { 154 | let source = yourCore.id; 155 | let target = obj.id; 156 | let id = md5(`${source}${target}`); 157 | return { 158 | id, 159 | source, 160 | target, 161 | }; 162 | }); 163 | 164 | // 165 | 166 | // 167 | return data; 168 | }; 169 | -------------------------------------------------------------------------------- /vfx/places/journey/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/journey-with-dear-God/journey.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | ...CommonAssets, 12 | }; 13 | 14 | processAQ({ AQ }); 15 | 16 | export const Assets = Object.values(AQ); 17 | 18 | // 19 | -------------------------------------------------------------------------------- /vfx/places/journey/Journey.js: -------------------------------------------------------------------------------- 1 | import { useGLTF } from "@react-three/drei"; 2 | import { createPortal, useFrame, useThree } from "@react-three/fiber"; 3 | import { Suspense, useEffect, useMemo } from "react"; 4 | import { Preload } from "../../canvas/Preload/Preload"; 5 | import { Starter } from "../../canvas/Starter/Starter"; 6 | import { Assets, AQ } from "./Assets"; 7 | import { Color, Object3D } from "three"; 8 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 9 | import { ColliderManager } from "../../classes/ColliderManager"; 10 | import { PlayerCollider } from "../../canvas/PlayerCollider/PlayerCollider"; 11 | import { Now } from "../../store/Now"; 12 | import { SkyViewControls } from "../../canvas/Controls/SkyViewControls"; 13 | import { PlayerDisplay } from "../../canvas/PlayerDisplay/PlayerDisplay"; 14 | import { SimpleBloomer } from "../../canvas/PostProcessing/SimpleBloomer"; 15 | import { StarSky } from "../../canvas/StarSky/StarSky"; 16 | import { useEnvLight } from "../../utils/use-env-light"; 17 | import { FlyTeleport } from "../../game/Portals/FlyTeleport"; 18 | import { WalkerFollowerControls } from "../../canvas/Controls/WalkerFollowerControls"; 19 | import { PathWay } from "../../canvas/MapAddons/PathWay"; 20 | import { StoryFlyControls } from "../../canvas/Controls/StoryFlyControls"; 21 | 22 | export default function Journey() { 23 | return ( 24 |
25 | 26 | 27 | 28 | 29 | 30 | {/* */} 31 | 32 | 33 |
34 | ); 35 | } 36 | 37 | function BG() { 38 | let { get } = useThree(); 39 | useEffect(() => { 40 | let orig = get().scene.background; 41 | 42 | get().scene.background = new Color("#333"); 43 | 44 | return () => { 45 | get().scene.background = orig; 46 | }; 47 | }); 48 | return null; 49 | } 50 | 51 | function MapLoader() { 52 | return ( 53 | 54 | 55 | 56 | 57 | 58 | ); 59 | } 60 | 61 | function MapContent() { 62 | let { get } = useThree(); 63 | let gltf = useGLTF(AQ.floorMap.url); 64 | let { envMap } = useEnvLight(); 65 | 66 | let floor = useMemo(() => { 67 | let floor = SkeletonUtils.clone(gltf.scene); 68 | // floor.rotation.y = Math.PI * 0.5; 69 | 70 | let startAt = floor.getObjectByName("startAt"); 71 | if (startAt) { 72 | startAt.getWorldPosition(Now.startAt); 73 | startAt.getWorldPosition(Now.avatarAt); 74 | startAt.getWorldPosition(Now.goingTo); 75 | Now.goingTo.y += 1.3; 76 | } 77 | return floor; 78 | }, [gltf]); 79 | 80 | let colliderManager = useMemo(() => { 81 | return new ColliderManager({ floor, scene: get().scene }); 82 | }, [floor]); 83 | 84 | let o3d = new Object3D(); 85 | 86 | return ( 87 | 88 | 89 | 90 | {createPortal(, o3d)} 91 | 92 | {createPortal( 93 | 94 | 95 | , 96 | o3d 97 | )} 98 | 99 | {/* 100 | 104 | 105 | 106 | */} 110 | 111 | {/* */} 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | {/* */} 120 | 121 | ); 122 | } 123 | 124 | // function Portals({ floor, envMap }) { 125 | // return ( 126 | // 127 | // 134 | 135 | // 142 | 143 | // 150 | 151 | // 158 | 159 | // 166 | 167 | // 174 | // 175 | // ); 176 | // } 177 | -------------------------------------------------------------------------------- /vfx/places/magnet/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/spaewalk/space-walk-v003.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | 12 | ...CommonAssets, 13 | }; 14 | 15 | processAQ({ AQ }); 16 | 17 | export const Assets = Object.values(AQ); 18 | -------------------------------------------------------------------------------- /vfx/places/simulation/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/orchid-sing/orchid-sing.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | butterfly: { 12 | slug: "butterfly", 13 | type: "glb", 14 | rawurl: "/objects/butterfly/butterfly.glb", 15 | cacheURL: false, 16 | preload: false, 17 | }, 18 | ...CommonAssets, 19 | }; 20 | 21 | processAQ({ AQ }); 22 | 23 | export const Assets = Object.values(AQ); 24 | 25 | // 26 | -------------------------------------------------------------------------------- /vfx/places/simulation/InteractionUI.js: -------------------------------------------------------------------------------- 1 | import { 2 | PlaneBufferGeometry, 3 | MeshBasicMaterial, 4 | Mesh, 5 | Vector3, 6 | // AdditiveBlending, 7 | } from "three"; 8 | 9 | export class InteractionUI { 10 | static fixTouchScreen({ target }) { 11 | let onEvent = (target, event, h) => { 12 | target.addEventListener(event, h, { passive: false }); 13 | return () => { 14 | target.removeEventListener(event, h); 15 | }; 16 | }; 17 | 18 | let cleanTouchStart = onEvent(target, "touchstart", (ev) => { 19 | ev.preventDefault(); 20 | }); 21 | 22 | let cleanTouchMove = onEvent(target, "toucmove", (ev) => { 23 | ev.preventDefault(); 24 | }); 25 | 26 | return () => { 27 | cleanTouchStart(); 28 | cleanTouchMove(); 29 | }; 30 | } 31 | 32 | static async hoverPlane({ mini }) { 33 | let raycaster = await mini.ready.raycaster; 34 | let mouse = await mini.ready.mouse; 35 | let camera = await mini.ready.camera; 36 | let scene = await mini.ready.scene; 37 | let viewport = await mini.ready.viewport; 38 | 39 | let geoPlane = new PlaneBufferGeometry( 40 | 3.0 * viewport.width, 41 | 3.0 * viewport.height, 42 | 2, 43 | 2 44 | ); 45 | 46 | let matPlane = new MeshBasicMaterial({ 47 | transparent: true, 48 | opacity: 0.25, 49 | color: 0xbababa, 50 | }); 51 | 52 | let planeMesh = new Mesh(geoPlane, matPlane); 53 | planeMesh.position.z = -camera.position.z / 2; 54 | 55 | mini.onResize(() => { 56 | let viewport = mini.now.viewport; 57 | let geoPlane = new PlaneBufferGeometry( 58 | 3.0 * viewport.width, 59 | 3.0 * viewport.height, 60 | 2, 61 | 2 62 | ); 63 | planeMesh.geometry = geoPlane; 64 | }); 65 | 66 | // scene.add(planeMesh); 67 | // mini.onClean(() => { 68 | // scene.remove(planeMesh); 69 | // }); 70 | 71 | let temppos = new Vector3(0, 0, 0); 72 | mini.onLoop(() => { 73 | planeMesh.lookAt(camera.position); 74 | raycaster.setFromCamera(mouse, camera); 75 | let res = raycaster.intersectObject(planeMesh); 76 | if (res && res[0]) { 77 | temppos.copy(res[0].point); 78 | } 79 | }); 80 | 81 | return temppos; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /vfx/places/sing/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/orchid-sing/orchid-sing.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | butterfly: { 12 | slug: "butterfly", 13 | type: "glb", 14 | rawurl: "/objects/butterfly/butterfly.glb", 15 | cacheURL: false, 16 | preload: false, 17 | }, 18 | ...CommonAssets, 19 | }; 20 | 21 | processAQ({ AQ }); 22 | 23 | export const Assets = Object.values(AQ); 24 | 25 | // 26 | -------------------------------------------------------------------------------- /vfx/places/sing/Butterflyer.js: -------------------------------------------------------------------------------- 1 | import { useGLTF } from "@react-three/drei"; 2 | import { createPortal, useFrame } from "@react-three/fiber"; 3 | import { useEffect, useMemo } from "react"; 4 | import { 5 | AnimationMixer, 6 | Color, 7 | Euler, 8 | MathUtils, 9 | Object3D, 10 | Vector3, 11 | } from "three"; 12 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 13 | import { AQ } from "./Assets"; 14 | 15 | export function Butterflyer({ speed = 0, to, from }) { 16 | let o3d = new Object3D(); 17 | 18 | let gltf = useGLTF(AQ.butterfly.rawurl); 19 | 20 | let butterfly = useMemo(() => { 21 | return SkeletonUtils.clone(gltf.scene); 22 | }, [gltf]); 23 | 24 | useMemo(() => { 25 | butterfly.traverse((it) => { 26 | it.userData.enableBloom = true; 27 | if (it.material) { 28 | it.material = it.material.clone(); 29 | it.material.metalness = 1.0; 30 | it.material.roughness = 0.5; 31 | if (Math.random() <= 0.5) { 32 | it.material.color = new Color("yellow").offsetHSL(0, -0.3, 0.2); 33 | } else { 34 | it.material.color = new Color("pink").offsetHSL(0, -0.3, -0.2); 35 | } 36 | } 37 | }); 38 | }, [butterfly]); 39 | 40 | let mixer = useMemo(() => { 41 | return new AnimationMixer(butterfly); 42 | }, [butterfly]); 43 | 44 | o3d.position.copy(from.position); 45 | 46 | useFrame((st, dt) => { 47 | let far = from.position.distanceTo(st.camera.position); 48 | if (far < 70) { 49 | mixer.update(dt + speed / 50); 50 | o3d.position.lerp(to.position, 0.005); 51 | 52 | o3d.lookAt(to.position); 53 | o3d.rotation.y += Math.PI; 54 | o3d.visible = true; 55 | o3d.scale.x = MathUtils.lerp(o3d.scale.x, 1, 0.1); 56 | o3d.scale.y = MathUtils.lerp(o3d.scale.y, 1, 0.1); 57 | o3d.scale.z = MathUtils.lerp(o3d.scale.z, 1, 0.1); 58 | } else { 59 | o3d.position.lerp(from.position, 0.1); 60 | o3d.scale.x = MathUtils.lerp(o3d.scale.x, 0, 0.1); 61 | o3d.scale.y = MathUtils.lerp(o3d.scale.y, 0, 0.1); 62 | o3d.scale.z = MathUtils.lerp(o3d.scale.z, 0, 0.1); 63 | } 64 | 65 | if (o3d.scale.x <= 0.1) { 66 | o3d.visible = false; 67 | } else { 68 | o3d.visible = true; 69 | } 70 | }); 71 | 72 | useEffect(() => { 73 | let fly = mixer.clipAction(gltf.animations[0], butterfly); 74 | fly.play(); 75 | }, [gltf, butterfly, mixer]); 76 | 77 | return ( 78 | 79 | {createPortal(, o3d)} 80 | 81 | 82 | ); 83 | } 84 | // 85 | -------------------------------------------------------------------------------- /vfx/places/spaceship/Assets.js: -------------------------------------------------------------------------------- 1 | import { CommonAssets, processAQ } from "../common/CommonAssets"; 2 | 3 | export const AQ = { 4 | floorMap: { 5 | slug: "floorMap", 6 | type: "glb", 7 | rawurl: "/map/spaewalk/space-walk-v003.glb", 8 | cacheURL: false, 9 | preload: false, 10 | }, 11 | 12 | ...CommonAssets, 13 | }; 14 | 15 | processAQ({ AQ }); 16 | 17 | export const Assets = Object.values(AQ); 18 | -------------------------------------------------------------------------------- /vfx/places/spaceship/SpaceStation.js: -------------------------------------------------------------------------------- 1 | import { useGLTF } from "@react-three/drei"; 2 | import { createPortal, useFrame, useThree } from "@react-three/fiber"; 3 | import { Suspense, useEffect, useMemo, useRef } from "react"; 4 | import { Preload } from "../../canvas/Preload/Preload"; 5 | import { Starter } from "../../canvas/Starter/Starter"; 6 | import { Assets, AQ } from "./Assets"; 7 | import { Object3D } from "three"; 8 | import { SkeletonUtils } from "three/examples/jsm/utils/SkeletonUtils"; 9 | import { ColliderManager } from "../../classes/ColliderManager"; 10 | import { PlayerCollider } from "../../canvas/PlayerCollider/PlayerCollider"; 11 | import { Now } from "../../store/Now"; 12 | import { SimpleBloomer } from "../../canvas/PostProcessing/SimpleBloomer"; 13 | import { StarSky } from "../../canvas/StarSky/StarSky"; 14 | import { useEnvLight } from "../../utils/use-env-light"; 15 | import { WalkerFollowerControls } from "../../canvas/Controls/WalkerFollowerControls"; 16 | import { PlayerDisplay } from "../../canvas/PlayerDisplay/PlayerDisplay"; 17 | import { ForceGraphR3F } from "../../explore/ForceGraphR3F"; 18 | import { useAutoEvent } from "../../utils/use-auto-event"; 19 | import { baseURL } from ".."; 20 | import router from "next/router"; 21 | 22 | export default function SpaceStation() { 23 | return ( 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | ); 34 | } 35 | 36 | function MapLoader() { 37 | return ( 38 | 39 | 40 | 41 | 42 | 43 | ); 44 | } 45 | 46 | function MapContent() { 47 | let { get } = useThree(); 48 | let gltf = useGLTF(AQ.floorMap.url); 49 | let { envMap } = useEnvLight(); 50 | 51 | let floor = useMemo(() => { 52 | let floor = SkeletonUtils.clone(gltf.scene); 53 | // floor.rotation.y = Math.PI * 0.5; 54 | 55 | let startAt = floor.getObjectByName("startAt"); 56 | if (startAt) { 57 | startAt.getWorldPosition(Now.startAt); 58 | startAt.getWorldPosition(Now.avatarAt); 59 | startAt.getWorldPosition(Now.goingTo); 60 | Now.goingTo.y += 1.3; 61 | } 62 | return floor; 63 | }, [gltf]); 64 | 65 | let colliderManager = useMemo(() => { 66 | return new ColliderManager({ floor, scene: get().scene }); 67 | }, [floor]); 68 | 69 | let o3d = new Object3D(); 70 | 71 | let metagraph = useRef(); 72 | 73 | useEffect(() => { 74 | // 75 | // 76 | if (metagraph.current) { 77 | floor 78 | .getObjectByName("startAt") 79 | .getWorldPosition(metagraph.current.position); 80 | metagraph.current.position.x += -1; 81 | metagraph.current.position.y += 1.3; 82 | metagraph.current.position.z += -5; 83 | metagraph.current.scale.setScalar(0.03); 84 | } 85 | // 86 | // 87 | }, []); 88 | 89 | return ( 90 | 91 | 92 | 93 | {createPortal(, o3d)} 94 | 95 | {createPortal( 96 | 97 | 98 | , 99 | o3d 100 | )} 101 | 102 | 106 | 107 | 114 | 115 | 116 | 117 | 118 | 119 | {/* 120 | */} 124 | 125 | 126 | 127 | ); 128 | } 129 | 130 | // 131 | 132 | // 133 | 134 | // 135 | -------------------------------------------------------------------------------- /vfx/store/Now.js: -------------------------------------------------------------------------------- 1 | import { makeNow, NowType } from "../utils/make-now"; 2 | 3 | /** @type {NowType} */ 4 | export const Now = makeNow(); 5 | -------------------------------------------------------------------------------- /vfx/store/Place.js: -------------------------------------------------------------------------------- 1 | // 2 | import { 3 | makeShallowStore, 4 | ShallowStoreMethods, 5 | } from "../utils/make-shallow-store"; 6 | 7 | let StateObject = { 8 | loadingProgress: "0%", 9 | }; 10 | 11 | let TypeObject = { 12 | ...ShallowStoreMethods, 13 | ...StateObject, 14 | }; 15 | 16 | /** @type {TypeObject} */ 17 | export const Place = makeShallowStore(StateObject); 18 | -------------------------------------------------------------------------------- /vfx/utils/get-id.js: -------------------------------------------------------------------------------- 1 | export const getID = function () { 2 | return ( 3 | "_" + 4 | Math.random().toString(36).substr(2, 9) + 5 | Math.random().toString(36).substr(2, 9) 6 | ); 7 | }; 8 | -------------------------------------------------------------------------------- /vfx/utils/make-now.js: -------------------------------------------------------------------------------- 1 | import { Vector3 } from "three"; 2 | import { makeShallowStore, ShallowStoreMethods } from "./make-shallow-store"; 3 | 4 | let getInternal = () => { 5 | return { 6 | // 7 | startLookAt: new Vector3(0, 1.5, 1), 8 | startAt: new Vector3(0, 1.5, 0), 9 | // 10 | moved: 0, 11 | goingTo: new Vector3(), 12 | camAt: new Vector3(), 13 | avatarAtDelta: new Vector3(), 14 | avatarAt: new Vector3(), 15 | avatarFlyTo: new Vector3(), 16 | avatarHead: new Vector3(), 17 | avatarRot: new Vector3(), 18 | avatarFaceLook: new Vector3(), 19 | followerPt: new Vector3(), 20 | avatarLoading: true, 21 | avatarMode: "standing", 22 | avatarSpeed: 1.0, 23 | 24 | // 25 | keyW: false, 26 | keyA: false, 27 | keyS: false, 28 | keyD: false, 29 | 30 | // 31 | locked: false, 32 | // 33 | cursorPos: new Vector3(), 34 | cursorNormal: new Vector3(), 35 | cursorType: "hide", 36 | 37 | // 38 | hint: "", 39 | hoverData: false, 40 | isDown: false, 41 | 42 | // avatarAtPhy: new Vector3(), 43 | 44 | camMode: "first", 45 | 46 | overlay: "", 47 | 48 | profile: false, 49 | user: false, 50 | 51 | reload: [], 52 | onlineUID: [], 53 | }; 54 | }; 55 | 56 | /** @type {Type} */ 57 | export let NowType = { 58 | ...getInternal(), 59 | ...ShallowStoreMethods, 60 | }; 61 | 62 | export const makeNow = () => { 63 | return makeShallowStore(getInternal()); 64 | }; 65 | -------------------------------------------------------------------------------- /vfx/utils/make-shallow-store.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { getID } from "./get-id"; 3 | 4 | export const ShallowStoreMethods = { 5 | onEvent: () => {}, 6 | makeKeyReactive: () => {}, 7 | reloadKey: () => {}, 8 | }; 9 | 10 | /** 11 | * @returns {ShallowStoreMethods} 12 | */ 13 | export const makeShallowStore = (myObject = {}) => { 14 | let ___NameSpaceID = getID(); 15 | let Utils = { 16 | exportJSON: () => { 17 | return JSON.parse(JSON.stringify(myObject)); 18 | }, 19 | 20 | /* */ 21 | getNameSpcaeID: () => { 22 | return ___NameSpaceID; 23 | }, 24 | 25 | /* */ 26 | onEvent: (key, func) => { 27 | let evName = `${___NameSpaceID}`; 28 | let hh = () => { 29 | func(myObject[key]); 30 | }; 31 | window.addEventListener(`${evName}-${key}`, hh); 32 | return () => { 33 | window.removeEventListener(`${evName}-${key}`, hh); 34 | }; 35 | }, 36 | 37 | makeKeyReactive: (key) => { 38 | let [vv, setSt] = useState(0); 39 | useEffect(() => { 40 | let evName = `${___NameSpaceID}`; 41 | 42 | let hh = () => { 43 | setSt((s) => { 44 | return s + 1; 45 | }); 46 | }; 47 | 48 | window.addEventListener(`${evName}-${key}`, hh); 49 | return () => { 50 | window.removeEventListener(`${evName}-${key}`, hh); 51 | }; 52 | }, [vv]); 53 | }, 54 | 55 | reloadKey: (key) => { 56 | window.dispatchEvent( 57 | new CustomEvent(`${___NameSpaceID}-${key}`, { detail: {} }) 58 | ); 59 | }, 60 | }; 61 | 62 | let proxy = new Proxy(myObject, { 63 | get: (o, k) => { 64 | // 65 | if (Utils[k]) { 66 | return Utils[k]; 67 | } 68 | 69 | return o[k]; 70 | }, 71 | set: (o, key, val) => { 72 | let currentVal = o[key]; 73 | 74 | if (currentVal !== val) { 75 | o[key] = val; 76 | 77 | if (typeof window !== "undefined") { 78 | window.dispatchEvent( 79 | new CustomEvent(`${___NameSpaceID}-${key}`, { detail: {} }) 80 | ); 81 | } 82 | } 83 | 84 | return true; 85 | }, 86 | }); 87 | 88 | let Type = { 89 | ...myObject, 90 | ...ShallowStoreMethods, 91 | }; 92 | /** @type {Type} */ 93 | return proxy; 94 | }; 95 | -------------------------------------------------------------------------------- /vfx/utils/use-auto-event.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | 3 | export const useAutoEvent = function ( 4 | ev, 5 | fnc, 6 | settings = { passive: false }, 7 | dom 8 | ) { 9 | useEffect(() => { 10 | dom = dom || window; 11 | dom.addEventListener(ev, fnc, settings); 12 | return () => { 13 | dom = dom || window; 14 | dom.removeEventListener(ev, fnc); 15 | }; 16 | }, []); 17 | }; 18 | 19 | export const applyAutoEvent = function ( 20 | dom, 21 | ev, 22 | fnc, 23 | settings = { passive: false } 24 | ) { 25 | dom = dom || window; 26 | dom.addEventListener(ev, fnc, settings); 27 | return () => { 28 | dom = dom || window; 29 | dom.removeEventListener(ev, fnc); 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /vfx/utils/use-compute-env-map.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree } from "@react-three/fiber"; 2 | import { useMemo } from "react"; 3 | 4 | import { 5 | WebGLCubeRenderTarget, 6 | Scene, 7 | Mesh, 8 | ShaderMaterial, 9 | CubeRefractionMapping, 10 | BackSide, 11 | NoBlending, 12 | BoxBufferGeometry, 13 | CubeCamera, 14 | LinearMipmapLinearFilter, 15 | RGBFormat, 16 | LinearFilter, 17 | CubeReflectionMapping, 18 | sRGBEncoding, 19 | } from "three"; 20 | 21 | // import { cloneUniforms } from "three/src/renderers/shaders/UniformsUtils.js"; 22 | // import * as dat from ''; 23 | 24 | let DefaultCode = ` 25 | const mat2 m = mat2( 0.80, 0.60, -0.60, 0.80 ); 26 | 27 | float noise( in vec2 p ) { 28 | return sin(p.x)*sin(p.y); 29 | } 30 | 31 | float fbm4( vec2 p ) { 32 | float f = 0.0; 33 | f += 0.5000 * noise( p ); p = m * p * 2.02; 34 | f += 0.2500 * noise( p ); p = m * p * 2.03; 35 | f += 0.1250 * noise( p ); p = m * p * 2.01; 36 | f += 0.0625 * noise( p ); 37 | return f / 0.9375; 38 | } 39 | 40 | float fbm6( vec2 p ) { 41 | float f = 0.0; 42 | f += 0.500000*(0.5 + 0.5 * noise( p )); p = m*p*2.02; 43 | f += 0.250000*(0.5 + 0.5 * noise( p )); p = m*p*2.03; 44 | f += 0.125000*(0.5 + 0.5 * noise( p )); p = m*p*2.01; 45 | f += 0.062500*(0.5 + 0.5 * noise( p )); p = m*p*2.04; 46 | f += 0.031250*(0.5 + 0.5 * noise( p )); p = m*p*2.01; 47 | f += 0.015625*(0.5 + 0.5 * noise( p )); 48 | return f/0.96875; 49 | } 50 | 51 | float pattern (vec2 p) { 52 | float vout = fbm4( p + time + fbm6( p + fbm4( p + time )) ); 53 | return abs(vout); 54 | } 55 | 56 | vec4 mainImage (vec2 uv) { 57 | return vec4(vec3( 58 | 0.35 + pattern(uv * 1.70123 + -0.17 * cos(time * 0.05)), 59 | 0.35 + pattern(uv * 1.70123 + 0.0 * cos(time * 0.05)), 60 | 0.35 + pattern(uv * 1.70123 + 0.17 * cos(time * 0.05)) 61 | ), 1.0); 62 | } 63 | `; 64 | 65 | export function useComputeEnvMap( 66 | code = DefaultCode, 67 | uniforms = {}, 68 | res = 128, 69 | frames = Infinity 70 | ) { 71 | let { get } = useThree(); 72 | 73 | let { envMap, compute } = useMemo(() => { 74 | let { gl } = get(); 75 | 76 | var scene = new Scene(); 77 | 78 | var shader = { 79 | uniforms: { 80 | ...uniforms, 81 | time: { value: 0.5 }, 82 | }, 83 | 84 | vertexShader: ` 85 | varying vec3 vPos; 86 | varying vec3 vWorldDirection; 87 | vec3 transformDirection( in vec3 dir, in mat4 matrix ) { 88 | return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); 89 | } 90 | void main() { 91 | vPos = position; 92 | vWorldDirection = transformDirection( position, modelMatrix ); 93 | #include 94 | #include 95 | } 96 | `, 97 | 98 | fragmentShader: ` 99 | varying vec3 vWorldDirection; 100 | varying vec3 vPos; 101 | #define RECIPROCAL_PI 0.31830988618 102 | #define RECIPROCAL_PI2 0.15915494 103 | 104 | uniform float time; 105 | 106 | ${code || DefaultCode} 107 | 108 | void main() { 109 | vec3 direction = normalize( vWorldDirection ); 110 | vec2 sampleUV; 111 | sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; 112 | sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5; 113 | 114 | gl_FragColor = mainImage(sampleUV, direction, vPos); 115 | 116 | } 117 | `, 118 | }; 119 | 120 | var material = new ShaderMaterial({ 121 | type: "CubemapFromEquirect", 122 | uniforms: shader.uniforms, 123 | vertexShader: shader.vertexShader, 124 | fragmentShader: shader.fragmentShader, 125 | side: BackSide, 126 | blending: NoBlending, 127 | }); 128 | 129 | var mesh = new Mesh(new BoxBufferGeometry(5, 5, 5), material); 130 | scene.add(mesh); 131 | 132 | var cubeRtt = new WebGLCubeRenderTarget(res, { 133 | format: RGBFormat, 134 | generateMipmaps: true, 135 | magFilter: LinearFilter, 136 | minFilter: LinearMipmapLinearFilter, 137 | }); 138 | 139 | var camera = new CubeCamera(1, 100000, cubeRtt); 140 | 141 | shader.uniforms.time.value = 0.4; 142 | camera.update(gl, scene); 143 | 144 | let compute = () => { 145 | shader.uniforms.time.value += 1 / 60; 146 | camera.update(gl, scene); 147 | }; 148 | 149 | cubeRtt.texture.mapping = CubeRefractionMapping; 150 | cubeRtt.texture.mapping = CubeReflectionMapping; 151 | cubeRtt.texture.encoding = sRGBEncoding; 152 | 153 | return { 154 | envMap: cubeRtt.texture, 155 | compute, 156 | }; 157 | }, [code]); 158 | 159 | let i = 0; 160 | useFrame(() => { 161 | if (i <= frames) { 162 | i++; 163 | compute(); 164 | } 165 | }); 166 | 167 | return envMap; 168 | } 169 | 170 | // 171 | -------------------------------------------------------------------------------- /vfx/utils/use-env-light.js: -------------------------------------------------------------------------------- 1 | import { useThree } from "@react-three/fiber"; 2 | import { useEffect } from "react"; 3 | import { useComputeEnvMap } from "./use-compute-env-map"; 4 | 5 | export function useEnvLight() { 6 | let { get } = useThree(); 7 | 8 | let envMap = useComputeEnvMap( 9 | /* glsl */ ` 10 | 11 | const float PI = 3.14159265; 12 | const float SCALE = 1.0; 13 | const mat3 m = mat3( 14 | cos(PI * SCALE), -sin(PI * SCALE), 0.0, 15 | sin(PI * SCALE), cos(PI * SCALE), 0.0, 16 | 0.0, 0.0, 1.0 17 | ); 18 | 19 | float noise( in vec3 p ) { 20 | return cos(p.x) * sin(p.y) * cos(p.z); 21 | } 22 | 23 | float fbm4( vec3 p ) { 24 | float f = 0.0; 25 | f += 0.5000 * noise( p ); p = m * p * 2.02; 26 | f += 0.2500 * noise( p ); p = m * p * 2.03; 27 | f += 0.1250 * noise( p ); p = m * p * 2.01; 28 | f += 0.0625 * noise( p ); 29 | return f / 0.9375; 30 | } 31 | 32 | float fbm6( vec3 p ) { 33 | float f = 0.0; 34 | f += 0.500000*(0.5 + 0.5 * noise( p )); p = m*p*2.02; 35 | f += 0.250000*(0.5 + 0.5 * noise( p )); p = m*p*2.03; 36 | f += 0.125000*(0.5 + 0.5 * noise( p )); p = m*p*2.01; 37 | f += 0.062500*(0.5 + 0.5 * noise( p )); p = m*p*2.04; 38 | f += 0.031250*(0.5 + 0.5 * noise( p )); p = m*p*2.01; 39 | f += 0.015625*(0.5 + 0.5 * noise( p )); 40 | return f/0.96875; 41 | } 42 | 43 | float pattern (vec3 p) { 44 | float vout = fbm4( p + time + fbm6( p + fbm4( p + time )) ); 45 | return abs(vout); 46 | } 47 | 48 | vec4 mainImage (vec2 uv, vec3 direction, vec3 pos) { 49 | return vec4(vec3( 50 | -0.2 + 1.0 - 1.0 * pow(pattern(direction.xyz + -0.15 * cos(time * 0.1)), 1.25), 51 | -0.2 + 1.0 - 1.0 * pow(pattern(direction.xyz + 0.0 * cos(time * 0.1)), 1.25), 52 | -0.2 + 1.0 - 1.0 * pow(pattern(direction.xyz + 0.15 * cos(time * 0.1)), 1.25) 53 | ), 1.0); 54 | } 55 | `.trim(), 56 | { 57 | // textureBG: { value: tex }, 58 | }, 59 | 64 60 | ); 61 | 62 | useEffect(() => { 63 | let { scene } = get(); 64 | scene.environment = envMap; 65 | return () => { 66 | scene.environment = null; 67 | }; 68 | }, [envMap]); 69 | 70 | return { envMap }; 71 | } 72 | -------------------------------------------------------------------------------- /vfx/utils/use-mini-engine.js: -------------------------------------------------------------------------------- 1 | import { useFrame, useThree } from "@react-three/fiber"; 2 | import { useEffect, useMemo } from "react"; 3 | import { Mini } from "../classes/Mini"; 4 | 5 | export function useMiniEngine() { 6 | const { get } = useThree(); 7 | const mini = useMemo(() => { 8 | return new Mini({}); 9 | }, []); 10 | 11 | useEffect(() => { 12 | return () => { 13 | mini.clean(); 14 | }; 15 | }, []); 16 | 17 | useFrame(() => { 18 | const st = get(); 19 | for (const kn in st) { 20 | mini.set(kn, st[kn]); 21 | } 22 | mini.work(); 23 | }); 24 | 25 | return { mini, get }; 26 | } 27 | --------------------------------------------------------------------------------