Reputation: 127
At this moment I have this working. I tryed many things. I tryed to get vertices positions from a geometry like in this example, but geometry.computeCentroids();
doesn't work in new three.js and now im having trouble with getting my sprites to vertices positions of a random geometry.
How can I make sprites morph into a other geometry? I want to know how to make sprites move to vertices positions of other geometry, lika a cone or OBJ model. Thanks in advance for all the help!
var camera, scene, renderer,controls;
var particlesTotal = 512,
positions = [],
objects = [],
current = 0;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 5000 );
camera.position.set( 600, 400, 1500 );
camera.lookAt( new THREE.Vector3() );
scene = new THREE.Scene();
var material=new THREE.SpriteMaterial({
//map:THREE.ImageUtils.loadTexture('http://threejs.org/examples/textures/sprite.png'),
color:0xffffff
});
for ( var i = 0; i < particlesTotal; i ++ ) {
var object = new THREE.Sprite(material);
// object.scale.x = 0.1;
// object.scale.y = 0.1;
object.position.x = Math.random() * 4000 - 2000,
object.position.y = Math.random() * 4000 - 2000,
object.position.z = Math.random() * 4000 - 2000
scene.add( object );
objects.push( object );
}
transition();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.rotateSpeed = 0.5;
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function transition() {
// Plane
var amountX = 16;
var amountZ = 32;
var separation = 150;
var offsetX = ( ( amountX - 1 ) * separation ) / 2;
var offsetZ = ( ( amountZ - 1 ) * separation ) / 2;
for ( var i = 0; i < particlesTotal; i ++ ) {
var x = ( i % amountX ) * separation;
var z = Math.floor( i / amountX ) * separation;
var y = ( Math.sin( x * 0.5 ) + Math.sin( z * 0.5 ) ) * 200;
positions.push( x - offsetX, y, z - offsetZ );
}
// Cube
var amount = 8;
var separation = 150;
var offset = ( ( amount - 1 ) * separation ) / 2;
for ( var i = 0; i < particlesTotal; i ++ ) {
var x = ( i % amount ) * separation;
var y = Math.floor( ( i / amount ) % amount ) * separation;
var z = Math.floor( i / ( amount * amount ) ) * separation;
positions.push( x - offset, y - offset, z - offset );
}
// Random
for ( var i = 0; i < particlesTotal; i ++ ) {
positions.push(
Math.random() * 4000 - 2000,
Math.random() * 4000 - 2000,
Math.random() * 4000 - 2000
);
}
// Sphere
var radius = 750;
for ( var i = 0; i < particlesTotal; i ++ ) {
var phi = Math.acos( -1 + ( 2 * i ) / particlesTotal );
var theta = Math.sqrt( particlesTotal * Math.PI ) * phi;
positions.push(
radius * Math.cos( theta ) * Math.sin( phi ),
radius * Math.sin( theta ) * Math.sin( phi ),
radius * Math.cos( phi )
);
}
var offset = current * particlesTotal * 3;
var duration = 2000;
for ( var i = 0, j = offset; i < particlesTotal; i ++, j += 3 ) {
var object = objects[ i ];
new TWEEN.Tween( object.position )
.to( {
x: positions[ j ],
y: positions[ j + 1 ],
z: positions[ j + 2 ]
}, Math.random() * duration + duration )
.easing( TWEEN.Easing.Exponential.InOut )
.start();
}
new TWEEN.Tween( this )
.to( {}, duration * 3 )
.onComplete( transition )
.start();
current = ( current + 1 ) % 4;
}
function animate() {
requestAnimationFrame( animate );
TWEEN.update();
controls.update();
var time = performance.now();
for ( var i = 0, l = objects.length; i < l; i ++ ) {
var object = objects[ i ];
var scale = Math.sin( ( Math.floor( object.position.x ) + time ) * 0.002 ) * 0.3 + 1;
scale*=100;
object.scale.set( scale, scale, scale );
}
renderer.render( scene, camera );
renderer.autoClear = false;
}
Upvotes: 0
Views: 1591
Reputation: 4234
Your question is not not hard but needs some maths homework. Here is the idea, writing the corresponding code should not be hard then ... :
In the example, for N particles, N positions are added to a position
array. That is why 'special' formulas are written (instead SphereGeometry
or BoxGeometry
) because each time the particles move to an other shape, their positions are tweened to their i+N new value in the array, and it's not regular to create a geometry by asking it to have N vertices.
If you want to use a custom geometry, or an existing geometry class instead of finding other formulas yourself, the solution is to :
geometry.vertices
array (let's call its length 'L')and apply some maths : basically, only copy the position met each L/N vertices.
for(var i=0;i<L;i+=L/N)position.push(geometry.vertices[i].clone());
However most of the time L/N will not result in an integer : it will have a remainder. So you need more maths. Let's use an example.
You have 50 particles so you need to push 50 new values in the position
array, to design your new shape.
If this shape has 111 vertices you cannot copy each position, there are more than 50. You can easily imagine to copy only each 111 / 50 = 2.22 (so each 2) vertices. Problem, the remainder is 11 : when you arrive at 2 * 50 = 100, your shape will have a hole of 11 / 2 ~= 5 vertices, in this case it is 10% of the copied shape. So sometimes you have to copy not each 2 but each 3 vertices to get an average offset and a correct spread of your sprites over your shape. How many times ? 11 / 3 = 3.6666.. ~= 3 times. Those times also have to be spread in the loop not to occur one after the other : 50 / 3 ~= 17. The first time has to be at the 17/2 = 8 or 9 (you decide) action, to delete the general shift. We are done.
Conclusion, you have to write a loop that checks all vertices. It pushes the value in the position
array every 2 vertices, until the 8th loop (so at the 16th position) where after the copy it jumps to the 16 + 3 = 19th position. It starts again every 2 values....
until the 19 + 17 * 2 = 53rd position where it jumps at the 56th....
same at the 56 + 17 * 2 = 90th position where it jumps at the 93rd....
That is it :)
Upvotes: 1