Three.js | Generate dynamically a BezierCurve - javascript

I don't find the right syntax to generate dynamically a BezierCurve from an array, I've tried to make a push, but it don't work.
var x = [0,10,100,220,100, etc,...];
var y = [10,0,100,200,200, etc,...];
var z = [100,220,10,0,100, etc,...];
var points = [];
for(i=0; i < x.length; i++){
points.push( new THREE.Vector3( x[i], y[i], z[i] ) );
}
var curve = new THREE.CubicBezierCurve3( points );
var geometry = new THREE.Geometry();
var curveObject = new THREE.Line( geometry, material );
scene.add(curveObject);
An idea ?

you can use
var curve = new (Function.bind.apply(THREE.CubicBezierCurve3, [null].concat(points)));
or if you target only ES6 compatible browsers spread operator
var curve = new THREE.CubicBezierCurve3(...points);

Related

ThreeCSG don't give expected result

I want to create a simple app in three.js
For this app, I need to subtract two meshes and I have found that ThreeCSG can do this. But somehow I don't get the expected result.
I have copied the code from an example, but even this doesn't work properly.
Trying some other function like the union. But instead of merging two meshes into one it removes it.
link to ThreeCSG: https://github.com/chandlerprall/ThreeCSG/blob/master/ThreeCSG.js
result that I get when subtracting
result that I get when I use union
var materialNormal = new THREE.MeshNormalMaterial( { side: THREE.DoubleSide } );
var diceCube = new THREE.Mesh( new THREE.BoxGeometry(10,10,10), materialNormal);
diceCube.position.x = 0;
diceCube.position.y = 5;
diceCube.position.z = 0;
diceCube.geometry.computeFaceNormals();
diceCube.geometry.computeVertexNormals();
var cubeBSP = new ThreeBSP(diceCube);
var sphereGeometry = new THREE.SphereGeometry(7.5,16,8);
var sphereMesh = new THREE.Mesh(sphereGeometry, materialNormal);
sphereMesh.scale.x = 0.17;
sphereMesh.scale.y = 0.17;
sphereMesh.scale.z = 0.17;
//coords of the spheres
var xPositions = [ 0, 3 ]; // coordinates for xPositions of sphereMesh
var yPositions = [ 10, 10 ];
var zPositions = [ 0, 0 ];
var diceDots = new THREE.Geometry();
for(var i = 0; i < xPositions.length; i++){
sphereMesh.position.x = xPositions[i];
sphereMesh.position.y = yPositions[i];
sphereMesh.position.z = zPositions[i];
sphereMesh.updateMatrix();
diceDots.merge( sphereMesh.geometry, sphereMesh.matrix );
}
var material = new THREE.MeshPhongMaterial( { color: 0xffaa00 });
var dotsMesh = new THREE.Mesh(diceDots);
dotsMesh.geometry.computeFaceNormals();
dotsMesh.geometry.computeVertexNormals();
var dotsBSP = new ThreeBSP(dotsMesh);
var resultBSP = cubeBSP.subtract(dotsBSP);
result = resultBSP.toMesh(material);
scene.add(result);
I have found a solution.
The threeCSG I used was corrupted this one works exactly how it must be done.
Link to working ThreeCSG: https://github.com/oathihs/ThreeCSG/blob/master/dist/THREE.CSG.js

Why mesh created with ThreeBSP.js is not working properly with any material other than MeshNormalMaterial?

The dice looks like a dice only if I use MeshNormalMaterial in the second last line (result = resultBSP.toMesh(materialNormal);). With any other material it just looks like a cube with no subtraction (dots) on it. The ThreeBSP (ThreeCSG upgrade) library I am using is located here.
There is no problem with using the MeshNormalMaterial. It just doesn't have almost any options to modify it. (It doesn't take parameters like other materials).
Here is my function that I am using to create a dice:
function buildDice(){
var materialNormal = new THREE.MeshNormalMaterial();
var diceCube = new THREE.Mesh( new THREE.BoxGeometry(100,100,100), materialNormal);
diceCube.position.x = 0;
diceCube.position.y = 50;
diceCube.position.z = 0;
diceCube.geometry.computeFaceNormals();
diceCube.geometry.computeVertexNormals();
var cubeBSP = new ThreeBSP(diceCube);
var sphereGeometry = new THREE.SphereGeometry(75,16,8);
var sphereMesh = new THREE.Mesh(sphereGeometry, materialNormal);
sphereMesh.scale.x = 0.17;
sphereMesh.scale.y = 0.17;
sphereMesh.scale.z = 0.17;
//coords of the spheres
var xPositions = [....]; // coordinates for xPositions of sphereMesh
var yPositions = [....];
var zPositions = [....];
var diceDots = new THREE.Geometry();
for(var i = 0; i < xPositions.length; i++){
sphereMesh.position.x = xPositions[i];
sphereMesh.position.y = yPositions[i];
sphereMesh.position.z = zPositions[i];
THREE.GeometryUtils.merge(diceDots, sphereMesh);
}
var dotsMesh = new THREE.Mesh(diceDots, materialNormal);
dotsMesh.geometry.computeFaceNormals();
dotsMesh.geometry.computeVertexNormals();
var dotsBSP = new ThreeBSP(dotsMesh);
var resultBSP = cubeBSP.subtract(dotsBSP);
result = resultBSP.toMesh(materialNormal);
scene.add(result);
}
It does work with other Materials, for example with a THREE.MeshPhongMaterial. This jsfiddle using your buildDice()-function may help you:
http://jsfiddle.net/L0rdzbej/152/
You have to update the mesh´s matrix before merging the geometry, and best not to use deprecated functions for this.
Three.js r73

