// https://codeburst.io/dynamic-modules-with-vuex-and-vue-b9c481ca792 // https://www.brophy.org/post/instance-aware-vuex-modules-1/ // import qs from 'querystring' // import { REST } from 'api/rest-axios' import * as THREE from 'three' import { ThreeBSP } from 'three-js-csg-es6' export default { namespaced: true, // initial state state: { obj3d: null, size: { x: 0, y: 0, z: 0 }, position: { x: 0, y: 0, z: 0 }, walls3dObj: null, wallsPos: null, wall: { wallW: 0.001, // dig windows on face and back winW: 2 + Math.random() * 2, winH: 4 + Math.random() * 4, margin: 2, nbrWinX: 0, paddingX: 0, nbrWinY: 0, paddingY: 0, nbrWinZ: 0, paddingZ: 0 }, grid: [] }, // getters getters: { position: (state) => { return state.position }, size: (state) => { return state.size } }, // mutations mutations: { setSize: (state, size) => { state.size = size }, setPosition: (state, pos) => { state.position = pos }, setWalls3dObj: (state, obj) => { state.walls3dObj = obj }, setWallsPos: (state, pos) => { state.wallsPos = pos } }, // actions actions: { init ({ dispatch, commit, state, rootGetters }) { console.log('Init Project module', state.id) dispatch('sizingBuilding') dispatch('build3dObjs') }, sizingBuilding ({ dispatch, commit, state, rootGetters }) { console.log('sizingBuilding', state.index) let totalW = rootGetters['Projects/totalW'] console.log('totalW', totalW) let margin = rootGetters['Projects/marginBetweenBuildings'] console.log('margin', margin) // positioning buildings on x regarding the widths // & setting up the window sizing // & setting up the content grid // let wall, a // let grid // X POS let x if (state.index === 0) { // if it's the first x = -1 * totalW / 2 } else { // else get the precedent pos let prevProjID = rootGetters['Projects/projectID'](state.index - 1) console.log('prevProjID', prevProjID) let prevProjPos = rootGetters[`project:${prevProjID}/position`] console.log(`project:${prevProjID}/position.x`, prevProjPos.x) let prevProjSize = rootGetters[`project:${prevProjID}/size`] console.log(`project:${prevProjID}/size.x`, prevProjSize.x) console.log('state.size.x', state.size.x) // prev X + alf of prev size x + margin + half of current size x x = prevProjPos.x + prevProjSize.x / 2 + margin + state.size.x / 2 } console.log('x', x) commit('setPosition', { x: x, y: -1 * state.size.y / 2 + 10 + Math.random() * 30, // -10 + Math.random() * this.size.y / 2 z: -10 + Math.random() * 10 }) // // WINDOWS // // removing windows on X until padding is enough // a = 0 // state.wall.nbrWinX = Math.floor((state.size.x - 2 * state.wall.margin) / state.wall.winW) // while (state.wall.paddingX < 0.4) { // state.wall.nbrWinX -= a // state.wall.paddingX = (state.size.x - 2 * state.wall.margin - state.wall.winW * state.wall.nbrWinX) / (state.wall.nbrWinX - 1) // a++ // } // // removing windows on Y until padding is enough // a = 0 // state.wall.nbrWinY = Math.floor((state.size.y - 2 * state.wall.margin) / state.wall.winH) // while (state.wall.paddingY < 0.4) { // state.wall.nbrWinY -= a // state.wall.paddingY = (state.size.y - 2 * state.wall.margin - state.wall.winH * state.wall.nbrWinY) / (state.wall.nbrWinY - 1) // a++ // } // state.wall = { ...wall } // // // CONTENTS GRID // a = 0 // state.wall.nbrWinZ = Math.floor((state.size.z - 2 * state.wall.margin) / state.wall.winW) // while (state.wall.paddingZ < 0.4) { // state.wall.nbrWinZ -= a // state.wall.paddingZ = (state.size.z - 2 * state.wall.margin - state.wall.winW * state.wall.nbrWinZ) / (state.wall.nbrWinZ - 1) // a++ // } // // grid = [] // for (var l = 0; l < state.wall.nbrWinZ * 2; l++) { // cols // for (var m = 0; m < state.wall.nbrWinY * 2; m++) { // rows // grid.push({ // z: margin + state.wall.winW / 2 * l, // y: margin + state.wall.winH / 2 * m // }) // } // } // // shuffle the grid // for (let n = grid.length - 1; n > 0; n--) { // const o = Math.floor(Math.random() * n) // const temp = grid[n] // grid[n] = grid[o] // grid[o] = temp // } // state.grid = [ ...grid ] }, build3dObjs ({ dispatch, commit, state, rootGetters }) { // http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/ let backGeom = new THREE.BoxGeometry(state.size.x, state.size.y, state.wall.wallW) let backMesh = new THREE.Mesh(backGeom) backMesh.position.z = -0.5 * state.size.z let backBSP = new ThreeBSP(backMesh) // TODO: use web workers // https://medium.com/techtrument/multithreading-javascript-46156179cf9a // let winGeom = new THREE.BoxGeometry(state.wall.winW, state.wall.winH, state.wall.wallW) // let winMesh = new THREE.Mesh(winGeom) // let winBSP // for (var i = 0; i < state.wall.nbrWinX; i++) { // for (var j = 0; j < state.wall.nbrWinY; j++) { // winMesh.position.z = -0.5 * state.size.z // winMesh.position.x = -0.5 * state.size.x + state.wall.margin + state.wall.winW * 0.5 + i * (state.wall.winW + state.wall.paddingX) // winMesh.position.y = 0.5 * state.size.y - state.wall.margin - state.wall.winH * 0.5 - j * (state.wall.winH + state.wall.paddingY) // winBSP = new ThreeBSP(winMesh) // backBSP = backBSP.subtract(winBSP) // } // } // // // let abovewWaterH = position.y + state.size.y / 2 // // let underWaterHThd = (-1 * position.y - state.size.y / 2) / 3 // // let levelH = 4 // // let levelGeom = new THREE.BoxGeometry(state.size.x, levelH, wallW) // // let levelMesh, levelBSP // // for (var l = 0; l < 2; l++) { // // levelMesh = new THREE.Mesh(levelGeom) // // levelMesh.position.z = -0.5 * state.size.z // // levelMesh.position.y = 0.5 * state.size.y - abovewWaterH - underWaterHThd - underWaterHThd * l + levelH * 0.5 // // levelBSP = new ThreeBSP(levelMesh) // // backBSP = backBSP.union(levelBSP) // // } backMesh = backBSP.toMesh() let faceMesh = backMesh.clone() faceMesh.position.z = 0.5 * state.size.z let faceBSP = new ThreeBSP(faceMesh) let rightGeom = new THREE.BoxGeometry(state.wall.wallW, state.size.y, state.size.z) let rightMesh = new THREE.Mesh(rightGeom) rightMesh.position.x = 0.5 * state.size.x // rightMesh.position.z = 0.5 * state.size.z let rightBSP = new ThreeBSP(rightMesh) // // WE MAY NO NEED TO DIG WINDOWS ON SIDE WALLS // // // dig windows on right // // let nbrWinZ = Math.floor((state.size.z - 2 * margin) / winW) // // let paddingZ = (state.size.z - 2 * margin - winW * nbrWinZ) / (nbrWinX - 1) // // winGeom = new THREE.BoxGeometry(wallW, winH, winW) // // for (i = 0; i < nbrWinZ; i++) { // // for (j = 0; j < nbrWinY; j++) { // // // right // // winMesh = new THREE.Mesh(winGeom) // // winMesh.position.x = 0.5 * state.size.x // // winMesh.position.z = -0.5 * state.size.z + margin + winW * 0.5 + i * (winW + paddingZ) // // winMesh.position.y = 0.5 * state.size.y - margin - winH * 0.5 - j * (winH + paddingY) // // winBSP = new ThreeBSP(winMesh) // // rightBSP = rightBSP.subtract(winBSP) // // } // // } // // rightMesh = rightBSP.toMesh() let leftMesh = rightMesh.clone() leftMesh.position.x = -0.5 * state.size.x // leftMesh.position.z = 0.5 * state.size.z let leftBSP = new ThreeBSP(leftMesh) // // let topGeom = new THREE.BoxGeometry(state.size.x, wallW, state.size.z) // // let topMesh = new THREE.Mesh(topGeom) // // // topMesh.position.y = -0.5 * state.size.y // // // let topBSP = new ThreeBSP(topMesh) // // // // let floorGeom = new THREE.BoxGeometry(state.size.x, wallW, state.size.z) // // let floorMesh = new THREE.Mesh(floorGeom) // // // floorMesh.position.y = 0.5 * state.size.y // // // let floorBSP = new ThreeBSP(floorMesh) let buildingBSP = backBSP.union(rightBSP) buildingBSP = buildingBSP.union(faceBSP) buildingBSP = buildingBSP.union(leftBSP) // buildingBSP = buildingBSP.union(topBSP) // buildingBSP = buildingBSP.union(floorBSP) // convert back to three.js mesh let building = buildingBSP.toMesh() // // create a custom shaderMaterial to had gradian colors // // var uniforms = THREE.UniformsUtils.merge([ // // THREE.UniformsLib['lights'], // // { // // 'topColor': { value: new THREE.Color(0xffffff) }, // // 'groundColor': { value: new THREE.Color(0xbcd6e4) }, // // 'bottomColor': { value: new THREE.Color(0x07223b) }, // // // 'bottomColor': { value: new THREE.Color(0x000000) }, // // // 'groundColor': { value: new THREE.Color(0xff0000) }, // // // 'bottomColor': { value: new THREE.Color(0x00ff00) }, // // lightIntensity: { type: 'f', value: 1.0 } // // } // // ]) // // var buildingMat = new THREE.ShaderMaterial({ // // uniforms: uniforms, // // vertexShader: BgVertex, // // fragmentShader: BuildingFragment, // // side: THREE.DoubleSide, // // lights: true // // }) // // building.material = buildingMat // // create a classical material for building // // let topColor = `hsla(201, 100%, 95%, 1)` // let hTop = Math.round(195 + Math.random() * 10) // let sTop = Math.round(100) // let lTop = Math.round(95) // let hFloor = Math.round(205 + Math.random() * 10) // let sFloor = Math.round(40 + Math.random() * 20) // let lFloor = Math.round(5 + Math.random() * 15) // let topColor = `hsla(${hTop}, ${sTop}%, ${lTop}%, 1)` // let bottomColor = `hsla(${hFloor}, ${sFloor}%, ${lFloor}%, 1)` // // let gradientTexture = new THREE.CanvasTexture(this.createGradientCanvas(topColor, bottomColor)) let materialOpts = { color: 0xffffff, side: THREE.DoubleSide, shininess: 30 // map: gradientTexture // wireframe: true, // transparent: true, // opacity: 0.6 // renderOrder: 0 } building.material = new THREE.MeshPhongMaterial(materialOpts) commit('setWalls3dObj', building) let buildingPos = { ...state.position, ...{ z: 0.5 * state.size.z } } commit('setWallsPos', buildingPos) // // TOP & FLOOR // let topGeom = new THREE.BoxGeometry(state.size.x, state.wall.wallW, state.size.z) // let topOpts = { // color: new THREE.Color(`hsl(${hTop}, ${sTop}%, ${lTop}%)`), // // side: THREE.DoubleSide, // shininess: 30 // } // let topMat = new THREE.MeshPhongMaterial(topOpts) // let topMesh = new THREE.Mesh(topGeom, topMat) // let topPosition = { ...position } // topPosition.y += 0.5 * state.size.y // // // let floorGeom = new THREE.BoxGeometry(state.size.x, state.wall.wallW, state.size.z) // let floorOpts = { // color: new THREE.Color(`hsl(${hFloor}, ${sFloor}%, ${lFloor}%)`), // // side: THREE.DoubleSide, // shininess: 10 // } // let floorMat = new THREE.MeshPhongMaterial(floorOpts) // let floorMesh = new THREE.Mesh(topGeom, floorMat) // let floorPosition = { ...position } // floorPosition.y -= 0.5 * state.size.y // // // LEVELS // let levelGeom = new THREE.BoxGeometry(state.size.x, 1, state.size.z) // let levelMesh = new THREE.Mesh(levelGeom) // let levelBSP = new ThreeBSP(levelMesh) // let levelHoleGeom = new THREE.BoxGeometry(state.size.x - 3, 1, state.size.z - 3) // let levelHoleMesh = new THREE.Mesh(levelHoleGeom) // let levelHoleBSP = new ThreeBSP(levelHoleMesh) // levelBSP = levelBSP.subtract(levelHoleBSP) // levelMesh = levelBSP.toMesh() // let levelOpts = { // color: 0xff0000, // shininess: 10 // } // let levelMat = new THREE.MeshPhongMaterial(levelOpts) // levelMesh.material = levelMat } } }