How do I revolve points around a mesh? - javascript

I'm trying to use Three.js to generate some points with Three.Points, and then make the points themselves revolve around a single point (or mesh). I've generated the points randomly in a cylinder region as mentioned in this answer and reviewed posts such as this one, which doesn't seem to work as it's rotating a mesh around a mesh.
Here's what I've got so far:
//Mesh that is to be revolved around
const blackHoleGeometry = new THREE.SphereGeometry(10, 64, 64);
const blackHoleMaterial = new THREE.MeshBasicMaterial({
color: 0x000000
});
const blackHole = new THREE.Mesh(blackHoleGeometry, blackHoleMaterial);
scene.add(blackHole);
//Points that are supposed to revolve around the mesh
const particles = new THREE.PointsMaterial({
color: 0xffffff
});
const geometry = new THREE.Geometry();
// [...] code to generate random points
const pointCloud = new THREE.Points(geometry, particles);
pointCloud.rotation.x = Math.PI / 2; //to rotate it 90*
You can see a full demo here. How can I have the points all revolve around the sphere mesh, as in each vertex of the point "cloud"'s geometry revolving around a center point, or the mesh like a planet and a star?

Couple problems with you code, but here is an updated fiddle for you: https://jsfiddle.net/pwwkght0/2/
So when you create your Three.js scene you want to keep all of your code in the init function. So I moved everything in there and then I called init outside of the variable. When you do this, init will create you scene until it reaches the last line and call animate. You want to call animate instead of render because animate will request animation frames and call render on each.
function init() {
//do all the things to make the scene
function animate() {
requestAnimationFrame(animate);
orbit();
controls.update();
render();
}
function render() {
renderer.render(scene, camera);
}
animate();
}
init()
So now that you are requesting animation frames, it's time to make things orbit. I made a very simple function to grab your point cloud and rotate it on its z-axis, to simulate it rotating around the sphere. Notice how orbit is called in animate:
function orbit() {
pointCloud.rotation.z += 0.01;
}
You can take this a step further and have each point rotate at a different speed around the sphere by accessing pointCloud's children property.

Related

Rotating looped meshes results unexpectedly

I have a three.js project where I'm adding in 100 meshes, that are divided into 10 scenes:
//add 100 meshes to 10 scenes based on an array containing 100 elements
for (var i = 0; i < data.length; i++) {
mesh = new THREE.Mesh(geometry, material);
//random positions so they don't spawn on same spot
mesh.position.x = THREE.Math.randInt(-500, 500);
mesh.position.z = THREE.Math.randInt(-500, 500);
They're added in by a loop, and all these meshes are assigned to 10 scenes:
// Assign 10 meshes per scene.
var sceneIndex = Math.floor(i/10);
scenes[sceneIndex].add(mesh);
I also wrote a functionality where I can rotate a mesh around the center of the scene.
But I don't know how to apply the rotation functionality to all meshes while still keeping them divided into their corresponding scenes. This probably sounds way too vague so I have a fiddle that holds all of the relevant code.
If you comment these two lines back in you'll see that the meshes all move to scenes[0], and they all rotate fine the way I wanted, but I still need them divided in their individual scenes.
spinningRig.add(mesh);
scenes[0].add(spinningRig);
How is the code supposed to look like? Waht is the logic to it?
The logic is fairly simple. The simplest format would be to have a separate spinningRig for each scene -- essentially a grouping of the meshes for each scene.
When you create each scene, you'll also create a spinningRig and add + assign it to that scene:
// Setup 10 scenes
for(var i=0;i<10;i++) {
scenes.push(new THREE.Scene());
// Add the spinningRig to the scene
var spinningRig = new THREE.Object3D();
scenes[i].add(spinningRig);
// Track the spinningRig on the scene, for convenience.
scenes[i].userData.spinningRig = spinningRig;
}
Then instead of adding the meshes directly to the scene, add them to the spinningRig for the scene:
var sceneIndex = Math.floor(i/10);
scenes[sceneIndex].userData.spinningRig.add(mesh);
And finally, rotate the spinningRig assigned to the currentScene:
currentScene.userData.spinningRig.rotation.y -= 0.025;
See jsFiddle: https://jsfiddle.net/712777ee/4/

updating mesh geometry in Three.js?

I have two meshes: mesh1 and mesh2. both have the same number of vertices and have extrusion.
mesh1 = 5000 vertices.
mesh2 = 5000 vertices.
I assign the vertices of mesh2 to mesh1. then I do:
mesh2.geometry.verticesNeedUpdate = true;
mesh2.geometry.vertices = mesh1.geometry.vertices;
thus the vertices of mesh2 are updated. but this happens too fast. I can not see an animation while it makes mesh2's vertices to mesh1's vertices.
I want to see the transformation when malla2 starts to become the malla1, I mean to see an animation of vertices when they are changing.
I used "Tween.js" for animations such as position and color. I'm not sure if this can help to view animations when vertices begin to change.
I do:
new TWEEN.Tween( mesh2.geometry.vertices ).to( mesh1.geometry.vertices, 1000 ).start();
but not works. sorry for my level of english.
As you've seen, this doesn't work -- in part because for each call to update the mesh vertices, you must also call geometry2.verticesNeedUpdate = true; for every one of these frames.
--
more specifically I think you will want to add .onUpdate(function() { geometry2.verticesNeedUpdate = true; }) to your tween.

How to move object from position {x,y} to {newx,newy} in Three.js

X and y are coordinates of object. Z is always 0. How can I move (with visible move animation, not popping up in different location) this object to new location using Three.js?
EDIT: Code example of object (mesh)
var mesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), new THREE.MeshBasicMaterial({img: THREE.ImageUtils.loadTexture('img.png')}))
scene.add(mesh)
EDIT 2: I can make my mesh jump to new position with mesh.position.x=newx and mesh.position.y=newy but I want it to look smooth like in JQuery animate().
The key to animating any kind of object is to move it small amounts, at a high refresh rate.
This means rendering the scene many times but moving the object in the direction you wish a little bit per frame.
e.g.
var direction = new THREE.Vector3(0.3, 0.5, 0); // amount to move per frame
function animate() {
object.position.add(direction); // add to position
renderer.render(camera, scene); // render new frame
requestAnimationFrame(animate); // keep looping
}
requestAnimationFrame(animate);

