Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreeJS: Sphere & Line Animation

see update below

hope you can help me.

I created a mesh containing lines and spheres, now i want to animate all of them at once, so they have a smooth, pulsing, moveset.

With my attempt down here, one of the lines and spheres does what i want, the others doesn't move or are dislocated.

Any ideas?

//      _
//  ___| |__   __ _ _ __   ___  ___
// / __| '_ \ / _` | '_ \ / _ \/ __|
// \__ \ | | | (_| | |_) |  __/\__ \
// |___/_| |_|\__,_| .__/ \___||___/
//                 |_|

var numSpheres = 5;
var angRand = [numSpheres];
var spread = 10;
var radius = windowY/5;
var radiusControl = 20;
var xPos;
var yPos;

//sphere
var sphereGeometry = new THREE.SphereGeometry(0.35, 100, 100);


//line
var lineGeometry = new THREE.Geometry();
var lineMaterial = new THREE.LineBasicMaterial({
    color: 0xCCCCCC
});

//create dynamically
for (var i = 0; i < numSpheres; i++) {
    var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x334455});
    var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

    var line = new THREE.Line(lineGeometry, lineMaterial);

    angRand[i] = Math.floor((Math.random() * 360) + 1);//random angle for each sphere/line
    var radiusIncr = spread * (angRand[i]+200)/180;
    var xPos = Math.cos((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
    var yPos = Math.sin((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
    var offsetY = Math.floor((Math.random()*5)+1);

    sphere.position.x = xPos/radiusControl;
    sphere.position.y = yPos/radiusControl + offsetY; 

    lineGeometry.vertices.push(
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(sphere.position.x, sphere.position.y, 0)
    );

    scene.add(sphere);
    scene.add(line);
}


//              _                 _   _
//   __ _ _ __ (_)_ __ ___   __ _| |_(_) ___  _ __
//  / _` | '_ \| | '_ ` _ \ / _` | __| |/ _ \| '_ \
// | (_| | | | | | | | | | | (_| | |_| | (_) | | | |
//  \__,_|_| |_|_|_| |_| |_|\__,_|\__|_|\___/|_| |_|

function animations() {

    var time = Date.now() * 0.001;
    var speed = 0.25;
    var speed1 = 0.145;
    var behave = speed * Math.cos(time);
    var behave1 = speed1 * Math.cos(time * 1.25);
    var behave2 = 10 + speed1 * Math.cos(time);
    var behave3 = 10 + speed * Math.cos(time * 0.5);

    for(var i = 0;i < scene.children.length;i++){
        sphere.position.x = xPos/radiusControl + behave;
        sphere.position.y = yPos/radiusControl + behave1;
        line.geometry.vertices[1].x = xPos/radiusControl + behave;
        line.geometry.vertices[1].y = yPos/radiusControl + behave1;
    }

Update: Now i push the Data of the Spheres into Arrays and all the spheres move as they are supposed to. But now to the lines: Here i also created an array wich is nested(because the lines got 2 vectors). In the loopmi try to grab one line after another and grab the second vector to set that point at the coordinates of the sphere. But like before, the whole thing only works for one line. Please give me some advice I am drowning in code here ;D

//      _
//  ___| |__   __ _ _ __   ___  ___
// / __| '_ \ / _` | '_ \ / _ \/ __|
// \__ \ | | | (_| | |_) |  __/\__ \
// |___/_| |_|\__,_| .__/ \___||___/
//                 |_|
// for going live better recode as class/objects
var numSpheres = 3;
var angRand = [numSpheres];
var spread = 10;
var radius = windowY/5;
var radiusControl = 20;
var xPos;
var yPos;
var offsetY;
var selectSpheres = [];
var selectxPosSpheres = [];
var selectyPosSpheres = [];
var selectLines = [];

//create dynamically
for (var i = 0; i < numSpheres; i++) {

    //sphere
    var sphereGeometry = new THREE.SphereGeometry(0.35, 100, 100);

    var sphereMaterial = new THREE.MeshBasicMaterial({color: 0x334455});
    var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);


    //line
    var lineGeometry = new THREE.Geometry();
    var lineMaterial = new THREE.LineBasicMaterial({
    color: 0xCCCCCC
    });

    var line = new THREE.Line(lineGeometry, lineMaterial);

    angRand[i] = Math.floor((Math.random() * 360) + 1);//random angle for each sphere/line
    var radiusIncr = spread * (angRand[i]+200)/180;
    var xPos = Math.cos((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
    var yPos = Math.sin((360/numSpheres * (i) + angRand[i]/2 )) * (radius - radiusIncr);
    var offsetY = Math.floor((Math.random()*5)+1);

    sphere.position.x = xPos/radiusControl;
    sphere.position.y = yPos/radiusControl + offsetY; 

    lineGeometry.vertices.push(
        new THREE.Vector3(0, 0, 0),
        new THREE.Vector3(sphere.position.x, sphere.position.y, 0)
    );

    scene.add(sphere);
    scene.add(line);

    selectLines.push(lineGeometry); //fetch the lines (array= [line1][line2][line3])
    selectSpheres.push(sphere);
    selectxPosSpheres.push(xPos);
    selectyPosSpheres.push(yPos);
    console.log("shapes", selectLines);
}


//              _                 _   _
//   __ _ _ __ (_)_ __ ___   __ _| |_(_) ___  _ __
//  / _` | '_ \| | '_ ` _ \ / _` | __| |/ _ \| '_ \
// | (_| | | | | | | | | | | (_| | |_| | (_) | | | |
//  \__,_|_| |_|_|_| |_| |_|\__,_|\__|_|\___/|_| |_|

function animations() {
    var time = Date.now() * 0.001;
    var speed = 0.25;
    var behave = speed * Math.cos(time);

    for (var i = 0; i < selectSpheres.length; i++) {
        sphere = selectSpheres[i];
        sphere.position.x =  selectxPosSpheres[i]/radiusControl + behave;
        sphere.position.y = (selectyPosSpheres[i]/radiusControl + offsetY) + behave;

        line = selectLines[i]; //put the value "i" of the array into variable "line"
        console.log("animations", line); //lets see if all lines are grabbed by the loop
        line.vertices[1].x = sphere.position.x; //fetch the 2nd vector of line"i" and put it on the x coords of the sphere
        line.vertices[1].y = sphere.position.y; //fetch the 2nd vector of line"i" and put it on the y coords of the sphere
        //why is only one line grabbed by the loop although the console says it grabbs every one of them?!?!
    };
}
like image 502
Mar Cel Avatar asked May 14 '26 21:05

Mar Cel


1 Answers

Got it! I had to put the "update function" inside the loop.

//              _                 _   _
//   __ _ _ __ (_)_ __ ___   __ _| |_(_) ___  _ __
//  / _` | '_ \| | '_ ` _ \ / _` | __| |/ _ \| '_ \
// | (_| | | | | | | | | | | (_| | |_| | (_) | | | |
//  \__,_|_| |_|_|_| |_| |_|\__,_|\__|_|\___/|_| |_|

function animations() {
    var time = Date.now() * 0.001;
    var speed = 0.55;
    var behave = speed * Math.cos(time);

    for (var i = 0; i < selectSpheres.length; i++) {
        sphere = selectSpheres[i];
        sphere.position.x =  selectxPosSpheres[i]/radiusControl + behave;
        sphere.position.y = (selectyPosSpheres[i]/radiusControl + offsetY) + behave;

        line = selectLines[i]; //put the value "i" of the array into variable "line"
        console.log("animations", line); //lets see if all lines are grabbed by the loop
        line.vertices[1].x = sphere.position.x; //fetch the 2nd vector of line"i" and put it on the x coords of the sphere
        console.log("lineX", line.vertices[1].x)
        console.log("sphereX", sphere.position.x)
        line.vertices[1].y = sphere.position.y; //fetch the 2nd vector of line"i" and put it on the y coords of the sphere
        //why is only one line grabbed by the loop although the console says it grabbs every one of them?!?!
        line.verticesNeedUpdate = true;
        sphereGeometry.normalsNeedUpdate = true;
    };
}

By the way: ThreeJS is awefully bad documentated.

like image 164
Mar Cel Avatar answered May 17 '26 11:05

Mar Cel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!