Advertisement
Guest User

Untitled

a guest
May 20th, 2018
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.95 KB | None | 0 0
  1. function World(){
  2. var objects = [];
  3. var epsilon = 0.5;
  4. // const gravity = -0.008;
  5. const gravity = 0;
  6. // this.velocities = {};
  7. // this.accelerations = {};
  8. var objectIndex = 0;
  9. var createObject = function(type = 'sphere',
  10. pos = new THREE.Vector3(),
  11. force = new THREE.Vector3(),
  12. rot = new THREE.Vector3(0,0,0),
  13. angle = 0,
  14. static = false,
  15. mass = 1.0,
  16. color) {
  17. console.log('create');
  18. var geometry, material;
  19. var vel = new THREE.Vector3();
  20. var acc = new THREE.Vector3(0.0, 0.0, 0.0);
  21. if(type === "plane"){
  22. color = color || "#103F97"
  23. geometry = new THREE.PlaneGeometry(120, 120);
  24. geometry.elementsNeedUpdate = true;
  25. material = new THREE.MeshBasicMaterial( { color: color} );
  26. } else if(type === "sphere"){
  27. color = color || "#433F81"
  28. geometry = new THREE.SphereGeometry(1.0, 10.0, 10.0);
  29. material = new THREE.MeshBasicMaterial( { color: color } );
  30. }
  31. else{
  32. type = 'box';
  33. geometry = new THREE.BoxGeometry(1.0, 1.0, 1.0);
  34. material = new THREE.MeshBasicMaterial( { color: "#433F81" } );
  35. }
  36. var newMesh = new THREE.Mesh(geometry, material);
  37. newMesh.setRotationFromAxisAngle(rot, angle);
  38. if(type === "plane"){
  39. newMesh.geometry.computeFaceNormals();
  40. console.log("faces: ",newMesh.geometry.faces)
  41. }
  42. newMesh.position.set(pos.x, pos.y, pos.z);
  43. scene.add(newMesh);
  44. objects.push({
  45. mesh: newMesh,
  46. type: type,
  47. mass: mass,
  48. moment_of_inertia: 0.0,
  49. pos: pos,
  50. rot: rot,
  51. vel: vel,
  52. acc: acc,
  53. static: static,
  54. force: force
  55. });
  56.  
  57. compute_moment_of_inertia(objects[objectIndex])
  58. objectIndex++;
  59. }
  60.  
  61. var compute_moment_of_inertia = function(object){
  62. if (object.type === "sphere"){
  63. object.moment_of_inertia = 2.0 / 5.0 * object.mass * object.mesh.geometry.parameters.radius ** 2;
  64. } else if(object.type === "box"){
  65. object.moment_of_inertia = 1.0 / 12.0 * object.mass * (object.mesh.geometry.parameters.width ** 2 +
  66. object.mesh.geometry.parameters.height ** 2);
  67. }
  68. }
  69.  
  70. var compute_force_applied = function() {
  71. // console.log("before force: ",objects[2].acc);
  72. for(var key = 0 ;key < objects.length;key++){
  73. var obj = objects[key];
  74. obj.force.y += (obj.mass * gravity);
  75. if (obj.force.x == 0 && obj.force.y == 0 && obj.force.z == 0) continue;
  76. obj.acc = obj.force.divideScalar(obj.mass);
  77. obj.force = new THREE.Vector3();
  78. }
  79. // console.log("after force: ",objects[2].acc);
  80. }
  81.  
  82. var detect_collision = function() {
  83. for(var key1 = 0;key1 < objects.length - 1;key1++){
  84. var obj1 = objects[key1];
  85. for(var key2 = key1 + 1;key2 < objects.length;key2++){
  86. var obj2 = objects[key2];
  87. if(obj1.type == "sphere" && obj2.type == "sphere"){
  88. var centers_distance = obj1.pos.distanceTo(obj2.pos);
  89. if(centers_distance <= obj1.mesh.geometry.parameters.radius + obj2.mesh.geometry.parameters.radius){
  90. console.log(key1 + "collides" + key2);
  91. solve_collision(key1, key2);
  92. }
  93. // obj1.mesh.geometry.computeBoundingSphere();
  94. // obj2.mesh.geometry.computeBoundingSphere();
  95. // var sphere1 = obj1.mesh.geometry.boundingSphere;
  96. // sphere1.set(obj1.pos, )
  97. // var sphere2 = obj2.mesh.geometry.boundingSphere;
  98. // if(sphere1.intersectsSphere(sphere2)){
  99. // // console.log(key1 + "collides" + key2);
  100. // console.log("bs1 ",obj1.mesh.geometry.boundingSphere);
  101. // console.log("sphere1 ",sphere1)
  102. // solve_collision(key1, key2);
  103. // }
  104. }
  105. if((obj1.type == "plane" && obj2.type == "sphere")||
  106. (obj1.type == "sphere" && obj2.type == "plane")){
  107. var key_plane, key_sphere;
  108. if(obj1.type == 'plane'){
  109. var obj_plane = obj1;
  110. var obj_sphere = obj2;
  111. key_plane = key1;
  112. key_sphere = key2;
  113. }else{
  114. var obj_plane = obj2;
  115. var obj_sphere = obj1;
  116. key_plane = key2;
  117. key_sphere = key1;
  118. }
  119. var bbs = new THREE.Box3();
  120. var bbp = new THREE.Box3();
  121. bbs.setFromObject(obj_sphere.mesh);
  122. bbp.setFromObject(obj_plane.mesh);
  123. // console.log("bbp: ",bbp)
  124. if(bbs.intersectsBox(bbp)){
  125. // solve_collision(key1,key2);
  126. // console.log(obj1.acc);
  127. // console.log(obj2.acc);
  128. console.log("intersected")
  129. // var contact_point = new THREE.Vector3();
  130. // var normal = obj_plane.up;
  131. // var plane = new THREE.Plane(new THREE.Vector3(0,1,0), obj_plane.pos.y); // TODO : should add constant distant too
  132. // var plane = new THREE.Plane();
  133. // // plane.setFromCoplanarPoints(bbp.max, bbp.min, new THREE.Vector3(bbp.max.x, bbp.max.z, bbp.min.z));
  134. // console.log("plane: ",plane)
  135. // var projection = new THREE.Vector3();
  136. // plane.projectPoint(obj_sphere.pos,projection);
  137. // var sphere = new THREE.Sphere(obj_sphere.pos, obj_sphere.mesh.geometry.parameters.radius);
  138. // console.log(sphere);
  139. // sphere.clampPoint(projection, contact_point);
  140. // console.log('center ',obj_sphere.pos);
  141. // console.log('projection',projection);
  142. // console.log("contact point",contact_point);
  143. contact_point = new THREE.Vector3(obj_sphere.pos.x, obj_sphere.pos.y - obj_sphere.mesh.geometry.parameters.radius, obj_sphere.pos.z);
  144. solve_collision_plane(key_sphere, key_plane,contact_point);
  145. }
  146. }
  147.  
  148. }
  149.  
  150. }
  151. }
  152.  
  153. var solve_collision_plane = function(key_sphere, key_plane, contact_point){
  154. var obj_sphere = objects[key_sphere];
  155. var obj_plane = objects[key_plane];
  156. var newSphereVel = compute_impulse(key_sphere, key_plane, contact_point);
  157. console.log("sphere vel before: ",obj_sphere.vel)
  158. obj_sphere.vel.sub(newSphereVel);
  159. console.log("sphere vel: ",obj_sphere.vel)
  160. }
  161.  
  162. var solve_collision = function(key1, key2){
  163. console.log("key1: ",key1);
  164. console.log("key2: ",key2);
  165. obj1 = objects[key1];
  166. obj2 = objects[key2];
  167. // tmp_vel = obj1.vel;
  168. // obj1.vel = obj2.vel;
  169. // obj2.vel = tmp_vel;
  170. // obj1acc = new THREE.Vector3(obj1.acc.x, obj1.acc.y, obj1.acc.z);
  171. // obj2acc = new THREE.Vector3(obj2.acc.x, obj2.acc.y, obj2.acc.z);
  172. // obj1.force = obj2acc.multiplyScalar(obj2.mass);
  173. // obj2.force = obj1acc.multiplyScalar(obj1.mass);
  174. // obj1.force = obj2.acc.multiplyScalar(obj2.mass);
  175. // obj2.force = obj1.acc.multiplyScalar(obj1.mass);
  176.  
  177. // console.log("solve col: ",objects[2].acc);
  178. // [obj1.vel,obj2.vel] = [obj2.vel,obj1.vel]; //TODO: not correct when hit in angle
  179. var newVel1 = compute_impulse(key1,key2);
  180.  
  181. var newVel2 = compute_impulse(key2,key1);
  182.  
  183.  
  184. obj1.vel.add(newVel1);
  185. // console.log("vel1: ", obj1.vel);
  186. // console.log("neVel1: ", newVel1)
  187. obj2.vel.add(newVel2);
  188. // console.log("obj1 vel:" + obj1.vel)
  189. // console.log("neVel1: " + newVel1);
  190. // console.log("after after solve col: ",objects[2].acc)
  191.  
  192. }
  193.  
  194. var compute_impulse = function(key1, key2, contact_point = null){
  195. obj1 = objects[key1];
  196. obj2 = objects[key2];
  197. var vel1 = new THREE.Vector3(obj1.vel.x, obj1.vel.y, obj1.vel.z);
  198. var vel2 = new THREE.Vector3(obj2.vel.x, obj2.vel.y, obj2.vel.z);
  199. var pos1 = new THREE.Vector3(obj1.pos.x, obj1.pos.y, obj1.pos.z);
  200. if(obj2.type === "plane"){
  201. var pos2 = contact_point;
  202. }
  203. else var pos2 = new THREE.Vector3(obj2.pos.x, obj2.pos.y, obj2.pos.z);
  204. var velr = new THREE.Vector3();
  205. var n = new THREE.Vector3();
  206. velr.addVectors(vel1,vel2);
  207. // console.log("pos1: ",pos1);
  208. // console.log("obj1.pos: ",obj1.pos);
  209. // console.log("vel1: ",vel1);
  210. console.log("contact_point: ",pos2)
  211. console.log("sphere center: ",pos1)
  212. n.subVectors((pos1), (pos2));
  213. console.log("n0: ", n);
  214. n = n.divideScalar(pos1.distanceTo(pos2));
  215. console.log("n1: ", n);
  216.  
  217. var pre_distance = pos1.distanceTo(pos2);
  218. var tmp1 = new THREE.Vector3(pos1.x, pos1.y, pos1.z);
  219. var tmp2 = new THREE.Vector3(pos2.x, pos2.y, pos2.z);
  220. var velRel1 = new THREE.Vector3(obj1.vel.x, obj1.vel.y, obj1.vel.z);
  221. var velRel2 = new THREE.Vector3(obj2.vel.x, obj2.vel.y, obj2.vel.z);
  222. velRel1.dot(n);
  223. velRel2.dot(n);
  224. var post_distance = (tmp1.add(velRel1).distanceTo(tmp2.add(velRel2)));
  225. console.log("pre: ",pre_distance);
  226. console.log("post: ",post_distance);
  227.  
  228. if(post_distance > pre_distance){
  229. console.log("not colliding");
  230. return new THREE.Vector3(0,0,0);
  231. }
  232. console.log("is colliding");
  233.  
  234. var velRelPre = new THREE.Vector3();
  235. velRelPre.subVectors(vel1,vel2).dot(n);
  236. // console.log("velRelPre: ",velRelPre)
  237. var epsilon_tmp;
  238. if(contact_point != null && velRelPre < 0.1) epsilon_tmp = 0;
  239. else epsilon_tmp = epsilon;
  240. var j = (-(1 + epsilon_tmp) * velRelPre.length()) / (1/obj1.mass + 1/obj2.mass);
  241. var newVel1 = new THREE.Vector3(n.x, n.y, n.z);
  242. newVel1.multiplyScalar(j);
  243. newVel1.divideScalar(obj1.mass);
  244. // console.log("j: ",j);
  245. return newVel1;
  246. }
  247.  
  248.  
  249. var updatePosition = function(){
  250. // console.log("before update: ",objects[2].acc)
  251. detect_collision();
  252. compute_force_applied();
  253. // console.log("after update: ",objects[2].acc)
  254. for(var key in objects){
  255. var currObj = objects[key];
  256. if(currObj.static){
  257. continue;
  258. }
  259. currObj.pos.add(currObj.vel);
  260. currObj.vel.add(currObj.acc);
  261.  
  262. currObj.mesh.position.set(currObj.pos.x, currObj.pos.y, currObj.pos.z);
  263.  
  264. // bounce on floor
  265. // if(currObj.pos.y < objects[0].pos.y + 1.0){
  266. // currObj.vel.y *= -1;
  267. // }
  268. }
  269. }
  270.  
  271. // var updateRotation = function(){
  272. // for(var key in objects){
  273. // var currObj = objects[key];
  274. // if(currObj.static){
  275. // continue;
  276. // }
  277. // currObj.rot.x += currObj.vel.x;
  278. // currObj.rot.y += currObj.vel.y;
  279. // currObj.rot.z += currObj.vel.z;
  280. // currObj.vel.x += currObj.acc.x;
  281. // currObj.vel.y += currObj.acc.y;
  282. // currObj.vel.z += currObj.acc.z;
  283.  
  284. // currObj.mesh.position.set(currObj.pos.x, currObj.pos.y, currObj.pos.z)
  285.  
  286. // if(currObj.pos.y < objects[0].pos.y + 1.0){
  287. // currObj.static = true;
  288. // }
  289. // }
  290. // }
  291.  
  292. return{
  293. objects: objects,
  294. create: createObject,
  295. update: updatePosition
  296. }
  297.  
  298.  
  299. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement