background.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';
  2. import {math} from './math.js';
  3. import {GLTFLoader} from 'https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/loaders/GLTFLoader.js';
  4. import {FBXLoader} from 'https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/loaders/FBXLoader.js';
  5. export const background = (() => {
  6. class BackgroundCloud {
  7. constructor(params) {
  8. this.params_ = params;
  9. this.position_ = new THREE.Vector3();
  10. this.quaternion_ = new THREE.Quaternion();
  11. this.scale_ = 1.0;
  12. this.mesh_ = null;
  13. this.LoadModel_();
  14. }
  15. LoadModel_() {
  16. const loader = new GLTFLoader();
  17. loader.setPath('./resources/Clouds/GLTF/');
  18. loader.load('Cloud' + math.rand_int(1, 3) + '.glb', (glb) => {
  19. this.mesh_ = glb.scene;
  20. this.params_.scene.add(this.mesh_);
  21. this.position_.x = math.rand_range(0, 2000);
  22. this.position_.y = math.rand_range(100, 200);
  23. this.position_.z = math.rand_range(500, -1000);
  24. this.scale_ = math.rand_range(10, 20);
  25. const q = new THREE.Quaternion().setFromAxisAngle(
  26. new THREE.Vector3(0, 1, 0), math.rand_range(0, 360));
  27. this.quaternion_.copy(q);
  28. this.mesh_.traverse(c => {
  29. if (c.geometry) {
  30. c.geometry.computeBoundingBox();
  31. }
  32. let materials = c.material;
  33. if (!(c.material instanceof Array)) {
  34. materials = [c.material];
  35. }
  36. for (let m of materials) {
  37. if (m) {
  38. m.specular = new THREE.Color(0x000000);
  39. m.emissive = new THREE.Color(0xC0C0C0);
  40. }
  41. }
  42. c.castShadow = true;
  43. c.receiveShadow = true;
  44. });
  45. });
  46. }
  47. Update(timeElapsed) {
  48. if (!this.mesh_) {
  49. return;
  50. }
  51. this.position_.x -= timeElapsed * 10;
  52. if (this.position_.x < -100) {
  53. this.position_.x = math.rand_range(2000, 3000);
  54. }
  55. this.mesh_.position.copy(this.position_);
  56. this.mesh_.quaternion.copy(this.quaternion_);
  57. this.mesh_.scale.setScalar(this.scale_);
  58. }
  59. };
  60. class BackgroundCrap {
  61. constructor(params) {
  62. this.params_ = params;
  63. this.position_ = new THREE.Vector3();
  64. this.quaternion_ = new THREE.Quaternion();
  65. this.scale_ = 1.0;
  66. this.mesh_ = null;
  67. this.LoadModel_();
  68. }
  69. LoadModel_() {
  70. const assets = [
  71. ['SmallPalmTree.glb', 'PalmTree.png', 3],
  72. ['BigPalmTree.glb', 'PalmTree.png', 5],
  73. ['Skull.glb', 'Ground.png', 1],
  74. ['Scorpion.glb', 'Scorpion.png', 1],
  75. ['Pyramid.glb', 'Ground.png', 40],
  76. ['Monument.glb', 'Ground.png', 10],
  77. ['Cactus1.glb', 'Ground.png', 5],
  78. ['Cactus2.glb', 'Ground.png', 5],
  79. ['Cactus3.glb', 'Ground.png', 5],
  80. ];
  81. const [asset, textureName, scale] = assets[math.rand_int(0, assets.length - 1)];
  82. const texLoader = new THREE.TextureLoader();
  83. const texture = texLoader.load('./resources/DesertPack/Blend/Textures/' + textureName);
  84. texture.encoding = THREE.sRGBEncoding;
  85. const loader = new GLTFLoader();
  86. loader.setPath('./resources/DesertPack/GLTF/');
  87. loader.load(asset, (glb) => {
  88. this.mesh_ = glb.scene;
  89. this.params_.scene.add(this.mesh_);
  90. this.position_.x = math.rand_range(0, 2000);
  91. this.position_.z = math.rand_range(500, -1000);
  92. this.scale_ = scale;
  93. const q = new THREE.Quaternion().setFromAxisAngle(
  94. new THREE.Vector3(0, 1, 0), math.rand_range(0, 360));
  95. this.quaternion_.copy(q);
  96. this.mesh_.traverse(c => {
  97. let materials = c.material;
  98. if (!(c.material instanceof Array)) {
  99. materials = [c.material];
  100. }
  101. for (let m of materials) {
  102. if (m) {
  103. if (texture) {
  104. m.map = texture;
  105. }
  106. m.specular = new THREE.Color(0x000000);
  107. }
  108. }
  109. c.castShadow = true;
  110. c.receiveShadow = true;
  111. });
  112. });
  113. }
  114. Update(timeElapsed) {
  115. if (!this.mesh_) {
  116. return;
  117. }
  118. this.position_.x -= timeElapsed * 10;
  119. if (this.position_.x < -100) {
  120. this.position_.x = math.rand_range(2000, 3000);
  121. }
  122. this.mesh_.position.copy(this.position_);
  123. this.mesh_.quaternion.copy(this.quaternion_);
  124. this.mesh_.scale.setScalar(this.scale_);
  125. }
  126. };
  127. class Background {
  128. constructor(params) {
  129. this.params_ = params;
  130. this.clouds_ = [];
  131. this.crap_ = [];
  132. this.SpawnClouds_();
  133. this.SpawnCrap_();
  134. }
  135. SpawnClouds_() {
  136. for (let i = 0; i < 25; ++i) {
  137. const cloud = new BackgroundCloud(this.params_);
  138. this.clouds_.push(cloud);
  139. }
  140. }
  141. SpawnCrap_() {
  142. for (let i = 0; i < 50; ++i) {
  143. const crap = new BackgroundCrap(this.params_);
  144. this.crap_.push(crap);
  145. }
  146. }
  147. Update(timeElapsed) {
  148. for (let c of this.clouds_) {
  149. c.Update(timeElapsed);
  150. }
  151. for (let c of this.crap_) {
  152. c.Update(timeElapsed);
  153. }
  154. }
  155. }
  156. return {
  157. Background: Background,
  158. };
  159. })();