Search code examples
physicsaframecannon.js

AFrame Physics Impulse is not at center


Very simply I want to shoot a cube straight up and have it land flat, not spinning as it goes. I would also like it to reliably end up in the same position if possible always when the same force vector is applied.... But that might be a cannon issue.

http://codepen.io/msj121/pen/zKOvPW

<a-scene physics>
    <!-- Camera -->
    <a-entity camera universal-controls position="0 1 0"></a-entity>

    <!-- Floor -->
    <a-grid static-body position="0 0 0"></a-grid>

    <!-- <a-sphere position="0 1 0.5" width="1" height="1" depth="1" color="#000000"></a-sphere>
    <a-sphere position="0 1 -0.5" width="1" height="1" depth="1" color="#000000"></a-sphere> -->
  <!-- Immovable box -->
  <!-- <a-sphere static-body position="0 2 -3" width="3" height="1" depth="1"></a-sphere> -->

  <!-- Dynamic box -->
  <a-entity geometry="box" id="cannon" src="/images/earth.jpg" dynamic-body position="0 1 -3" width="1" height="1" depth="1" color="#33AA33"></a-entity>

    <!-- Dynamic box -->
    <!-- <a-box dynamic-body position="0 1 -1" width="1" height="1" depth="1" color="#000000"></a-box> -->
  </a-scene>
  <div class="card card-block" style="position:absolute;left:0px;bottom:0px;width:250px;background-color:white;z-index:999">
    <h3 class="card-title">Forces:</h3>
    <div class="form-group row">
      <label for="example-text-input" class="col-xs-7 col-form-label">X Direction:</label>
      <div class="col-xs-5">
        <input class="form-control" type="text" value="0" id="x">
      </div>
    </div>
    <div class="form-group row">
      <label for="example-text-input" class="col-xs-7 col-form-label">Y Direction:</label>
      <div class="col-xs-5">
        <input class="form-control" type="text" value="20" id="y">
      </div>
    </div>
    <div class="form-group row">
      <label for="example-text-input" class="col-xs-7 col-form-label">Z Direction:</label>
      <div class="col-xs-5">
        <input class="form-control" type="text" value="0" id="z">
      </div>
    </div>
    <a id="impulseButton" class="btn btn-success" style="float:right;color:white" >Apply Force</a>
  </div>
  <script type="text/javascript">
    $(document).ready(function(){
      $("#impulseButton").on("click",function(){
        applyImpulse();
      });

      function applyImpulse(){
        var x = $("#x").val();
        var y = $("#y").val();
        var z = $("#z").val();
        if(x>=0 && y>=0 && z>=0){
          var el = $('#cannon')[0];
          console.log(new CANNON.Vec3(x,y,z));
          console.log(new CANNON.Vec3().copy(el.body.position));
          console.log(new CANNON.Vec3().copy(el.object3D.position));
          el.body.applyImpulse(
            /* impulse */        new CANNON.Vec3(x,y,z),
            /* world position */ new CANNON.Vec3().copy(el.body.position)
          );
        }
        else{
          alert("Values must be greater or equal to 0")
        }
      }
    });
  </script>

Solution

  • I think it's just simulation noise, but you can constrain rotation using CANNON.Body methods:

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