I am using this:
new THREE.Mesh( new THREE.PlaneGeometry( 1000, 1000 ), new THREE.MeshBasicMaterial() );
To create a new plane. How to change the height along z axis? None of the arguments are related to it.
Assuming your mesh is captured as a variable like this:
var planeMesh = new THREE.Mesh(
new THREE.PlaneGeometry( 1000, 1000 ),
new THREE.MeshBasicMaterial() );
Then, all you need to do just to move it back is:
planeMesh.position.z += 50;
Also, Icemonster is correct a plane will render facing you to start, thus depending on your use, you may want to rotate it as mentioned in the comment.
You can rotate the mesh. Try something like this:
mesh.rotation.set(-Math.PI/2, Math.PI/2000, Math.PI);
Related
In this demo:
https://threejs.org/examples/?q=clipping#webgl_clipping_advanced
if you enable the "visualize" option, you can see the 3d pyramid "cutting" the inside object.
Here:
https://threejs.org/examples/?q=clipping#webgl_clipping
there is a simple 2d plane cutting the object, but there is no such option to "see" the plane. I just started learning threejs and I am not too familiar with any 3d engine (other than fully understanding the math behind it), so I tried some basic stuff, e.g.:
localPlane.visible = true
But of course it didn't work. Any 'simple' way to make the second demo display the cutting plane?
Thank you
Here's some code to add the plane in the position you want:
const planeGeometry = new THREE.PlaneGeometry( 1.5, 1.5 );
const planeMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
const plane = new THREE.Mesh( planeGeometry, planeMaterial );
plane.position.copy(localPlane.normal);
plane.position.multiplyScalar(-localPlane.constant);
plane.quaternion.setFromUnitVectors(new THREE.Vector3(0, 0, 1), localPlane.normal);
plane.material.opacity = 0.5;
plane.material.transparent = true;
scene.add( plane );
And here's what that looks like...
However, depending on what you are implementing, you may find it easier to create a Plane Mesh in the position you want, and then derive the clipping plane THREE.Plane from that.
If you want to be able to move the clipping plane around, the reasoning involved in moving a Plane Mesh Object3D is probably more straightforward than reasoning about moving a THREE.Plane.
(update)
Another alternative approach I've come across: you could simply use the built in THREE.PlaneHelper, which can be used to visualize any THREE.Plane.
https://threejs.org/docs/#api/en/helpers/PlaneHelper
The sample code offered on that page is this:
const plane = new THREE.Plane( new THREE.Vector3( 1, 1, 0.2 ), 3 );
const helper = new THREE.PlaneHelper( plane, 1, 0xffff00 );
scene.add( helper );
I´m very new to three js and I want to create a half Cylinder as roof.
var geometry = new THREE.CylinderGeometry(100,100,150);
var material = new THREE.MeshNormalMaterial();
var cylinder = new THREE.Mesh( geometry, material);
scene.add(cylinder);
This is the Basic Cylinder but unfortunately I couldn´t find an specific answer to a half cylinder yet.
Is it possible to create this with vertices?
The last 2 params of CylinderGeometry constructor allows this. For example:
var geometry = new THREE.CylinderGeometry(100,100,150, 8, 1, false, 0, Math.PI);
0 is the start angle and Math.PI is the end angle; i.e. half of a circle.
(Please also refer to my illustration of the problem: http://i.stack.imgur.com/SfwwP.png)
problem description and ideas
I am creating several objects in the standard XYZ coordinate system.
Those are added to a THREE.group.
Please think of the group as a wall with several frames and image hung on it.
I want to create my frame objects with eg. dimension of (40, 20, 0.5). So I get a rather flat landscape formatted frame/artwork. I create and place several of those. Then I add them to the group, which I wanted to freely rotate in the world along two vectors start and end.
The problem I am struggling with is how to rotate and position the group from a given vector start to a give vector end.
So far I tried to solve it with a THREE.Matrix4().lookAt :
var group = new THREE.Group();
startVec = new THREE.Vector3( 100, 0, -100 );
endVec = new THREE.Vector3( -200, 0, 200 );
matrix = new THREE.Matrix4().lookAt(startVec, endVec, new THREE.Vector3( 0, 1, 0 ));
group.matrixAutoUpdate = false;
var object1 = new THREE.Mesh(new THREE.BoxGeometry(0.5, 20, 40), mat);
// etc. -> notice the swapping of X and Z coordinates I have to do.
group.add(object1);
group.applyMatrix(matrix);
You can see the example on jsfiddle:
http://jsfiddle.net/y6b9Lumw/1/
If you open jsfiddle, you can see that the objects are not placed along the line from start to end, although I their are placed along the groups internal X-Axis like: addBox(new THREE.Vector3( i * 30, 0 , 0 ));
Full code:
<html>
<head>
<title>testing a rotation matrix</title>
<style>body { margin: 0; } canvas { width: 100%; height: 100% } </style>
</head> <body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script>
<script>
var scene, camera, renderer, light, matrix;
var startVec, endVec;
var boxes;
function addBox(v) {
var boxmesh;
var boxgeom = new THREE.BoxGeometry( 15, 5, 1 );
var boxmaterial = new THREE.MeshLambertMaterial( {color: 0xdd2222} );
boxmesh = new THREE.Mesh( boxgeom, boxmaterial );
//boxmesh.matrix.makeRotationY(Math.PI / 2);
boxmesh.matrix.setPosition(v);
boxmesh.matrixAutoUpdate = false;
boxes.add(boxmesh);
}
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0x222222 );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( -20, 30, 300 );
var light = new THREE.PointLight (0xCCCCCC, 0.5 );
scene.add(light);
startVec = new THREE.Vector3( 100, 0, -100 );
endVec = new THREE.Vector3( -200, 0, 200 );
matrix = new THREE.Matrix4().lookAt(startVec, endVec, new THREE.Vector3( 0, 1, 0 ));
boxes = new THREE.Group();
for (var i = -100; i < 100; i++) {
addBox(new THREE.Vector3( i * 30, 0 , 0 ));
}
boxes.matrixAutoUpdate = false;
boxes.applyMatrix(matrix);
scene.add(boxes);
var linegeometry = new THREE.Geometry();
linegeometry.vertices.push( startVec, endVec);
var line = new THREE.Line(linegeometry, new THREE.LineBasicMaterial({color: 0x33eeef}));
scene.add(line);
render();
}
function render(){
requestAnimationFrame(render);
renderer.render(scene, camera);
}
init();
</script>
</body> </html>
This works only nicely to some extend. As the look vector is usually oriented along the Z-Axis (i think it is (0,0,1)). So unfortunately the objects inside the group get rotated like that aswell.
This is actually what you would expect from a lookAt() rotational transformation. It's not what I would like to have though, as this places all the children in the group, on their Z-Axis, instead of their X-Axis.
In order to have things look properly I had to initialize my groups children with X and Z swapped.
Instead of:
var object1 = new THREE.BoxGeometry( 40, 20, 0.5 );
I have to do:
var object1 = new THREE.BoxGeometry( 0.5, 20, 40 );
same if I want to translate objects in the group on the X-Axis, I have to use the Z-Axis, as that is the look-vector along which the whole wall is oriented by the matrix transformation.
my question is:
How does my matrix have to be constructed/look like to accomplish what I want: Normally create objects, and then have their X-Axis placed along vector start and vector end, like placing artworks on a wall, which can be moved around?
I thought about creating a matrix, whose X-Axis is end.sub(start), so the vector from start end end, might this be what I need to do? If so, how would I construct it?
problem illustration with an image
I tried to illustrate my sitation in two images. One being the wall, one being the wall inside the world, with the same objects attached to the wall (see top of the post).
In the first figure you see the local coordinate system of the group, with two added children, one translated along X.
In the second figure, you can see the same localsystem inside the world how I would like it to be. The green axes are the world axes. The start and end vectors are shown aswell. You can see, both boxes, are properly placed along that line.
I would like to answer my own question by disregarding the idea of manipulating the matrix myself. Thx to #WestLangley I adapted my idea to the following by setting the groups quaternion via .setFromUnitVectors.
So the rotation is derived from the rotation from the x-axis to the direction vector of start and end, as explained in three.js' documentation:
"Sets this quaternion to the rotation required to rotate direction vector vFrom to direction vector vTo."
(http://threejs.org/docs/#Reference/Math/Quaternion.setFromUnitVectors)
Below is the relevant part of my solution:
// define the starting and ending vector of the wall
start = new THREE.Vector3( -130, -40, 300 );
end = new THREE.Vector3( 60, 20, -100 );
// dir is the direction from start to end, normalized
var dir = new THREE.Vector3().copy(end).sub(start).normalize();
// position wall in the middle of start and end
var middle = new THREE.Vector3().copy(start).lerp(end, 0.5);
wall.position.copy(middle);
// rotate wall by applying rotation from X-Axis to dir
wall.quaternion.setFromUnitVectors( new THREE.Vector3(1, 0, 0), dir );
The result can be seen here: http://jsfiddle.net/L9dmqqvy/1/
I want to merge two meshes in threejs. I want to create a geometry of two planes that are intersecting each other perpendicular. Both of the planes must have the same texture.
I've tried the following.
Currently this error occurs: THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.
var texture = THREE.ImageUtils.loadTexture('/img/foo.png');
var material = new THREE.MeshPhongMaterial( { map: texture, side: THREE.DoubleSide, transparent: true });
var m_plane_1 = new THREE.PlaneGeometry( 128, 128);
var m_plane_2 = new THREE.PlaneGeometry(128, 128);
var plane_1 = new THREE.Mesh(m_plane_1, material);
var plane_2 = new THREE.Mesh(m_plane_2, material);
plane_2.rotation.y = Math.PI / 2;
var combined = new THREE.Geometry();
combined.merge(plane_1); // does not work
//combined.merge(plane_1.geometry, plane_1.matrix); // this does not work
//combined.merge(m_plane_1.geometry, m_plane_1.matrix); // this does not work
scene.add(combined);
I've tried to read the source code for merge() but could not come to any conclusion. I've read stackoverflow threads but their approach does not work for me.
How can I solve this?
You want to get the intersection of the geometries. Then you can apply whatever texture you want to that new geometry.
To get the intersection, you should use Chandler Prall's Constructive Solid Geometry code: http://evanw.github.io/csg.js/
There are several ways to merge two geometries, but probably the simplest way to achieve what you want is to use the following pattern:
var geometry = new THREE.PlaneGeometry( 128, 128 );
var geometry2 = new THREE.PlaneGeometry( 128, 128 );
geometry2.applyMatrix( new THREE.Matrix4().makeRotationY( Math.PI / 2 ) );
geometry.merge( geometry2 );
three.js r.69
Try this:
plane_1.updateMatrix();
//Now the function merge
combined.merge(plane_1.geometry, plane_1.matrix);
//combined.merge(plane_1); // does not work
//combined.merge(plane_1.geometry, plane_1.matrix); // this does not work
//combined.merge(m_plane_1.geometry, m_plane_1.matrix); // this does not work
I want to create some simple 3D points.
Is there any way to create this geometry without tricks?
- I don't need a pointcloud ( or do I need ? )
- I don't want a sprite ( I don't want to load any image).
Maybe I'm some clumsy but I don't see the way.
Any idea & advise ? Thanks.
You maybe want to use a simple sphere geometry with a small radius for your project.
var pointGeometry = new THREE.SphereGeometry( 2, 16, 16 ), // adjust the first value for the 'point' radius
pointMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00} ), // adjust the color of your 'point'
point3D = new THREE.Mesh( pointGeometry, pointMaterial );
scene.add( point3D );
Important side notice: the radius of the sphere and the size it takes on your screen depends on the distance from the camera and the camera.['far'] value, you set while initiating.