2015-08-28 4 views
0

У меня есть знаменитые установки двигателя и работа с физикой/сопротивление и т.д.Известного двигатель BruteForce столкновения

Но, похоже, есть и другие варианты физики, BruteForce, SweepAndPrune и т.д. Я подозреваю, что это может быть то, что мне нужно улучшить обнаружение столкновения между элементами.

Я пытался добавить обнаружение столкновения BruteForce так: this.collision = new collision([rightWall, leftWall, topWall, bottomWall]);

Но я получаю ошибку о неправильном ограничении. this.simulation.addConstraint(this.collision);

У кого-нибудь есть опыт в решении этой проблемы?

Вы можете посмотреть демо здесь:

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([rightWall, leftWall, topWall, bottomWall]); 
 
    console.log(this.collision) 
 
    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 (once) { 
 
      console.log(this.items[i][1]._node.moving) 
 
      once = false; 
 
     } 
 
     if (this.items[i][1]._node.moving) { 
 
      console.log('moving!') 
 
     } else { 
 
      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.denisboudreau.org/presentations/2014/CSUN/Browser%20Zoom%20and%20Low%20Vision/Comps/ToM_EnsoCircle.png' 
 
    } 
 
    }); 
 
    centerPoint = new Sphere({ 
 
    radius: 50, 
 
    mass: 10000, 
 
    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: [100, 100, 100], 
 
    mass: 10, 
 
    position: new Vec3(100, 100, 0) 
 
    }); 
 

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

 
    box.setVelocity(0.5, 0.5, 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 = 100; 
 
    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: 10, 
 
    position: new Vec3(x + window.innerWidth/2, y + window.innerHeight/2, 0) 
 
    }); 
 

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

 
    //console.log(color); 
 
    // satellite.setVelocity(-y/Math.PI, -x/Math.PI/2, y/2); 
 
    satellite.setVelocity(0.5, 0.5, 0); 
 
    // this.gravity.addTarget(satellite); 
 
    this.simulation.add(satellite, spring); 
 
    this.items.push([satellite, position]); 
 
    this.collision.addTarget(satellite); 
 
    //Drag 
 
    var nodeGesture = new gestures(node); 
 
    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>

ответ

-1

Это решение с использованием BruteForceAABB.

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 (once) { 
 
      console.log(this.items[i][1]._node.moving) 
 
      once = false; 
 
     } 
 
     if (this.items[i][1]._node.moving) { 
 
      console.log('moving!') 
 
     } else { 
 
      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: './images/famous_logo.png' 
 
    } 
 
    }); 
 
    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) 
 
    }); 
 

 
    // 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); 
 
    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

К сожалению я установил предварительный просмотр – MichaelBell