代码之家  ›  专栏  ›  技术社区  ›  duhaime

3.js:显示.obj文件中每个顶点的索引号

  •  0
  • duhaime  · 技术社区  · 5 年前

    在THREE.js中是否有一个helper方法允许一个人查看从obj文件加载的网格中分配给每个顶点的编号?[ minimal obj file ]

    我正在尝试在网格中装配一些骨骼,并希望将这些骨骼定位在特定顶点之间,但还不知道顶点编号。像这样的一个小工具可能对这个目的非常有帮助。

    如果在THREE.js中没有这样的方法,我可能会为此构建一个工具,但是如果可以的话,我想节省时间。如果您有任何关于在THREE.js中查找此功能的建议,我们将不胜感激!

    0 回复  |  直到 5 年前
        1
  •  2
  •   Alex Khoroshylov    5 年前

    解决办法是:

    1. 在每个顶点放置小方框,
    2. 在每个框中添加工具提示,
    3. 工具提示文本设置为顶点索引。

    show vertex indexes in three.js

    如何在three.js中添加工具提示请参见我的答案: Threejs Tooltip

    为方便您使用jsfiddle,请参见: http://jsfiddle.net/mmalex/fux6srgv/

    Javascript代码:

    var scene = new THREE.Scene();
    var raycaster = new THREE.Raycaster();
    
    //create some camera
    camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.x = 3;
    camera.position.y = 3;
    camera.position.z = 3;
    camera.lookAt(0, 0, 0);
    
    var controls = new THREE.OrbitControls(camera);
    
    var renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(new THREE.Color(0x595959));
    document.body.appendChild(renderer.domElement);
    
    // white spotlight shining from the side, casting a shadow
    var spotLight = new THREE.SpotLight(0xffffff, 2.5, 25, Math.PI / 6);
    spotLight.position.set(4, 10, 7);
    scene.add(spotLight);
    
    // collect objects for raycasting, 
    // for better performance don't raytrace all scene
    var tooltipEnabledObjects = [];
    
    var colors = new RayysWebColors();
    var dodecahedronGeometry = new THREE.DodecahedronBufferGeometry(1, 0);
    var dodecahedronMaterial = new THREE.MeshPhongMaterial({
      color: colors.pickRandom().hex,
      transparent: true,
      opacity: 0.75
    });
    var dodecahedron = new THREE.Mesh(dodecahedronGeometry, dodecahedronMaterial);
    scene.add(dodecahedron);
    
    var size = 0.1;
    var vertGeometry = new THREE.BoxGeometry(size, size, size);
    var vertMaterial = new THREE.MeshBasicMaterial({
      color: 0x0000ff,
      transparent: false
    });
    
    var verts = dodecahedronGeometry.attributes.position.array;
    for (let k=0; k<verts.length; k+=3) {
      var vertMarker = new THREE.Mesh(vertGeometry, vertMaterial);
    
      // this is how tooltip text is defined for each box
      let tooltipText = `idx: ${k}, pos: [${verts[k].toFixed(3)},${verts[k+1].toFixed(3)},${verts[k+2].toFixed(3)}]`;
      vertMarker.userData.tooltipText = tooltipText;
    
      vertMarker.applyMatrix(new THREE.Matrix4().makeTranslation(verts[k],verts[k+1],verts[k+2]));
      scene.add(vertMarker);
      tooltipEnabledObjects.push(vertMarker);
    }
    
    function animate() {
      requestAnimationFrame(animate);
      controls.update();
      renderer.render(scene, camera);
    };
    
    // this will be 2D coordinates of the current mouse position, [0,0] is middle of the screen.
    var mouse = new THREE.Vector2();
    
    var latestMouseProjection; // this is the latest projection of the mouse on object (i.e. intersection with ray)
    var hoveredObj; // this objects is hovered at the moment
    
    // tooltip will not appear immediately. If object was hovered shortly,
    // - the timer will be canceled and tooltip will not appear at all.
    var tooltipDisplayTimeout;
    
    // This will move tooltip to the current mouse position and show it by timer.
    function showTooltip() {
      var divElement = $("#tooltip");
    
      if (divElement && latestMouseProjection) {
        divElement.css({
          display: "block",
          opacity: 0.0
        });
    
        var canvasHalfWidth = renderer.domElement.offsetWidth / 2;
        var canvasHalfHeight = renderer.domElement.offsetHeight / 2;
    
        var tooltipPosition = latestMouseProjection.clone().project(camera);
        tooltipPosition.x = (tooltipPosition.x * canvasHalfWidth) + canvasHalfWidth + renderer.domElement.offsetLeft;
        tooltipPosition.y = -(tooltipPosition.y * canvasHalfHeight) + canvasHalfHeight + renderer.domElement.offsetTop;
    
        var tootipWidth = divElement[0].offsetWidth;
        var tootipHeight = divElement[0].offsetHeight;
    
        divElement.css({
          left: `${tooltipPosition.x - tootipWidth/2}px`,
          top: `${tooltipPosition.y - tootipHeight - 5}px`
        });
    
        // var position = new THREE.Vector3();
        // var quaternion = new THREE.Quaternion();
        // var scale = new THREE.Vector3();
        // hoveredObj.matrix.decompose(position, quaternion, scale);
        divElement.text(hoveredObj.userData.tooltipText);
    
        setTimeout(function() {
          divElement.css({
            opacity: 1.0
          });
        }, 25);
      }
    }
    
    // This will immediately hide tooltip.
    function hideTooltip() {
      var divElement = $("#tooltip");
      if (divElement) {
        divElement.css({
          display: "none"
        });
      }
    }
    
    // Following two functions will convert mouse coordinates
    // from screen to three.js system (where [0,0] is in the middle of the screen)
    function updateMouseCoords(event, coordsObj) {
      coordsObj.x = ((event.clientX - renderer.domElement.offsetLeft + 0.5) / window.innerWidth) * 2 - 1;
      coordsObj.y = -((event.clientY - renderer.domElement.offsetTop + 0.5) / window.innerHeight) * 2 + 1;
    }
    
    function handleManipulationUpdate() {
      raycaster.setFromCamera(mouse, camera);
      {
        var intersects = raycaster.intersectObjects(tooltipEnabledObjects);
        if (intersects.length > 0) {
          latestMouseProjection = intersects[0].point;
          hoveredObj = intersects[0].object;
        }
      }
    
      if (tooltipDisplayTimeout || !latestMouseProjection) {
        clearTimeout(tooltipDisplayTimeout);
        tooltipDisplayTimeout = undefined;
        hideTooltip();
      }
    
      if (!tooltipDisplayTimeout && latestMouseProjection) {
        tooltipDisplayTimeout = setTimeout(function() {
          tooltipDisplayTimeout = undefined;
          showTooltip();
        }, 330);
      }
    }
    
    function onMouseMove(event) {
      updateMouseCoords(event, mouse);
    
      latestMouseProjection = undefined;
      hoveredObj = undefined;
      handleManipulationUpdate();
    }
    
    window.addEventListener('mousemove', onMouseMove, false);
    
    animate();
    

    HTML代码:

    <p style="margin-left: 12px;">Mouse hover verts to see vert index and coordinates</p>
    <div id="tooltip"></div>
    

    工具提示元素的CSS:

    #tooltip {
      position: fixed;
      left: 0;
      top: 0;
      min-width: 10px;
      text-align: center;
      padding: 2px 2px;
      font-family: monospace;
      background: #a0c020;
      display: none;
      opacity: 0;
      border: 0px solid transparent;
      box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
      transition: opacity 0.25s linear;
      border-radius: 0px;
    }
    

    给定的方法允许每个顶点附加和显示任何文本信息。