project.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. // https://codeburst.io/dynamic-modules-with-vuex-and-vue-b9c481ca792
  2. // https://www.brophy.org/post/instance-aware-vuex-modules-1/
  3. // import qs from 'querystring'
  4. // import { REST } from 'api/rest-axios'
  5. import * as THREE from 'three'
  6. import { ThreeBSP } from 'three-js-csg-es6'
  7. export default {
  8. namespaced: true,
  9. // initial state
  10. state: {
  11. obj3d: null,
  12. size: { x: 0, y: 0, z: 0 },
  13. position: { x: 0, y: 0, z: 0 },
  14. walls3dObj: null,
  15. wallsPos: null,
  16. wall: {
  17. wallW: 0.001,
  18. // dig windows on face and back
  19. winW: 2 + Math.random() * 2,
  20. winH: 4 + Math.random() * 4,
  21. margin: 2,
  22. nbrWinX: 0,
  23. paddingX: 0,
  24. nbrWinY: 0,
  25. paddingY: 0,
  26. nbrWinZ: 0,
  27. paddingZ: 0
  28. },
  29. grid: []
  30. },
  31. // getters
  32. getters: {
  33. position: (state) => {
  34. return state.position
  35. },
  36. size: (state) => {
  37. return state.size
  38. }
  39. },
  40. // mutations
  41. mutations: {
  42. setSize: (state, size) => {
  43. state.size = size
  44. },
  45. setPosition: (state, pos) => {
  46. state.position = pos
  47. },
  48. setWalls3dObj: (state, obj) => {
  49. state.walls3dObj = obj
  50. },
  51. setWallsPos: (state, pos) => {
  52. state.wallsPos = pos
  53. }
  54. },
  55. // actions
  56. actions: {
  57. init ({ dispatch, commit, state, rootGetters }) {
  58. console.log('Init Project module', state.id)
  59. dispatch('sizingBuilding')
  60. dispatch('build3dObjs')
  61. },
  62. sizingBuilding ({ dispatch, commit, state, rootGetters }) {
  63. console.log('sizingBuilding', state.index)
  64. let totalW = rootGetters['Projects/totalW']
  65. console.log('totalW', totalW)
  66. let margin = rootGetters['Projects/marginBetweenBuildings']
  67. console.log('margin', margin)
  68. // positioning buildings on x regarding the widths
  69. // & setting up the window sizing
  70. // & setting up the content grid
  71. // let wall, a
  72. // let grid
  73. // X POS
  74. let x
  75. if (state.index === 0) {
  76. // if it's the first
  77. x = -1 * totalW / 2
  78. } else {
  79. // else get the precedent pos
  80. let prevProjID = rootGetters['Projects/projectID'](state.index - 1)
  81. console.log('prevProjID', prevProjID)
  82. let prevProjPos = rootGetters[`project:${prevProjID}/position`]
  83. console.log(`project:${prevProjID}/position.x`, prevProjPos.x)
  84. let prevProjSize = rootGetters[`project:${prevProjID}/size`]
  85. console.log(`project:${prevProjID}/size.x`, prevProjSize.x)
  86. console.log('state.size.x', state.size.x)
  87. // prev X + alf of prev size x + margin + half of current size x
  88. x = prevProjPos.x + prevProjSize.x / 2 + margin + state.size.x / 2
  89. }
  90. console.log('x', x)
  91. commit('setPosition', {
  92. x: x,
  93. y: -1 * state.size.y / 2 + 10 + Math.random() * 30, // -10 + Math.random() * this.size.y / 2
  94. z: -10 + Math.random() * 10
  95. })
  96. // // WINDOWS
  97. // // removing windows on X until padding is enough
  98. // a = 0
  99. // state.wall.nbrWinX = Math.floor((state.size.x - 2 * state.wall.margin) / state.wall.winW)
  100. // while (state.wall.paddingX < 0.4) {
  101. // state.wall.nbrWinX -= a
  102. // state.wall.paddingX = (state.size.x - 2 * state.wall.margin - state.wall.winW * state.wall.nbrWinX) / (state.wall.nbrWinX - 1)
  103. // a++
  104. // }
  105. // // removing windows on Y until padding is enough
  106. // a = 0
  107. // state.wall.nbrWinY = Math.floor((state.size.y - 2 * state.wall.margin) / state.wall.winH)
  108. // while (state.wall.paddingY < 0.4) {
  109. // state.wall.nbrWinY -= a
  110. // state.wall.paddingY = (state.size.y - 2 * state.wall.margin - state.wall.winH * state.wall.nbrWinY) / (state.wall.nbrWinY - 1)
  111. // a++
  112. // }
  113. // state.wall = { ...wall }
  114. //
  115. // // CONTENTS GRID
  116. // a = 0
  117. // state.wall.nbrWinZ = Math.floor((state.size.z - 2 * state.wall.margin) / state.wall.winW)
  118. // while (state.wall.paddingZ < 0.4) {
  119. // state.wall.nbrWinZ -= a
  120. // state.wall.paddingZ = (state.size.z - 2 * state.wall.margin - state.wall.winW * state.wall.nbrWinZ) / (state.wall.nbrWinZ - 1)
  121. // a++
  122. // }
  123. //
  124. // grid = []
  125. // for (var l = 0; l < state.wall.nbrWinZ * 2; l++) { // cols
  126. // for (var m = 0; m < state.wall.nbrWinY * 2; m++) { // rows
  127. // grid.push({
  128. // z: margin + state.wall.winW / 2 * l,
  129. // y: margin + state.wall.winH / 2 * m
  130. // })
  131. // }
  132. // }
  133. // // shuffle the grid
  134. // for (let n = grid.length - 1; n > 0; n--) {
  135. // const o = Math.floor(Math.random() * n)
  136. // const temp = grid[n]
  137. // grid[n] = grid[o]
  138. // grid[o] = temp
  139. // }
  140. // state.grid = [ ...grid ]
  141. },
  142. build3dObjs ({ dispatch, commit, state, rootGetters }) {
  143. // http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/
  144. let backGeom = new THREE.BoxGeometry(state.size.x, state.size.y, state.wall.wallW)
  145. let backMesh = new THREE.Mesh(backGeom)
  146. backMesh.position.z = -0.5 * state.size.z
  147. let backBSP = new ThreeBSP(backMesh)
  148. // TODO: use web workers
  149. // https://medium.com/techtrument/multithreading-javascript-46156179cf9a
  150. // let winGeom = new THREE.BoxGeometry(state.wall.winW, state.wall.winH, state.wall.wallW)
  151. // let winMesh = new THREE.Mesh(winGeom)
  152. // let winBSP
  153. // for (var i = 0; i < state.wall.nbrWinX; i++) {
  154. // for (var j = 0; j < state.wall.nbrWinY; j++) {
  155. // winMesh.position.z = -0.5 * state.size.z
  156. // winMesh.position.x = -0.5 * state.size.x + state.wall.margin + state.wall.winW * 0.5 + i * (state.wall.winW + state.wall.paddingX)
  157. // winMesh.position.y = 0.5 * state.size.y - state.wall.margin - state.wall.winH * 0.5 - j * (state.wall.winH + state.wall.paddingY)
  158. // winBSP = new ThreeBSP(winMesh)
  159. // backBSP = backBSP.subtract(winBSP)
  160. // }
  161. // }
  162. //
  163. // // let abovewWaterH = position.y + state.size.y / 2
  164. // // let underWaterHThd = (-1 * position.y - state.size.y / 2) / 3
  165. // // let levelH = 4
  166. // // let levelGeom = new THREE.BoxGeometry(state.size.x, levelH, wallW)
  167. // // let levelMesh, levelBSP
  168. // // for (var l = 0; l < 2; l++) {
  169. // // levelMesh = new THREE.Mesh(levelGeom)
  170. // // levelMesh.position.z = -0.5 * state.size.z
  171. // // levelMesh.position.y = 0.5 * state.size.y - abovewWaterH - underWaterHThd - underWaterHThd * l + levelH * 0.5
  172. // // levelBSP = new ThreeBSP(levelMesh)
  173. // // backBSP = backBSP.union(levelBSP)
  174. // // }
  175. backMesh = backBSP.toMesh()
  176. let faceMesh = backMesh.clone()
  177. faceMesh.position.z = 0.5 * state.size.z
  178. let faceBSP = new ThreeBSP(faceMesh)
  179. let rightGeom = new THREE.BoxGeometry(state.wall.wallW, state.size.y, state.size.z)
  180. let rightMesh = new THREE.Mesh(rightGeom)
  181. rightMesh.position.x = 0.5 * state.size.x
  182. // rightMesh.position.z = 0.5 * state.size.z
  183. let rightBSP = new ThreeBSP(rightMesh)
  184. // // WE MAY NO NEED TO DIG WINDOWS ON SIDE WALLS
  185. // // // dig windows on right
  186. // // let nbrWinZ = Math.floor((state.size.z - 2 * margin) / winW)
  187. // // let paddingZ = (state.size.z - 2 * margin - winW * nbrWinZ) / (nbrWinX - 1)
  188. // // winGeom = new THREE.BoxGeometry(wallW, winH, winW)
  189. // // for (i = 0; i < nbrWinZ; i++) {
  190. // // for (j = 0; j < nbrWinY; j++) {
  191. // // // right
  192. // // winMesh = new THREE.Mesh(winGeom)
  193. // // winMesh.position.x = 0.5 * state.size.x
  194. // // winMesh.position.z = -0.5 * state.size.z + margin + winW * 0.5 + i * (winW + paddingZ)
  195. // // winMesh.position.y = 0.5 * state.size.y - margin - winH * 0.5 - j * (winH + paddingY)
  196. // // winBSP = new ThreeBSP(winMesh)
  197. // // rightBSP = rightBSP.subtract(winBSP)
  198. // // }
  199. // // }
  200. // // rightMesh = rightBSP.toMesh()
  201. let leftMesh = rightMesh.clone()
  202. leftMesh.position.x = -0.5 * state.size.x
  203. // leftMesh.position.z = 0.5 * state.size.z
  204. let leftBSP = new ThreeBSP(leftMesh)
  205. // // let topGeom = new THREE.BoxGeometry(state.size.x, wallW, state.size.z)
  206. // // let topMesh = new THREE.Mesh(topGeom)
  207. // // // topMesh.position.y = -0.5 * state.size.y
  208. // // // let topBSP = new ThreeBSP(topMesh)
  209. // //
  210. // // let floorGeom = new THREE.BoxGeometry(state.size.x, wallW, state.size.z)
  211. // // let floorMesh = new THREE.Mesh(floorGeom)
  212. // // // floorMesh.position.y = 0.5 * state.size.y
  213. // // // let floorBSP = new ThreeBSP(floorMesh)
  214. let buildingBSP = backBSP.union(rightBSP)
  215. buildingBSP = buildingBSP.union(faceBSP)
  216. buildingBSP = buildingBSP.union(leftBSP)
  217. // buildingBSP = buildingBSP.union(topBSP)
  218. // buildingBSP = buildingBSP.union(floorBSP)
  219. // convert back to three.js mesh
  220. let building = buildingBSP.toMesh()
  221. // // create a custom shaderMaterial to had gradian colors
  222. // // var uniforms = THREE.UniformsUtils.merge([
  223. // // THREE.UniformsLib['lights'],
  224. // // {
  225. // // 'topColor': { value: new THREE.Color(0xffffff) },
  226. // // 'groundColor': { value: new THREE.Color(0xbcd6e4) },
  227. // // 'bottomColor': { value: new THREE.Color(0x07223b) },
  228. // // // 'bottomColor': { value: new THREE.Color(0x000000) },
  229. // // // 'groundColor': { value: new THREE.Color(0xff0000) },
  230. // // // 'bottomColor': { value: new THREE.Color(0x00ff00) },
  231. // // lightIntensity: { type: 'f', value: 1.0 }
  232. // // }
  233. // // ])
  234. // // var buildingMat = new THREE.ShaderMaterial({
  235. // // uniforms: uniforms,
  236. // // vertexShader: BgVertex,
  237. // // fragmentShader: BuildingFragment,
  238. // // side: THREE.DoubleSide,
  239. // // lights: true
  240. // // })
  241. // // building.material = buildingMat
  242. // // create a classical material for building
  243. // // let topColor = `hsla(201, 100%, 95%, 1)`
  244. // let hTop = Math.round(195 + Math.random() * 10)
  245. // let sTop = Math.round(100)
  246. // let lTop = Math.round(95)
  247. // let hFloor = Math.round(205 + Math.random() * 10)
  248. // let sFloor = Math.round(40 + Math.random() * 20)
  249. // let lFloor = Math.round(5 + Math.random() * 15)
  250. // let topColor = `hsla(${hTop}, ${sTop}%, ${lTop}%, 1)`
  251. // let bottomColor = `hsla(${hFloor}, ${sFloor}%, ${lFloor}%, 1)`
  252. //
  253. // let gradientTexture = new THREE.CanvasTexture(this.createGradientCanvas(topColor, bottomColor))
  254. let materialOpts = {
  255. color: 0xffffff,
  256. side: THREE.DoubleSide,
  257. shininess: 30
  258. // map: gradientTexture
  259. // wireframe: true,
  260. // transparent: true,
  261. // opacity: 0.6
  262. // renderOrder: 0
  263. }
  264. building.material = new THREE.MeshPhongMaterial(materialOpts)
  265. commit('setWalls3dObj', building)
  266. let buildingPos = { ...state.position, ...{ z: 0.5 * state.size.z } }
  267. commit('setWallsPos', buildingPos)
  268. // // TOP & FLOOR
  269. // let topGeom = new THREE.BoxGeometry(state.size.x, state.wall.wallW, state.size.z)
  270. // let topOpts = {
  271. // color: new THREE.Color(`hsl(${hTop}, ${sTop}%, ${lTop}%)`),
  272. // // side: THREE.DoubleSide,
  273. // shininess: 30
  274. // }
  275. // let topMat = new THREE.MeshPhongMaterial(topOpts)
  276. // let topMesh = new THREE.Mesh(topGeom, topMat)
  277. // let topPosition = { ...position }
  278. // topPosition.y += 0.5 * state.size.y
  279. //
  280. // // let floorGeom = new THREE.BoxGeometry(state.size.x, state.wall.wallW, state.size.z)
  281. // let floorOpts = {
  282. // color: new THREE.Color(`hsl(${hFloor}, ${sFloor}%, ${lFloor}%)`),
  283. // // side: THREE.DoubleSide,
  284. // shininess: 10
  285. // }
  286. // let floorMat = new THREE.MeshPhongMaterial(floorOpts)
  287. // let floorMesh = new THREE.Mesh(topGeom, floorMat)
  288. // let floorPosition = { ...position }
  289. // floorPosition.y -= 0.5 * state.size.y
  290. //
  291. // // LEVELS
  292. // let levelGeom = new THREE.BoxGeometry(state.size.x, 1, state.size.z)
  293. // let levelMesh = new THREE.Mesh(levelGeom)
  294. // let levelBSP = new ThreeBSP(levelMesh)
  295. // let levelHoleGeom = new THREE.BoxGeometry(state.size.x - 3, 1, state.size.z - 3)
  296. // let levelHoleMesh = new THREE.Mesh(levelHoleGeom)
  297. // let levelHoleBSP = new ThreeBSP(levelHoleMesh)
  298. // levelBSP = levelBSP.subtract(levelHoleBSP)
  299. // levelMesh = levelBSP.toMesh()
  300. // let levelOpts = {
  301. // color: 0xff0000,
  302. // shininess: 10
  303. // }
  304. // let levelMat = new THREE.MeshPhongMaterial(levelOpts)
  305. // levelMesh.material = levelMat
  306. }
  307. }
  308. }