how to change starting position of a sphere in threejs - three.js

I created a 3D Earth using three.js that rotates, but the problem is that it starts spinning over the ocean.
i triedto change starting position using matrixWorld but didn't change anything
can someone help plz
here is my js:
...
const earthgeometry = new THREE.SphereGeometry(0.344,64,32);
const eatrhmaterial = new THREE.MeshPhongMaterial({
roughness: 1,
metalness:0,
map: THREE.ImageUtils.loadTexture('static/img/earthmap1k.jpg'),
bumpMap: THREE.ImageUtils.loadTexture('static/img/earthbump.jpg'),
bumpScale: 0.3,
});
const earthmesh = new THREE.Mesh(earthgeometry,eatrhmaterial);
earthmesh.position.set (0.49,0.035,0.58);
earthmesh.matrixWorld.setPosition(new THREE.Vector3(100, 100, 100));
...

The same way you set a position, you can set a rotation of your object.
const earthgeometry = new THREE.SphereGeometry(0.344,64,32);
const earthmaterial = new THREE.MeshPhongMaterial({
//material definition here
});
const earthmesh = new THREE.Mesh(earthgeometry,earthmaterial);
earthmesh.position.set (0.49,0.035,0.58);
earthmesh.rotation.set (0,1.1,0);//or any other values
remember :
rotation are in radians: 360° = 2*Math.PI
Y axis is the vertical one

Related

Get center position of hole in ExtrudeGeometry

I trying to get position of hole in extruded geometry. I created plane and made hole in her geometry. I want get x,y,z coordinates in center of hole. Is there some methods to get it?
Here demo: https://codepen.io/DYDOI-NSK/pen/XWqJzXG?editors=0011
Here code:
I created shape of plane
let shape = new THREE.Shape();
let width = 30;
let height = 30;
shape.moveTo(-width, height);
shape.lineTo(-width, -height);
shape.lineTo(width, -height);
shape.lineTo(width, height);
shape.lineTo(-width, height);
I created hole path and add it to shape
let hole = new THREE.Path();
hole.absarc(20, 10, 10, 0, Math.PI * 2, false) //first two argumets is x,y coord of hole
shape.holes.push(hole)
I created plane add add extruded geometry
let geometry = new THREE.PlaneGeometry( 30, 30);
let material = new THREE.MeshBasicMaterial( {color: new THREE.Color('#cea6a6'), side: THREE.DoubleSide} );
let mesh = new THREE.Mesh( geometry, material );
let newGeometry = new THREE.ExtrudeGeometry(shape, settings);
mesh.geometry.dispose()
mesh.geometry = newGeometry;
After 4 days I understand how can do it. I simple created line from mesh center to hole config position. Applied quaternion to line and got x,y,z cords of hole.
Maybe there are more optimized solutions, but it only that I could create. I will be glad if someone share more optimized solution :D
Here codepen: https://codepen.io/DYDOI-NSK/pen/XWqJzXG?editors=0011
Here code:
/*
* findCoords - function to find hole coords in 3d space
* data - parameter that require x,y of hole
*/
let findCoords = function (data) {
let vertexes = [];
//Set coords where you was created hole
let hole = new THREE.Vector3(
data.x,
data.y,
0
);
vertexes.push( new THREE.Vector3() );
vertexes.push(hole)
//Create line
const material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
const geometry = new THREE.BufferGeometry().setFromPoints( vertexes );
const line = new THREE.Line( geometry, material );
scene.add(line)
//Set line to center of mesh
line.position.copy(mesh.position)
//Rotate line like rotated mesh
line.applyQuaternion(mesh.quaternion)
//Extract hole coords from second vertex of line
let holeCoord = new THREE.Vector3()
const positionAttribute = line.geometry.getAttribute( 'position' );
holeCoord.fromBufferAttribute( positionAttribute, 1);
return holeCoord;
}

how to get the boundingSphere for a whole scene in three.js?

