【问题标题】:two collada object colliding两个 collada 对象碰撞
【发布时间】:2013-02-26 16:37:54
【问题描述】:

我正在尝试使用 Ray intersect 来确定 2 个 collada 对象是否发生碰撞。 但到目前为止没有成功:(

我的代码http://jsfiddle.net/XqQzF/

        object.updateMatrix();

        // ray
        var f_vector = new THREE.Vector3( 0, 0, -1 );
        var b_vector = new THREE.Vector3( 0, 0, 1 );
        var l_vector = new THREE.Vector3( -1, 0, 0 );
        var r_vector = new THREE.Vector3( 1, 0, 0 );

每次我使用它从最新的 three.js 修订版中删除的东西。 你能在路上帮我吗?

【问题讨论】:

    标签: three.js collision-detection raytracing intersect collada


    【解决方案1】:

    我最近更新了我的 three.js 示例集合以与最新版本(撰写本文时为 v56)兼容,其中包括一个碰撞检测示例。查看http://stemkoski.github.com/Three.js/Collision-Detection.html(有关说明,请参阅http://stemkoski.github.com/Three.js/#collision-detection)。

    您的情况的主要区别是选择模型的中心点作为光线的原点,并选择模型的一组顶点作为光线的端点,因为光线用于碰撞检测。

    希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      @Lee Stemkoski 答案是好的,当我们不使用 collada 数据时。 首先,我知道我们需要分钟。 2 网格对象。所以我从 collada 对象中获取了所有 Mesh 对象。我写了两个脚本 - 首先尝试碰撞 2 个 collada 对象。第二次尝试将 collada 对象与墙壁(简单网格)碰撞。在这两种情况下,脚本都无法识别碰撞?。那我应该怎么写呢? 最后,我尝试在 collada 对象上检测鼠标。这不是关于这个话题,而是类似的问题,所以我写在这里。 Dae 文件由 SketchUp 生成。

      两个collada对象的代码:

       var container;
       var meshs = [];
       var camera, scene, renderer, raycaster;
       var controls;
       var mouse = new THREE.Vector2();
       var dae, dae2;
       var collidableMeshList = [];
       var clock = new THREE.Clock();
       var keyboard = new THREEx.KeyboardState();
      
       $(document).ready(function() {
           init();
           animate();
       });
      
       function init() {
      
           container = document.createElement('div');
           $('.container').append(container);
      
           camera = new THREE.PerspectiveCamera(45, 500 / 500, 1, 1000);
           group = new THREE.Group();
      
           scene = new THREE.Scene();
      
           scene.add(camera);
      
           camera.position.set(10 * 10, 12 * 10, 16 * 10);
      
           camera.lookAt(scene.position);
      
           // Lights
      
           group.add(new THREE.AmbientLight(0x777777));
      
           var light = new THREE.DirectionalLight(0xdfebff, 1.25);
           light.position.set(300, 400, 50);
           light.position.multiplyScalar(1.3);
      
           light.castShadow = true;
      
           group.add(light);
      
           renderer = new THREE.WebGLRenderer({
               antialias: true
           });
      
           renderer.setClearColor(0xcccccc, 1);
      
           renderer.setSize(500, 500);
      
           container.appendChild(renderer.domElement);
      
           controls = new THREE.OrbitControls(camera, renderer.domElement);
      
           var loader = new THREE.ColladaLoader();
           loader.options.convertUpAxis = true;
           loader.load('./sample.dae', loadDae);
      
           function loadDae(collada) {
               dae = collada.scene;
      
               dae.scale.x = 0.5;
               dae.scale.y = 0.3;
               dae.scale.z = 0.3;
               dae.updateMatrix();
      
               group.add(dae);
           }
      
           var wallGeometry = new THREE.CubeGeometry(10, 10, 20, 1, 1, 1);
           var wallMaterial = new THREE.MeshBasicMaterial({
               color: 0x8888ff
           });
           var wireMaterial = new THREE.MeshBasicMaterial({
               color: 0x000000,
               wireframe: true
           });
      
           loader = new THREE.ColladaLoader();
           loader.options.convertUpAxis = true;
           loader.load('./sample.dae', loadDae2);
      
           function loadDae2(collada) {
               dae2 = collada.scene;
      
               dae2.scale.x = 0.5;
               dae2.scale.y = 0.3;
               dae2.scale.z = 0.3;
               dae2.updateMatrix();
      
               dae2.position.set(-40, 0, 0);
      
               dae2.traverse(function(child) {
                   if (child instanceof THREE.Mesh) {
                       collidableMeshList.push(child);
                   }
               });
               group.add(dae2);
           }
      
           group.translateX(-20);
           scene.add(group);
      
           raycaster = new THREE.Raycaster();
      
           window.addEventListener('resize', onWindowResize, false);
           window.addEventListener('mousemove', onDocumentMouseMove, false);
       }
      
       function onDocumentMouseMove(event) {
      
           event.preventDefault();
      
           mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
           mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      
       }
      
       function onWindowResize() {
      
           camera.aspect = 500 / 500;
           camera.updateProjectionMatrix();
      
           renderer.setSize(500, 500);
       }
      
       function update() {
           var delta = clock.getDelta();
           var moveDistance = 200 * delta;
           var rotateAngle = Math.PI / 2 * delta;
      
           if (keyboard.pressed("A"))
               dae.rotation.y += rotateAngle;
           if (keyboard.pressed("D"))
               dae.rotation.y -= rotateAngle;
      
           if (keyboard.pressed("left"))
               dae.translateX(-moveDistance);
           if (keyboard.pressed("right"))
               dae.translateX(moveDistance);
           if (keyboard.pressed("up"))
               dae.translateZ(-moveDistance);
           if (keyboard.pressed("down"))
               dae.translateZ(moveDistance);
      
           meshs = [];
           if (typeof dae !== 'undefined') {
               dae.traverse(function(child) {
                   if (child instanceof THREE.Mesh) {
                       meshs.push(child);
                   }
               });
               $.each(meshs, function(number_mesh, mesh) {
                   var originPoint = mesh.position.clone();
      
                   for (var vertexIndex = 0; vertexIndex < mesh.geometry.vertices.length; vertexIndex++) {
                       var localVertex = mesh.geometry.vertices[vertexIndex].clone();
                       var globalVertex = localVertex.applyMatrix4(mesh.matrix);
                       var directionVector = globalVertex.sub(mesh.position);
      
                       var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
                       var collisionResults = ray.intersectObjects(collidableMeshList);
                       if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
                           console.log(" Hit ");
                       }
                   }
               });
           }
           controls.update();
       }
      
       function animate() {
      
           requestAnimationFrame(animate);
           render();
           update();
      
       }
      
       function render() {
      
           renderer.render(scene, camera);
      
       }
      

      collada + wall(Mesh)的代码:

      var container;
      var meshs = [];
      var camera, scene, renderer, raycaster;
      var controls;
      var mouse = new THREE.Vector2();
      var dae;
      var collidableMeshList = [];
      var clock = new THREE.Clock();
      var keyboard = new THREEx.KeyboardState();
      
      $(document).ready(function() {
          init();
          animate();
      });
      
      function init() {
      
          container = document.createElement('div');
          $('.container').append(container);
      
          camera = new THREE.PerspectiveCamera(45, 500 / 500, 1, 1000);
          group = new THREE.Group();
      
          scene = new THREE.Scene();
      
          scene.add(camera);
      
          camera.position.set(10 * 10, 12 * 10, 16 * 10);
      
          camera.lookAt(scene.position);
      
          // Lights
      
          group.add(new THREE.AmbientLight(0x777777));
      
          var light = new THREE.DirectionalLight(0xdfebff, 1.25);
          light.position.set(300, 400, 50);
          light.position.multiplyScalar(1.3);
      
          light.castShadow = true;
      
          group.add(light);
      
          renderer = new THREE.WebGLRenderer({
              antialias: true
          });
      
          renderer.setClearColor(0xcccccc, 1);
      
          renderer.setSize(500, 500);
      
          container.appendChild(renderer.domElement);
      
          controls = new THREE.OrbitControls(camera, renderer.domElement);
      
          var loader = new THREE.ColladaLoader();
          loader.options.convertUpAxis = true;
          loader.load('./sample.dae', loadDae);
      
          function loadDae(collada) {
              dae = collada.scene;
      
              dae.scale.x = 0.5;
              dae.scale.y = 0.3;
              dae.scale.z = 0.3;
              dae.updateMatrix();
      
              group.add(dae);
          }
      
          var wallGeometry = new THREE.CubeGeometry(10, 10, 20, 1, 1, 1);
          var wallMaterial = new THREE.MeshBasicMaterial({
              color: 0x8888ff
          });
          var wireMaterial = new THREE.MeshBasicMaterial({
              color: 0x000000,
              wireframe: true
          });
      
          var wall = new THREE.Mesh(wallGeometry, wallMaterial);
          wall.position.set(-40, 5, -10);
          group.add(wall);
          collidableMeshList.push(wall);
          var wall = new THREE.Mesh(wallGeometry, wireMaterial);
          wall.position.set(-40, 5, -10);
          group.add(wall);
      
          group.translateX(-20);
          scene.add(group);
      
          raycaster = new THREE.Raycaster();
      
          window.addEventListener('resize', onWindowResize, false);
          window.addEventListener('mousemove', onDocumentMouseMove, false);
      }
      
      function onDocumentMouseMove(event) {
      
          event.preventDefault();
      
          mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
          mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      
      }
      
      function onWindowResize() {
      
          camera.aspect = 500 / 500;
          camera.updateProjectionMatrix();
      
          renderer.setSize(500, 500);
      }
      
      function update() {
          var delta = clock.getDelta();
          var moveDistance = 200 * delta;
          var rotateAngle = Math.PI / 2 * delta;
      
          if (keyboard.pressed("A"))
              dae.rotation.y += rotateAngle;
          if (keyboard.pressed("D"))
              dae.rotation.y -= rotateAngle;
      
          if (keyboard.pressed("left"))
              dae.translateX(-moveDistance);
          if (keyboard.pressed("right"))
              dae.translateX(moveDistance);
          if (keyboard.pressed("up"))
              dae.translateZ(-moveDistance);
          if (keyboard.pressed("down"))
              dae.translateZ(moveDistance);
      
          meshs = [];
          if (typeof dae !== 'undefined') {
              dae.traverse(function(child) {
                  if (child instanceof THREE.Mesh) {
                      meshs.push(child);
                  }
              });
              $.each(meshs, function(number_mesh, mesh) {
                  var originPoint = mesh.position.clone();
      
                  for (var vertexIndex = 0; vertexIndex < mesh.geometry.vertices.length; vertexIndex++) {
                      var localVertex = mesh.geometry.vertices[vertexIndex].clone();
                      var globalVertex = localVertex.applyMatrix4(mesh.matrix);
                      var directionVector = globalVertex.sub(mesh.position);
      
                      var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
                      var collisionResults = ray.intersectObjects(collidableMeshList);
                      if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
                          console.log(" Hit ");
                      }
                  }
              });
          }
          controls.update();
      }
      
      function animate() {
      
          requestAnimationFrame(animate);
          render();
          update();
      
      }
      
      function render() {
      
          renderer.render(scene, camera);
      
      }
      

      检测 collada 对象上的鼠标。短代码版本:

      var meshs = [],
          raycaster,
          mouse = new THREE.Vector2();
      ...
      function init() {
          ...
          function loadDae(collada) {
              dae = collada.scene;
              dae.scale.x = 0.5;
              dae.scale.y = 0.3;
              dae.scale.z = 0.3;
              dae.updateMatrix();
              group.add(dae);
              dae.traverse(function(child) {
                  if (child instanceof THREE.Mesh) {
                      meshs.push(child);
                  }
              });
          }
      
          var loader = new THREE.ColladaLoader();
      
          loader.options.convertUpAxis = true;
          loader.load('./sample.dae', loadDae);
          raycaster = new THREE.Raycaster();
          window.addEventListener('mousemove', onDocumentMouseMove, false);
          ...
      }
      ...
      function onDocumentMouseMove(event) {
      
          event.preventDefault();
      
          mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
          mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
      
      }
      
      function render() {
          raycaster.setFromCamera(mouse, camera);
      
          if (group.children.length === 5) {
              var intersects = raycaster.intersectObjects(meshs);
      
              if (intersects.length > 0) {
                  console.log(" Hit ");
              }
          }
          renderer.render(scene, camera);
      }
      ...
      

      一般 - 是的,它有效,但会抛出一些 $meshs 的错误 ?。

      TypeError: undefined is not an object (evalating 'O')

      三个.min.js:8304
      cthree.min.js:3544
      intersectObjectsthree.min.js:3609:144

      为什么以及如何识别哪些网格对 intersectObjects 是正确的,哪些不是?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-19
        相关资源
        最近更新 更多