THREE.ExplodeModifier hacking

I'm using the ExplodeModifier to duplicate the vertices so I can have individual control over Face3 objects.
For my specific example, this alone looks visually poor, so I decided to add 3 extra faces (per existing face) so I can have a pyramid shape pointing inwards the geometry.
I managed to modify the ExplodeModifier and create the extra faces, however I get several errors:
THREE.DirectGeometry.fromGeometry(): Undefined vertexUv and THREE.BufferAttribute.copyVector3sArray(): vector is undefined
I understand that now I have 9 extra vertices per face, so I need according uv's, and since I don't need a texture but a solid color I don't mind having the wrong uvs... So, I also duplicated the uvs and avoid the first warning but I can't get rid of the copyVector2sArray...
pseudo code:
var geometry = new THREE.IcosahedronGeometry( 200, 1 );
var material = new THREE.MeshPhongMaterial( { shading: THREE.FlatShading } );
var explodeModifier = new THREE.ExplodeModifier();
explodeModifier.modify( geometry );
var mesh = new THREE.Mesh( geometry, material );
scene.addChild( mesh );
The Explode Modifier has this pseudo code:
var vertices = [];
var faces = [];
for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
(...)
var extraFace1 = new THREE.Face3().copy(face)
extraFace1.c = geometry.vertices[0]
var extraFace2 = new THREE.Face3().copy(face)
extraFace2.b = geometry.vertices[0]
var extraFace3 = new THREE.Face3().copy(face)
extraFace3.a = geometry.vertices[0]
faces.push( extraFace1 );
faces.push( extraFace2 );
faces.push( extraFace3 );
}
geometry.vertices = vertices;
geometry.faces = faces;
```
I added an example HERE. It works, but I want to avoid the console warnings...
As pointed out by #mrdoob I was assigning a THREE.Vector3 and not an index to the added THREE.Face3.
var extraFace1 = new THREE.Face3().copy(face)
extraFace1.a = geometry.faces.length * 3 - 1
var extraFace2 = new THREE.Face3().copy(face)
extraFace2.b = geometry.faces.length * 3 - 1
var extraFace3 = new THREE.Face3().copy(face)
extraFace3.c = geometry.faces.length * 3 - 1
jsfiddle updated

Three.js finding vertices of buffergeometry after .fromGeometry();

How do I find vertices positions of a mesh after I used .fromGeometry(); code? I created a buffergeometry from a geomtery that I used for a mesh. Here is an example.
var geom = new THREE.BoxGeometry(1,1,1);
var buffgeom = new THREE.BufferGeometry();
buffgeom.fromGeometry(geom);
var mat = new THREE.MeshBasicMaterial({ color: 0x0000ff });
var cube = new THREE.Mesh(buffgeom, mat);
geometryvertices.vertices = buffgeom.vertices;
The geometryvertices.vertices = buffgeom.vertices; code doesn't work for buffgeom. How do I find vertices positions of buffgeom? Can somebody please help?
After that I want to push the vertices of a geometry into THREE.Vector3. This is how it worked with a geometry.
geom.vertices.push(Vector3);
And it doesn't work with a buffergeometry.
var tempGeo = new THREE.Geometry().fromBufferGeometry(myMesh.geometry);
for (var i= 0; i< tempGeo.vertices.length; i++) {
var pos = tempGeo.vertices[i].applyMatrix4(myMesh.matrix);
}

Three js merging Geometries and Mesh

Three js ver67
Current code something like this -
var materials = [];
var totalGeom = new THREE.Geometry();
var cubeMat;
for (var i = 0; i < dataSetArray.length; i++) {
var ptColor = dataSetArray[i].color;
var value = dataSetArray[i].value;
var position = latLongToVector3(dataSetArray[i].y, dataSetArray[i].x, 600, 1);
var cubeGeom = new THREE.BoxGeometry(5, 5, 1 + value / 20);
cubeMat = new THREE.MeshLambertMaterial({
color: new THREE.Color(ptColor),
opacity: 0.6
});
materials.push(cubeMat);
// cubeGeom.updateMatrix();
var cubeMesh = new THREE.Mesh(cubeGeom, cubeMat);
cubeMesh.position = position;
cubeMesh.lookAt(scene.position);
// totalGeom.merge(cubeMesh.geometry, cubeMesh.geometry.matrix);
//THREE.GeometryUtils.setMaterialIndex(cubeMesh.geometry, i);
THREE.GeometryUtils.merge(totalGeom, cubeMesh);
}
var total = new THREE.Mesh(totalGeom, new THREE.MeshFaceMaterial(materials));
scene.add(total);
However I get the message
DEPRECATED: GeometryUtils's .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.
in chrome dev tools.
When I try something like -
totalGeom.merge(cubeMesh.geometry, cubeMesh.geometry.matrix);
instead of THREE.GeometryUtils.merge(totalGeom, cubeMesh); I get exceptions.
How will I do the above merge? Please help.
Note: This answer applies to legacy versions of three.js.
Do this:
cubeMesh.updateMatrix();
totalGeom.merge( cubeMesh.geometry, cubeMesh.matrix );
For a further understanding, see the source code of THREE.Geometry.merge().
three.js r.69

Categories