How to get the bounding sphere for a whole scene in three.js?
I may try to get the bounding sphere for each object and compute the resulting union of them, but I think there may be a more straight forward method.
There are different methods to get a boundingSphere of multiple objects dynamically. You can get first the bounding box of all of them, and then create a sphere of that bounding box... here is a sample fiddle I have shaped on boundingSphere of a boundingBox.
Basically you put all the geometries into a Group, you get the Box3 of the group, and then you do getBoundingSphere from the Box3 and position at the center. Code in the fiddle would be this.
let g = new THREE.Group();
scene.add(g);
for (let i = 0; i < 5; i++) {
// geometry
var geometry = new THREE.BoxGeometry(20, 20, 20);
// material
var material = new THREE.MeshToonMaterial({
color: 0xff0000,
opacity: 0.7,
});
// mesh
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(100 * Math.random(), 100 * Math.random(), 100 * Math.random());
g.add(mesh);
}
//g.updateWorldMatrix(true);
var gridHelper = new THREE.GridHelper(400, 40, 0x0000ff, 0x808080);
gridHelper.position.y = 0;
gridHelper.position.x = 0;
scene.add(gridHelper);
let bbox = new THREE.Box3().setFromObject(g);
let helper = new THREE.Box3Helper(bbox, new THREE.Color(0, 255, 0));
scene.add(helper);
const center = new THREE.Vector3();
bbox.getCenter(center);
let bsphere = bbox.getBoundingSphere(new THREE.Sphere(center));
let m = new THREE.MeshStandardMaterial({
color: 0xffffff,
opacity: 0.3,
transparent: true
});
var geometry = new THREE.SphereGeometry(bsphere.radius, 32, 32);
let sMesh = new THREE.Mesh(geometry, m);
scene.add(sMesh);
sMesh.position.copy(center);
EDITED: If you want to include in the boundingSphere for the scene including the lights (which could get you a huge sphere), just start from let bbox = new THREE.Box3().setFromObject(scene)

Get 3D cube from an Obb3

given an Obb3 (Center, HalfVector and axis[3]),
how can I create a cube that has the same bounds as this Obb3 ?
I'll then use this cube to display my obb3 bounds.
I use vector_math and three.dart libraries
So far, my code is :
Matrix3 rot_mat = new Matrix3(node.box.axis0[0], node.box.axis1[0], node.box.axis2[0],
node.box.axis0[1], node.box.axis1[1], node.box.axis2[1],
node.box.axis0[2], node.box.axis1[2], node.box.axis2[2]);
Vector3 diag = rot_mat.absoluteRotate(node.box.halfExtents.clone());
var geometry = new CubeGeometry(diag[0] * 2.0, diag[1] * 2.0, diag[2] * 2.0);
var material = new MeshBasicMaterial(color: 0x00ff00,
wireframe: true,
blending: NormalBlending,
side: DoubleSide,
shading: FlatShading);
var obj = new Mesh(geometry, material);
obj.position = node.box.center;
obj.matrix.setRotation(rot_mat);
obj.updateMatrix();
scene.add(obj);
Thanks a lot for your help :]

three.js How to render a simple white dot/point/pixel

I'm using THREE.WebGLRenderer and I would like to draw a few same-sized white dots at specific positions in 3D space.
Should I use sprites, calculate the 2D screen coordinates and use SpriteMaterial.useScreenCoordinate?
Should I simply recalculate the size of the sprites using the distance of them to the camera?
Can I use SpriteMaterial.scaleByViewport or SpriteMaterial.sizeAttenuation? Is there any documentation for this?
Is there something like GL_POINTS? It would be nice to just define 1 vertex and get a colored pixel at that position. Should I experiment with PointCloud?
Thanks for any hints!
Edit: All points should have the same size on the screen.
Using .sizeAttenuation and a single-vertex PointCloud works, but it feels a bit… overengineered:
var dotGeometry = new THREE.Geometry();
dotGeometry.vertices.push(new THREE.Vector3( 0, 0, 0));
var dotMaterial = new THREE.PointsMaterial( { size: 1, sizeAttenuation: false } );
var dot = new THREE.Points( dotGeometry, dotMaterial );
scene.add( dot );
For r125
The excerpt is taken from threejs official example. After some modification here how made it to work.
var dotGeometry = new BufferGeometry();
dotGeometry.setAttribute( 'position', new Float32BufferAttribute( [0,0,0], 3 ) );
var dotMaterial = new PointsMaterial( { size: 0.1, color: 0x00ff00 } );
var dot = new Points( dotGeometry, dotMaterial );
scene.add( dot );
Yet another update: The interface for attribute has changed somewhat:
For r139
const dotGeometry = new THREE.BufferGeometry();
dotGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array([0,0,0]), 3));
const dotMaterial = new THREE.PointsMaterial({ size: 0.1, color: 0xff0000 });
const dot = new THREE.Points(dotGeometry, dotMaterial);
scene.add(dot);

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