Famous Engine Collision while dragging

90 Views Asked by At

I have a scene, with a a number of nodes / Dom elements that have a string physics applied. I have also added in a gesturehandler on the drag event.

Unfortunately it seems the collisions dont seem to work as well when dragging. i.e shapes overlap with each other instead of respecting the collision mask.

Its easiest to see in the attached example. Im curious if there is an easy fix as this still occurs if I remove the string physics.

var famous = famous;
var FamousEngine = famous.core.FamousEngine;

var Camera = famous.components.Camera;


var DOMElement = famous.domRenderables.DOMElement;
var Gravity3D = famous.physics.Gravity3D;
var MountPoint = famous.components.MountPoint;
var PhysicsEngine = famous.physics.PhysicsEngine;
var Position = famous.components.Position;
var Size = famous.components.Size;
var Wall = famous.physics.Wall;
var Sphere = famous.physics.Sphere;
var Vec3 = famous.math.Vec3;
var math = famous.math;
var physics = famous.physics;
var collision = famous.physics.Collision;
var gestures = famous.components.GestureHandler;
var Spring = famous.physics.Spring;
console.log(famous)
var anchor = new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0);

//Create Walls
var rightWall = new Wall({
  direction: Wall.LEFT
}).setPosition(window.innerWidth - 20, 0, 0);
var leftWall = new Wall({
  direction: Wall.RIGHT
}).setPosition(window.innerWidth + 20, 0, 0);
var topWall = new Wall({
  direction: Wall.DOWN
}).setPosition(0, 20, 0);
var bottomWall = new Wall({
  direction: Wall.UP
}).setPosition(0, window.innerHeight - 20, 0);

var centerPoint;

function Demo() {
  this.scene = FamousEngine.createScene('body');
  // this.collision = new collision.({broadphase: 'BruteForce'});
  var broadPhase = new physics.Collision.BruteForceAABB([rightWall, leftWall, topWall, bottomWall]);
  this.collision = new collision([topWall], {
    'broadPhase': broadPhase
  });

  this.simulation = new PhysicsEngine();
  this.simulation.setOrigin(0.5, 0.5);
  this.simulation.addConstraint(this.collision);
  this.items = [];
  this.walls = [];

  //Create Items
  for (var i = 0; i < 10; i++) {
    var node = this.scene.addChild();
    node.setMountPoint(0.5, 0.5);
    var size = new Size(node).setMode(1, 1);
    var position = new Position(node);
    if (i === 0) {
      createLogo.call(this, node, size, position);

    }
    if (i !== 0 && i !== 9) {
      node.id = i;
      createSatellites.call(this, node, size, position);
    }
    if (i === 9) {
      node.id = i;
      createAlternateShape.call(this, node, size, position);

    }
  }

  //Create Walls
  var node = this.scene.addChild();
  createWalls(node);

  var once = true;

  Demo.prototype.onUpdate = function(time) {
    this.simulation.update(time);
    // this.collision.resolve(time, 360)

    //Postition walls
    var wallPosition = topWall.getPosition();
    node.setPosition(wallPosition.x, wallPosition.y);

    //Position elements
    if (this.items.length > 0) {
      for (var i = 0; i < this.items.length; i++) {
        if (!this.items[i][1]._node.moving) {
          var itemPosition = this.simulation.getTransform(this.items[i][0]).position;
          this.items[i][1].set(itemPosition[0], itemPosition[1], 0);
        }


      }
    }

    FamousEngine.requestUpdateOnNextTick(this);
  };

  FamousEngine.requestUpdateOnNextTick(this);
}

function createWalls(wallNode) {
  wallNode.setSizeMode('absolute', 'absolute', 'absolute').setAbsoluteSize(window.innerWidth, 10, 0);
  var wallDOMElement = new DOMElement(wallNode, {
    tagName: 'div'
  }).setProperty('background-color', 'lightblue');
}

