I'm trying to build a Mesh with holes from an original Shape and then an ExtrudedGeometry. The problem is that the holes I add always go trough the whole height of the resulting Mesh. Is there any way to make the holes shorter in height, so in the end these don't go across the whole shape?
Reference code for the shape to extruded:
var heartShape = new THREE.Shape();
heartShape.moveTo( 25, 25 );
heartShape.bezierCurveTo( 25, 25, 20, 0, 0, 0 );
blah
var innerCircle = new THREE.Path();
innerCircle.moveTo(blah);
heartShape.holes.push(innerCircle);
var extrudeSettings = { amount: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 };
var geometry = new THREE.ExtrudeGeometry( heartShape, extrudeSettings );
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial() );
Thanks!
There is no separate argument for hole depth in THREE.ExtrudeGeometry. You will need two separate operations to solve it.
One solution could be to "plug" it with another extrude based on your inner circle path (convert to Shape first).
var extrudeSettingsForPlug = { amount: 4, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 };
var geometry = new THREE.ExtrudeGeometry( innerCircleShape, extrudeSettingsForPlug );
Related
I am currently working on a voxel Minecraft like JavaScript game to improve my JS/TS skills but i am facing an issue.
I draw my voxels by drawing multiple faces of blocks in a BufferGeometry but, between two faces, there is a glitched line like in this image.
Here are some parts of my code that could be usefull to understand where the problem come from:
My material:
const texture = loader.load(this.instance.ressourceMapUrl);
texture.magFilter = THREE.NearestFilter;
texture.minFilter = THREE.NearestFilter;
const material = this.blockMaterial = new THREE.MeshLambertMaterial({
map: texture,
alphaTest: 0.1,
transparent: true,
vertexColors: THREE.VertexColors
});
My BufferGeometry:
const geometry = new THREE.BufferGeometry();
const positionNumComponents = 3;
geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(positions), positionNumComponents));
const normalNumComponents = 3;
geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), normalNumComponents));
const uvNumComponents = 2;
geometry.setAttribute('uv', new THREE.BufferAttribute(new Float32Array(uvs), uvNumComponents));
geometry.setIndex(indices);
geometry.colors = new Float32Array(colors);
geometry.setAttribute( 'color', new THREE.BufferAttribute( geometry.colors, 3, true) );
geometry.computeBoundingSphere();
A little sample of the vertexes of a normal chunk:
[0, 12, 0, 0, 12, 1, 1, 12, 0, 1, 12, 1, 1, 12, 0, 1, 12, 1, 2, 12, 0, 2, 12, 1, 2, 12, 0, 2, 12, 1, 3, 12, 0, 3, 12, 1, 3, 12, 0, 3, 12, 1, 4, 12, 0, 4, 12, 1, 4, 12, 0, 4, 12, 1, 5, 12, 0, 5, 12...]
Vertexes are used in this order:
let ndx = positions.length/3;
indices.push(
ndx, ndx + 1, ndx + 2,
ndx + 2, ndx + 1, ndx + 3,
);
My far & near variables:
const near = 0.101;
const far = 240
Thank you a lot for reading this, I know it may be an idiot question but I'm struggling on that for a week and can't manage to find any solution on the web.
Have a nice day.
I found the problem and how to solve it :
This was coming from my textures. Since floats are not precise, it was making these lines.
In order to fix this, I moved the corners I used for my texture by 0.0001 to the center.
The coordinates of my textures from my texture map are stored like this : [x1, y1 x2, y2].
I did this:
let uv: [number, number, number, number] = ...;
let correction = uv[0] > uv[2] ? 0.0001 : -0.0001;
uv[0] -= correction;
uv[2] += correction;
correction = uv[1] > uv[3] ? 0.0001 : -0.0001;
uv[1] -= correction;
uv[3] += correction;
Thank you to everyone that tried to help me and I hope it can help some other people as well !
I was wondering how you use the TextGeometry.js from the extras folder in three.js in your three.js scene. I was trying to add text to my scene. I found this file and have no idea how to implement/use it. Here's a link to the file:
https://github.com/mrdoob/three.js/blob/master/src/extras/geometries/TextGeometry.js
First create a JSON font here.
Then load it like this:
var loader = new THREE.FontLoader();
loader.load("fonts/your_font.json", function(font) {
var textGeo = new THREE.TextGeometry("This is a 3D text", {
font: font,
size: 50,
height: 10,
curveSegments: 12,
bevelThickness: 1,
bevelSize: 1,
bevelEnabled: true
});
var textMat = new THREE.MeshLambertMaterial({color: 0xFF00FF});
var textMesh = new THREE.Mesh(textGeo, textMat);
scene.add(textMesh);
});
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
I had created a shape using extrude geometry , and now with the extrude settings i need to increase the thickness i had used bevelThickness it increases the thickness along y axis , but need to increase it along x and z axis.
Here my working jsfiddle
Below is my code for extrude settings ,
var extrusionSettings = {
curveSegments:5,
steps: 10,
amount: 10,
bevelEnabled: true,
bevelThickness: 120,
bevelSize: 0,
bevelSegments: 8,
material: 0,
extrudeMaterial: 1
};
var geometry1 = new THREE.ExtrudeGeometry( shape1, extrusionSettings );
var materialLeft = new THREE.MeshLambertMaterial({
color: 0xd6d6d6,// red
transparent:true,
side: THREE.DoubleSide,
ambient: 0xea6767,
opacity:-0.5
});
var materialRight = new THREE.MeshLambertMaterial({
color: 0xcc49c3,//violet
side: THREE.DoubleSide,
ambient: 0xcc49c3
});
var materials = [ materialLeft, materialRight
];
var material = new THREE.MeshFaceMaterial( materials );
var mesh1 = new THREE.Mesh( geometry1, material );
object.add( mesh1 );
object.rotation.x = Math.PI / 2;
scene.add( object );
Below is sample image
is there any setting to increase it ? Can any one guide me ?
Finally i did the trick to fix it, What i did is just i cloned a Mesh add added the position to cloned mesh, so i got the wall nearby another inner wall, by this way i have added multiple clone with the loop, multiple inner wall nearby other created the wall thickens,
Demo : Fiddle
//outer wall mesh
var mesh1 = new THREE.Mesh( geometry1, material );
object.add( mesh1 );
var mesh_arr=new Array();
for(i=0.1;i<15;i++)
{
//cloned mesh,add position to the cloning mesh
mesh_arr[i] = mesh1.clone();
mesh_arr[i].position.set(i,i,i);
mesh_arr[i].updateMatrix();
object.add( mesh_arr[i] );
}
I'm having an issue, how can I obtain a kind of "open ring" like the torus but squared?
I tried with a shape plus a path as a hole:
var arcShape = new THREE.Shape();
arcShape.moveTo( 40, 0 );
arcShape.arc( 0, 0, 40, 0, 2*Math.PI, false );
var holePath = new THREE.Path();
holePath.moveTo( 30,0 )
holePath.arc( 0, 0, 30, 0, 2*Math.PI, true );
And until now, making a mesh:
new THREE.Mesh( arcShape.extrude({ amount: 5, bevelEnabled: false }), MATERIAL );
it works, but how to make a middle ring? I mean, with:
var arcShape = new THREE.Shape();
arcShape.moveTo( 40, 0 );
arcShape.arc( 0, 0, 40, 0, Math.PI, false );
var holePath = new THREE.Path();
holePath.moveTo( 30,0 );
holePath.arc( 0, 0, 30, 0, Math.PI, true );
It works, but it remains a subtle face between the terminal parts... is there a way to make it completely open?
Rather than start from square one, try changing the parameters in the Torus geometry constructor:
// Torus geometry parameters:
// radius of entire torus,
// diameter of tube (should be less than total radius),
// segments around radius,
// segments around torus ("sides")
var torusGeom = new THREE.TorusGeometry( 25, 10, 4, 4 );