levelloader.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import * as THREE from 'three'
  2. import { loadGltf } from './loadgltf.js'
  3. export default class LevelLoader {
  4. constructor(inGame) {
  5. this.game = inGame
  6. }
  7. async load(levelData) {
  8. let instancedMeshes = []
  9. for(let i = 0; i < levelData.models.length; i++) {
  10. let count = levelData.tiles.reduce((count, tile) => {
  11. if (tile.model == i) {
  12. return ++count
  13. } else {
  14. return count
  15. }
  16. }, 0)
  17. if(count == 0) {
  18. console.warn(`model ${levelData.models[i]} at index ${i} not used.`)
  19. continue
  20. }
  21. let model = levelData.models[i]
  22. const tileMeshScene = await loadGltf(this.game, model)
  23. let firstMesh
  24. tileMeshScene.traverse((child) => {
  25. if (child.isMesh) {
  26. firstMesh = child
  27. return
  28. }
  29. })
  30. const tileMesh = new THREE.InstancedMesh(firstMesh.geometry, firstMesh.material, count)
  31. tileMesh.receiveShadow = true
  32. instancedMeshes[i] = tileMesh
  33. }
  34. const matrix = new THREE.Matrix4()
  35. levelData.models.forEach((model, modelIndex) => {
  36. levelData.tiles.filter(tile => tile.model == modelIndex).forEach((tile, tileIndex) => {
  37. const position = new THREE.Vector3(tile.position[0] * 4, tile.position[1], tile.position[2] * 4)
  38. const quaternion = new THREE.Quaternion()
  39. quaternion.setFromAxisAngle(THREE.Object3D.DEFAULT_UP, tile.rotation)
  40. const scale = new THREE.Vector3(1, 1, 1)
  41. matrix.compose(position, quaternion, scale)
  42. instancedMeshes[modelIndex].setMatrixAt(tileIndex, matrix)
  43. })
  44. })
  45. levelData.meta.shadow.forEach(modelIndex => {
  46. if(instancedMeshes[modelIndex]) {
  47. instancedMeshes[modelIndex].castShadow = true
  48. instancedMeshes[modelIndex].receiveShadow = true
  49. }
  50. })
  51. return instancedMeshes
  52. }
  53. }