// @ts-nocheck /** OR */ /** @ ts-ignore */ /** OR */ /** @ ts-expect-error */ import { useRef, useEffect, useState } from "react" import * as THREE from "three" // import Stats from 'three/examples/jsm/libs/stats.module' import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' // import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' // import { CSS3DRenderer } from 'three/examples/jsm/renderers/CSS3DRenderer' // import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer' // types import type { Scene, Plane, Camera, Renderer, Object3D, AnimationMixer, LoadingManager } from "three" // import { TWEEN } from 'three/examples/jsm/libs/tween.module.min' import TWEEN from '@tweenjs/tween.js' // three.js joystick // import { JoystickControls, RotationJoystickControls } from 'three-joystick' // dat.gui import * as dat from 'dat.gui' // farmbot // import FarmBot from "~/components/farmbot/FarmBot" // console.log("FarmBot", FarmBot) // ================================================================ // TS interface IPostData { plugin_name: string, plugin_version: string, plugin_url: string, theme_uri: "light" | "dark", rest_url: string, world_id: number | string, scene_id: number | string, } interface IThreeDEnv { pluginName: string, pluginVersion: string, pluginURL: string, themeURI: "light" | "dark", restURL: string, worldID: number | string, sceneID: number | string, } interface IPlayer { action: string, actionTime: number | Date, object: Object3D, mixer: AnimationMixer, setAction: Function, getAction: Function, toggleAnimation: Function, move: Function, movePlayer: Function, playerControl: Function } // ================================================================ // SETUP BEGINS HERE // const toJSON = (proto: any) => { // const jsoned = {} // const toConvert = proto || this // Object.getOwnPropertyNames(toConvert).forEach((prop) => { // const val = toConvert[prop] // // do not include these // if (prop === 'toJSON' || prop === 'constructor') { // return // } // if (typeof val === 'function') { // jsoned[prop] = val.bind(jsoned) // return // } // jsoned[prop] = val // }) // const inherited = Object.getPrototypeOf(toConvert) // if (inherited !== null) { // Object.keys(toJSON(inherited)).forEach(key => { // if (!!jsoned[key] || key === 'constructor' || key === 'toJSON') // return // if (typeof inherited[key] === 'function') { // jsoned[key] = inherited[key].bind(jsoned) // return // } // jsoned[key] = inherited[key] // }); // } // return jsoned // } // PARAMETERS FROM PHP // console.log("window", window) // console.log(window.postdata) // const postdata = window?.postdata ? window.postdata : {} // const appVersion = process.env.npm_package_version const appVersion = require("../../../../../package.json").version // console.log("appVersion", appVersion) const postdata: IPostData = { plugin_name: "ThreeD Garden", plugin_version: appVersion, plugin_url: "https://garden.university.local/", theme_uri: "dark", rest_url: "https://garden.university.local/wp-json/wp/v2/", world_id: 1, scene_id: 1 } const env: IThreeDEnv = { pluginName: postdata.plugin_name, pluginVersion: postdata.plugin_version, pluginURL: postdata.plugin_url, themeURI: postdata.theme_uri, restURL: postdata.rest_url, worldID: postdata.world_id, sceneID: postdata.scene_id } console.log("pluginName", env.pluginName, env.pluginVersion) console.log("postdata", postdata) // INSTANTIATE COMMON VARIABLES const debug: boolean = false // const debugPhysics: boolean = false // STATS // const stats = Stats() // document.body.appendChild(stats.dom) // // DAT.GUI // const gui = new dat.GUI({ // name: "ThreeDGarden Controls", // autoPlace: true, // closeOnTop: true, // width: 180, // // closed: true, // // useLocalStorage: true, // }) // gui.domElement.id = "gui" // gui.close() // // folders // const guiFolderAnimation = gui.addFolder("Animation") // const guiFolderRotation = gui.addFolder("Rotation") // const guiFolderCameras = gui.addFolder("Camera") // const guiFolderLights = gui.addFolder("Lights") // const guiFolderAllotments = gui.addFolder("Allotments") // const guiFolderBeds = gui.addFolder("Beds") // const guiFolderPlants = gui.addFolder("Plants") // // const guiFolderInfospots = gui.addFolder("Infospots") // const guiFolderAnnotations = gui.addFolder("Annotations") // const guiFolderPlayer = gui.addFolder("Character") // ===================================================================== // THREE.JS ENVIRONMENT let scene: Scene let plane: Plane let camera: Camera let controls: any let renderer: Renderer let container: any let canvas: any const animations = {} let anims = ["Breathing Idle", "Driving", "Idle", "Left Turn", "Pointing", "Pointing Gesture"] anims = [...anims, "Right Turn", "Running", "Talking", "Turn", "Walking", "Walking Backwards"] // let anims2 = ["ascend-stairs", "gather-objects", "look-around", "push-button", "run"] // let tweens = [] // let cellSize = 16 // let interactive = false // let levelIndex = 0 // let _hints = 0 // let score = 0 // let cameraFade = 0.05 // let mute = false // let collect = [] const player: IPlayer = { action: "Idle", // player.action = "Idle" actionTime: Date.now(), // player.actionTime = Date.now() object: new THREE.Object3D(), mixer: new THREE.AnimationMixer(new THREE.Object3D()), move: () => { }, /** * PLAYER "CHARACTER" ACTIONS */ setAction(name: string) { const action = player.mixer.clipAction(animations[name]) action.time = 0 console.log("CHARACTER: action name", name) // console.log("CHARACTER: animations[name]", animations[name]) // console.log("CHARACTER: action object", action) player.mixer.stopAllAction() player.action = name player.actionTime = Date.now() // console.log("player", player) // action.fadeIn(0.5) // causes arms to move awkwardly action.play() }, getAction() { if (player === undefined || player.action === undefined) { return "doesn't exist yet" } return player.action }, toggleAnimation() { if (player.action === "Idle") { this.setAction("Pointing Gesture") } else { this.setAction("Idle") } }, movePlayer(dt: any) { const pos = player.object.position.clone() pos.y += 60 const dir = new THREE.Vector3() player.object.getWorldDirection(dir) if (player.move.forward < 0) dir.negate() let raycaster = new THREE.Raycaster(pos, dir) let blocked = false const { colliders } = params if (colliders !== undefined){ const intersect = raycaster.intersectObjects(colliders) if (intersect.length>0){ if (intersect[0].distance<50) blocked = true } } if (!blocked) { if (player.move.forward > 0) { const speed = (player.action === "Running") ? 24 : 8 player.object.translateZ(dt * speed) } else if (player.move.forward < 0) { player.object.translateZ(-dt * 2) } } // COLLIDERS if (colliders !== undefined) { // cast left dir.set(-1, 0, 0) dir.applyMatrix4(player.object.matrix) dir.normalize() raycaster = new THREE.Raycaster(pos, dir) let intersect = raycaster.intersectObjects(colliders) if (intersect.length > 0) { if (intersect[0].distance < 50) player.object.translateX(100 - intersect[0].distance) } // cast right dir.set(1, 0, 0) dir.applyMatrix4(player.object.matrix) dir.normalize() raycaster = new THREE.Raycaster(pos, dir) intersect = raycaster.intersectObjects(colliders) if (intersect.length > 0) { if (intersect[0].distance < 50) player.object.translateX(intersect[0].distance - 100) } // cast down dir.set(0, -1, 0) pos.y += 200 raycaster = new THREE.Raycaster(pos, dir) const gravity = 30 intersect = raycaster.intersectObjects(colliders) if (intersect.length > 0) { const targetY = pos.y - intersect[0].distance if (targetY > player.object.position.y) { // Going up player.object.position.y = 0.8 * player.object.position.y + 0.2 * targetY player.velocityY = 0 } else if (targetY < player.object.position.y) { // Falling if (player.velocityY === undefined) player.velocityY = 0 player.velocityY += dt * gravity player.object.position.y -= player.velocityY if (player.object.position.y < targetY) { player.velocityY = 0 player.object.position.y = targetY } } } else if (player.object.position.y > 0) { if (player.velocityY === undefined) player.velocityY = 0 player.velocityY += dt * gravity player.object.position.y -= player.velocityY if (player.object.position.y < 0) { player.velocityY = 0 player.object.position.y = 0 } } } // player.object.rotateY(player.move.turn * dt) }, playerControl(forward, turn) { turn = -turn if (forward > 0.2) { if (player.action !== "Walking" && player.action !== "Running") { this.setAction("Walking") } } else if (forward < -0.2) { if (player.action !== "Walking Backwards") { this.setAction("Walking Backwards") } } else { forward = 0 if (Math.abs(turn) > 0.05) { if (player.action !== "Left Turn") { this.setAction("Left Turn") } } else if (player.action !== "Idle") { this.setAction("Idle") } // else { // this.setAction("Idle") // } } // if ( forward === 0 && turn === 0 ) { // player.move = {} // } // else { player.move = { forward, turn } // } }, } // ===================================================================== // MESSAGES (to client) const messages = { text: [ "Welcome to your ThreeD Garden", "GO GROW!" ], index: 0 } // ===================================================================== // PARAMS (props) const params = { /** SET MODES */ mode: "", modes: Object.freeze({ NONE: "none", PRELOAD: "preload", INITIALIZING: "initializing", BUILDING: "building", BUILT: "built", LOADING: "loading", LOADED: "loaded", ACTIVE: "active", GAMEOVER: "game_over" }), /** turn on/off animation */ ANIMATE: true, // starting value /** where multimedia files are located */ assetsPath: `${env.pluginURL}assets/`, /** all the data from rest api calls to be stored here */ data: { world: [{ id: env.worldID }], scene: [{ id: env.sceneID }], allotment: [{}], bed: [{}], plant: [{}], planting_plan: [{}] }, /** POINTER HOVERS + CLICKS */ intersectedObject1: {}, intersectedObject2: {}, /** PLAYER COLLISION INTO OBJECTS */ colliders: [{}], // params.colliders.push(object3D) // town.fbx environment: {}, // custom fbx farmhouse: {}, } params.mode = params.modes.NONE console.log("params.mode", params.mode) // guiFolderAnimation.add(params, "ANIMATE").name("Run Animation") params.mode = params.modes.PRELOAD console.log("params.mode", params.mode) console.log("params", params) // // PARAMS.ASSETS ??? // // NEED TO LOAD AUDIO ASSET FILES ??? // const sfxExt = SFX.supportsAudioType('mp3') ? 'mp3' : 'ogg' // console.log("SFX", SFX) // // NEED TO LOAD KNOWN ASSET FILES ??? // const blobs = {'fish.gltf': blob1, 'diffuse.png': blob2, 'normal.png': blob3} ??? // const options = { // assets: [ // // `${params.assetsPath}sfx/gliss.${sfxExt}`, // // `${params.assetsPath}sfx/factory.${sfxExt}`, // // `${params.assetsPath}sfx/button.${sfxExt}`, // // `${params.assetsPath}sfx/door.${sfxExt}`, // // `${params.assetsPath}sfx/fan.${sfxExt}`, // `${params.assetsPath}fbx/environment.fbx`, // `${params.assetsPath}fbx/girl-walk.fbx`, // `${params.assetsPath}fbx/usb.fbx`, // ], // } // anims.forEach( function(anim){ // options.assets.push(`${params.assetsPath}fbx/anims2/${anim}.fbx`) // }) // console.log("options", options) /** TIME CLOCK */ const clock = new THREE.Clock() console.log("clock", clock) /** POINTER HOVERS + CLICKS */ const raycaster = new THREE.Raycaster() const raycaster2 = new THREE.Raycaster() const pointer = new THREE.Vector2() // create a Ray with origin at the pointer position and direction into the scene (camera direction) // const vector = new THREE.Vector3( pointer.x, pointer.y, 1 ) // projector.unprojectVector( vector, camera ) // const raycaster2 = new THREE.Raycaster( // event.target.camera.position, // vector.sub( event.target.camera.position ).normalize() // ) /** REST API URLS */ const API_URL_SCENES = `${env.restURL}scene/?_embed&per_page=100` const API_URL_ALLOTMENTS = `${env.restURL}allotment/?_embed&per_page=100` const API_URL_BEDS = `${env.restURL}bed/?_embed&per_page=100` const API_URL_PLANTING_PLANS = `${env.restURL}planting_plan/?_embed&per_page=100` const API_URL_PLANTS = `${env.restURL}plant/?_embed&per_page=100` const API_URLS = [ API_URL_SCENES, API_URL_ALLOTMENTS, API_URL_BEDS, API_URL_PLANTING_PLANS, API_URL_PLANTS ] // ================================================================ // LOGIC BEGINS HERE // three.js // LOADING MANAGER // :) APP EXECUTION BEGINS HERE <3 THREE.DefaultLoadingManager.onStart = function (url, itemsLoaded, itemsTotal) { console.log('Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.'); }; THREE.DefaultLoadingManager.onLoad = function () { console.log('Loading Complete!'); const startTime = new Date().toISOString() console.log("manager.onLoad", startTime) if (params.mode === params.modes.LOADING) { params.mode = params.modes.LOADED console.log("params.mode manager.onLoad", params.mode, startTime) player.setAction("Idle") animate() console.log("animating ****************************** ") params.mode = params.modes.ACTIVE console.log("params.mode manager.onLoad", params.mode, new Date().toISOString()) } else { console.log("still building ************************* ") console.log("params.mode manager.onLoad", params.mode, startTime) } }; THREE.DefaultLoadingManager.onProgress = function (url, itemsLoaded, itemsTotal) { console.log('Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.'); }; THREE.DefaultLoadingManager.onError = function (url) { console.log('There was an error loading ' + url); }; // const [manager, setManager] = useState(new THREE.LoadingManager()) const bootManager = () => { const manager = new THREE.LoadingManager() // const wtfayd = toJSON(manager) // console.log("HEY HEY HEY wtfayd", wtfayd) manager.onStart = (url, itemsLoaded, itemsTotal) => { console.log(`Started loading file: ${url}.\nLoaded ${itemsLoaded} of ${itemsTotal} files.`) } manager.onProgress = (url, itemsLoaded, itemsTotal) => { // console.log(`Loading file: ${url}.\nLoaded ${itemsLoaded} of ${itemsTotal} files.`) } manager.onError = (url) => { console.error(`There was an error loading ${url}`) } manager.onLoad = () => { const startTime = new Date().toISOString() console.log("manager.onLoad", startTime) // console.log('starting timer...') // const millis = Date.now() - startTime // console.log(`milliseconds elapsed = ${Math.floor(millis)}`) // console.log(`seconds elapsed = ${Math.floor(millis / 1000)}`) if (params.mode === params.modes.LOADING) { params.mode = params.modes.LOADED console.log("params.mode manager.onLoad", params.mode, startTime) player.setAction("Idle") animate() console.log("animating ****************************** ") params.mode = params.modes.ACTIVE console.log("params.mode manager.onLoad", params.mode, new Date().toISOString()) } else { console.log("still building ************************* ") console.log("params.mode manager.onLoad", params.mode, startTime) } } // } // const wtfayd2 = toJSON(manager) // console.log("HEY HEY HEY wtfayd2", wtfayd2) const loaders = { loaderFBX: new FBXLoader(manager), loaderGLTF: new GLTFLoader(manager), loaderOBJ: new OBJLoader(manager), loaderTexture: new THREE.TextureLoader(manager), } return (
BEGIN BOOT PROCESS
) } // ================================================================== // LOADERS // ================================================================== // FUNCTIONS // render scene + camera const render = () => { renderer.render(scene, camera) } // watch for window resize, then adjust canvas appropriately const onWindowResize = () => { console.log("window resize to: ", window.innerWidth, window.innerHeight) camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) // controls.handleResize() or something similar to update controls render() } // (now using vueuse useEventListener) ... // watch for window resize, then adjust canvas appropriately // window.addEventListener( 'resize', onWindowResize, false ) const getPlane = (x, y, color1) => { const geometry = new THREE.PlaneGeometry(x, y) const material = new THREE.MeshStandardMaterial({ color: color1, side: THREE.DoubleSide }) const mesh = new THREE.Mesh(geometry, material) mesh.receiveShadow = true return mesh } const getPointLight = (color, intensity) => { let light = new THREE.PointLight(color, intensity) light.castShadow = true light.shadow.bias = 0.001 light.shadow.mapSize.width = 4096 //default = 1024 light.shadow.mapSize.height = 4096 //default = 1024 return light } const getSpotLight = (color, intensity) => { let light = new THREE.SpotLight(color, intensity) light.castShadow = true light.shadow.bias = 0.001 light.shadow.mapSize.width = 2048 //default = 1024 light.shadow.mapSize.height = 2048 //default = 1024 return light } const getDirectionalLight = (color, intensity) => { let light = new THREE.DirectionalLight(color, intensity) light.castShadow = true light.shadow.bias = 0.0001 light.shadow.mapSize.width = 4096 //default = 512 light.shadow.mapSize.height = 4096 //default = 512 light.shadow.camera.left = -1000 //default = -5 light.shadow.camera.bottom = -1000 //default = -5 light.shadow.camera.right = 1000 //default = 5 light.shadow.camera.top = 1000 //default = 5 light.shadow.camera.near = 0.5 // default light.shadow.camera.far = 500 // default return light } const getAmbientLight = (color, intensity) => { let light = new THREE.AmbientLight(color, intensity) return light } const getGeometry = (shape, x, y, z, color) => { let geometry let material let mesh switch (shape) { case "Box": geometry = new THREE.BoxGeometry(x, y, z) // let opacMaterial = new THREE.MeshStandardMaterial({ // transparent: true, // opacity: 0.0, // alphaTest: 1.0, // color: color, // side: THREE.DoubleSide, // depthWrite: false // }) material = new THREE.MeshStandardMaterial({ transparent: true, opacity: 0.8, color: color, side: THREE.DoubleSide, depthWrite: true }) mesh = new THREE.Mesh( geometry, [ material, material, material, material ] ) mesh.castShadow = true break case "Cone": geometry = new THREE.ConeGeometry(x / 2, y / 2, z, 32, 1, true) material = new THREE.MeshStandardMaterial({ color: color, side: THREE.DoubleSide }) mesh = new THREE.Mesh(geometry, material) mesh.castShadow = true mesh.rotation.x = Math.PI / 2 // 90 degrees in radians break case "Cylinder": geometry = new THREE.CylinderGeometry(x / 2, y / 2, z, 32, 1, true) material = new THREE.MeshStandardMaterial({ color: color, side: THREE.DoubleSide }) mesh = new THREE.Mesh(geometry, material) mesh.castShadow = true mesh.rotation.x = Math.PI / 2 // 90 degrees in radians break case "InfoSphere": geometry = new THREE.SphereGeometry(x, y, z) material = new THREE.MeshStandardMaterial({ color: color, side: THREE.DoubleSide }) mesh = new THREE.Mesh(geometry, material) mesh.castShadow = true //mesh.rotation.x = Math.PI / 2 // 90 degrees in radians break case "Sphere": geometry = new THREE.SphereGeometry(x, y, z) material = new THREE.MeshStandardMaterial({ color: color, side: THREE.DoubleSide }) mesh = new THREE.Mesh(geometry, material) mesh.castShadow = true //mesh.rotation.x = Math.PI / 2 // 90 degrees in radians break // case "Tree": // let tree = new THREE.Tree({ // generations : 3, // # for branch hierarchy // length : 1.0, // length of root branch // uvLength : 3.0, // uv.v ratio against geometry length (recommended is generations * length) // radius : 0.1, // radius of root branch // radiusSegments : 8, // # of radius segments for each branch geometry // heightSegments : 8 // # of height segments for each branch geometry // }) // geometry = THREE.TreeGeometry.build(tree) // //geometry = new THREE.SphereGeometry(x, y, z) // material = new THREE.MeshStandardMaterial({ // color: color, // side: THREE.DoubleSide // }) // mesh = new THREE.Mesh(geometry, material) // mesh.castShadow = true // //mesh.rotation.x = Math.PI / 2 // 90 degrees in radians // break case "Bush": // [MM] // CAST geometry = new THREE.BoxGeometry(x, y, z) //color = new THREE.Color(0xff0000) color = new THREE.Color("rgb(153,90,0)") // material = new THREE.MeshPhongMaterial({ color: color, wireframe: false }) // material = new THREE.MeshStandardMaterial({ // transparent: true, // opacity: 0.8, // color: color, // side: THREE.DoubleSide, // depthWrite: true // }) //mesh = new THREE.Mesh(geometry, material) // mesh = new THREE.Mesh( // geometry, // [ // material, material, // material, material // ] // ) // mesh.castShadow = true // [MM] //plane.add(mesh) // mesh.matrix.makeTranslation(0,-125,0) // mesh.matrixAutoUpdate = false var levels = 4 // slow? lower this var edge_w = 100 var edge_h = 150 function bush(n, mat, c) { if (n > 0) { var new_mat = new THREE.Matrix4() var new_mat2 = new THREE.Matrix4() var new_mat_t0 = new THREE.Matrix4() var new_mat_t = new THREE.Matrix4() var new_mat_r = new THREE.Matrix4() var new_mat_r2 = new THREE.Matrix4() var new_mat_s = new THREE.Matrix4() var mat2 = mat.clone() var col1 = c.clone() var col2 = c.clone() //col1.offsetHSL(0.12,0,0) col1.g += 0.64 / levels material = new THREE.MeshPhongMaterial({ color: col1, wireframe: false }) mesh = new THREE.Mesh(geometry, material) new_mat_t0.makeTranslation(edge_w / 2, 0, 0) new_mat_t.makeTranslation(0, edge_h, 0) new_mat_r.makeRotationZ(-Math.PI / 4) new_mat_r2.makeRotationY(Math.PI / 2) new_mat_s.makeScale(0.75, 0.75, 0.75) new_mat.multiply(new_mat_r2) // new_mat.multiply(new_mat_t0) new_mat.multiply(new_mat_r) new_mat.multiply(new_mat_s) new_mat.multiply(new_mat_t) new_mat.multiply(mat) mesh.matrix.copy(new_mat) mesh.matrixAutoUpdate = false mesh.updateMatrix = false // plane.add(mesh) bush(n - 1, mesh.matrix.clone(), col1) //col2.offsetHSL(0.12,0,0) col2.g += 0.64 / levels material = new THREE.MeshPhongMaterial({ color: col2, wireframe: false }) mesh = new THREE.Mesh(geometry, material) new_mat_t0.makeTranslation(-edge_w / 2, 0, 0) new_mat_t.makeTranslation(0, edge_h, 0) new_mat_r.makeRotationZ(Math.PI / 4) new_mat_r2.makeRotationY(Math.PI / 2) new_mat_s.makeScale(0.75, 0.75, 0.75) new_mat2.multiply(new_mat_r2) new_mat2.multiply(new_mat_t0) new_mat2.multiply(new_mat_r) new_mat2.multiply(new_mat_s) new_mat2.multiply(new_mat_t) new_mat2.multiply(mat) mesh.matrix.copy(new_mat2) mesh.matrixAutoUpdate = false mesh.updateMatrix = false // plane.add(mesh) bush(n - 1, mesh.matrix.clone(), col2) } } // [MM] //bush(levels, mesh.matrix, color) default: geometry = new THREE.BoxGeometry(x, y, z) material = new THREE.MeshStandardMaterial({ color: color, side: THREE.DoubleSide }) mesh = new THREE.Mesh(geometry, material) mesh.castShadow = true break } return mesh } // LOADERS function loadTown() { loaders.loaderFBX.load(`${params.assetsPath}fbx/town.fbx`, function (object) { params.environment = object params.colliders = [] object.scale.set(0.025, 0.025, 0.025) plane.add(object) object.traverse(function (child) { if (child.isMesh) { if (child.name.startsWith("proxy")) { params.colliders.push(child) child.material.visible = false } else { child.castShadow = true child.receiveShadow = true } } }) loadNextAnim(loader) }) } function loadFarmHouse() { // loaders.loaderFBX.load(`${params.assetsPath}fbx/SM_Bld_Farmhouse_01.fbx`, function(object){ loaders.loaderFBX.load(`${params.assetsPath}fbx/Building_Farm_House_02.fbx`, function (object) { // loaders.loaderFBX.load(`${params.assetsPath}fbx/Building_Barn_Big_03.fbx`, function(object){ params.farmhouse = object params.colliders = [] object.rotation.y = 270 * (Math.PI / 180) // 90 degrees in radians object.rotation.z = 270 * (Math.PI / 180) // 90 degrees in radians object.position.set(0, -100, 0) // object.scale.set(0.025, 0.025, 0.025) object.scale.set(2.2, 2.2, 2.2) plane.add(object) object.traverse(function (child) { if (child.isMesh) { if (child.name.startsWith("proxy")) { params.colliders.push(child) child.material.visible = false } else { child.castShadow = true child.receiveShadow = true } } }) // loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_01_A.png`, function(texture) { loaderTexture.load(`${params.assetsPath}textures/SimpleFarm.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { child.material.map = texture } }) }) //loadNextAnim(loader) }) } function loadFarmHouseGLTF() { // loaders.loaderFBX.load( `${params.assetsPath}fbx/Building_Farm_House_02.fbx`, function (object) { loaderGLTF.load(`${params.assetsPath}gltf/Residential House.glb`, function (object) { let model = object.scene model.name = "Farm House" model.position.set(0, 0, 100) model.scale.set(20, 20, 20) model.traverse(function (child) { if (child.isMesh) child.castShadow = true }) plane.add(model) helper = new THREE.SkeletonHelper(model) helper.material.linewidth = 5 helper.visible = true plane.add(helper) console.log("loadFarmHouseGLTF object", object) console.log("loadFarmHouseGLTF model", model) guiFolderPlayer.add(model, "visible").name("Show House").listen() }) } function loadCoop() { loaders.loaderFBX.load(`${params.assetsPath}fbx/Prop_Chicken_Coop_02.fbx`, function (object) { params.farmhouse = object params.colliders = [] object.rotation.x = 180 * (Math.PI / 180) // 90 degrees in radians object.rotation.y = 90 * (Math.PI / 180) // 90 degrees in radians object.rotation.z = 270 * (Math.PI / 180) // 90 degrees in radians object.position.set(80, 0, 0) object.scale.set(2.2, 2.2, 2.2) plane.add(object) object.traverse(function (child) { if (child.isMesh) { if (child.name.startsWith("proxy")) { params.colliders.push(child) child.material.visible = false } else { child.castShadow = true child.receiveShadow = true } } }) loaderTexture.load(`${params.assetsPath}textures/SimpleFarm.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { child.material.map = texture } }) }) }) } function loadChicken() { loaderGLTF.load(`${params.assetsPath}gltf/Chicken.glb`, function (object) { let model = object.scene model.name = "Chicken GLB" model.position.set(-3, 0, 0) model.rotation.x = 90 * (Math.PI / 180) // 90 degrees in radians model.scale.set(4, 4, 4) model.traverse(function (child) { if (child.isMesh) child.castShadow = true }) plane.add(model) // helper = new THREE.SkeletonHelper(model) // helper.material.linewidth = 5 // helper.visible = true // plane.add(helper) console.log("loadChicken object", object) console.log("loadChicken model", model) //guiFolderPlayer.add(model, "visible").name("Show Chicken").listen() }) } function loadChicken0() { loaders.loaderFBX.load(`${params.assetsPath}fbx/Chicken.fbx`, function (object) { console.log("BIRD----------------") console.log(object) //params.farmhouse = object //params.colliders = [] //object.rotation.y = 90 * (Math.PI/180) // 90 degrees in radians object.position.set(0, 0, 0) //object.scale.set(2.2, 2.2, 2.2) plane.add(object) object.traverse(function (child) { if (child.isMesh) { // if (child.name.startsWith("proxy")){ // params.colliders.push(child) // child.material.visible = false // }else{ child.castShadow = true child.receiveShadow = true //} } }) // loaderTexture.load(`${params.assetsPath}textures/SimpleAnimalsFarm.png`, function(texture) { // object.traverse( function ( child ) { // if ( child.isMesh ){ // child.material.map = texture // } // } ) // }) }) } function loadChicken1() { loaders.loaderFBX.load(`${params.assetsPath}fbx/SA_Animal_Birds.fbx`, function (object) { console.log("BIRD----------------") console.log(object) //params.farmhouse = object //params.colliders = [] //object.rotation.y = 90 * (Math.PI/180) // 90 degrees in radians object.position.set(0, 0, 0) //object.scale.set(2.2, 2.2, 2.2) plane.add(object) object.traverse(function (child) { if (child.isMesh) { // if (child.name.startsWith("proxy")){ // params.colliders.push(child) // child.material.visible = false // }else{ child.castShadow = true child.receiveShadow = true //} } }) loaderTexture.load(`${params.assetsPath}textures/SimpleAnimalsFarm.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { child.material.map = texture } }) }) }) } function loadChicken2() { loaders.loaderFBX.load(`${params.assetsPath}fbx/SA_Animal_Pig.fbx`, function (object) { // loaders.loaderFBX.load( `${params.assetsPath}fbx/people/Trucker.fbx`, function (object) { // loaders.loaderFBX.load( `${params.assetsPath}characters/SK_Chr_Farmer_Male_01.fbx`, function (object) { console.log("object----------------") console.log(object) // object.mixer = new THREE.AnimationMixer( object ) // mixers.push( object.mixer ) // var action = object.mixer.clipAction( object.animations[ 0 ] ) // action.play() // plane.add( object ) /* object.mixer = new THREE.AnimationMixer( object ) mixers.push( object.mixer ) var action = object.mixer.clipAction( object.animations[ 0 ] ) action.play() object.name = "Chicken" object.traverse( function ( child ) { if ( child.isMesh ) { child.castShadow = true child.receiveShadow = false } } ) loaderTexture.load(`${params.assetsPath}textures/SimpleAnimalsFarm.png`, function(texture) { //loaderTexture.load(`${params.assetsPath}images/SimpleScarecrow.png`, function(texture) { //loaderTexture.load(`${params.assetsPath}images/SimpleFarmer_Farmer_Brown.png`, function(texture) { //loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_01_A.png`, function(texture) { object.traverse( function ( child ) { if ( child.isMesh ){ child.material.map = texture } } ) }) plane.add( object ) console.log("-----------------------") console.log("object----------------") console.log(object) console.log("-----------------------") */ /* player.mixer = object.mixer player.root = object.mixer.getRoot() object.name = "Chicken" object.traverse( function ( child ) { if ( child.isMesh ) { child.castShadow = true child.receiveShadow = false } } ) loaderTexture.load(`${params.assetsPath}textures/SimpleAnimalsFarm.png`, function(texture) { //loaderTexture.load(`${params.assetsPath}images/SimpleScarecrow.png`, function(texture) { //loaderTexture.load(`${params.assetsPath}images/SimpleFarmer_Farmer_Brown.png`, function(texture) { //loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_01_A.png`, function(texture) { object.traverse( function ( child ) { if ( child.isMesh ){ child.material.map = texture } } ) }) console.log("-----------------------") console.log("object----------------") console.log(object) console.log("-----------------------") player.object = new THREE.Object3D() player.object.add(object) player.object.scale.set(0.022, 0.022, 0.022) player.object.rotation.x = Math.PI/2 // 90 degrees in radians player.mixer.clipAction(object.animations[0]).play() animations.Idle = object.animations[0] //setAction("Idle") plane.add(player.object) guiFolderPlayer.add(player.object, "visible").name("Show Chicken").listen() console.log("-----------------------") console.log("player.object----------------") console.log(player.object) console.log("-----------------------") */ }) } // NOT USED or TESTED function loadChickenGLTF() { loaderGLTF.load(`${params.assetsPath}gltf/Animals.glb`, function (object) { console.log("Animals object----------------") console.log(object) object.mixer = new THREE.AnimationMixer(object.scene) player.mixer = object.mixer player.root = object.mixer.getRoot() object.name = "Chicken Dance" object.scene.traverse(function (child) { if (child.isMesh) { child.castShadow = true child.receiveShadow = false } }) player.object = new THREE.Object3D() player.object.add(object.scene) player.object.position.set(0, 0, 10) player.object.scale.set(4, 4, 4) player.object.rotation.x = Math.PI / 2 // 90 degrees in radians player.mixer.timeScale = 0.5 player.mixer.clipAction(object.animations[2]).play() //animations.Idle = object.animations[0] //setAction("Idle") plane.add(player.object) //guiFolderPlayer.add(player.object, "visible").name("Show Character").listen() }) } // // NOT USED or TESTED function loadChickGLTF() { loaderGLTF.load(`${params.assetsPath}gltf/Chick.glb`, function (object) { let model = object.scene model.name = "Chick GLB" model.position.set(3, 0, 0) //model.rotation.y = 90 * (Math.PI/180) // 90 degrees in radians model.scale.set(2, 2, 2) model.traverse(function (child) { if (child.isMesh) child.castShadow = true }) plane.add(model) // helper = new THREE.SkeletonHelper(model) // helper.material.linewidth = 5 // helper.visible = true // plane.add(helper) console.log("loadChickGLTF object") console.log(object) console.log("loadChickGLTF model") console.log(model) //guiFolderPlayer.add(model, "visible").name("Show Chicken").listen() }) } // // NOT USED or TESTED function loadHen() { loaders.loaderFBX.load(`${params.assetsPath}Hen&Chicken_FBX/Hen_HP.fbx`, function (object) { params.farmhouse = object params.colliders = [] //object.rotation.y = 270 * (Math.PI/180) // 90 degrees in radians object.position.set(3, 0, 0) object.scale.set(0.05, 0.05, 0.05) object.traverse(function (child) { if (child.isMesh) { if (child.name.startsWith("proxy")) { params.colliders.push(child) child.material.visible = false } else { child.castShadow = true child.receiveShadow = true } } }) loaderTexture.load(`${params.assetsPath}Hen&Chicken_FBX/Textures/Hen&Chicken_A.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { child.material.map = texture console.log("loadHen child----------") console.log(child) console.log(child.geometry.attributes.uv) console.log("-----------------------") } }) }) console.log("loadHen object----------------") console.log(object) plane.add(object) }) } function loadHenGLTF() { // loaders.loaderFBX.load( `${params.assetsPath}fbx/Building_Farm_House_02.fbx`, function (object) { loaderGLTF.load(`${params.assetsPath}gltf/Hen_HP.glb`, function (object) { let model = object.scene //model.name = "Hen" //model.position.set(10, 0, 0) //model.scale.set(0.2, 0.2, 0.2) model.traverse(function (child) { if (child.isMesh) child.castShadow = true }) plane.add(model) // helper = new THREE.SkeletonHelper(model) // helper.material.linewidth = 5 // helper.visible = true // plane.add(helper) console.log("loadHenGLTF object----------------") console.log(object) console.log("loadHenGLTF model----------------") console.log(model) //guiFolderPlayer.add(model, "visible").name("Show Hen GLTF").listen() }) } function loadKitchenSink() { loaders.loaderFBX.load(`${params.assetsPath}fbx/Prop_KitchenSink_Black.fbx`, function (object) { params.farmhouse = object params.colliders = [] object.rotation.y = 270 * (Math.PI / 180) // 90 degrees in radians object.position.set(0, 0, 10) //object.scale.set(0.025, 0.025, 0.025) object.scale.set(2.2, 2.2, 2.2) plane.add(object) object.traverse(function (child) { if (child.isMesh) { if (child.name.startsWith("proxy")) { params.colliders.push(child) child.material.visible = false } else { child.castShadow = true child.receiveShadow = true } } }) //loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_01_A.png`, function(texture) { loaderTexture.load(`${params.assetsPath}textures/SimpleInteriorsHouses.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { child.material.map = texture } }) }) }) } function loadChickenFree() { loaderOBJ.load(`${params.assetsPath}obj/chicken_01.obj`, function (object) { // params.farmhouse = object // params.colliders = [] //object.rotation.y = 270 * (Math.PI/180) // 90 degrees in radians //object.position.set(0, 0, 10) //object.scale.set(0.025, 0.025, 0.025) //object.scale.set(2.2, 2.2, 2.2) plane.add(object) // object.traverse( function ( child ) { // if ( child.isMesh ) { // if (child.name.startsWith("proxy")){ // params.colliders.push(child) // child.material.visible = false // }else{ // child.castShadow = true // child.receiveShadow = true // } // } // } ) // //loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_01_A.png`, function(texture) { // loaderTexture.load(`${params.assetsPath}textures/SimpleInteriorsHouses.png`, function(texture) { // object.traverse( function ( child ) { // if ( child.isMesh ){ // child.material.map = texture // } // } ) // }) }) } function loadRooster() { loaders.loaderFBX.load(`${params.assetsPath}fbx/rooster_1.0.1.fbx`, function (object) { // params.farmhouse = object // params.colliders = [] //object.rotation.y = 270 * (Math.PI/180) // 90 degrees in radians object.position.set(0, 0, 10) object.scale.set(0.025, 0.025, 0.025) //object.scale.set(2.2, 2.2, 2.2) plane.add(object) // object.traverse( function ( child ) { // if ( child.isMesh ) { // if (child.name.startsWith("proxy")){ // params.colliders.push(child) // child.material.visible = false // }else{ // child.castShadow = true // child.receiveShadow = true // } // } // } ) // //loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_01_A.png`, function(texture) { // loaderTexture.load(`${params.assetsPath}textures/SimpleInteriorsHouses.png`, function(texture) { // object.traverse( function ( child ) { // if ( child.isMesh ){ // child.material.map = texture // } // } ) // }) }) } // LOAD ROAD function loadRoad() { let i let count = 8 let startX = -45 let offsetX = 0 let startZ = -138 let offsetZ = 20 const roadPromise1 = new Promise((resolve, reject) => { // ROAD A for (i = 1; i <= count; i++) { loaders.loaderFBX.load(`${params.assetsPath}fbx/SM_Env_Road_Gravel_Straight_01.fbx`, function (object) { // console.log("ROAD object", object) //params.farmhouse = object //params.colliders = [] object.rotation.x = 90 * (Math.PI / 180) // 90 degrees in radians object.position.set(startX, startZ, 0) startX = startX + offsetX startZ = startZ + offsetZ console.log("ROAD A startX, startZ", startX, startZ) object.scale.set(0.02, 0.01, 0.02) object.traverse(function (child) { if (child.isMesh) { // if (child.name.startsWith("proxy")) { // params.colliders.push(child) // child.material.visible = false // } else { child.castShadow = true child.receiveShadow = true // } } }) loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_03_A.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { //child.material.color.setHex(0x000000) child.material.transparent = true child.material.opacity = 0.7 //child.material.depthWrite = true child.material.map = texture } }) }) plane.add(object) //console.log("ROAD A object", object) }) } resolve(startX, startZ) }) roadPromise1.then((startX, startZ) => { // ROAD T for (i = 1; i <= 1; i++) { loaders.loaderFBX.load(`${params.assetsPath}fbx/SM_Env_Road_Gravel_T_Section_01.fbx`, function (object) { console.log("ROAD T startX, startZ", startX, startZ) //params.farmhouse = object //params.colliders = [] //object.rotation.y = 90 * (Math.PI/180) // 90 degrees in radians object.position.set(startX, 0, startZ) startX = startX + offsetX startZ = startZ + offsetZ console.log("ROAD T startX, startZ", startX, startZ) object.scale.set(0.02, 0.01, 0.02) object.traverse(function (child) { if (child.isMesh) { // if (child.name.startsWith("proxy")) { // params.colliders.push(child) // child.material.visible = false // } else { child.castShadow = true child.receiveShadow = true // } } }) loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_03_A.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { //child.material.color.setHex(0x000000) child.material.transparent = true child.material.opacity = 0.7 //child.material.depthWrite = true child.material.map = texture } }) }) plane.add(object) //console.log("ROAD T object", object) }) } }) } /** * POINTER HOVERS + CLICKS */ // when the pointer moves and hovers function watchPointer(camera: Camera, targetList) { //console.log("targetList", targetList) // update the picking ray with the camera and pointer position raycaster.setFromCamera(pointer, camera) //raycaster.set( camera.getWorldPosition(), camera.getWorldDirection() ) //let helper2 = new THREE.CameraHelper(directionalLight.shadow.camera) // calculate objects intersecting the picking ray //const intersects = raycaster.intersectObjects(targetList, true) let intersects = [] try { intersects = raycaster.intersectObjects(targetList, true) } catch (e) { intersects = [] } // if there is one (or more) intersections if (intersects.length > 0) { // console.log("INTERSECTS", intersects) // return // do something to object intersected? (testing purposes only) // for (let i = 0;i < intersects.length;i++) { // // hightlight object // for (let j = 0;j < intersects[i].object.material.length;j++) { // intersects[i].object.material[j].color.setHex( 0xff0000 ) // } // } // if the closest object intersected is not the currently stored intersection object if (intersects[0].object !== params.intersectedObject1) { // restore previous intersection object (if it exists) to its original color if (params.intersectedObject1) { if (params.intersectedObject1.material.constructor.name === "Array") { for (let i = 0; i < params.intersectedObject1.material.length; i++) { params.intersectedObject1.material[i].color.setHex(params.intersectedObject1.currentHex) } } else { params.intersectedObject1.material.color.setHex(params.intersectedObject1.currentHex) } } // store reference to closest object as current intersection object params.intersectedObject1 = intersects[0].object // console.log("params.intersectedObject1, params.intersectedObject1) if (params.intersectedObject1.material.constructor.name === "Array") { // SEPARATE FOR LOOPS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // store color of closest object (for later restoration) for (let i = 0; i < params.intersectedObject1.material.length; i++) { params.intersectedObject1.currentHex = params.intersectedObject1.material[i].color.getHex() } // set a new color for closest object for (let i = 0; i < params.intersectedObject1.material.length; i++) { params.intersectedObject1.material[i].color.setHex(0xdddd00) } // SEPARATE FOR LOOPS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! } else { // store color of closest object (for later restoration) params.intersectedObject1.currentHex = params.intersectedObject1.material.color.getHex() // set a new color for closest object params.intersectedObject1.material.color.setHex(0xdddd00) } } } // there are no intersections else { // restore previous intersection object (if it exists) to its original color if (params.intersectedObject1) { if (params.intersectedObject1.material.constructor.name === "Array") { for (let i = 0; i < params.intersectedObject1.material.length; i++) { params.intersectedObject1.material[i].color.setHex(params.intersectedObject1.currentHex) } } else { params.intersectedObject1.material.color.setHex(params.intersectedObject1.currentHex) } } // remove previous intersection object reference // by setting current intersection object to "nothing" params.intersectedObject1 = null } } // when the pointer moves, call the given function //document.addEventListener( "pointermove", onPointerMove, false ) function onPointerMove(event) { // the following line would stop any other event handler from firing // (such as the pointer's TrackballControls) // event.preventDefault() // update the pointer variable // pointer.x = (event.clientX / window.innerWidth) * 2 - 1 // pointer.y = -(event.clientY / window.innerHeight) * 2 + 1 // pointer.x = (event.offsetX / (window.innerWidth - 240)) * 2 - 1 // pointer.y = -(event.offsetY / (window.innerHeight - 100)) * 2 + 1 pointer.x = (event.offsetX / canvas.clientWidth) * 2 - 1 pointer.y = -(event.offsetY / canvas.clientHeight) * 2 + 1 // console.log("pointer hover, pointer.x, pointer.y) // probably shouldn't log this } // when the pointer moves, call the given function // document.addEventListener( "pointerdown", onPointerDown, false ) function onPointerDown(event) { console.log("event ****************************************", event) // the following line would stop any other event handler from firing // (such as the pointer's TrackballControls) event.preventDefault() // update the pointer variable // pointer.x = (event.clientX / window.innerWidth) * 2 - 1 // pointer.y = -(event.clientY / window.innerHeight) * 2 + 1 // pointer.x = (event.offsetX / (window.innerWidth - 240)) * 2 - 1 // pointer.y = -(event.offsetY / (window.innerHeight - 100)) * 2 + 1 pointer.x = (event.offsetX / canvas.clientWidth) * 2 - 1 pointer.y = -(event.offsetY / canvas.clientHeight) * 2 + 1 console.log("pointer clicked x y", pointer.x, pointer.y) // find intersections raycaster2.setFromCamera(pointer, event.target.camera) // raycaster2.set( // event.target.camera.getWorldPosition(), // event.target.camera.getWorldDirection() // ) console.log("raycaster2", raycaster2) // create an array containing all objects in the scene with which the raycaster2 intersects //var intersects = raycaster2.intersectObjects(event.target.targetList) const intersects = raycaster2.intersectObjects(event.target.targetList) console.log("intersects", intersects) // if there is one (or more) intersections if (intersects.length > 0) { //console.log("Hit @ " + xyzToString( intersects[0].point ) ) // change the color of the closest face. // intersects[0].face.color.setRGB( 0.8 * Math.random() + 0.2, 0, 0 ) // intersects[0].object.geometry.colorsNeedUpdate = true // if the closest object intersected is not the currently stored intersection object const theIntersectedObject = intersects[0].object // for testing only // if ( theIntersectedObject !== params.intersectedObject2 ) { // console.log("-----------------------------") // console.log("params.intersectedObject2 null------------") // console.log("theIntersectedObject NEW--------") // console.log(theIntersectedObject) // console.log("-----------------------------") // } // else { // console.log("-----------------------------") // console.log("params.intersectedObject2 already stored--") // console.log("theIntersectedObject -----------") // console.log(theIntersectedObject) // console.log("-----------------------------") // } // restore previous intersection object (if it exists) to its original color if (params.intersectedObject2) { //params.intersectedObject2.material[i].color.setHex( params.intersectedObject2.currentHex ) // zoom out //panCam(100, 200, 200, 800, event.target.camera, event.target.controls) } else { // zoom in //panCam(params.intersectedObject2.position.x, params.intersectedObject2.position.y, params.intersectedObject2.position.z, 800, event.target.camera, event.target.controls) } // store reference to closest object as current intersection object params.intersectedObject2 = theIntersectedObject // store color of closest object (for later restoration) //params.intersectedObject2.currentHex = params.intersectedObject2.material.color.getHex() // set a new color for closest object //params.intersectedObject2.material.color.setHex( 0xff0000 ) // point the camera controls to the intersected object? //event.target.controls.reset() //event.target.controls.target = new THREE.Vector3(params.intersectedObject2.position.x, params.intersectedObject2.position.y, params.intersectedObject2.position.z) //event.target.camera.position.set(100, 200, 200) // if (event.button === 2) { // // zoom in // panCam(params.intersectedObject2.position.x, params.intersectedObject2.position.y, params.intersectedObject2.position.z, 1200, event.target.camera, event.target.controls) // } else if (event.button === 1) { // // zoom out // panCam(100, 200, 200, 1200, event.target.camera, event.target.controls) // } // console.log("------------------") // console.log("event.target.controls--------") // console.log(event.target.controls) // console.log("------------------") // show/hide infospheres if (params.intersectedObject2.userData.type === "structure" && event.button === 0) { let infospotObject = scene.getObjectByName(`INFOSPOT: ${params.intersectedObject2.name}`) // , true for recursive if (infospotObject) { if (infospotObject.visible === true) { infospotObject.visible = false } else { infospotObject.visible = true } } // console.log("infospotObject", infospotObject) } // show/hide annotations params.intersectedObject2.children.forEach(function (key) { // console.log("--------------------------------------") // console.log("key (pre-process)------") // console.log(`key.type: ${key.type}`) // console.log(`key.visible: ${key.visible}`) // console.log(`key.element.hidden: ${key.element.hidden}`) // console.log(key) // console.log("--------------------------------------") // if ( key.type === "Sprite" && event.button === 1 ) { // if (key.visible === true) { // key.visible = false // } // else { // key.visible = true // } // } if (key.type === "Object3D" && event.button === 0) { if (key.element.hidden === true) { //if (key.visible === false) { // console.log("-------------------------") // console.log("TRUE------") // console.log(key.element.hidden) // console.log("-------------------------") key.element.hidden = false key.element.style.display = "block" key.visible = true // does nothing, but keeps status accurate } else { // console.log("-------------------------") // console.log("FALSE------") // console.log(key.element.hidden) // console.log("-------------------------") key.element.hidden = true key.element.style.display = "none" key.visible = false // does nothing, but keeps status accurate } // console.log("--------------------------------------") // console.log("key (post-process)------") // console.log(`key.type: ${key.type}`) // console.log(`key.visible: ${key.visible}`) // console.log(`key.element.hidden: ${key.element.hidden}`) // console.log(key) // console.log("--------------------------------------") } }) // if ( params.intersectedObject2.userData.annotation ) { // console.log("ANNOTATION", params.intersectedObject2.userData.annotation) // } // else { // console.log("ANNOTATION?", params.intersectedObject2.userData) // } } else // there are no intersections { // restore previous intersection object (if it exists) to its original color if (params.intersectedObject2) { //params.intersectedObject2.material.color.setHex( params.intersectedObject2.currentHex ) } // remove previous intersection object reference by setting current intersection object to "nothing" params.intersectedObject2 = null } } // OR // document.addEventListener( "mousedown", onDocumentMouseDown, false ) function onDocumentMouseDown(e) { e.preventDefault(); var mouseVector = new THREE.Vector3( (e.clientX / window.innerWidth) * 2 - 1, - (e.clientY / window.innerHeight) * 2 + 1, 1 ); projector.unprojectVector(mouseVector, camera); var raycaster = new THREE.Raycaster(camera.position, mouseVector.subSelf(camera.position).normalize()); // create an array containing all objects in the scene with which the ray intersects var intersects = raycaster.intersectObjects(scene.children); console.log(intersects); if (intersects.length > 0) { console.log("Intersected object:", intersects.length); intersects[0].object.material.color.setHex(Math.random() * 0xffffff); } } /** * GET FEATURED IMAGE */ function getFeaturedImage(postObject) { let featImage = {} // If there is no featured image, exit the function returning blank. if (0 === postObject.featured_media) { return featImage } else { featImage.featuredObject = postObject._embedded["wp:featuredmedia"][0] featImage.imgUrl = featImage.featuredObject.source_url featImage.imgMediumUrl = "" featImage.imgLargeUrl = "" featImage.imgWidth = featImage.featuredObject.media_details.width featImage.imgHeight = featImage.featuredObject.media_details.height if (featImage.featuredObject.media_details.sizes.hasOwnProperty("large")) { featImage.imgWidth = featImage.featuredObject.media_details.sizes.full.width featImage.imgHeight = featImage.featuredObject.media_details.sizes.full.height featImage.imgLargeUrl = featImage.featuredObject.media_details.sizes.large.source_url + " 1024w, " } // console.log("featImage", featImage) } return featImage } /** * CUSTOM ARRAY PROTOTYPES */ // check if an element exists in array using a comparer function // comparer : function(currentElement) Array.prototype.inArray = function (comparer) { for (let i = 0; i < this.length; i++) { if (comparer(this[i])) return true } return false } // adds an element to the array // if it does not already exist using a comparer function Array.prototype.pushIfNotExist = function (element, comparer) { if (!this.inArray(comparer)) { this.push(element) } } /** ANIMATE + RENDER (continuous rendering) ******************************************** */ const animate = () => { const dt = clock.getDelta() watchPointer(camera, plane.children) controls.update() TWEEN.update() requestAnimationFrame(animate) /** ANIMATE SCENE? */ if (params.ANIMATE) { // plane.rotation.x += 0.002 // plane.rotation.y += 0.002 plane.rotation.z -= 0.0007 } /** PLAYER CHARACTER */ if (player.mixer !== undefined) { player.mixer.update(dt) } // Running if (player.action === "Walking") { const elapsedTime = Date.now() - player.actionTime if (elapsedTime > 2000 && player.move.forward > 0.7) { //setAction("Running") } } // Move Player if (player.move !== undefined) { player.movePlayer(dt) } // Move Cameras if (player.cameras !== undefined && player.cameras.active !== undefined) { camera.position.lerp(player.cameras.active.getWorldPosition(new THREE.Vector3()), 0.05) const pos = player.object.position.clone() pos.y += 200 camera.lookAt(pos) } // RENDER SCENE (CONTINUOUSLY) //renderer.render(scene, camera) render() // stats.update() } /** LOADERS (??? here ???) */ const loadAssets = () => { params.mode = params.modes.LOADING console.log("params.mode", params.mode) /** FBX ******************************************************************************** */ //loaders.loaderFBX.load( `${params.assetsPath}characters/SimplePeople.fbx`, function (object) { //loaders.loaderFBX.load( `${params.assetsPath}fbx/people/FireFighter.fbx`, function (object) { //loaders.loaderFBX.load( `${params.assetsPath}fbx/people/Trucker.fbx`, function (object) { loaders.loaderFBX.load(`${params.assetsPath}characters/SK_Chr_Farmer_Male_01.fbx`, function (object) { object.mixer = new THREE.AnimationMixer(object) player.mixer = object.mixer player.root = object.mixer.getRoot() object.name = "Gardener" object.traverse(function (child) { if (child.isMesh) { child.castShadow = true child.receiveShadow = false } }) //loaderTexture.load(`${params.assetsPath}images/SimpleFarmer_Farmer_Brown.png`, function(texture) { loaderTexture.load(`${params.assetsPath}textures/PolygonFarm_Texture_01_B.png`, function (texture) { object.traverse(function (child) { if (child.isMesh) { child.material.map = texture } }) }) // console.log("object", object) player.object = new THREE.Object3D() player.object.add(object) //player.object.scale.set(0.022, 0.022, 0.022) player.object.scale.set(0.033, 0.033, 0.033) player.object.rotation.x = Math.PI / 2 // 90 degrees in radians //player.mixer.clipAction(object.animations[0]).play() //animations.Idle = object.animations[0] //setAction("Idle") // console.log("player.object", player.object) plane.add(player.object) // guiFolderPlayer.add(player.object, "visible").name("Show Character").listen() }) /** LOAD 3D OBJECTS ******************************************************************** */ //loadTown() loadFarmHouse() loadRoad() //loadKitchenSink() loadCoop() loadChicken() // PRIMARY WORKING CHICKEN (GLTF) //loadHen() //loadHenGLTF() //loadRooster() //loadChickenGLTF() //loadChickGLTF() //loadChickenFree() /** * LOAD ANIMATIONS */ let loadNextAnim = function (loader) { let anim = anims.pop() // console.log("anim", anim) loader.load(`${params.assetsPath}fbx/anims2/${anim}.fbx`, function (object) { // console.log("object") animations[anim] = object.animations[0] if (anims.length > 0) { // console.log("anims.length") // console.log("getAction()") // console.log("player.action") loadNextAnim(loader) } else { // console.log("anims.length") anims = [] } }) } // RECURSIVE FUNCTION TO LOAD ANIMATIONS loadNextAnim(loaders.loaderFBX) } // end loadAssets() /** * BEGIN BUILD (MAIN/INIT) * ****************************************************** */ const build = async () => { params.mode = params.modes.BUILDING console.log("params.mode", params.mode) console.log("building ********************************* ") try { let a1 = await getSceneData() console.log("a1 boolean getSceneData", a1, new Date().toISOString()) console.log("data retrieved ************************* ") let a2 = await buildScene(a1) console.log("a2 plane returned from buildScene", a2, new Date().toISOString()) let a3 = async function (a4) { console.log("a4 plane object returned from buildScene", a4, new Date().toISOString()) params.mode = params.modes.BUILT console.log("params.mode", params.mode) console.log("scene built ************************** ") loadAssets(a2) console.log("loading assets *********************** ") } await a3(a2) console.log("a3 async function (complete)", a3, new Date().toISOString()) } catch (e) { console.log("error ***: ", e) } // const preloader = new Preloader(options) // console.log("preloader", preloader) } // end build() const getSceneData = async () => { // get data let getDataFromLocalStorage = true // LOCALSTORAGE -- look for data in localStorage first if (localStorage && getDataFromLocalStorage && !debug) { const getdata = localStorage.getItem('threedgarden') || '' const threedgarden = getdata ? JSON.parse(getdata) : undefined if (threedgarden !== undefined) { console.log("LOCALSTORAGE ITEM RETRIEVED", threedgarden) //this.threedgarden = threedgarden params.data = threedgarden.data } else { console.log("LOCALSTORAGE ITEM NOT RETRIEVED", threedgarden) getDataFromLocalStorage = false } } else { console.log("LOCALSTORAGE NOT AVAILABLE") getDataFromLocalStorage = false } if (1 === 0 || !getDataFromLocalStorage) { // PROMISE REST API -- call WP Rest API for data second await Promise.allSettled( API_URLS.map( url => fetch(url) .then(results => results.json()) .then(data => { let type = data[0].type switch (type) { case "scene": params.data.scene = [...data] break case "allotment": params.data.allotment = [...data] break case "bed": params.data.bed = [...data] break case "plant": params.data.plant = [...data] break case "planting_plan": params.data.planting_plan = [...data] break default: break } console.log("data", data) }) ) ) .then(results => { console.log("results", results) results.forEach((result, num) => { if (result.status === "fulfilled") { //alert(`${urls[num]}: ${result.value.status}`) //console.log(result) } if (result.status === "rejected") { //alert(`${urls[num]}: ${result.reason}`) console.log(result) } }) console.log("params.data", params.data) // save to localStorage localStorage.setItem('threedgarden', JSON.stringify(params)) // fulfill Promise? return true } ) } else if (getDataFromLocalStorage) { // fulfill Promise? return true } else { // fulfill Promise? return false } } /** * BUILD SCENE * *************************************************************************************** */ const buildScene = async (a5) => { console.log("a5 boolean === a1 boolean", a5) params.mode = params.modes.BUILDING console.log("params.mode", params.mode) console.log("params.data.scene", params.data.scene) let wpScene = params.data.scene[0] let sceneID = wpScene.id // console.log("wpScene", wpScene) /** THREE JS SCENE ******************************************************************* */ scene = new THREE.Scene() scene.name = wpScene.title.rendered console.log("scene", scene) // load the 3D cube map? if (wpScene.acf.scene_background_image_px) { let cubeMapURLs = [ wpScene.acf.scene_background_image_px, wpScene.acf.scene_background_image_nx, wpScene.acf.scene_background_image_py, wpScene.acf.scene_background_image_ny, wpScene.acf.scene_background_image_pz, wpScene.acf.scene_background_image_nz ] let reflectionCube = new THREE.CubeTextureLoader().load(cubeMapURLs) reflectionCube.format = THREE.RGBFormat scene.background = reflectionCube } // load the 2D background image? else if (wpScene.acf.scene_background_image) { // let bgTexture = loaderTexture.load(wpScene.acf.scene_background_image) // scene.background = bgTexture let bgTexture = loaderTexture.load( wpScene.acf.scene_background_image, () => { const rt = new THREE.WebGLCubeRenderTarget(bgTexture.image.height) rt.fromEquirectangularTexture(renderer, bgTexture) scene.background = rt } ) } // load the background color? else if (wpScene.acf.scene_background_color) { scene.background = new THREE.Color(wpScene.acf.scene_background_color) //scene.fog = new THREE.Fog(0xFFFFFF, 0, 500) } /** GEOMETRIES *********************************************************************** */ plane = getPlane( wpScene.acf.scene_plane_width_x, wpScene.acf.scene_plane_length_y, wpScene.acf.scene_plane_background_color ) plane.name = "plane-jane" plane.rotation.x = -Math.PI / 2 // -90 degrees in radians //plane.position.z = 10 //plane.rotation.z += 0.002 guiFolderRotation.add(plane.rotation, "x", -Math.PI, Math.PI).listen() guiFolderRotation.add(plane.rotation, "y", -Math.PI, Math.PI).listen() guiFolderRotation.add(plane.rotation, "z", -Math.PI, Math.PI).listen() /** TEXTURES ************************************************************************* */ if (wpScene.acf.scene_plane_texture_image) { plane.material.roughness = 0.0 //plane.material.map = loaderTexture.load("/wp-content/plugins/threed-garden/admin/media/textures/grasslight-big.jpg") plane.material.map = loaderTexture.load(wpScene.acf.scene_plane_texture_image) // plane.material.bumpMap = loaderTexture.load("/wp-content/plugins/threed-garden/admin/media/textures/grasslight-big-nm.jpg") // plane.material.bumpMap = loaderTexture.load(wpScene.acf.scene_plane_texture_image) // plane.material.bumpScale = 0.01 let planeTextureMap = plane.material.map planeTextureMap.wrapS = THREE.RepeatWrapping planeTextureMap.wrapT = THREE.RepeatWrapping planeTextureMap.repeat.set(4, 4) } /** LIGHTS *************************************************************************** */ // let pointLight = getPointLight(0xFFFFFF, 4.0) // pointLight.position.set( -20, -60, 20 ) // //pointLight.intensity = 3.0 // let spotLight = getSpotLight(0xFFFFFF, 4.0) // spotLight.position.set( -20, -60, 20 ) // //spotLight.intensity = 3.0 // ambient sunlight let ambientLight = getAmbientLight(0xFFFFFF, 0.75) //ambientLight.position.set( 0, 0, 0 ) // does nothing guiFolderLights.add(ambientLight, "visible").name("Show Ambient Light") guiFolderLights.add(ambientLight, "intensity", -2.0, 2.0) guiFolderLights.add(ambientLight.position, "x", -800, 800) guiFolderLights.add(ambientLight.position, "y", -800, 800) guiFolderLights.add(ambientLight.position, "z", -800, 800) // the sun let directionalLight = getDirectionalLight(0xFFFFFF, 0.75) // x = sun?, y = time of day?, z = ??? directionalLight.position.set(-90, -120, 135) directionalLight.castShadow = true //directionalLight.intensity = 1.6 // overwrite? let helperDirectionalLight = new THREE.CameraHelper(directionalLight.shadow.camera) helperDirectionalLight.visible = false // indirect sunlight //let directionalLight2 = directionalLight.clone() let directionalLight2 = getDirectionalLight(0xFFFFFF, 0.66) directionalLight2.position.set(-90, 135, 135) // direct opposite x,y of primary? directionalLight2.castShadow = false //directionalLight2.intensity = 1.0 // overwrite? let helperDirectionalLight2 = new THREE.CameraHelper(directionalLight2.shadow.camera) helperDirectionalLight2.visible = true guiFolderLights.add(directionalLight, "visible").name("Show Light") guiFolderLights.add(helperDirectionalLight, "visible").name("Show Light Helper") guiFolderLights.add(directionalLight, "intensity", -2.0, 2.0) guiFolderLights.add(directionalLight.position, "x", -800, 800) guiFolderLights.add(directionalLight.position, "y", -800, 800) guiFolderLights.add(directionalLight.position, "z", -800, 800) guiFolderLights.add(directionalLight2, "visible").name("Show Light 2") guiFolderLights.add(helperDirectionalLight2, "visible").name("Show Light 2 Helper") guiFolderLights.add(directionalLight2, "intensity", -2.0, 2.0) guiFolderLights.add(directionalLight2.position, "x", -800, 800) guiFolderLights.add(directionalLight2.position, "y", -800, 800) guiFolderLights.add(directionalLight2.position, "z", -800, 800) /** SCENE ***************************************************************************** */ // add objects to scene //plane.add(structure) //plane.add(pointLight) //plane.add(spotLight) plane.add(directionalLight) plane.add(directionalLight2) plane.add(ambientLight) scene.add(helperDirectionalLight) scene.add(helperDirectionalLight2) scene.add(plane) /** CAMERA **************************************************************************** */ camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.1, 1000 ) camera.name = "gardencam1" camera.position.set(86, 64, 182) //camera.lookAt(new THREE.Vector3(0, 0, 0)) // overridden by OrbitControls.target let helperCamera = new THREE.CameraHelper(camera) helperCamera.visible = false scene.add(helperCamera) guiFolderCameras.add(helperCamera, "visible", 0, 20).name("Show Camera Helper") guiFolderCameras.add(camera.position, "x", -800, 800).listen() guiFolderCameras.add(camera.position, "y", -800, 800).listen() guiFolderCameras.add(camera.position, "z", -800, 800).listen() /** RENDERER ************************************************************************** */ renderer = new THREE.WebGLRenderer( { alpha: true, antialias: true } ) renderer.shadowMap.enabled = true //renderer.setSize(window.innerWidth - 240, window.innerHeight - 100) //admin renderer.setSize(window.innerWidth - 100, window.innerHeight - 100) //public // utilize javascript prototyping.. add variables to the dom element :) renderer.domElement.camera = camera renderer.domElement.targetList = plane.children renderer.domElement.addEventListener("pointermove", onPointerMove, false) renderer.domElement.addEventListener("pointerdown", onPointerDown, false) //renderer.domElement.addEventListener("mousedown", onDocumentMouseDown, false) /** CONTROLS *************************************************************************** */ controls = new OrbitControls(camera, renderer.domElement) controls.enableDamping = true controls.dampingFactor = 0.25 controls.enableZoom = true controls.rotateSpeed = 0.5 controls.autoRotate = false controls.autoRotateSpeed = 0.03 controls.minDistance = 0.01 controls.maxDistance = 340 controls.maxPolarAngle = Math.PI / 2 - .04 controls.target = new THREE.Vector3(0, 0, 0) // where the camera actually points //controls.target.set(0, 5, 0) // alternate way of setting target of camera renderer.domElement.controls = controls /** LOAD CAMERAS *********************************************************************** */ //createCameras() /** WEBGL CANVAS *********************************************************************** */ // console.log("document", document) container = document.getElementById("webgl") // console.log("container", container) canvas = renderer.domElement // console.log("canvas = renderer.domElement", canvas) container.append(gui.domElement) container.append(renderer.domElement) /** JOYSTICK <+> *********************************************************************** */ // OG working let joystick = new JoyStick({ onMove: playerControl, game: container // document.querySelector("#webgl") }) console.log("joystick", joystick) // Fried Chicken testing (meh) // const joystickControls = new JoystickControls( // camera, // scene, // ) // const rotationJoystick = new RotationJoystickControls( // camera, // scene, // player // ) /** BUILD ALLOTMENTS ******************************************************************* */ alert("HEY HEY HEY: BUILD ALLOTMENTS?") // return plane // buildAllotments( // params.data.allotment, // plane, // sceneID // the post-to-post relationship <3 // ) // fulfill Promise // return true return plane } // end buildScene /** * BUILD "ALLOTMENTS" FROM REST API POST OBJECT ************************************************************ */ function buildAllotments(postObject, plane, sceneID) { console.log("ALLOTMENTS", postObject) // alert("HEY HEY HEY: BUILD ALLOTMENTS..") var filteredPostObject = postObject.filter(function (obj) { return obj.acf.allotment_scene === sceneID }) // console.log("filteredPostObject", filteredPostObject) filteredPostObject.forEach(function (key) { // console.log("-------------------------") // console.log("key.id (postObject)------") // console.log(key.id) // console.log(key) // console.log("-------------------------") // BUILD ALLOTMENT OBJECT GROUP let allotment = {} allotment.parameters = {} allotment.position = {} allotment.images = {} allotment.parameters.x = parseInt(key.acf.allotment_width) allotment.parameters.y = parseInt(key.acf.allotment_length) allotment.parameters.z = parseInt(key.acf.allotment_height) // 0 allotment.position.x = parseInt(key.acf.allotment_position_x) allotment.position.y = parseInt(key.acf.allotment_position_y) allotment.position.z = parseInt(key.acf.allotment_position_z) allotment.images.texture = key.acf.allotment_texture_image allotment.images.featured = getFeaturedImage(key) allotment.shape = key.acf.allotment_shape allotment.color = key.acf.allotment_color allotment.title = key.title.rendered allotment.postID = key.id allotment.description = key.content.rendered allotment.link = key.link // console.log("allotment", allotment) let structure = getGeometry( allotment.shape, allotment.parameters.x, allotment.parameters.y, allotment.parameters.z, allotment.color ) structure.name = allotment.title structure.userData.type = "structure" structure.userData.postID = allotment.postID structure.userData.description = allotment.description structure.userData.annotation = allotment.title structure.userData.link = allotment.link structure.position.x = allotment.position.x structure.position.y = allotment.position.y structure.position.z = (structure.geometry.parameters.depth / 2) + allotment.position.z // - 10 for gap between plane structure.material.roughness = 0.9 if (allotment.images.texture !== null && allotment.images.texture !== false) { structure.material.map = loaderTexture.load(allotment.images.texture) for (let i = 0; i < structure.material.length; i++) { // hightlight object //structure.material[i].color.set(0xff0000) structure.material[i].map = loaderTexture.load(allotment.images.texture) //structure.faces[i].materialIndex = 1 //console.log(intersects[i]) // structure.material[i].bumpMap = loaderTexture.load(allotment.images.texture) // structure.material[i].bumpScale = 0.05 let structureTextureMap = structure.material[i].map structureTextureMap.wrapS = THREE.RepeatWrapping structureTextureMap.wrapT = THREE.RepeatWrapping structureTextureMap.repeat.set(4, 4) } } plane.add(structure) //params.colliders.push(structure) //guiFolderAllotments.add(structure.geometry.parameters, "depth", 0, allotment.parameters.z) // console.log("allotment structure", structure) /** BUILD BEDS IN THIS ALLOTMENT ************************************************** */ //alert("HEY HEY HEY: BUILD BEDS??") buildBeds( params.data.bed, plane, allotment.postID, // the post-to-post relationship <3 structure.position.x, structure.position.y, 0 //structure.position.z ) /** INFOSPOTS ********************************************************************* */ //alert("HEY HEY HEY: BUILD INFOSPOTS??") // let infospot = makeInfospotSphere( // structure.name, // structure.position.x, // structure.position.y, // allotment.parameters.z + 3, // allotment.postID, // structure.userData.annotation, // structure.userData.link // ) // infospot.name = `INFOSPOT: ${structure.name}` // infospot.visible = true // guiFolderAllotments.add(infospot, "visible").name("InfoSphere").listen() // plane.add(infospot) }) /** END ALLOTMENTS ****************************************************************** */ // console.log("plane.children", plane.children) } /** * BUILD "BEDS" FROM REST API POST OBJECT ************************************************************ */ function buildBeds(postObject, plane, allotmentID, posOffsetX, posOffsetY, posOffsetZ) { // console.log("BEDS postObject", postObject) // only show beds for this allotment structure var filteredPostObject = postObject.filter(function (obj) { return obj.acf.bed_allotment === allotmentID }) // console.log("filteredPostObject", filteredPostObject) filteredPostObject.forEach(function (key) { // console.log("-------------------------") // console.log("key.id (postObject)------") // console.log(key.id) // console.log(key) // console.log("-------------------------") let bed = {} bed.parameters = {} bed.position = {} bed.images = {} bed.parameters.x = parseInt(key.acf.bed_width) / 12 bed.parameters.y = parseInt(key.acf.bed_length) / 12 bed.parameters.z = parseInt(key.acf.bed_height) / 12 bed.position.x = parseInt(key.acf.bed_position_x) / 12 + posOffsetX bed.position.y = parseInt(key.acf.bed_position_y) / 12 + posOffsetY bed.position.z = parseInt(key.acf.bed_position_z) / 12 + (bed.parameters.z / 2) // + posOffsetZ bed.images.texture = key.acf.bed_texture_image bed.images.featured = getFeaturedImage(key) bed.shape = key.acf.bed_shape bed.color = key.acf.bed_color bed.title = key.title.rendered bed.postID = key.id bed.description = key.content.rendered bed.link = key.link // console.log("bed", bed) let structure = getGeometry( bed.shape, bed.parameters.x, bed.parameters.y, bed.parameters.z, bed.color ) structure.name = bed.title structure.userData.type = "structure" structure.userData.postID = bed.postID structure.userData.description = bed.description structure.userData.annotation = bed.title structure.userData.link = bed.link structure.position.x = bed.position.x ? bed.position.x : 0 structure.position.y = bed.position.y ? bed.position.y : 0 structure.position.z = bed.position.z ? bed.position.z : 0 //structure.rotation.x = -Math.PI / 2 // -90 degrees in radians structure.material.roughness = 0.9 if (bed.images.texture !== null && bed.images.texture !== false) { structure.material.map = loaderTexture.load(bed.images.texture) for (let i = 0; i < structure.material.length; i++) { // hightlight object //structure.material[i].color.set(0xff0000) structure.material[i].map = loaderTexture.load(bed.images.texture) //structure.faces[i].materialIndex = 1 //console.log(intersects[i]) // structure.material[i].bumpMap = loaderTexture.load(bed.images.texture) // structure.material[i].bumpScale = 0.05 let structureTextureMap = structure.material[i].map structureTextureMap.wrapS = THREE.RepeatWrapping structureTextureMap.wrapT = THREE.RepeatWrapping structureTextureMap.repeat.set(4, 4) } } plane.add(structure) params.colliders.push(structure) // console.log("bed structure", structure) /** BUILD PLANTS IN THIS BED, ACCORDING TO PLANTING PLANS ************************* */ //alert("HEY HEY HEY: BUILD PLANTING PLANS??") buildPlantingPlans( params.data.planting_plan, plane, bed.postID, // the post-to-post relationship <3 structure.position.x, structure.position.y, 0 //structure.position.z ) /** INFOSPOTS ********************************************************************* */ //alert("HEY HEY HEY: BUILD INFOSPOTS??") // let infospot = makeInfospotSphere( // structure.name, // structure.position.x, // structure.position.y, // bed.parameters.z + 3, // bed.postID, // structure.userData.annotation, // structure.userData.link // ) // infospot.name = `INFOSPOT: ${structure.name}` // infospot.visible = false // guiFolderBeds.add(infospot, "visible").name("InfoSphere").listen() // plane.add(infospot) }) /** END BEDS *********************************************************************** */ // console.log("plane.children", plane.children) } /** * BUILD "PLANTS" FROM REST API POST OBJECT ************************************************************ */ function buildPlantingPlans(postObject, plane, bedID, posOffsetX, posOffsetY, posOffsetZ) { //console.log("PLANTING PLANS postObject", postObject) //return null // only show plants for this planting plan's bed structure var filteredPostObject = [] var matches = [] postObject.forEach(function (obj) { obj.acf.planting_plan_bed_plant_schedule.forEach(function (i) { if (i.planting_plan_bed === bedID) { //console.log("MATCHED at: ", i) //matches.push(i) //matches.push(obj) matches.pushIfNotExist(obj, function (e) { return e.id === obj.id }) } }) filteredPostObject = [...matches] }) if (filteredPostObject.length > 0) { console.log("filteredPostObject", filteredPostObject) } // for each planting plan.. filteredPostObject.forEach(function (key) { // console.log("-------------------------") // console.log("key.id (filteredPostObject)") // console.log(key.id) // console.log(key) // console.log("-------------------------") // for each planting plan bed-plant schedule.. key.acf.planting_plan_bed_plant_schedule.forEach(function (key2) { // console.log("key2", key2) // only for this bed.. if (key2.planting_plan_bed === bedID) { // show this plant (or multiple plants) in this bed.. var filteredPlant = params.data.plant.filter(function (obj) { return obj.id === key2.planting_plan_plant }) // console.log("filteredPlant", filteredPlant) // for this plant in this bed.. filteredPlant.forEach(function (key3) { // console.log("key3", key3) let plant = {} plant.parameters = {} plant.position = {} plant.images = {} plant.parameters.x = Number(key3.acf.plant_width) / 12 plant.parameters.y = Number(key3.acf.plant_length) / 12 plant.parameters.z = Number(key3.acf.plant_height) / 12 plant.position.x = parseInt(key2.plant_position_x) / 12 + posOffsetX plant.position.y = parseInt(key2.plant_position_y) / 12 + posOffsetY plant.position.z = parseInt(key2.plant_position_z) / 12 + (plant.parameters.z / 2) // + posOffsetZ plant.images.texture = key3.acf.plant_texture_image plant.images.featured = getFeaturedImage(key) plant.shape = key3.acf.plant_shape plant.color = key3.acf.plant_color plant.title = key3.title.rendered plant.postID = key3.id plant.description = key3.content.rendered plant.link = key3.link console.log("PLANT", plant) let structure = getGeometry( plant.shape, // "Tree", "Bush", "Box", plant.parameters.x, plant.parameters.y, plant.parameters.z, plant.color ) structure.name = plant.title structure.userData.type = "structure" structure.userData.postID = plant.postID structure.userData.description = plant.description structure.userData.annotation = plant.title structure.userData.link = plant.link structure.position.x = plant.position.x ? plant.position.x : 0 structure.position.y = plant.position.y ? plant.position.y : 0 structure.position.z = plant.position.z ? plant.position.z : 0 structure.rotation.x = Math.PI / 2 // 90 degrees in radians structure.material.roughness = 0.9 if (plant.images.texture !== null && plant.images.texture !== false) { structure.material.map = loaderTexture.load(plant.images.texture) for (let i = 0; i < structure.material.length; i++) { // hightlight object //structure.material[i].color.set(0xff0000) structure.material[i].map = loaderTexture.load(plant.images.texture) //structure.faces[i].materialIndex = 1 //console.log(intersects[i]) // structure.material[i].bumpMap = loaderTexture.load(plant.images.texture) // structure.material[i].bumpScale = 0.05 let structureTextureMap = structure.material[i].map structureTextureMap.wrapS = THREE.RepeatWrapping structureTextureMap.wrapT = THREE.RepeatWrapping structureTextureMap.repeat.set(4, 4) } } console.log("plant structure", structure) plane.add(structure) // colliders params.colliders.push(structure) /** INFOSPOTS ********************************************************************* */ // let infospot = makeInfospotSphere( // structure.name, // structure.position.x, // structure.position.y, // plant.parameters.z + 3, // plant.postID, // structure.userData.annotation, // structure.userData.link // ) // infospot.name = `INFOSPOT: ${structure.name}` // infospot.visible = false // guiFolderBeds.add(infospot, "visible").name("InfoSphere").listen() // plane.add(infospot) }) } // end if }) }) /** END PLANTS *************************************************************************** */ // console.log("plane.children", plane.children) } const MyComponent = () => { useEffect(() => { console.log('MyComponent onMount') return () => { console.log('MyComponent onUnmount') }; }, []) return (
Component body here...
) } const ThreeDGarden = (): JSX.Element => { const word = "HEY HEY HEY" const title = useRef() const root = useRef() // const scene = new THREE.Scene() useEffect(() => { bootManager() }, []) return (
ThreeDGarden: {word}
Three root: {JSON.stringify(root)}
) } export default ThreeDGarden