2016-10-07 2 views
1

J'utilise Physijs pour déterminer la collision statique entre mes mailles. Comme j'ai besoin de savoir quelles surfaces se croisent. J'ai piraté une démo simple qui semble fonctionner.Physique simple collision entre les mailles sans gravité

Actuellement, je dois configurer ma scène pour utiliser la gravité, ce qui m'empêche de positionner mes maillages dans n'importe quelle position y, car ils commencent à tomber ou à flotter.

y a-t-il un moyen simple d'enlever la gravité de la simulation, et d'utiliser simplement la détection de collision de maillage? --update --- J'ai dû définir explicitement la masse de chaque maillage sur 0 plutôt que sur blanc. Avec la masse = 0, la gravité n'a aucun effet. génial!

Toutefois, les maillages ne signalent pas de collision. des idées où je vais mal?

grâce

-lp

Répondre

1

Vous ne pouvez pas utiliser Physijs pour la détection de collision seule. Il vient tout juste équipé de la simulation physique en temps réel, basée sur la bibliothèque ammo.js. Lorsque vous définissez la masse des mailles sur 0, cela les rend statiques. Ils étaient alors insensibles aux forces externes, telles que les réponses de collision (c'est-à-dire le changement de vitesse appliqué sur le maillage après la détection de la collision) ou la gravité. De même, deux maillages statiques qui se chevauchent l'un l'autre ne déclenchent pas un événement de collision.

Solution A: Utilisation de directement

Ported de Bullet Physics, la bibliothèque fournit les outils nécessaires pour générer des simulations de physique ou de détecter simplement des collisions entre des formes définies (qui Physijs ne veut pas voir). Voici un extrait de détection de collision entre 2 sphères rigides:

var bt_collision_configuration; 
var bt_dispatcher; 
var bt_broadphase; 
var bt_collision_world; 

var scene_size = 500; 
var max_objects = 10; // Tweak this as needed 

bt_collision_configuration = new Ammo.btDefaultCollisionConfiguration(); 
bt_dispatcher = new Ammo.btCollisionDispatcher(bt_collision_configuration); 

var wmin = new Ammo.btVector3(-scene_size, -scene_size, -scene_size); 
var wmax = new Ammo.btVector3(scene_size, scene_size, scene_size); 

// This is one type of broadphase, Ammo.js has others that might be faster 
bt_broadphase = new Ammo.bt32BitAxisSweep3(
     wmin, wmax, max_objects, 0, true /* disable raycast accelerator */); 

bt_collision_world = new Ammo.btCollisionWorld(bt_dispatcher, bt_broadphase, bt_collision_configuration); 

// Create two collision objects 
var sphere_A = new Ammo.btCollisionObject(); 
var sphere_B = new Ammo.btCollisionObject(); 

// Move each to a specific location 
sphere_A.getWorldTransform().setOrigin(new Ammo.btVector3(2, 1.5, 0)); 
sphere_B.getWorldTransform().setOrigin(new Ammo.btVector3(2, 0, 0)); 

// Create the sphere shape with a radius of 1 
var sphere_shape = new Ammo.btSphereShape(1); 

// Set the shape of each collision object 
sphere_A.setCollisionShape(sphere_shape); 
sphere_B.setCollisionShape(sphere_shape); 

// Add the collision objects to our collision world 
bt_collision_world.addCollisionObject(sphere_A); 
bt_collision_world.addCollisionObject(sphere_B); 

// Perform collision detection 
bt_collision_world.performDiscreteCollisionDetection(); 

var numManifolds = bt_collision_world.getDispatcher().getNumManifolds(); 

// For each contact manifold 
for(var i = 0; i < numManifolds; i++){ 
    var contactManifold = bt_collision_world.getDispatcher().getManifoldByIndexInternal(i); 
    var obA = contactManifold.getBody0(); 
    var obB = contactManifold.getBody1(); 
    contactManifold.refreshContactPoints(obA.getWorldTransform(), obB.getWorldTransform()); 
    var numContacts = contactManifold.getNumContacts(); 

    // For each contact point in that manifold 
    for(var j = 0; j < numContacts; j++){ 

     // Get the contact information 
     var pt = contactManifold.getContactPoint(j); 
     var ptA = pt.getPositionWorldOnA(); 
     var ptB = pt.getPositionWorldOnB(); 
     var ptdist = pt.getDistance(); 

     // Do whatever else you need with the information... 
    } 
} 

// Oh yeah! Ammo.js wants us to deallocate 
// the objects with 'Ammo.destroy(obj)' 

I transformé this C++ code en son équivalent JS. Il se peut qu'il y ait eu une syntaxe manquante, donc vous pouvez vérifier le Ammo.js API binding changes pour tout ce qui ne fonctionne pas.

Solution B: Utilisez le lanceur de sorts de rayons de TROIS

Le lanceur de rayons est moins précis, mais peut être plus précis avec l'ajout de nombre de vertex supplémentaire dans vos formes. Voici un code pour détecter une collision entre 2 boîtes:

// General box mesh data 
var boxGeometry = new THREE.CubeGeometry(100, 100, 20, 1, 1, 1); 
var boxMaterial = new THREE.MeshBasicMaterial({color: 0x8888ff, wireframe: true}); 

// Create box that detects collision 
var dcube = new THREE.Mesh(boxGeometry, boxMaterial); 

// Create box to check collision with 
var ocube = new THREE.Mesh(boxGeometry, boxMaterial); 

// Create ray caster 
var rcaster = new THREE.Raycaster(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 1, 0)); 

// Cast a ray through every vertex or extremity 
for(var vi = 0, l = dcube.geometry.vertices.length; vi < l; vi++){  
    var glovert = dcube.geometry.vertices[vi].clone().applyMatrix4(dcube.matrix); 

    var dirv = glovert.sub(dcube.position); 

    // Setup ray caster 
    rcaster.set(dcubeOrigin, dirv.clone().normalize()); 

    // Get collision result 
    var hitResult = rcaster.intersectObject(ocube); 

    // Check if collision is within range of other cube 
    if(hitResult.length && hitResult[0].distance < dirv.length()){ 
     // There was a hit detected between dcube and ocube 
    } 
} 

Découvrez ces liens pour plus d'informations (et peut-être leur code source):

+0

quelle excellente réponse! j'aime avec la solution de munitions. Je vais essayer sur un maillage concave et voir comment il fonctionne. – lpic

+0

la solution de munitions fonctionne très bien pour les maillages concaves ... merci encore – lpic

+0

@ XavCo7, s'il vous plaît jeter un oeil à https: // stackoverflow.com/questions/46423290/glisser-un-maillage sur un autre-et-limiter-il-dans-les-côtés-trois-js, j'ai expliqué l'exigence. Je dois faire glisser une fenêtre sur le mur dans les limites du mur. J'ai créé l'ensemble de l'application dans trois.js. Will Physijs travaillera pour la tâche? – Deeps