THREE.js - How to fade the background?

I'm trying to recreate the effect of fading the drawing buffer and leaving trails of the drawn objects, instead of clearing it every frame. It's a pretty simple effect that in 2D would be done like this: http://jsfiddle.net/faRW3/1/
// draw stuff
c.fillStyle = "red";
c.fillRect(Math.sin( time )*50+70, Math.cos( time )*50+70, 20, 20);
// fade background
c.fillStyle = "rgba(255, 255, 255, 0.25)";
c.fillRect(0, 0, canvas.width, canvas.height);
But I haven't found the way to do it in WebGL, especially using Three.js. I tried to do it by setting preserveDrawingBuffer to true and playing with the Effect Composer but haven't been successful.
I would appreciate any advice.
One way is to place a transparent plane behind the scene and set preserveDrawingBuffer = true.
renderer = new THREE.WebGLRenderer( { preserveDrawingBuffer: true } );
renderer.autoClearColor = false;
// background plane
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 100, 100 ), new THREE.MeshBasicMaterial( { transparent: true, opacity: 0.1 } ) );
plane.position.z = -10;
scene.add( plane );
For a live example see: http://vincemckelvie.com/Potluck/Cartwheel/
three.js r.64
The technique described by WestLangley works very well, but if you want more control over your motion trails you can also use WebGLRenderTarget.
You might have noticed for example that setting the opacity of the plane to values lower than 0.1 results in permanent stains on the screen. With render targets it is possible to fix that.
The technique requires three scenes and three textures:
sceneContent contains cube
sceneComp contains quadComp with material (textureNew + textureOld)
sceneScreen contains quadScreen with material (textureComp)
And they should be rendered like this:
render sceneContent, cameraPerspective onto textureNew
render sceneComp, cameraOrto onto textureComp
render sceneScreen, cameraOrto onto textureOld
render sceneScreen, cameraOrto onto screen
There is no need to set autoClear to false or preserveDrawingBuffer to true.
For a live example see: https://codepen.io/brunoimbrizi/pen/MoRJaN

Wrap a material around a cube in Three.js

I have been following this tutorial, creating a Cube with a texture.
The problem is, the texture repeats on every face of the cube.
I would like to use a single texture that 'wraps' around the cube. Is this possible?
// material
var material = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('http://www.html5canvastutorials.com/demos/assets/crate.jpg')
});
// this has no effect!
material.wrapAround = true;
// cube
var cube = new THREE.Mesh(new THREE.CubeGeometry(200, 200, 200), material);
cube.overdraw = true;
cube.rotation.x = Math.PI * 0.1;
scene.add(cube);
Typically, with a THREE.CubeGeometry, you can either:
(1) Choose a single texture that repeats on each side of the cube, or
(2) Have a different texture for each of the six sides
You can also use repeat the number of times a texture is displayed on each side.
For examples of each of these, check out the source code of the demos at:
http://stemkoski.github.io/Three.js/Textures.html
and
http://stemkoski.github.io/Three.js/Texture-Repeat.html
Hope this helps!

Categories