n5ro / aframe-physics-system

Physics system for A-Frame VR, built on CANNON.js.
https://n5ro.github.io/aframe-physics-system/
MIT License
507 stars 137 forks source link

applyImpulse not working #109

Closed nirajupadhyay11 closed 6 years ago

nirajupadhyay11 commented 6 years ago

Hi,

I am trying to create a dynamic-body and then apply impulse to it so that it can move through the space.

Here is how I am building the body and then applying impulse, all inside a component -

const el = document.createElement('a-entity')
        el.setAttribute('id', this.data.id);
        el.setAttribute('gltf-model', this.data.src)
        const offset = new THREE.Vector3(rg.real(-jx,jx), rg.real(0.5,jy), rg.real(-jz,jz));
        el.setAttribute('position', center.clone().add(offset));
        el.object3D.scale.set(0.01,0.01,0.01);
        el.setAttribute('dynamic-body', 'shape:sphere; sphereRadius: .3; mass: 5');
        el.body.applyImpulse(new CANNON.Vec3(0, 1, 23), new 
            CANNON.Vec3().copy(el.getComputedAttribute('position')));

        el.setAttribute('sleepy', 'allowSleep: true; linearDamping: 0.5; angularDamping: 0.5');

        sceneEl.appendChild(el);

But I am getting the following error - Cannot read property 'applyImpulse' of undefined

I have spent a lot of time trying to figure this out. Could you please help?

Thanks, Niraj

donmccurdy commented 6 years ago

You'll need to wait for the body to be created, after a body-loaded event. This does not happen until after the element is added to the scene, and any geometry is loaded.

See: https://github.com/donmccurdy/aframe-physics-system#events

nirajupadhyay11 commented 6 years ago

Thank you Don. The body loads now but I am not sure why it falls to the ground and starts to rotate vigorously instead of flying and moves forward slowly due to impulse. I tried to stop the rotation by adding following code -

el.body.fixedRotation = true;
el.body.updateMassProperties();

This stopped the rotation but then the body does not move forward at all. Here is my updated code -

const el = document.createElement('a-entity')
        el.setAttribute('id', this.data.id);
        el.setAttribute('gltf-model', this.data.src)
        const offset = new THREE.Vector3(rg.real(-jx,jx), rg.real(0.5,jy), rg.real(-jz,jz));
        el.setAttribute('position', center.clone().add(offset));
        el.object3D.scale.set(0.01,0.01,0.01);
        el.setAttribute('dynamic-body', 'shape:sphere; sphereRadius: .3; mass: 5');
        el.setAttribute('sleepy', 'allowSleep: true; linearDamping: 0.5; angularDamping: 0.5');
        console.log(el);
        sceneEl.appendChild(el);

        el.addEventListener('body-loaded', function () {
          el.body.applyImpulse(new CANNON.Vec3(0, 1, 53), new CANNON.Vec3().copy(el.body.position));
          console.log(el.body);
        });

I am looking to make the body fly in one direction. I suspect that the the force might be on one point of the body which is why the rotation is occurring and I need to figure out a way to apply the force to the whole body in one direction (i. e. Z in my case)

nirajupadhyay11 commented 6 years ago

@donmccurdy an update:

When I change the shape to box, the body moves forward but when I change it to an sphere, it falls to the ground. Here is my new code -

const el = document.createElement('a-entity')
 el.setAttribute('id', this.data.id);
 el.setAttribute('gltf-model', this.data.src)
 const offset = new THREE.Vector3(rg.real(-jx,jx), rg.real(0.5,jy), rg.real(-jz,jz));
 el.setAttribute('position', center.clone().add(offset));
 el.object3D.scale.set(0.01,0.01,0.01);
 el.setAttribute('dynamic-body', 'shape:box; mass: 5');
  el.setAttribute('sleepy', 'allowSleep: true; linearDamping: 0.5; angularDamping: 0.5');
   sceneEl.appendChild(el);

 el.addEventListener('body-loaded', function () {
     el.body.fixedRotation = true;
     el.body.updateMassProperties();
     let pStart = new CANNON.Vec3(0,1,-53);
     let force = el.body.position.vsub(pStart);
     force.scale(4, force);
     el.body.applyImpulse(force, el.body.position);
    });
nirajupadhyay11 commented 6 years ago

I have solved this problem. I will post the solution and my learning here for other's benefit