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

时间:2019-02-14 18:48:59

标签: three.js

THREE.js中是否有一些帮助程序方法,允许您查看从obj文件加载的网格中分配给每个顶点的编号? [minimal obj file]

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

如果THREE.js中没有这样的方法,我可能会构建一个达到这种效果的工具,但是我想尽可能地节省时间。对于在THREE.js中查找此功能的任何建议将不胜感激!

1 个答案:

答案 0 :(得分:1)

解决方案是:

  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;
}

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