three texture sphere raycaster javascript 3d three.js

javascript - texture - Three.js: ¿Unen dos formas juntas como una?



three js light (2)

Actualicé el contenedor para THREE.js r62, lo puede encontrar aquí: https://github.com/kraag22/csg-wrapper

Soy nuevo en el mundo three.js ... Mi pregunta es: ¿Puedo unir dos formas diferentes como una sola forma? Por ejemplo, atar la esfera y el cilindro juntos como uno


Algo así, sí, hay múltiples opciones:

  1. a través de la jerarquía Simplemente puede agregar una malla a otra utilizando la función add()
  2. a través de la función merge() GeometryUtil para combinar vértices y mallas de dos objetos Geometry en uno
  3. utilizando un editor 3D básico que admite operaciones booleanas entre mallas y exportaciones.

El método 1 es bastante sencillo:

var sphere = new THREE.Mesh( new THREE.SphereGeometry(100,16,12),new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } )); var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ),new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } )); cylinder.position.y = -100; scene.add(sphere); scene.add(cylinder);

Observe que 16 se repite, por lo que el nivel de subdivisiones en una malla coincide con la otra (para un aspecto decente)

Método 2.1 - a través de GeometryUtils

//make a sphere var sg = new THREE.SphereGeometry(100,16,12); //make cylinder - ideally the segmentation would be similar to predictable results var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ); //move vertices down for cylinder, so it maches half the sphere - offset pivot for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100; //merge meshes THREE.GeometryUtils.merge(sg,cg); var mesh = new THREE.Mesh( sg,new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } )); scene.add(mesh);

Método 2.2 fusionando una media esfera de Torno y un cilindro:

var pts = [];//points array var detail = .1;//half-circle detail - how many angle increments will be used to generate points var radius = 100;//radius for half_sphere var total = Math.PI * .51; for(var angle = 0.0; angle < total ; angle+= detail)//loop from 0.0 radians to PI (0 - 180 degrees) pts.push(new THREE.Vector3(0,Math.cos(angle) * radius,Math.sin(angle) * radius));//angle/radius to x,z var lathe = new THREE.LatheGeometry( pts, 16 );//create the lathe with 12 radial repetitions of the profile //rotate vertices in lathe geometry by 90 degrees var rx90 = new THREE.Matrix4(); rx90.setRotationFromEuler(new THREE.Vector3(-Math.PI * .5,0,0)); lathe.applyMatrix(rx90); //make cylinder - ideally the segmentation would be similar for predictable results var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ); //move vertices down for cylinder, so it maches half the sphere for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100; //merge meshes THREE.GeometryUtils.merge(lathe,cg); var mesh = new THREE.Mesh( lathe, new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ) ); mesh.position.y = 150; scene.add(mesh);

El único problema que no puedo abordar en este momento proviene de las caras que están dentro de la malla. Lo ideal sería que se invirtieran las normales para que no se renderizaran, pero no han encontrado una solución rápida para eso.

El tercero es bastante sencillo. La mayoría de los paquetes 3D permiten la operación booleana en mallas (por ejemplo, la combinación de dos mallas con la operación ADD (meshA + meshB)). Intente crear un cilindro y una esfera en Blender (free, opensource), que ya tiene un exportador de three.js . Alternativamente, puede exportar un archivo .obj de las mallas combinadas desde su editor 3d o su elección y usar el script convert_obj_three .

Actualizar

He encontrado otro método, que podría ser más fácil / más intuitivo. ¿Recuerdas las operaciones booleanas que he mencionado anteriormente?

Resulta que hay una increíble biblioteca js solo para eso: Geometría sólida constructiva :

Chandler Prall escribió algunas funciones útiles para conectar CSG con three.js . Así que con la biblioteca CSG y el contenedor three.js para ella , simplemente puede hacer esto:

var cylinder = THREE.CSG.toCSG(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ),new THREE.Vector3(0,-100,0)); var sphere = THREE.CSG.toCSG(new THREE.SphereGeometry(100,16,12)); var geometry = cylinder.union(sphere); var mesh = new THREE.Mesh(THREE.CSG.fromCSG( geometry ),new THREE.MeshNormalMaterial());

Lo que te da un buen resultado (no hay problemas con caras adicionales / volteando normales / etc):