How to draw a costom cube in three.js? - three.js

I just want to draw one cube, such as one building(I got the places on the ground which is consisted of four points),and I also knew the height of the building. So how to draw? Thanks very much.

This is pretty straightforward:
http://threejs.org/docs/#Reference/Extras.Geometries/CubeGeometry
var building = new THREE.CubeGeometry(width, height, depth, 1, 1, 1);
var material = new THREE.MeshLambertMaterial({ color: 0xFF0000 });
var mesh = new THREE.Mesh(building, material);
scene.add(mesh);

Related

Sphere object deformation after changing position of sphere

I have two sphere objects on the scene. Both of them been made with default position (scene center). There is no problem when objects are in the middle, however when I want to move one to the right and second to the left, strange deformation has a place. When spheres moving away from the center on X axis they seems to be more squeezed on Y axis. It is kind of "FishEye" lens effect. Is it possible that some default cameras value is interfering to make such a result? FOV value does not bring solution for that, and I did not find information about camera lens properties. What is wrong with that?
I have tried to play with Vector3 as a position provider and spheres has the same result.
I have tried object.position.set(vector3) with no result.
Also object.position.copy(vector3) gave the same result.
Trying translate position without animation gave the same result.
Playing with FOV parameter in camera object also did not solve the problem.
// init
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(100, window.innerWidth/window.innerHeight, 0.1,10000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//creating sphere
var geometry = new THREE.SphereGeometry(6, 16, 16);
var material = new THREE.MeshBasicMaterial({color: 0xffffff, wireframe: true});
var sphere = new THREE.Mesh(geometry, material);
//earth
var geometry = new THREE.SphereGeometry(3, 16, 16);
var material = new THREE.MeshBasicMaterial({color: 0x0000ff, wireframe: true});
var earth = new THREE.Mesh(geometry, material);
scene.add(sphere, earth);
camera.position.z = 10;
var animation = function(){
requestAnimationFrame(animation);
update();
renderer.render(scene,camera);
}
var update = function(){
earth.rotation.y +=0.001;
sphere.rotation.y -=0.001;
sphere.rotation.x -=0.001;
sphere.position.x +=0.001;
}
I expect to move sphere.postion.x -=1; and earth.position.x+=1; without squeezing and deformation of spheres on Y axis.
Welcome to Stack Overflow. Thank you for taking the time to take the tour, and for including your code.
The fish-eye effect is likely being caused by your camera defintion:
var camera = new THREE.PerspectiveCamera(100, window.innerWidth/window.innerHeight, 0.1,10000);
The 100 is the FOV (Field of View) for your camera, and is quite wide. In a PerspectiveCamera, the wider your FOV, the more distortion you'll see for objects closer to the edges. Try setting it lower to get a more natural effect.
Do some searches for "Perspective Distortion" and you should find a host of articles on why it happens and how to mitigate it. For starters, here's the Wikipedia page: https://en.wikipedia.org/wiki/Perspective_distortion_(photography) which has a nice animation of changing the FOV for an image of a house.

Three.js: How to prevent parts of mesh from shape dissapearing at larger distance

I have a geometry that should be visible from a close and large distance. It is a shape geometry. The material used is the basic mesh material. The code is like this:
var shape = new THREE.Shape(geoPoints);
var geometry = new THREE.ShapeGeometry(shape);
var material = new THREE.MeshBasicMaterial({
color: 0x0000FF,
wireframe: true
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
When I use the wireframe property of the material, the geometry stays entirely visible. However, when I turn off the wireframe parts of the mesh dissapear from larger distance. This can be seen in the added figures:
Mesh basic material, wireframe off
Mesh basic material, wireframe on
How can this be solved? Many thanks in advance.

Why three.js textured faces are looking askew when rotated?

What's wrong in the example below?
The faces are looking askew when they are not parallel to the viewport.
http://jsfiddle.net/mneja2mr/
geometry = new THREE.CubeGeometry(10, 10, 10);
texture=new THREE.ImageUtils.loadTexture(dataUrl);
material = new THREE.MeshBasicMaterial({
map: texture
});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
The CanvasRenderer do not interpolate attributes correctly for perspective cameras; this break texture mapping.
If you need to render with CanvasRenderer, a quick fix is to subdivide the geometry: http://jsfiddle.net/41g0ffb3/2/
geometry = new THREE.CubeGeometry(10, 10, 10, 10, 10, 10);

threejs relation between mesh position and its binded geometry vertices position

I am looking for a way to manipulate a bundle of objects, usually one trick is to make groups, put objects as a group's children. But it is not working properly in my case.
What I want to do is binding a geometry and its wireframe together so I can manipulate them together. In the case of cube, I used a BoxGeometry and a BoxHelper. I created a mesh with BoxGeometry and created BoxHelper of the mesh. Then I want to translate/rotate/scale this bundle.
I did: geometry.applyMatrix( new THREE.Matrix4().makeTranslation(x, y, z) );
and I add this geometry to parent which worked fine.
But I notice the parent and mesh position is (0, 0, 0), and the BoxHelper position is (0, 0, 0) too. Why is the value not changing along with the geometry vertices? Is the position of an Object3D/Mesh/geometry a relative position to the its parent or in world space?
I tried to apply matrix to the parent. The result is, the mesh is in the right position but the frame is way off. Can anyone explain that? Thank you.
var newcube = new THREE.BoxGeometry(20, 20, 20);
// newcube.applyMatrix( new THREE.Matrix4().makeTranslation(x, y, z);
var mats = [];
mats.push(new THREE.MeshBasicMaterial({ color: 0xffd500 }));
mats.push(new THREE.MeshBasicMaterial({ color: 0x009e60 }));
mats.push(new THREE.MeshBasicMaterial({ color: 0x0051ba }));
mats.push(new THREE.MeshBasicMaterial({ color: 0xffffff }));
mats.push(new THREE.MeshBasicMaterial({ color: "yellow" })); // backward
mats.push(new THREE.MeshBasicMaterial({ color: 0xC41E3A }));
var faceMaterial = new THREE.MeshFaceMaterial(mats);
var parent = new THREE.Object3D();
var mesh = new THREE.Mesh(newcube, faceMaterial);
parent.add(mesh);
var cubeframe = new THREE.BoxHelper( mesh );
cubeframe.material.color.set( 0x0066ff );
parent.add( cubeframe );
parent.applyMatrix( new THREE.Matrix4().makeTranslation(x, y, z);
scene.add(parent);
objects.push(parent);

Check if point is inside a custom mesh geometry

What would be the easiest way to check if a point is inside a custom (irregular) mesh geometry?
If your mesh is close-up. You can use the THREE.js built-in ray-caster. Sample code is as
const point = new THREE.Vector3(2,2,2) // Your point
const geometry = new THREE.BoxBufferGeometry( 5, 5, 5 )
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } )
const mesh = new THREE.Mesh( geometry, material )
const raycaster = new THREE.Raycaster()
raycaster.set(point, new THREE.Vector3(1,1,1))
const intersects = raycaster.intersectObject(mesh)
if( intersects.length %2 === 1) { // Points is in objet
console.log(`Point is in object`)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.js"></script>
Just raycast once from the point to any direction, then check the intersects num, if is odd, the point is in the geometry, here is the demo
This is a computational geometry problem. You can look at Finding if point is inside geometry. Since your geometry is irregular the problem is much harder.
But if precision is not too important you can check if the point is inside the bounding box of the geometry.
Its better to check it using the dot product of ray direction and face normal
tested on three.js (r103)
const point = new THREE.Vector3(2, 2, 2) // Your point
const direction = new THREE.Vector3(1, 1, 1);
const geometry = new THREE.BoxGeometry(5, 5, 5)
const material = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide });
const mesh = new THREE.Mesh(geometry, material)
const raycaster = new THREE.Raycaster()
raycaster.set(point, direction)
const intersects = raycaster.intersectObject(mesh);
if (intersects.length && direction.dot(intersects[0].face.normal) > 0) {
console.log(`Point is in object`);
} else {
console.log(`Point is out of object`);
}
In rare cases you can get even number of interections with point located inside the mesh
(try point = new THREE.Vector3(0, 0, 0), that should give 4 intersections)

Resources