You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
11 KiB

4 years ago
  1. window.addEventListener('DOMContentLoaded', function(){
  2. // get the canvas DOM element
  3. var canvas = document.getElementById('renderCanvas');
  4. // load the 3D engine
  5. var engine = new BABYLON.Engine(canvas, true);
  6. // A to turn left D to turn right SPACE to accelerate.
  7. //Click on the car before pressing any keys.
  8. var createScene = function() {
  9. var scene = new BABYLON.Scene(engine);
  10. // camera
  11. var camera = new BABYLON.ArcRotateCamera("camera1", 0, 0, 20, new BABYLON.Vector3(0, 0, 0), scene);
  12. camera.setPosition(new BABYLON.Vector3(11.5, 3.5, 0));
  13. // lights
  14. var light1 = new BABYLON.DirectionalLight("light1", new BABYLON.Vector3(1, 2, 0), scene);
  15. var light2 = new BABYLON.HemisphericLight("light2", new BABYLON.Vector3(0, 1, 0), scene);
  16. light2.intensity = 0.75;
  17. /***************************Car*********************************************/
  18. /*-----------------------Car Body------------------------------------------*/
  19. //Car Body Material
  20. var bodyMaterial = new BABYLON.StandardMaterial("body_mat", scene);
  21. bodyMaterial.diffuseColor = new BABYLON.Color3(1.0, 0.25, 0.25);
  22. bodyMaterial.backFaceCulling = false;
  23. //Array of points for trapezium side of car.
  24. var side = [new BABYLON.Vector3(-6.5, 1.5, -2),
  25. new BABYLON.Vector3(2.5, 1.5, -2),
  26. new BABYLON.Vector3(3.5, 0.5, -2),
  27. new BABYLON.Vector3(-9.5, 0.5, -2)
  28. ];
  29. side.push(side[0]); //close trapezium
  30. //Array of points for the extrusion path
  31. var extrudePath = [new BABYLON.Vector3(0, 0, 0), new BABYLON.Vector3(0, 0, 4)];
  32. //Create body and apply material
  33. var carBody = BABYLON.MeshBuilder.ExtrudeShape("body", {shape: side, path: extrudePath, cap : BABYLON.Mesh.CAP_ALL}, scene);
  34. carBody.material = bodyMaterial;
  35. camera.parent = carBody;
  36. /*-----------------------End Car Body------------------------------------------*/
  37. /*-----------------------Wheel------------------------------------------*/
  38. //Wheel Material
  39. var wheelMaterial = new BABYLON.StandardMaterial("wheel_mat", scene);
  40. var wheelTexture = new BABYLON.Texture("http://i.imgur.com/ZUWbT6L.png", scene);
  41. wheelMaterial.diffuseTexture = wheelTexture;
  42. //Set color for wheel tread as black
  43. var faceColors=[];
  44. faceColors[1] = new BABYLON.Color3(0,0,0);
  45. //set texture for flat face of wheel
  46. var faceUV =[];
  47. faceUV[0] = new BABYLON.Vector4(0,0,1,1);
  48. faceUV[2] = new BABYLON.Vector4(0,0,1,1);
  49. //create wheel front inside and apply material
  50. var wheelFI = BABYLON.MeshBuilder.CreateCylinder("wheelFI", {diameter: 3, height: 1, tessellation: 24, faceColors:faceColors, faceUV:faceUV}, scene);
  51. wheelFI.material = wheelMaterial;
  52. //rotate wheel so tread in xz plane
  53. wheelFI.rotate(BABYLON.Axis.X, Math.PI/2, BABYLON.Space.WORLD);
  54. /*-----------------------End Wheel------------------------------------------*/
  55. /*-------------------Pivots for Front Wheels-----------------------------------*/
  56. var pivotFI = new BABYLON.Mesh("pivotFI", scene);
  57. pivotFI.parent = carBody;
  58. pivotFI.position = new BABYLON.Vector3(-6.5, 0, -2);
  59. var pivotFO = new BABYLON.Mesh("pivotFO", scene);
  60. pivotFO.parent = carBody;
  61. pivotFO.position = new BABYLON.Vector3(-6.5, 0, 2);
  62. /*----------------End Pivots for Front Wheels--------------------------------*/
  63. /*------------Create other Wheels as Instances, Parent and Position----------*/
  64. var wheelFO = wheelFI.createInstance("FO");
  65. wheelFO.parent = pivotFO;
  66. wheelFO.position = new BABYLON.Vector3(0, 0, 1.8);
  67. var wheelRI = wheelFI.createInstance("RI");
  68. wheelRI.parent = carBody;
  69. wheelRI.position = new BABYLON.Vector3(0, 0, -2.8);
  70. var wheelRO = wheelFI.createInstance("RO");
  71. wheelRO.parent = carBody;
  72. wheelRO.position = new BABYLON.Vector3(0, 0, 2.8);
  73. wheelFI.parent = pivotFI;
  74. wheelFI.position = new BABYLON.Vector3(0, 0, -1.8);
  75. /*------------End Create other Wheels as Instances, Parent and Position----------*/
  76. /*---------------------Create Car Centre of Rotation-----------------------------*/
  77. pivot = new BABYLON.Mesh("pivot", scene); //current centre of rotation
  78. pivot.position.z = 50;
  79. carBody.parent = pivot;
  80. carBody.position = new BABYLON.Vector3(0, 0, -50);
  81. /*---------------------End Create Car Centre of Rotation-------------------------*/
  82. /*************************** End Car*********************************************/
  83. /*****************************Add Ground********************************************/
  84. var groundSize = 400;
  85. var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: groundSize, height: groundSize}, scene);
  86. var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
  87. groundMaterial.diffuseColor = new BABYLON.Color3(0.75, 1, 0.25);
  88. ground.material = groundMaterial;
  89. ground.position.y = -1.5;
  90. /*****************************End Add Ground********************************************/
  91. /*****************************Particles to Show Movement********************************************/
  92. var box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);
  93. box.position = new BABYLON.Vector3(20, 0, 10);
  94. var boxesSPS = new BABYLON.SolidParticleSystem("boxes", scene, {updatable: false});
  95. //function to position of grey boxes
  96. var set_boxes = function(particle, i, s) {
  97. particle.position = new BABYLON.Vector3(-200 + Math.random()*400, 0, -200 + Math.random()*400);
  98. }
  99. //add 400 boxes
  100. boxesSPS.addShape(box, 400, {positionFunction:set_boxes});
  101. var boxes = boxesSPS.buildMesh(); // mesh of boxes
  102. boxes.material = new BABYLON.StandardMaterial("", scene);
  103. boxes.material.alpha = 0.25;
  104. /*****************************Particles to Show Movement********************************************/
  105. /****************************Key Controls************************************************/
  106. var map ={}; //object for multiple key presses
  107. scene.actionManager = new BABYLON.ActionManager(scene);
  108. scene.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnKeyDownTrigger, function (evt) {
  109. map[evt.sourceEvent.key] = evt.sourceEvent.type == "keydown";
  110. }));
  111. scene.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnKeyUpTrigger, function (evt) {
  112. map[evt.sourceEvent.key] = evt.sourceEvent.type == "keydown";
  113. }));
  114. /****************************End Key Controls************************************************/
  115. /****************************Variables************************************************/
  116. var theta = 0;
  117. var deltaTheta = 0;
  118. var D = 0; //distance translated per second
  119. var R = 50; //turning radius, initial set at pivot z value
  120. var NR; //Next turning radius on wheel turn
  121. var A = 4; // axel length
  122. var L = 4; //distance between wheel pivots
  123. var r = 1.5; // wheel radius
  124. var psi, psiRI, psiRO, psFI, psiFO; //wheel rotations
  125. var phi; //rotation of car when turning
  126. var F; // frames per second
  127. /****************************End Variables************************************************/
  128. /****************************Animation******************************************************/
  129. scene.registerAfterRender(function() {
  130. F = engine.getFps();
  131. if(map[" "] && D < 15 ) {
  132. D += 1;
  133. };
  134. if(D > 0.15) {
  135. D -= 0.15;
  136. }
  137. else {
  138. D = 0;
  139. }
  140. distance = D/F;
  141. psi = D/(r * F);
  142. if((map["a"] || map["A"]) && -Math.PI/6 < theta) {
  143. deltaTheta = -Math.PI/252;
  144. theta += deltaTheta;
  145. pivotFI.rotate(BABYLON.Axis.Y, deltaTheta, BABYLON.Space.LOCAL);
  146. pivotFO.rotate(BABYLON.Axis.Y, deltaTheta, BABYLON.Space.LOCAL);
  147. if(Math.abs(theta) > 0.00000001) {
  148. NR = A/2 +L/Math.tan(theta);
  149. }
  150. else {
  151. theta = 0;
  152. NR = 0;
  153. }
  154. pivot.translate(BABYLON.Axis.Z, NR - R, BABYLON.Space.LOCAL);
  155. carBody.translate(BABYLON.Axis.Z, R - NR, BABYLON.Space.LOCAL);
  156. R = NR;
  157. };
  158. if((map["d"] || map["D"]) && theta < Math.PI/6) {
  159. deltaTheta = Math.PI/252;
  160. theta += deltaTheta;
  161. pivotFI.rotate(BABYLON.Axis.Y, deltaTheta, BABYLON.Space.LOCAL);
  162. pivotFO.rotate(BABYLON.Axis.Y, deltaTheta, BABYLON.Space.LOCAL);
  163. if(Math.abs(theta) > 0.00000001) {
  164. NR = A/2 +L/Math.tan(theta);
  165. }
  166. else {
  167. theta = 0;
  168. NR = 0;
  169. }
  170. pivot.translate(BABYLON.Axis.Z, NR - R, BABYLON.Space.LOCAL);
  171. carBody.translate(BABYLON.Axis.Z, R - NR, BABYLON.Space.LOCAL);
  172. R = NR;
  173. };
  174. if(D > 0) {
  175. phi = D/(R * F);
  176. if(Math.abs(theta)>0) {
  177. pivot.rotate(BABYLON.Axis.Y, phi, BABYLON.Space.WORLD);
  178. psiRI = D/(r * F);
  179. psiRO = D * (R + A)/(r * F);
  180. psiFI = D * Math.sqrt(R* R + L * L)/(r * F);
  181. psiFO = D * Math.sqrt((R + A) * (R + A) + L * L)/(r * F);
  182. wheelFI.rotate(BABYLON.Axis.Y, psiFI, BABYLON.Space.LOCAL);
  183. wheelFO.rotate(BABYLON.Axis.Y, psiFO, BABYLON.Space.LOCAL);
  184. wheelRI.rotate(BABYLON.Axis.Y, psiRI, BABYLON.Space.LOCAL);
  185. wheelRO.rotate(BABYLON.Axis.Y, psiRO, BABYLON.Space.LOCAL);
  186. }
  187. else {
  188. pivot.translate(BABYLON.Axis.X, -distance, BABYLON.Space.LOCAL);
  189. wheelFI.rotate(BABYLON.Axis.Y, psi, BABYLON.Space.LOCAL);
  190. wheelFO.rotate(BABYLON.Axis.Y, psi, BABYLON.Space.LOCAL);
  191. wheelRI.rotate(BABYLON.Axis.Y, psi, BABYLON.Space.LOCAL);
  192. wheelRO.rotate(BABYLON.Axis.Y, psi, BABYLON.Space.LOCAL);
  193. }
  194. }
  195. });
  196. /****************************End Animation************************************************/
  197. return scene;
  198. }
  199. // call the createScene function
  200. var scene = createScene();
  201. // run the render loop
  202. engine.runRenderLoop(function(){
  203. scene.render();
  204. });
  205. // the canvas/window resize event handler
  206. window.addEventListener('resize', function(){
  207. engine.resize();
  208. });
  209. });