Project.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <template>
  2. <div>
  3. <object3d ref="block3d" name="Project" :obj="building" :position="building_position"/>
  4. <mesh ref="label3d" name="Label" :position="label_position">
  5. <geometry type="Plane" :args="[label_size.x, label_size.y]" />
  6. <material type="MeshLambert" :options="label_opts">
  7. <texture :options="label_texture_opts" />
  8. </material>
  9. </mesh>
  10. <div v-if="isOpened">
  11. <ContentBlock
  12. v-for="item in data.visibles"
  13. :key="item.id"
  14. :prtPosition="position"
  15. :prtSize="size"
  16. type="visible"
  17. :data="item"
  18. />
  19. <ContentBlock
  20. v-for="item in data.contexts"
  21. :key="item.id"
  22. :prtPosition="position"
  23. :prtSize="size"
  24. type="context"
  25. :data="item"
  26. />
  27. <ContentBlock
  28. v-for="item in data.processes"
  29. :key="item.id"
  30. :prtPosition="position"
  31. :prtSize="size"
  32. type="process"
  33. :data="item"
  34. />
  35. <ContentBlock
  36. v-for="item in data.concepts"
  37. :key="item.id"
  38. :prtPosition="position"
  39. :prtSize="size"
  40. type="concept"
  41. :data="item"
  42. />
  43. </div>
  44. </div>
  45. </template>
  46. <script>
  47. import * as THREE from 'three'
  48. // import { toCSG, fromCSG } from 'three-csg'
  49. import { ThreeBSP } from 'three-js-csg-es6'
  50. import mixins from 'components/mixins'
  51. import ContentBlock from 'components/objects/ContentBlock'
  52. import BgVertex from 'assets/glsl/BgVertex'
  53. import BuildingFragment from 'assets/glsl/BuildingFragment'
  54. export default {
  55. name: 'Project',
  56. components: {
  57. ContentBlock
  58. },
  59. mixins: [mixins],
  60. // props: { size: Object, texture: String, position: Object, color: Number },
  61. props: { data: Object, len: Number, index: Number },
  62. data () {
  63. console.log('Project data() : data', this.data)
  64. // get size and positions from project store
  65. let size = { ...this.data.size }
  66. let position = { ...this.data.position }
  67. // http://learningthreejs.com/blog/2011/12/10/constructive-solid-geometry-with-csg-js/
  68. // console.log('ThreeBSP', ThreeBSP)
  69. let wallW = 0.001
  70. let topGeom = new THREE.BoxGeometry(size.x, wallW, size.z)
  71. let topMesh = new THREE.Mesh(topGeom)
  72. topMesh.position.y = -0.5 * size.y
  73. let topBSP = new ThreeBSP(topMesh)
  74. let floorGeom = new THREE.BoxGeometry(size.x, wallW, size.z)
  75. let floorMesh = new THREE.Mesh(floorGeom)
  76. floorMesh.position.y = 0.5 * size.y
  77. let floorBSP = new ThreeBSP(floorMesh)
  78. let backGeom = new THREE.BoxGeometry(size.x, size.y, wallW)
  79. let backMesh = new THREE.Mesh(backGeom)
  80. backMesh.position.z = -0.5 * size.z
  81. let backBSP = new ThreeBSP(backMesh)
  82. // dig windows on face and back
  83. let winW = 4
  84. let winH = 8
  85. let margin = 2
  86. let nbrWinX = 0
  87. let paddingX = 0
  88. let a = 0
  89. // removing windows until padding is enough
  90. while (paddingX < 0.4) {
  91. nbrWinX = Math.floor((size.x - 2 * margin) / winW) - a
  92. paddingX = (size.x - 2 * margin - winW * nbrWinX) / (nbrWinX - 1)
  93. a++
  94. }
  95. // console.log('paddingX', paddingX)
  96. let nbrWinY = 0
  97. let paddingY = 0
  98. a = 0
  99. // removing windows until padding is enough
  100. while (paddingY < 0.4) {
  101. nbrWinY = Math.floor((size.y - 2 * margin) / winH) - a
  102. paddingY = (size.y - 2 * margin - winH * nbrWinY) / (nbrWinY - 1)
  103. a++
  104. }
  105. let winGeom = new THREE.BoxGeometry(winW, winH, wallW)
  106. let winMesh, winBSP
  107. for (var i = 0; i < nbrWinX; i++) {
  108. for (var j = 0; j < nbrWinY; j++) {
  109. // back
  110. winMesh = new THREE.Mesh(winGeom)
  111. winMesh.position.z = -0.5 * size.z
  112. winMesh.position.x = -0.5 * size.x + margin + winW * 0.5 + i * (winW + paddingX)
  113. winMesh.position.y = 0.5 * size.y - margin - winH * 0.5 - j * (winH + paddingY)
  114. winBSP = new ThreeBSP(winMesh)
  115. backBSP = backBSP.subtract(winBSP)
  116. }
  117. }
  118. // let abovewWaterH = position.y + size.y / 2
  119. // let underWaterHThd = (-1 * position.y - size.y / 2) / 3
  120. // let levelH = 4
  121. // let levelGeom = new THREE.BoxGeometry(size.x, levelH, wallW)
  122. // let levelMesh, levelBSP
  123. // for (var l = 0; l < 2; l++) {
  124. // levelMesh = new THREE.Mesh(levelGeom)
  125. // levelMesh.position.z = -0.5 * size.z
  126. // levelMesh.position.y = 0.5 * size.y - abovewWaterH - underWaterHThd - underWaterHThd * l + levelH * 0.5
  127. // levelBSP = new ThreeBSP(levelMesh)
  128. // backBSP = backBSP.union(levelBSP)
  129. // }
  130. backMesh = backBSP.toMesh()
  131. let faceMesh = backMesh.clone()
  132. faceMesh.position.z = 0.5 * size.z
  133. let faceBSP = new ThreeBSP(faceMesh)
  134. let rightGeom = new THREE.BoxGeometry(wallW, size.y, size.z)
  135. let rightMesh = new THREE.Mesh(rightGeom)
  136. rightMesh.position.x = 0.5 * size.x
  137. // rightMesh.position.z = 0.5 * size.z
  138. let rightBSP = new ThreeBSP(rightMesh)
  139. // WE MAY NO NEED TO DIG WINDOWS ON SIDE WALLS
  140. // // dig windows on right
  141. // let nbrWinZ = Math.floor((size.z - 2 * margin) / winW)
  142. // let paddingZ = (size.z - 2 * margin - winW * nbrWinZ) / (nbrWinX - 1)
  143. // winGeom = new THREE.BoxGeometry(wallW, winH, winW)
  144. // for (i = 0; i < nbrWinZ; i++) {
  145. // for (j = 0; j < nbrWinY; j++) {
  146. // // right
  147. // winMesh = new THREE.Mesh(winGeom)
  148. // winMesh.position.x = 0.5 * size.x
  149. // winMesh.position.z = -0.5 * size.z + margin + winW * 0.5 + i * (winW + paddingZ)
  150. // winMesh.position.y = 0.5 * size.y - margin - winH * 0.5 - j * (winH + paddingY)
  151. // winBSP = new ThreeBSP(winMesh)
  152. // rightBSP = rightBSP.subtract(winBSP)
  153. // }
  154. // }
  155. // rightMesh = rightBSP.toMesh()
  156. let leftMesh = rightMesh.clone()
  157. leftMesh.position.x = -0.5 * size.x
  158. // leftMesh.position.z = 0.5 * size.z
  159. let leftBSP = new ThreeBSP(leftMesh)
  160. let buildingBSP = backBSP.union(rightBSP)
  161. buildingBSP = buildingBSP.union(faceBSP)
  162. buildingBSP = buildingBSP.union(leftBSP)
  163. buildingBSP = buildingBSP.union(topBSP)
  164. buildingBSP = buildingBSP.union(floorBSP)
  165. // convert back to three.js mesh
  166. let building = buildingBSP.toMesh()
  167. // create a custom shaderMaterial to had gradian colors
  168. var uniforms = THREE.UniformsUtils.merge([
  169. THREE.UniformsLib['lights'],
  170. {
  171. 'topColor': { value: new THREE.Color(0xffffff) },
  172. 'groundColor': { value: new THREE.Color(0xbcd6e4) },
  173. 'bottomColor': { value: new THREE.Color(0x07223b) },
  174. // 'bottomColor': { value: new THREE.Color(0x000000) },
  175. // 'groundColor': { value: new THREE.Color(0xff0000) },
  176. // 'bottomColor': { value: new THREE.Color(0x00ff00) },
  177. lightIntensity: { type: 'f', value: 1.0 }
  178. }
  179. ])
  180. var buildingMat = new THREE.ShaderMaterial({
  181. uniforms: uniforms,
  182. vertexShader: BgVertex,
  183. fragmentShader: BuildingFragment,
  184. side: THREE.DoubleSide,
  185. lights: true
  186. })
  187. building.material = buildingMat
  188. // create a classical material for building
  189. // let materialOpts = {
  190. // color: 0xffffff,
  191. // side: THREE.DoubleSide
  192. // // wireframe: true,
  193. // // transparent: true,
  194. // // opacity: 0.6
  195. // // renderOrder: 0
  196. // }
  197. // building.material = new THREE.MeshLambertMaterial(materialOpts)
  198. // building.castShadow = true
  199. // building.receiveShadow = true
  200. // let buildingGeom = fromCSG(boxCSG)
  201. // buildingGeom.computeVertexNormals()
  202. // result
  203. // let subtractCSG = boxMeshCSG.subtract(holeMeshCSG)
  204. // let building = fromCSG(boxMeshCSG) // converting CSG back into ThreeJS object
  205. //
  206. let buildingPos = { ...position }
  207. buildingPos.z -= 0.5 * size.z
  208. return {
  209. block3d: null,
  210. // block_opts: materialOpts,
  211. label3d: null,
  212. label_opts: {
  213. side: THREE.DoubleSide,
  214. // wireframe: false,
  215. transparent: true
  216. // opacity: 0.6
  217. // renderOrder: 0
  218. },
  219. // size and positions are defined in store project
  220. size: size,
  221. position: position,
  222. // geometry: geometry,
  223. building: building,
  224. building_position: buildingPos,
  225. label_position: { x: 0, y: 0, z: 0 },
  226. color: 0xffffff,
  227. label_canvas: null,
  228. label_size: null,
  229. isOpened: false
  230. }
  231. },
  232. computed: {
  233. label_texture_opts () {
  234. return {
  235. canvas: this.label_canvas,
  236. minFilter: THREE.LinearFilter,
  237. wrapS: THREE.ClampToEdgeWrapping,
  238. wrapT: THREE.ClampToEdgeWrapping
  239. }
  240. }
  241. },
  242. created () {
  243. console.log('Project created: data', this, this.data)
  244. this.label_canvas = this.createLabelCanvas(this.data.Titre.replace(/ /g, '\n').toUpperCase(), 48, 21, '#000000', '#ffffff')
  245. this.label_position.x = this.position.x - this.size.x / 2 + this.label_size.x / 2 + 1
  246. this.label_position.y = this.position.y + this.size.y / 2 - this.label_size.y / 2 - 1
  247. this.label_position.z = this.position.z + this.size.z / 2 + 0.5
  248. // console.log('this.label_canvas', this.label_canvas)
  249. },
  250. mounted () {
  251. console.log('project mounted', this)
  252. // record self references
  253. this.block3d = this.$refs.block3d.curObj
  254. // this.block3d.castShadow = true
  255. // this.block3d.receiveShadow = true
  256. this.block3d.userData = {
  257. vnode: this
  258. }
  259. this.label3d = this.$refs.label3d.curObj
  260. // light
  261. // console.log('project mounted', this.$env3d)
  262. // var light = new THREE.AmbientLight(0xbf1a1a) // soft white light
  263. // this.$env3d.scene.add(light)
  264. }
  265. // ,
  266. // methods: {
  267. //
  268. // }
  269. }
  270. </script>