Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BoxGeometry not aligning with SphereGeometry properly

I am trying to create spikes on earth(sphere geometry). Though everything works fines, but spikes dont align with globe. I want spike to align something like below image. But my spikes dont lookAt(new THREE.Vector3(0,0,0)) despite mentioned. Please help me out.

I purposefully mentioned code required for debugging. Let me know if you need more code for this. Below image is how i want my spikes to align with sphere.

enter image description here

But this is how it looks

enter image description here

My Main JS initialization file.

$(document).ready(function () {

  // Initializing Camera
  Influx.Camera = new Influx.Camera({
    fov: 60,
    aspectRatio: window.innerWidth / window.innerHeight,
    near: 1,
    far: 1000,
    position: {
      x: 0,
      y: 0,
      z: 750
    }
  });

  //Initializing Scene
  Influx.Scene = new Influx.Scene();

  // Initializing renderer
  Influx.Renderer = new Influx.Renderer({
    clearColor: 0x000000,
    size: {
      width: window.innerWidth,
      height: window.innerHeight
    }
  });

  Influx.Globe  = new Influx.Globe({
    radius: 300,
    width:  50,
    height: 50
  });

  //
  Influx.Stars  = new Influx.Stars({
    particleCount: 15000,
    particle: {
      color: 0xFFFFFF,
      size: 1
    }
  });

  Influx.moveTracker = new Influx.moveTracker();

  Influx.EventListener  = new Influx.EventListener();

  (function animate() {
    requestAnimationFrame( animate );
    render();
    controls.update();
  })();

  function render() {
    camera.lookAt(scene.position);
    group.rotation.y -= 0.001;
    renderer.render( scene, camera );
  };

});

Below is code responsible for generating spikes on Globe.

Influx.Spikes = function (lat, long) {

  // convert the positions from a lat, lon to a position on a sphere.
  var latLongToVector3 = function(lat, lon, RADIUS, heigth) {
    var phi   = (lat) * Math.PI/180,
        theta = (lon-180) * Math.PI/180;

    var x = -(RADIUS+heigth) * Math.cos(phi) * Math.cos(theta),
        y =  (RADIUS+heigth) * Math.sin(phi),
        z =  (RADIUS+heigth) * Math.cos(phi) * Math.sin(theta);

    return new THREE.Vector3(x, y, z);
  };

  var geom        = new THREE.Geometry();
  var BoxGeometry = new THREE.BoxGeometry(1, 100, 1);

  //iterates through the data points and makes boxes with the coordinates
  var position = latLongToVector3(lat, long, 300, 2);

  var box = new THREE.Mesh( BoxGeometry );

  //each position axis needs to be set separately, otherwise the box
  //will instantiate at (0,0,0)
  box.position.x = position.x;
  box.position.y = position.y;
  box.position.z = position.z;

  box.lookAt(new THREE.Vector3(0, 0, 0));
  box.updateMatrix();

  //merges the geometry to speed up rendering time, don't use THREE.GeometryUtils.merge because it's deprecated
  geom.merge(box.geometry, box.matrix);

  var total = new THREE.Mesh(geom, new THREE.MeshBasicMaterial({
    color: getRandomColor(),
    morphTargets: true
  }));

  function getRandomColor() {
    var letters = '0123456789ABCDEF';
    var color = '#';
    for (var i = 0; i < 6; i++ ) {
      color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
  };

  //add boxes to the group
  group.add(total);
  scene.add(group);
};

Influx.Camera = function(params = {}) {

  if ( !$.isEmptyObject(params) ) {
    window.camera = new THREE.PerspectiveCamera(params.fov, params.aspectRatio, params.near, params.far);
    camera.position.set(params.position.x, params.position.y, params.position.z);
    camera.lookAt(new THREE.Vector3(0,0,0));
  } else {
    console.log("Trouble with Initializing Camera");
    return;
  }

};
like image 725
Rahul Dess Avatar asked Aug 15 '16 22:08

Rahul Dess


1 Answers

Remember that lookAt takes a direction vector, you give to this method the vector (0, 0, 0), this is actually not a normalized direction vector. So you must calculate the direction:

from your box position to the center of the sphere AND normalize it.

var dir = box.position.sub(world.position).normalize();
box.lookAt(dir);

And now just a set of code good conventions that may help you:

var BoxGeometry = new THREE.BoxGeometry(1, 100, 1);

Here I would rather use another var name for the box geometry, not to mix up with the "class" definition from THREE and to follow naming conventions:

var boxGeometry = new THREE.BoxGeometry(1, 100, 1);

And here:

box.position.x = position.x;
box.position.y = position.y;
box.position.z = position.z;

You can just set:

box.position.copy(position);
like image 163
juagicre Avatar answered Nov 06 '22 06:11

juagicre