Here I bumped to the problem since I need to merge two geometries (or meshes) to one. Using the earlier versions of three.js there was a nice function:
THREE.GeometryUtils.merge(pendulum, ball);
However, it is not on the new version anymore.
I tried to merge pendulum
and ball
with the following code:
ball
is a mesh.
var ballGeo = new THREE.SphereGeometry(24,35,35); var ballMat = new THREE.MeshPhongMaterial({color: 0xF7FE2E}); var ball = new THREE.Mesh(ballGeo, ballMat); ball.position.set(0,0,0); var pendulum = new THREE.CylinderGeometry(1, 1, 20, 16); ball.updateMatrix(); pendulum.merge(ball.geometry, ball.matrix); scene.add(pendulum);
After all, I got the following error:
THREE.Object3D.add: object not an instance of THREE.Object3D. THREE.CylinderGeometry {uuid: "688B0EB1-70F7-4C51-86DB-5B1B90A8A24C", name: "", type: "CylinderGeometry", vertices: Array[1332], colors: Array[0]…}THREE.error @ three_r71.js:35THREE.Object3D.add @ three_r71.js:7770(anonymous function) @ pendulum.js:20
A Three. js Mesh is a base class that inherits from Object3d and is used to instantiate polygonal objects by combining a Geometry with a Material. Mesh is also the base class for the more advanced MorphAnimMesh and SkinnedMesh classes.
To explain Darius' answer more clearly (as I struggled with it, while trying to update a version of Mr Doob's procedural city to work with the Face3 boxes):
Essentially you are merging all of your Meshes into a single Geometry. So, if you, for instance, want to merge a box and sphere:
var box = new THREE.BoxGeometry(1, 1, 1); var sphere = new THREE.SphereGeometry(.65, 32, 32);
...into a single geometry:
var singleGeometry = new THREE.Geometry();
...you would create a Mesh for each geometry:
var boxMesh = new THREE.Mesh(box); var sphereMesh = new THREE.Mesh(sphere);
...then call the merge method of the single geometry for each, passing the geometry and matrix of each into the method:
boxMesh.updateMatrix(); // as needed singleGeometry.merge(boxMesh.geometry, boxMesh.matrix); sphereMesh.updateMatrix(); // as needed singleGeometry.merge(sphereMesh.geometry, sphereMesh.matrix);
Once merged, create a mesh from the single geometry and add to the scene:
var material = new THREE.MeshPhongMaterial({color: 0xFF0000}); var mesh = new THREE.Mesh(singleGeometry, material); scene.add(mesh);
A working example:
<!DOCTYPE html> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.js"></script> <!-- OrbitControls.js is not versioned and may stop working with r77 --> <script src='http://threejs.org/examples/js/controls/OrbitControls.js'></script> <body style='margin: 0px; background-color: #bbbbbb; overflow: hidden;'> <script> // init renderer var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // init scene and camera var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 3000); camera.position.z = 5; var controls = new THREE.OrbitControls(camera) // our code var box = new THREE.BoxGeometry(1, 1, 1); var sphere = new THREE.SphereGeometry(.65, 32, 32); var singleGeometry = new THREE.Geometry(); var boxMesh = new THREE.Mesh(box); var sphereMesh = new THREE.Mesh(sphere); boxMesh.updateMatrix(); // as needed singleGeometry.merge(boxMesh.geometry, boxMesh.matrix); sphereMesh.updateMatrix(); // as needed singleGeometry.merge(sphereMesh.geometry, sphereMesh.matrix); var material = new THREE.MeshPhongMaterial({color: 0xFF0000}); var mesh = new THREE.Mesh(singleGeometry, material); scene.add(mesh); // a light var light = new THREE.HemisphereLight(0xfffff0, 0x101020, 1.25); light.position.set(0.75, 1, 0.25); scene.add(light); // render requestAnimationFrame(function animate(){ requestAnimationFrame(animate); renderer.render(scene, camera); }) </script> </body>
At least, that's how I am interpreting things; apologies to anyone if I have something wrong, as I am no where close to being a three.js expert (currently learning). I just had the "bad luck" to try my hand at customizing Mr. Doob's procedural city code, when the latest version breaks things (the merge stuff being one of them, the fact that three.js no longer uses quads for cube -ahem- box geometry the other - which has led to all kinds of fun getting the shading and such to work properly again).
Finally, I found a possible solution. I am posting since it could be useful for somebody else while I wasted a lot of hours. The tricky thing is about manipulating the concept of meshes and geometries:
var ballGeo = new THREE.SphereGeometry(10,35,35); var material = new THREE.MeshPhongMaterial({color: 0xF7FE2E}); var ball = new THREE.Mesh(ballGeo, material); var pendulumGeo = new THREE.CylinderGeometry(1, 1, 50, 16); ball.updateMatrix(); pendulumGeo.merge(ball.geometry, ball.matrix); var pendulum = new THREE.Mesh(pendulumGeo, material); scene.add(pendulum);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With