I'm on r68 and I'm trying to find an example of someone creating a rectangular pyramid which I can apply THREE.MeshFaceMaterial() to, most of the examples seem fairly out of date and throw errors with my current build.
I just need to be able to
Texturise each face
Rotate it so the rectangular face is at the -y position
Thanks in advance!
The accepted answer works only for pyramids with a base that has equal sides. In case you want a pyramid with a rectangular foot you can do like this:
var geometry = new THREE.Geometry();
geometry.vertices = [
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( 0, 1, 0 ),
new THREE.Vector3( 1, 1, 0 ),
new THREE.Vector3( 1, 0, 0 ),
new THREE.Vector3( 0.5, 0.5, 1 )
];
geometry.faces = [
new THREE.Face3( 0, 1, 2 ),
new THREE.Face3( 0, 2, 3 ),
new THREE.Face3( 1, 0, 4 ),
new THREE.Face3( 2, 1, 4 ),
new THREE.Face3( 3, 2, 4 ),
new THREE.Face3( 0, 3, 4 )
];
Now you have a pyramid geometry with a square base of 1 x 1 and a height of 1. By applying a scaling matrix we can make this pyramid to any desired width/length/height combination:
var transformation = new THREE.Matrix4().makeScale( width, length, height );
geometry.applyMatrix( transformation );
This can also be wrapped in a custom Pyramid geometry class so you can use it like this:
new THREE.Pyramid( width, length, height );
As #WestLangley stated, using a THREE.CylinderGeometry() to do this is the correct way, here's how I did mine
var geometry = new THREE.CylinderGeometry( 1, TILE_SIZE*3, TILE_SIZE*3, 4 );
var material = new THREE.MeshBasicMaterial( {color: 0xffff00 , wireframe:true} );
var cylinder = new THREE.Mesh( geometry, material );
this.scene.add( cylinder );
Works perfect!
Use ConeBufferGeometry geometry and change radialSegments to 4
BufferGeometry are faster than normal Geometry
Other parameters you can tweak:
ConeBufferGeometry(radius : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)
Result:
Live Demo:
https://threejs.org/docs/#api/en/geometries/ConeBufferGeometry
Related
I want to draw a triangle and i know only all angles (Alpha,Beta,Gamma) and all side length (10).
For drawing a triangle i need to set 3 vertices to geometry with absolute Vector3 values.
Is in THREE.js any integrated tool or practice fit for this?
geometry.vertices.push(
new THREE.Vector3( 0, 0, 0 ),
new THREE.Vector3( -10, -10, 0 ),
new THREE.Vector3( 10, -10, 0 ),
);
geometry.faces.push( new THREE.Face3( 0, 1, 2 ));
var material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
var mesh = new THREE.Mesh( geometry, material );
Only THREE method i can imagine is to create a 2 vector geometry with vector distance of side lengths, use matrix translation to set rotation pivot on vector[0] and change its position and rotation, each time set globalToWorld() for its vector[1]. But I think this is not a good solution.
I used this:
var length = 10;
var aplpha = 0.3;//rad
var beta= 1;//rad
geometry.vertices.push(
new THREE.Vector3(),
new THREE.Vector3(length ,0,0).applyAxisAngle(new THREE.Vector3(0,1,0),aplpha ),
new THREE.Vector3(length ,0,0).applyAxisAngle(new THREE.Vector3(0,1,0),beta ),
new THREE.Vector3(),
);
https://threejs.org/docs/#api/en/math/Vector3
THREE.JS r 96
I am trying to construct a cube manually using three.js by declaring its vectors and faces; I am able to do it using the code below, however, the material does not seem to be working as expected, instead the cube is rendering in a solid black color.
var geom = new THREE.Geometry();
var v1 = new THREE.Vector3( -1, 1, 0.1 ),
v2 = new THREE.Vector3( 1, 1, 0.1 ),
v3 = new THREE.Vector3( 1, -1, 0.1 ),
v4 = new THREE.Vector3( -1, -1, 0.1 ),
v5 = new THREE.Vector3( -1, 1, 2 ),
v6 = new THREE.Vector3( 1, 1, 2 ),
v7 = new THREE.Vector3( 1, -1, 2 ),
v8 = new THREE.Vector3( -1, -1, 2 );
geom.vertices.push(v1,v2,v3,v4,v5,v6,v7,v8);
geom.faces.push(
new THREE.Face3(0,1,3),
new THREE.Face3(1,2,3),
new THREE.Face3(4,5,7),
new THREE.Face3(5,6,7),
new THREE.Face3(1,4,5),
new THREE.Face3(0,1,4),
new THREE.Face3(2,3,7),
new THREE.Face3(2,6,7),
new THREE.Face3(0,3,7),
new THREE.Face3(0,4,7),
new THREE.Face3(1,2,5),
new THREE.Face3(2,5,6)
);
var mat = new THREE.MeshNormalMaterial();
mat.side = THREE.DoubleSide;
var cube = new THREE.Mesh( geom, mat);
scene.add(cube);
If I render the cube normally, using the code that follows, the cube renders as expected.
cube = new THREE.Mesh(new THREE.CubeGeometry(2, 2, 2), new THREE.MeshNormalMaterial());
scene.add(cube);
You haven't specified vertex normals. For something quick, compute face normals, like so:
geom.computeFaceNormals();
but you should learn how to set vertex normals in your custom geometry.
Also, face "winding order" should be counter-clockwise. You are not consistently doing that.
If you define faces correctly, you can remove side = THREE.DoubleSide.
three.js r.90
I am currently playing with ThreeJS decals. I have been able to put a beautiful stain on my sphere.
Here is the piece of code I use to "apply" the decal on my sphere. (I have some custom classes, but don't worry about this.
// Create sphere
var mainMesh = new THREE.Mesh(
new THREE.SphereGeometry(7, 16, 16),
new THREE.MeshBasicMaterial({ color: 0x00a1fd })
);
// Declare decal material
var decalMaterial = new THREE.MeshPhongMaterial({
color : 0xff0000,
specular : 0x444444,
map : TextureLoader.instance.getTexture('http://threejs.org/examples/textures/decal/decal-diffuse.png'),
normalMap : TextureLoader.instance.getTexture('http://threejs.org/examples/textures/decal/decal-normal.jpg'),
normalScale : new THREE.Vector2( 1, 1 ),
shininess : 30,
transparent : true,
depthTest : true,
depthWrite : false,
polygonOffset : true,
polygonOffsetFactor : -4,
wireframe : false
});
// Create decal itself
var decal = new THREE.Mesh(
new THREE.DecalGeometry(
mainMesh,
new THREE.Vector3(0, 2.5, 3),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(8, 8, 8),
new THREE.Vector3(1, 1, 1)
),
decalMaterial.clone()
);
// Add mesh + decal + helpers
scene.add(
mainMesh,
new THREE.HemisphereLight(0xffffff, 0, 1),
decal,
new THREE.WireframeHelper(decal, 0xffff00)
);
decal.add(new THREE.BoxHelper(decal, 0xffff00));
Now, I woud like to move this stain on my sphere, and thus, update the geometry of my decal.
Unfortunately, when I call decal.geometry.computeDecal(), the mesh of the decal does not update. I can't find any solution about this.
function moveDecal()
{
decal.translateX(1);
decal.geometry.computeDecal();
};
According to the DecalGeometry class, the function computeDecal already set to true various members required to update vertices, colors, UVs, ....
this.computeDecal = function() {
// [...]
this.verticesNeedUpdate = true;
this.elementsNeedUpdate = true;
this.morphTargetsNeedUpdate = true;
this.uvsNeedUpdate = true;
this.normalsNeedUpdate = true;
this.colorsNeedUpdate = true;
};
Thank you for your help ! :D
PS : ThreeJS r80
You are trying to update vertices of your geometry.
You can change the value of a vertex componnent,
geometry.vertices[ 0 ].x += 1;
but you can't add new veritices
geometry.vertices.push( new THREE.Vector3( x, y, z ) ); // not allowed
or assign a new vertex array
geometry.vertices = new_array; // not allowed
after the geometry has been rendered at least once.
Similalry, for other attributes, such as UVs.
For more info, see this answer: verticesNeedUpdate in Three.js.
three.js r.80
Basicially I like to connect the right side of mesh 1 to the left side of mesh 2.
Currently, If I scale mesh1 I have to reposition mesh2 in order to have the same distance as before.
So let's scale mesh 1 to z: 2
var tween = new TWEEN.Tween(mesh1.scale).to({ z: 2 }, 1000).start();
tween.easing(TWEEN.Easing.Elastic.InOut);
In order to have the same distance to mesh 1 as before I have to reposition mesh 2 to z:1.5
var tween = new TWEEN.Tween(mesh2.position).to({ z: 1.5 }, 1000).start();
tween.easing(TWEEN.Easing.Elastic.InOut);
Are there any options in connecting the colored mesh faces. So If I scale mesh 1, mesh 2 automatically change it's position?
...
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var mesh1 = new THREE.Mesh( geometry,
new THREE.MeshPhongMaterial({color: 0x222222}));
mesh1 .position.set( 0, 0, 0 );
mesh1 .scale.set( 1, 1, 1 );
scene.add( mesh1 );
var mesh2 = new THREE.Mesh( geometry,
new THREE.MeshPhongMaterial({color: 0x222222}));
mesh2 .position.set( 0, 0, 1 );
mesh2 .scale.set( 1, 1, 1 );
scene.add( mesh2 );
This is a geometric problem.
I haven't worked with three.js before, but I believe I have a geometric solution.
Consider a third imaginary mesh, mesh3, such that it is a combination of mesh1 and mesh2.
That is:
mesh1: position(0, 0, 0), scale(1, 1, 1);
mesh2: position(0, 0, 1), scale(1, 1, 1);
mesh3: position(0, 0, 0), scale(1, 1, 2); // Loosely, mesh3 = mesh1 + mesh2
Now to scale the structure by a scalar k, I propose two approaches:
Approach 1:
Scale mesh1 and mesh3 each by k.
Compute the difference between mesh3 and mesh1, meshDiff.
Set mesh2 = meshDiff.
Approach 2:
Scale mesh3 by k.
Compute two halves of mesh3, mesh31 and mesh32, such that they are oriented along mesh1 and mesh2 respectively.
Set mesh1 = mesh31 and mesh2 = mesh32.
The approaches are very similar. Keep three.js's API in mind to choose the best approach.
Note: You needn't ever render mesh3. It only exists as a computational aid.
Generality:
The idea presented above can be used in other situations as well, wherein geometries sharing a common feature need to be scaled.
Hope this helps.
PS: I realize that this answer is a little abstract. Nonetheless, I hope it helps.
I need to reverse vertex order in faces of my geometry.
In example:
// create geometry
var geometry = new THREE.Geometry();
// create vertices
geometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
geometry.vertices.push( new THREE.Vector3( 0, 100, 0 ) );
geometry.vertices.push( new THREE.Vector3( 100, 0, 0 ) );
// create face
var face = new THREE.Face3( 0, 1, 2 );
geometry.faces.push ( face );
// compute normals
geometry.computeFaceNormals();
geometry.computeVertexNormals();
// add to scene
var mesh = new THREE.Mesh(
geometry,
new THREE.MeshBasicMaterial({color: 0x00ffff})
);
scene.add( mesh );
Now I need to change order of vertices in face from 0,1,2 to 2,1,0. But when I do this manually it does not work no matter which flags for update I set to true.
The question - is it possible to reverse vertices order on the fly and if yes then how?
Important - It's better to avoid using negative scale for geometry in this case. And it's also better to avoid re-creating of object.
THREE.js: r73
delete mesh.geometry.__directGeometry;
This should apply yours changes. In some reason in r72 and r73 __directGeometry not updated automatically.