RoundEdgedBox

Approach 3

by Paul West

HTML

<script src="https://threejs.org/build/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>
  function RoundEdgedBox(w, h, d, r, wSegs, hSegs, dSegs, rSegs) {
  
  	w = w || 1;
    h = h || 1;
    d = d || 1;
    let minimum = Math.min(Math.min(w, h), d);
    r = r || minimum * .25;
    r = r > minimum * .5 ? minimum * .5 : r;
    wSegs = Math.floor(wSegs) || 1;
    hSegs = Math.floor(hSegs) || 1;
    dSegs = Math.floor(dSegs) || 1;
    rSegs = Math.floor(rSegs) || 1;

    let fullGeometry = new THREE.BufferGeometry();

    let fullPosition = [];
    let fullUvs = [];
    let fullIndex = [];
    let fullIndexStart = 0;
    
    let groupStart = 0;

    bendedPlane(w, h, r, wSegs, hSegs, rSegs, d * .5, 'y', 0, 0);
    bendedPlane(w, h, r, wSegs, hSegs, rSegs, d * .5, 'y', Math.PI, 1);
    bendedPlane(d, h, r, dSegs, hSegs, rSegs, w * .5, 'y', Math.PI * .5, 2);
    bendedPlane(d, h, r, dSegs, hSegs, rSegs, w * .5, 'y', Math.PI * -.5, 3);
    bendedPlane(w, d, r, wSegs, dSegs, rSegs, h * .5, 'x', Math.PI * -.5, 4);
    bendedPlane(w, d, r, wSegs, dSegs, rSegs, h * .5, 'x', Math.PI * .5, 5);

    fullGeometry.addAttribute("position", new THREE.BufferAttribute(new Float32Array(fullPosition), 3));
    fullGeometry.addAttribute("uv", new THREE.BufferAttribute(new Float32Array(fullUvs), 2));
    fullGeometry.setIndex(fullIndex);
    
    fullGeometry.computeVertexNormals();
    
    return fullGeometry;

    function bendedPlane(width, height, radius, widthSegments, heightSegments, smoothness, offset, axis, angle, materialIndex) {

      let halfWidth = width * .5;
      let halfHeight = height * .5;
      let widthChunk = width / (widthSegments + smoothness * 2);
      let heightChunk = height / (heightSegments + smoothness * 2);

      let planeGeom = new THREE.PlaneBufferGeometry(width, height, widthSegments + smoothness * 2, heightSegments + smoothness * 2);

      let v = new THREE.Vector3(); // current...

CSS

body {
  overflow: hidden;
  margin: 0;
}

JavaScript

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(0, 3, 7);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x808080);
document.body.appendChild(renderer.domElement);

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

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

var width = 5;
var height = 3;
var depth = 2;
var radius = .75;
var widthSegments = 3;
var heightSegments = 3;
var depthSegments= 2;
var smoothness = 20;


var planeGeom = RoundEdgedBox(width, height, depth, radius, widthSegments, heightSegments, depthSegments, smoothness);

var textureLoader = new THREE.TextureLoader();
textureLoader.setCrossOrigin("");
var texture = textureLoader.load("https://threejs.org/examples/textures/uv_grid_opengl.jpg");

var materials = //[
	new THREE.MeshStandardMaterial({map: texture})/*,
  new THREE.MeshBasicMaterial({color: "red"}),
  new THREE.MeshLambertMaterial({color:"blue"}),
  new THREE.MeshNormalMaterial(),
  new THREE.MeshPhongMaterial({color:"green", map: texture}),
  new THREE.MeshBasicMaterial({color:"purple", wireframe: true})
]*/;

var plane = new THREE.Mesh(planeGeom, materials);
scene.add(plane);

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects = [];

renderer.domElement.addEventListener("mousedown", onMouseDown, false);

function onMouseDown(event){
	mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
	mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
	
  raycaster.setFromCamera(mouse, camera);
  intersects = raycaster.intersectObjects([plane]);
  let objString = "none";
  if (intersects.length != 0) {
  	objString = intersects[0].object.type;
  }
  objClicked.innerHTML = "You've...