ThreeJS在形状的边缘添加45度切割

问题描述 投票:1回答:1

我已尽力找到解决方案,但我没有成功。我正在使用THREE.Shape创建形状,我在文件中有顶点数据,该形状是直的而没有在边缘处切割。我必须在边缘处添加45度切割。

示例屏幕截图:

enter image description here


enter image description here

javascript three.js shapes
1个回答
3
投票

根据我的评论对您的问题的处理方式,根据框架的最新修订,进行了一些更改:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(5, 5, 10);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xffffff, 0.75);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.25));

var helper = new THREE.GridHelper(20, 20);
//helper.geometry.rotateX(Math.PI * -.5);
scene.add(helper);

var profileShape1 = new THREE.Shape();
profileShape1.moveTo(0, 0);
profileShape1.lineTo(0, 1);
profileShape1.absarc(1, 1, 0.5, Math.PI, Math.PI * 1.5);
profileShape1.lineTo(1, 0);

var contour1 = [
  new THREE.Vector2(-1, 2),
  new THREE.Vector2(1, 2),
  new THREE.Vector2(1, -2),
  new THREE.Vector2(-1, -2)
];

var geometry1 = ProfiledContourGeometry(profileShape1, contour1, true);
var fullProfile1 = new THREE.Mesh(geometry1, new THREE.MeshStandardMaterial({
  color: 0xFACE8D,
  wireframe: false,
  metalness: 0,
  roughness: 0.75,
  flatShading: true
}));
scene.add(fullProfile1);

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
  function ProfiledContourGeometry(profileShape, contour, contourClosed, openEnded) {

    contourClosed = contourClosed !== undefined ? contourClosed : true;
    openEnded = openEnded !== undefined ? openEnded : false;
    openEnded = contourClosed === true ? false : openEnded;

    let profileGeometry = new THREE.ShapeBufferGeometry(profileShape);
    let flipProfileGeometry = flipShapeGeometry(profileGeometry);
    profileGeometry.rotateX(Math.PI * 0.5);
    let profile = profileGeometry.attributes.position;

    let addEnds = openEnded === false ? 2 : 0;
    let profilePoints = new Float32Array(profile.count * (contour.length + addEnds) * 3);

    let endProfiles = [];

    for (let i = 0; i < contour.length; i++) {
      let v1 = new THREE.Vector2().subVectors(contour[i - 1 < 0 ? contour.length - 1 : i - 1], contour[i]);
      let v2 = new THREE.Vector2().subVectors(contour[i + 1 == contour.length ? 0 : i + 1], contour[i]);
      let angle = v2.angle() - v1.angle();
      let halfAngle = angle * 0.5;

      let hA = halfAngle;
      let tA = v2.angle() + Math.PI * 0.5;
      if (!contourClosed) {
        if (i == 0 || i == contour.length - 1) {
          hA = Math.PI * 0.5;
        }
        if (i == contour.length - 1) {
          tA = v1.angle() - Math.PI * 0.5;
        }
      }

      let shift = Math.tan(hA - Math.PI * 0.5);
      let shiftMatrix = new THREE.Matrix4().set(
        1, 0, 0, 0, -shift, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
      );


      let tempAngle = tA;
      let rotationMatrix = new THREE.Matrix4().set(
        Math.cos(tempAngle), -Math.sin(tempAngle), 0, 0,
        Math.sin(tempAngle), Math.cos(tempAngle), 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
      );

      let translationMatrix = new THREE.Matrix4().set(
        1, 0, 0, contour[i].x,
        0, 1, 0, contour[i].y,
        0, 0, 1, 0,
        0, 0, 0, 1,
      );

      let cloneProfile = profile.clone();
      cloneProfile.applyMatrix4(shiftMatrix);
      cloneProfile.applyMatrix4(rotationMatrix);
      cloneProfile.applyMatrix4(translationMatrix);

      /*shiftMatrix.applyToBufferAttribute(cloneProfile);
      rotationMatrix.applyToBufferAttribute(cloneProfile);
      translationMatrix.applyToBufferAttribute(cloneProfile);*/

      profilePoints.set(cloneProfile.array, cloneProfile.count * i * 3);
      if (openEnded === false && (i === 0 || i === contour.length - 1)) {
        endProfiles.push(cloneProfile);
      }
    }

    endProfiles.forEach((ep, idx) => {
      profilePoints.set(ep.array, ep.count * (contour.length + idx) * 3)
    });

    let fullProfileGeometry = new THREE.BufferGeometry();
    fullProfileGeometry.setAttribute("position", new THREE.BufferAttribute(profilePoints, 3));
    let index = [];

    let lastCorner = contourClosed == false ? contour.length - 1 : contour.length;
    for (let i = 0; i < lastCorner; i++) {
      for (let j = 0; j < profile.count; j++) {
        let currCorner = i;
        let nextCorner = i + 1 == contour.length ? 0 : i + 1;
        let currPoint = j;
        let nextPoint = j + 1 == profile.count ? 0 : j + 1;

        let a = nextPoint + profile.count * currCorner;
        let b = currPoint + profile.count * currCorner;
        let c = currPoint + profile.count * nextCorner;
        let d = nextPoint + profile.count * nextCorner;


        index.push(a, b, d);
        index.push(b, c, d);
      }
    }

    if (openEnded === false) {
      // add indices from profile geometries
      flipProfileGeometry.index.array.forEach(i => {
        index.push(i + profile.count * (contour.length))
      });
      profileGeometry.index.array.forEach(i => {
        index.push(i + profile.count * (contour.length + 1))
      });

    }

    fullProfileGeometry.setIndex(index);
    fullProfileGeometry.computeVertexNormals();

    return fullProfileGeometry;
  }

  function flipShapeGeometry(shapeGeometry) {
    let flipGeom = shapeGeometry.clone();
    for (let i = 0; i < flipGeom.attributes.position.count; i++) {
      flipGeom.attributes.position.array[i * 3] *= -1;
    }
    flipGeom.attributes.position.needsUpdate = true;

    var index = flipGeom.index.array;
    for (let i = 0; i < index.length; i += 3) {
      let v2 = index[i + 1];
      let tmp = v2;
      let v3 = index[i + 2];
      index[i + 1] = index[i + 2];
      index[i + 2] = tmp;
    }
    flipGeom.computeVertexNormals();
    return flipGeom;
  }
</script>
© www.soinside.com 2019 - 2024. All rights reserved.