function createLogo(node, size, position) {
  node.moving = false;
  size.setAbsolute(100, 100);
  var mp = new MountPoint(node).set(0.5, 0.5);
  var el = new DOMElement(node, {
    tagName: 'img',
    attributes: {
      src: 'http://www.clker.com/cliparts/H/n/S/a/f/H/circle-small-chosen-hi.png',
      fill: 'black'
    }
  });
  centerPoint = new Sphere({
    radius: 50,
    mass: 100000,
    restrictions: ['xy'],
    position: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
  });

  var spring = new Spring(null, centerPoint, {
    stiffness: 95,
    period: 0.6,
    dampingRatio: 1.0,
    anchor: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
  });

  centerPoint.setVelocity(0, 0, 0);
  this.simulation.add(centerPoint, spring);
  this.items.push([centerPoint, position]);
  this.collision.addTarget(centerPoint);
}

function createAlternateShape(node, size, position) {
  node.moving = false;
  size.setAbsolute(100, 100);
  var el = new DOMElement(node, {
    properties: {
      'background-color': 'red',
    }
  });

  var box = new physics.Box({
    size: [101, 101, 101],
    mass: 100,
    position: new Vec3(100, 100, 0)
  });

  // Attach the box to the anchor with a `Spring` force
  var spring = new Spring(null, box, {
    period: 1.5,
    dampingRatio: 0.8,
    anchor: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
  });

  box.setVelocity(0.1, 0.1, 0);
  this.simulation.add(box, spring);
  this.items.push([box, position]);
  this.collision.addTarget(box);
}

function createSatellites(node, size, position, i) {
  node.moving = false;
  var rand = Math.round(Math.random() * 100 + 30);
  size.setAbsolute(rand, rand);
  var radius = rand;
  var x = Math.floor(Math.random() * radius * 2) - radius;
  var y = (Math.round(Math.random()) * 2 - 1) * Math.sqrt(radius * radius - x * x);
  var color = 'rgb(' + Math.abs(x) + ',' + Math.abs(Math.round(y)) + ',' + (255 - node.id) + ')';
  var el = new DOMElement(node, {
    properties: {
      'background-color': color,
      'border-radius': '50%'
    }
  });

  var satellite = new Sphere({
    radius: rand / 2,
    mass: 100,
    position: new Vec3(x + window.innerWidth / 2, y + window.innerHeight / 2, 0),
    restitution: 0,
    friction: 0.8
  });

  // Attach the box to the anchor with a `Spring` force
  var spring = new Spring(null, satellite, {
    // stiffness: 10,
    period: 1.5,
    dampingRatio: 0.8,
    anchor: anchor
  });

  //console.log(color);
  // satellite.setVelocity(-y / Math.PI, -x / Math.PI / 2, y / 2);
  satellite.setVelocity(0.1, 0.1, 0);
  // this.gravity.add(satellite);
  this.simulation.add(satellite, spring);
  this.items.push([satellite, position]);
  this.collision.addTarget(satellite);
  //Drag
  var nodeGesture = new gestures(node);
  console.log(nodeGesture)
  var count = 0;
  nodeGesture.on('drag', function(e, p) {
    if (e.status == "move") {
      node.moving = true;
      var currentPos = node.getPosition()
      var newPosX = currentPos[0] + e.centerDelta.x
      var newPosY = currentPos[1] + e.centerDelta.y
      satellite.setPosition(newPosX, newPosY)
      node.setPosition(newPosX, newPosY)
    }


    if (e.status == "end") {
      node.moving = false;
    }
  });
  //event
  node.addUIEvent('click');
  node.addComponent({
    onReceive: function(event, payload) {
      if (event === 'click') {
        el.setContent('I\'ve been clicked')
      }
    }
  });
}

setTimeout(function() {
  // Boilerplate
  FamousEngine.init();
}, 500);


// App Code
var demo = new Demo();
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Famous :: Seed Project</title>
  <link rel="icon" href="favicon.ico?v=1" type="image/x-icon">
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      margin: 0px;
      padding: 0px;
    }
    body {
      position: absolute;
      -webkit-transform-style: preserve-3d;
      transform-style: preserve-3d;
      -webkit-font-smoothing: antialiased;
      -webkit-tap-highlight-color: transparent;
      -webkit-perspective: 0;
      perspective: none;
      overflow: hidden;
    }
  </style>
</head>

<body>
  <script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script>
</body>

</html>

0

There are 0 best solutions below