test2.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. class Scenario {
  2. /*
  3. * Description: Testing physics
  4. * Version: 0.1
  5. */
  6. constructor(ctx) {
  7. console.log('constructor', ctx);
  8. this.$ = ctx.scope;
  9. this.THREE = ctx.THREE;
  10. this.elapsed = 0;
  11. this.timeOfLastBall = 0;
  12. this.dropEvery = 0.25; // 4 per second
  13. this.rigidBodies = [];
  14. this.tmpTrans = new this.$.ammo.btTransform();
  15. }
  16. async setup() {
  17. const $ = this.$;
  18. const THREE = this.THREE;
  19. const Ammo = $.ammo;
  20. await $.loadVrm(
  21. // 'https://vrm.heyamica.com/file/amica-vrm/82754e287e0b26b5d7a1fd223ed0fd5debcabed81f36549fb2c16b201f3e5ca9',
  22. '/vrm/AvatarSample_B.vrm',
  23. (progress) => {
  24. console.log(`loading model ${progress}`);
  25. },
  26. );
  27. const floor = new THREE.Mesh(
  28. new THREE.PlaneGeometry(2, 2),
  29. new THREE.MeshBasicMaterial({
  30. color: 0xFFFFFF,
  31. side: THREE.DoubleSide,
  32. }),
  33. );
  34. floor.rotation.x = Math.PI / 2;
  35. $.scene.add(floor);
  36. const transform = new Ammo.btTransform();
  37. transform.setIdentity();
  38. transform.setOrigin(new Ammo.btVector3(0, 0, 0));
  39. const motionState = new Ammo.btDefaultMotionState(transform);
  40. const shape = new Ammo.btBoxShape(new Ammo.btVector3(1, 0.1, 1));
  41. const mass = 0; // Static object
  42. const rbInfo = new Ammo.btRigidBodyConstructionInfo(
  43. mass,
  44. motionState,
  45. shape,
  46. new Ammo.btVector3(0, 0, 0)
  47. );
  48. const body = new Ammo.btRigidBody(rbInfo);
  49. $.physicsWorld.addRigidBody(body);
  50. }
  51. update(delta) {
  52. const $ = this.$;
  53. const Ammo = $.ammo;
  54. this.elapsed += delta;
  55. if (this.elapsed - this.timeOfLastBall >= this.dropEvery) {
  56. this.createBall();
  57. }
  58. for (let i = 0; i < this.rigidBodies.length; i++) {
  59. const objThree = this.rigidBodies[i];
  60. const objAmmo = objThree.userData.physicsBody;
  61. const ms = objAmmo.getMotionState();
  62. if (ms) {
  63. ms.getWorldTransform(this.tmpTrans);
  64. const p = this.tmpTrans.getOrigin();
  65. const q = this.tmpTrans.getRotation();
  66. objThree.position.set(p.x(), p.y(), p.z());
  67. objThree.quaternion.set(q.x(), q.y(), q.z(), q.w());
  68. }
  69. }
  70. }
  71. createBall() {
  72. const $ = this.$;
  73. const THREE = this.THREE;
  74. const Ammo = this.$.ammo;
  75. const radius = 0.1;
  76. const mass = 1;
  77. // Three.js geometry
  78. const geometry = new THREE.SphereGeometry(radius);
  79. const material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
  80. const ball = new THREE.Mesh(geometry, material);
  81. $.scene.add(ball);
  82. // Ammo.js physics
  83. const transform = new Ammo.btTransform();
  84. transform.setIdentity();
  85. transform.setOrigin(new Ammo.btVector3(-1 + Math.random()*2, 2, -1 + Math.random()*2));
  86. const motionState = new Ammo.btDefaultMotionState(transform);
  87. const shape = new Ammo.btSphereShape(radius);
  88. shape.calculateLocalInertia(mass);
  89. const rbInfo = new Ammo.btRigidBodyConstructionInfo(
  90. mass,
  91. motionState,
  92. shape,
  93. shape.calculateLocalInertia(mass)
  94. );
  95. const body = new Ammo.btRigidBody(rbInfo);
  96. $.physicsWorld.addRigidBody(body);
  97. // Store reference to mesh and body
  98. ball.userData.physicsBody = body;
  99. this.rigidBodies.push(ball);
  100. this.timeOfLastBall = this.elapsed;
  101. }
  102. }