Project.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <template>
  2. <div>
  3. <object3d ref="block3d" name="Project" :obj="building" :position="building_position" />
  4. <object3d ref="top" :obj="top_mesh" :position="top_position" />
  5. <object3d ref="floor" :obj="floor_mesh" :position="floor_position" />
  6. <object3d ref="level" :obj="level_mesh" :position="level_position" />
  7. <!-- <light :obj="light" :position="building_position" /> -->
  8. <mesh ref="label3d" name="Label" :position="label_position">
  9. <geometry type="Plane" :args="[label_size.x, label_size.y]" />
  10. <material type="MeshLambert" :options="label_opts">
  11. <texture :options="label_texture_opts" />
  12. </material>
  13. </mesh>
  14. <!-- <div v-if="isOpened">
  15. <ContentBlock
  16. v-for="item in data.visibles"
  17. :key="item.id"
  18. :prtPosition="position"
  19. :prtSize="size"
  20. :prtIndex="index"
  21. type="visible"
  22. :data="item"
  23. />
  24. <ContentBlock
  25. v-for="item in data.contexts"
  26. :key="item.id"
  27. :prtPosition="position"
  28. :prtSize="size"
  29. :prtIndex="index"
  30. type="context"
  31. :data="item"
  32. />
  33. <ContentBlock
  34. v-for="item in data.processes"
  35. :key="item.id"
  36. :prtPosition="position"
  37. :prtSize="size"
  38. :prtIndex="index"
  39. type="process"
  40. :data="item"
  41. />
  42. <ContentBlock
  43. v-for="item in data.concepts"
  44. :key="item.id"
  45. :prtPosition="position"
  46. :prtSize="size"
  47. :prtIndex="index"
  48. type="concept"
  49. :data="item"
  50. />
  51. </div> -->
  52. </div>
  53. </template>
  54. <script>
  55. import { mapInstanceState } from '@urbn/vuex-helpers'
  56. import * as THREE from 'three'
  57. // import { toCSG, fromCSG } from 'three-csg'
  58. import { ThreeBSP } from 'three-js-csg-es6'
  59. import mixins from 'components/mixins'
  60. // import ContentBlock from 'components/objects/ContentBlock'
  61. // import BgVertex from 'assets/glsl/BgVertex'
  62. // import BuildingFragment from 'assets/glsl/BuildingFragment'
  63. // We'll determine our module based on the moduleName prop on this component
  64. // https://www.npmjs.com/package/@urbn/vuex-helpers
  65. const getModuleName = cmp => `project:${cmp.id}`
  66. export default {
  67. name: 'Project',
  68. components: {
  69. // ContentBlock
  70. },
  71. mixins: [mixins],
  72. props: { id: Number, title: String },
  73. data () {
  74. console.log('Project data() : data', this.data)
  75. // get size and positions from project store
  76. let size = { ...this.data.size }
  77. let position = { ...this.data.position }
  78. let wall = { ...this.data.wall }
  79. // http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/
  80. // console.log('ThreeBSP', ThreeBSP)
  81. let backGeom = new THREE.BoxGeometry(size.x, size.y, wall.wallW)
  82. let backMesh = new THREE.Mesh(backGeom)
  83. backMesh.position.z = -0.5 * size.z
  84. let backBSP = new ThreeBSP(backMesh)
  85. let winGeom = new THREE.BoxGeometry(wall.winW, wall.winH, wall.wallW)
  86. let winMesh = new THREE.Mesh(winGeom)
  87. let winBSP
  88. for (var i = 0; i < wall.nbrWinX; i++) {
  89. for (var j = 0; j < wall.nbrWinY; j++) {
  90. winMesh.position.z = -0.5 * size.z
  91. winMesh.position.x = -0.5 * size.x + wall.margin + wall.winW * 0.5 + i * (wall.winW + wall.paddingX)
  92. winMesh.position.y = 0.5 * size.y - wall.margin - wall.winH * 0.5 - j * (wall.winH + wall.paddingY)
  93. winBSP = new ThreeBSP(winMesh)
  94. backBSP = backBSP.subtract(winBSP)
  95. }
  96. }
  97. // let abovewWaterH = position.y + size.y / 2
  98. // let underWaterHThd = (-1 * position.y - size.y / 2) / 3
  99. // let levelH = 4
  100. // let levelGeom = new THREE.BoxGeometry(size.x, levelH, wallW)
  101. // let levelMesh, levelBSP
  102. // for (var l = 0; l < 2; l++) {
  103. // levelMesh = new THREE.Mesh(levelGeom)
  104. // levelMesh.position.z = -0.5 * size.z
  105. // levelMesh.position.y = 0.5 * size.y - abovewWaterH - underWaterHThd - underWaterHThd * l + levelH * 0.5
  106. // levelBSP = new ThreeBSP(levelMesh)
  107. // backBSP = backBSP.union(levelBSP)
  108. // }
  109. backMesh = backBSP.toMesh()
  110. let faceMesh = backMesh.clone()
  111. faceMesh.position.z = 0.5 * size.z
  112. let faceBSP = new ThreeBSP(faceMesh)
  113. let rightGeom = new THREE.BoxGeometry(wall.wallW, size.y, size.z)
  114. let rightMesh = new THREE.Mesh(rightGeom)
  115. rightMesh.position.x = 0.5 * size.x
  116. // rightMesh.position.z = 0.5 * size.z
  117. let rightBSP = new ThreeBSP(rightMesh)
  118. // WE MAY NO NEED TO DIG WINDOWS ON SIDE WALLS
  119. // // dig windows on right
  120. // let nbrWinZ = Math.floor((size.z - 2 * margin) / winW)
  121. // let paddingZ = (size.z - 2 * margin - winW * nbrWinZ) / (nbrWinX - 1)
  122. // winGeom = new THREE.BoxGeometry(wallW, winH, winW)
  123. // for (i = 0; i < nbrWinZ; i++) {
  124. // for (j = 0; j < nbrWinY; j++) {
  125. // // right
  126. // winMesh = new THREE.Mesh(winGeom)
  127. // winMesh.position.x = 0.5 * size.x
  128. // winMesh.position.z = -0.5 * size.z + margin + winW * 0.5 + i * (winW + paddingZ)
  129. // winMesh.position.y = 0.5 * size.y - margin - winH * 0.5 - j * (winH + paddingY)
  130. // winBSP = new ThreeBSP(winMesh)
  131. // rightBSP = rightBSP.subtract(winBSP)
  132. // }
  133. // }
  134. // rightMesh = rightBSP.toMesh()
  135. let leftMesh = rightMesh.clone()
  136. leftMesh.position.x = -0.5 * size.x
  137. // leftMesh.position.z = 0.5 * size.z
  138. let leftBSP = new ThreeBSP(leftMesh)
  139. //
  140. // let topGeom = new THREE.BoxGeometry(size.x, wallW, size.z)
  141. // let topMesh = new THREE.Mesh(topGeom)
  142. // // topMesh.position.y = -0.5 * size.y
  143. // // let topBSP = new ThreeBSP(topMesh)
  144. //
  145. // let floorGeom = new THREE.BoxGeometry(size.x, wallW, size.z)
  146. // let floorMesh = new THREE.Mesh(floorGeom)
  147. // // floorMesh.position.y = 0.5 * size.y
  148. // // let floorBSP = new ThreeBSP(floorMesh)
  149. let buildingBSP = backBSP.union(rightBSP)
  150. buildingBSP = buildingBSP.union(faceBSP)
  151. buildingBSP = buildingBSP.union(leftBSP)
  152. // buildingBSP = buildingBSP.union(topBSP)
  153. // buildingBSP = buildingBSP.union(floorBSP)
  154. // convert back to three.js mesh
  155. let building = buildingBSP.toMesh()
  156. console.log('building.faces', building)
  157. // create a custom shaderMaterial to had gradian colors
  158. // var uniforms = THREE.UniformsUtils.merge([
  159. // THREE.UniformsLib['lights'],
  160. // {
  161. // 'topColor': { value: new THREE.Color(0xffffff) },
  162. // 'groundColor': { value: new THREE.Color(0xbcd6e4) },
  163. // 'bottomColor': { value: new THREE.Color(0x07223b) },
  164. // // 'bottomColor': { value: new THREE.Color(0x000000) },
  165. // // 'groundColor': { value: new THREE.Color(0xff0000) },
  166. // // 'bottomColor': { value: new THREE.Color(0x00ff00) },
  167. // lightIntensity: { type: 'f', value: 1.0 }
  168. // }
  169. // ])
  170. // var buildingMat = new THREE.ShaderMaterial({
  171. // uniforms: uniforms,
  172. // vertexShader: BgVertex,
  173. // fragmentShader: BuildingFragment,
  174. // side: THREE.DoubleSide,
  175. // lights: true
  176. // })
  177. // building.material = buildingMat
  178. // create a classical material for building
  179. // let topColor = `hsla(201, 100%, 95%, 1)`
  180. let hTop = Math.round(195 + Math.random() * 10)
  181. let sTop = Math.round(100)
  182. let lTop = Math.round(95)
  183. let hFloor = Math.round(205 + Math.random() * 10)
  184. let sFloor = Math.round(40 + Math.random() * 20)
  185. let lFloor = Math.round(5 + Math.random() * 15)
  186. let topColor = `hsla(${hTop}, ${sTop}%, ${lTop}%, 1)`
  187. let bottomColor = `hsla(${hFloor}, ${sFloor}%, ${lFloor}%, 1)`
  188. let gradientTexture = new THREE.CanvasTexture(this.createGradientCanvas(topColor, bottomColor))
  189. let materialOpts = {
  190. color: 0xffffff,
  191. side: THREE.DoubleSide,
  192. shininess: 30,
  193. map: gradientTexture
  194. // wireframe: true,
  195. // transparent: true,
  196. // opacity: 0.6
  197. // renderOrder: 0
  198. }
  199. building.material = new THREE.MeshPhongMaterial(materialOpts)
  200. // building.castShadow = true
  201. // building.receiveShadow = true
  202. // let buildingGeom = fromCSG(boxCSG)
  203. // buildingGeom.computeVertexNormals()
  204. // result
  205. // let subtractCSG = boxMeshCSG.subtract(holeMeshCSG)
  206. // let building = fromCSG(boxMeshCSG) // converting CSG back into ThreeJS object
  207. //
  208. let buildingPos = { ...position }
  209. buildingPos.z -= 0.5 * size.z
  210. // TOP & FLOOR
  211. let topGeom = new THREE.BoxGeometry(size.x, wall.wallW, size.z)
  212. let topOpts = {
  213. color: new THREE.Color(`hsl(${hTop}, ${sTop}%, ${lTop}%)`),
  214. // side: THREE.DoubleSide,
  215. shininess: 30
  216. }
  217. let topMat = new THREE.MeshPhongMaterial(topOpts)
  218. let topMesh = new THREE.Mesh(topGeom, topMat)
  219. let topPosition = { ...position }
  220. topPosition.y += 0.5 * size.y
  221. // let floorGeom = new THREE.BoxGeometry(size.x, wall.wallW, size.z)
  222. let floorOpts = {
  223. color: new THREE.Color(`hsl(${hFloor}, ${sFloor}%, ${lFloor}%)`),
  224. // side: THREE.DoubleSide,
  225. shininess: 10
  226. }
  227. let floorMat = new THREE.MeshPhongMaterial(floorOpts)
  228. let floorMesh = new THREE.Mesh(topGeom, floorMat)
  229. let floorPosition = { ...position }
  230. floorPosition.y -= 0.5 * size.y
  231. // LEVELS
  232. let levelGeom = new THREE.BoxGeometry(size.x, 1, size.z)
  233. let levelMesh = new THREE.Mesh(levelGeom)
  234. let levelBSP = new ThreeBSP(levelMesh)
  235. let levelHoleGeom = new THREE.BoxGeometry(size.x - 3, 1, size.z - 3)
  236. let levelHoleMesh = new THREE.Mesh(levelHoleGeom)
  237. let levelHoleBSP = new ThreeBSP(levelHoleMesh)
  238. levelBSP = levelBSP.subtract(levelHoleBSP)
  239. levelMesh = levelBSP.toMesh()
  240. let levelOpts = {
  241. color: 0xff0000,
  242. shininess: 10
  243. }
  244. let levelMat = new THREE.MeshPhongMaterial(levelOpts)
  245. levelMesh.material = levelMat
  246. return {
  247. modName: null,
  248. block3d: null,
  249. // block_opts: materialOpts,
  250. label3d: null,
  251. label_opts: {
  252. side: THREE.DoubleSide,
  253. // wireframe: false,
  254. transparent: true
  255. // opacity: 0.6
  256. // renderOrder: 0
  257. },
  258. // size and positions are defined in store project
  259. size: size,
  260. position: position,
  261. // geometry: geometry,
  262. // light: light,
  263. building: building,
  264. building_position: buildingPos,
  265. top_mesh: topMesh,
  266. top_position: topPosition,
  267. floor_mesh: floorMesh,
  268. floor_position: floorPosition,
  269. level_mesh: levelMesh,
  270. level_position: { ...position },
  271. label_position: { x: 0, y: 0, z: 0 },
  272. color: 0xffffff,
  273. label_canvas: null,
  274. label_size: null,
  275. isOpened: false
  276. }
  277. },
  278. computed: {
  279. ...mapInstanceState(getModuleName, {
  280. storeID: state => state.id
  281. }),
  282. label_texture_opts () {
  283. return {
  284. canvas: this.label_canvas,
  285. minFilter: THREE.LinearFilter,
  286. wrapS: THREE.ClampToEdgeWrapping,
  287. wrapT: THREE.ClampToEdgeWrapping
  288. }
  289. }
  290. },
  291. created () {
  292. console.log('Project created: data', this, this.data)
  293. console.log('Project created: getModuleName', getModuleName)
  294. // TODO: create dynamic vuex module for each project
  295. // this.modNameSpace = `project:${this.data.id}`
  296. // this.label_canvas = this.createLabelCanvas(this.data.Titre.replace(/ /g, '\n').toUpperCase(), 48, 21, '#000000', '#ffffff')
  297. this.label_canvas = this.createLabelCanvas(this.storeID.replace(/ /g, '\n').toUpperCase(), 48, 21, '#000000', '#ffffff')
  298. this.label_position.x = this.position.x - this.size.x / 2 + this.label_size.x / 2 + 1
  299. this.label_position.y = this.position.y + this.size.y / 2 - this.label_size.y / 2 - 1
  300. this.label_position.z = this.position.z + this.size.z / 2 + 0.5
  301. // console.log('this.label_canvas', this.label_canvas)
  302. },
  303. mounted () {
  304. console.log('project mounted', this)
  305. // record self references
  306. this.block3d = this.$refs.block3d.curObj
  307. // this.block3d.castShadow = true
  308. // this.block3d.receiveShadow = true
  309. this.block3d.userData = {
  310. vnode: this
  311. }
  312. this.label3d = this.$refs.label3d.curObj
  313. // light
  314. // console.log('project mounted', this.$env3d)
  315. // var light = new THREE.AmbientLight(0xbf1a1a) // soft white light
  316. // this.$env3d.scene.add(light)
  317. },
  318. methods: {
  319. }
  320. }
  321. </script>