I have a parent container called 'cubeAndLabelContainer' and a cube and a label (sprite) inside it.
The problem is that the location for pivot of the label is different than the cube's, even though the mesh and the sprite are both part of the 'cubeAndLabelContainer':
var cubeAndLabelContainer;
function initObjects()
{
cubeAndLabelContainer = new THREE.Object3D();
var cube = _createCube();
var label = _createLabel();
cube.position.set( 0, 0, 0 );
label.position.set(0, 20, 0 );
cubeAndLabelContainer.position.set( 0, 0, 0 );
cubeAndLabelContainer.add( cube );
cubeAndLabelContainer.add( label );
scene.add( cubeAndLabelContainer );
}
The label should rotate around the cube, but instead they appear like two separate objects rotating at the same rate.
http://codepen.io/anon/pen/pRpgPp
If I add more meshes to the 'cubeAndLabelContainer', their rotation and location is perfectly fine and aligned correctly relative to each other. But when I do the same with sprites, the pivot is different for some reason..
Any suggestions please?
Related
I have created a transparent floor from a PlaneGeometry. But the requirement is that other objects will rise up from beneath that plane. They must not be visible until they are above the floor.
Is it possible to hide those objects despite being behind something with transparency?
You could use a local clipping plane, so these objects will only be visible above the plane.
See this three.js example: https://threejs.org/examples/?q=clipping#webgl_clipping
Important parts:
// plane on ground/floor level
var clippingPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
// material of objects that will rise up
var material = new THREE.MeshPhongMaterial({
color: 0x80ee10,
clippingPlanes: [ clippingPlane ]
clipShadows: true
});
The application displays photos.
When the user clicks on a photo I want to change its size and location
Changing the location works with this code:
photo.position.y=700;
photo.position.x=700;
but I do not know how to change width and height which where set using:
Three.PlaneGeometry ( width,height,1,1)
( I do not want to move the camera nor frustrom )
Once you've created your Mesh, you can modify its scale parameter.
var imageGeom = new THREE.PlaneGeometry(1, 1, 1, 1); // Create a 1x1 plane
var imageFrame = new THREE.Mesh(geometry, material); // Build mesh with geometry
// Now you set up the desired dimensions of the resulting mesh
imageFrame.scale.x = 2;
imageFrame.scale.y = 1.5;
This will give you a mesh that's scaled up, and its final dimensions are 2 x 1.5. You shouldn't need to alter the PlaneGeometry after you first create it; to keep things simple, start with a 1x1, and scale the Mesh instead.
Is there a way to setup the Three.js renderer in such a way that the lookat point of the camera is not in the center of the rendered image?
To clarify: image a scene with just one 1x1x1m cube at ( 0, 0, 0 ). The camera is located at ( 0, 0, 10 ) and the lookat point is at the origin, coinciding with the center of the cube. If I render this scene as is, I might end up with something like this:
normal render
However I'd like to be able to render this scene in such a way that the lookat point is in the upper left corner, giving me something like this:
desired render
If the normal image is 800x600, then the result I envision would be as if I rendered a 1600x1200 image with the lookat in the center and then cropped that normal image so that only the lower right part remains.
Of course, I can change the lookat to make the cube go to the upper left corner, but then I view the cube under an angle, giving me an undesired result like this:
test.moobels.com/temp/cube_angle.jpg
I could also actually render the full 1600x1200 image and hide 3/4 of the image, but one would hope there is a more elegant solution. Does anybody know it?
If you want your perspective camera to have an off-center view, the pattern you need to use is:
camera = new THREE.PerspectiveCamera( for, aspect, near, far );
camera.setViewOffset( fullWidth, fullHeight, viewX, viewY, viewWidth, viewHeight );
See the docs: https://threejs.org/docs/#api/cameras/PerspectiveCamera
You can find examples of this usage in this example and this example.
three.js r.73
Here's a simple solution:
Assuming your cube is 4 x 4 x 4, at position 0, 0, 0:
var geometry = new THREE.BoxGeometry( 4, 4, 4 );
var material = new THREE.MeshBasicMaterial( { color: 0x777777 } );
var cube = new THREE.Mesh( geometry, material );
cube.position.set( 0, 0, 0 );
Get cube's position:
var Vx = cube.position.x,
Vy = cube.position.y,
Vz = cube.position.z;
Then deduct by 2 from x position, then add 2 to y and z position, and use the values to create a new Vector3:
var newVx = Vx - 2,
newVy = Vy + 2;
newVz = Vz + 2;
var xyz = new THREE.Vector3(newVx, newVy, newVz)
Then camera lookAt:
camera.lookAt(xyz);
Using console log, it would show that the camera is now looking at -2, 2, 2, which is the upper-left of your cube.
console.log(xyz);
I am creating a scene & have used a boolean function to cut out holes in my wall. However the lighting reveals that the resultant shapes have messed up faces. I want the surface to look like one solid piece, rather than fragmented and displaying lighting backwards. Does anyone know what could be going wrong with my geometry?
The code that booleans objects is as follows:
//boolean subtract two shapes, convert meshes to bsps, subtract, then convert back to mesh
var booleanSubtract = function (Mesh1, Mesh2, material) {
//Mesh1 conversion
var mesh1BSP = new ThreeBSP( Mesh1 );
//Mesh2 conversion
var mesh2BSP = new ThreeBSP( Mesh2 );
var subtract_bsp = mesh1BSP.subtract( mesh2BSP );
var result = subtract_bsp.toMesh( material );
result.geometry.computeVertexNormals();
return result;
};
I have two lights in the scene:
var light = new THREE.DirectionalLight( 0xffffff, 0.75 );
light.position.set( 0, 0, 1 );
scene.add( light );
//create a point light
var pointLight = new THREE.PointLight(0xFFFFFF);
// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
// add to the scene
scene.add(pointLight);
EDIT: Using WestLangley's suggestion, I was able to partially fix the wall rendering. And by using material.wireframe=true; I can see that after the boolean operation my wall faces are not merged. Is there a way to merge them?
Your problems are due to two issues.
First, you should be using FlatShading.
Second, as explained in this stackoverflow post, MeshLambert material only calculates the lighting at each vertex, and interpolates the color across each face. MeshPhongMaterial calculates the color at each texel.
You need to use MeshPhongMaterial to avoid the lighting artifacts you are seeing.
three.js r.68
I am new to three.js but here is what I am trying to do.
I have a sphere.. and I want to add an id label at a distance (say) 2 units to its surface.
So
var geometry = new THREE.SphereGeometry( 50, 25, 25 );
var draw_object = new THREE.Mesh( geometry, [ new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) ] );
now I want to give it a name "sphere 1"
and then at a distance "x" units from surface of sphere.. assign a label to it.
The catch is this sphere moves in space..so the label has to stay with it.
I have been trying since past two days without any luck.
Help
Any s
You will probably want to use a Sprite as in the example referenced above (how to add Label to a THREE.Mesh?) However, instead of setting the position to be the mouse coordinates, calculate the offset from the sphere -- say it was, for example, (3,4,5) -- and do something like
label.position.set( sphere.position.add( new THREE.Vector3(3,4,5) ) );
This way, the label's position stores a reference to the sphere's position, and as the sphere moves the label will move with it.