Render a lot of spheres with different theta length with THREE.js - javascript

I am using
var geometry = new THREE.SphereGeometry( 15, 32, 16, 0, 2*Math.PI, 0, x);
with x < 2*PI to create a part of a sphere looking like that :
The thing is I need to have tens of thousands of those, all with the same center and radius but with different rotations and different and very small x values.
I have done research about instancing but can't find a way to use it the way I want to. Any suggestions ?

Use an additional InstancedBufferAttribute to pass phi angles per instance in InstancedMesh, and process those values in vertex shader to form the parts you want, using .onBeforeCompile() method.
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.136.0/build/three.module.js";
import {OrbitControls} from "https://cdn.skypack.dev/three#0.136.0/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 5000);
camera.position.set(0, 0, 50);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", (event) => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
let control = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(1);
scene.add(light, new THREE.AmbientLight(0xffffff, 0.5));
const MAX_COUNT = 10000;
let g = new THREE.SphereGeometry(1, 20, 10, 0, Math.PI * 2, Math.PI * 0.25, Math.PI * 0.5);
let m = new THREE.MeshLambertMaterial({
side: THREE.DoubleSide,
onBeforeCompile: shader => {
shader.vertexShader = `
attribute float instPhi;
// straight from the docs on Vector3.setFromSphericalCoords
vec3 setFromSphericalCoords( float radius, float phi, float theta ) {
float sinPhiRadius = sin( phi ) * radius;
float x = sinPhiRadius * sin( theta );
float y = cos( phi ) * radius;
float z = sinPhiRadius * cos( theta );
return vec3(x, y, z);
}
${shader.vertexShader}
`.replace(
`#include <beginnormal_vertex>`,
`#include <beginnormal_vertex>
vec3 sphPos = setFromSphericalCoords(1., instPhi * (1. - uv.y), PI * 2. * uv.x); // compute position
objectNormal = normalize(sphPos); // normal is just a normalized vector of the computed position
`).replace(
`#include <begin_vertex>`,
`#include <begin_vertex>
transformed = sphPos; // set computed position
`
);
//console.log(shader.vertexShader);
}
});
let im = new THREE.InstancedMesh(g, m, MAX_COUNT);
scene.add(im);
let v3 = new THREE.Vector3();
let c = new THREE.Color();
let instPhi = []; // data for Phi values
let objMats = new Array(MAX_COUNT).fill().map((o, omIdx) => {
let om = new THREE.Object3D();
om.position.random().subScalar(0.5).multiplyScalar(100);
om.rotation.setFromVector3(v3.random().multiplyScalar(Math.PI));
om.updateMatrix();
im.setMatrixAt(omIdx, om.matrix);
im.setColorAt(omIdx, c.set(Math.random() * 0xffffff))
instPhi.push((Math.random() * 0.4 + 0.1) * Math.PI);
return om;
});
g.setAttribute("instPhi", new THREE.InstancedBufferAttribute(new Float32Array(instPhi), 1));
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
</script>
PS May be turned into the using of InstancedBufferGeometry. Creativity is up to you :)

Related

How to get a random Vector3 within a sphere?

I am trying to create a random point within a sphere, and I am not sure how to do this. I came up with this but I think it is returning a point within a cube I think I have to do something with Math.PI but not sure how.
#createParticlePosition() {
const shape = this.options.shape;
// shape.radius = 2;
if (shape.type === 'sphere') {
return new Three.Vector3(
(Math.random() * shape.radius - (shape.radius / 2)) * 1.0,
(Math.random() * shape.radius - (shape.radius / 2)) * 1.0,
(Math.random() * shape.radius - (shape.radius / 2)) * 1.0
);
}
}
You are indeed just creating boxes. You're only calculating the x,y,z values linearly, not spherically. Three.js has a Vector3.randomDirection method that could do these calculations for you:
const maxRadius = 2;
// Randomize to range [0, 2]
const randomRadius = Math.random() * maxRadius;
// Create vec3
const randomVec = new THREE.Vector3();
// Make vector point in a random direction with a radius of 1
randomVec.randomDirection();
// Scale vector to match random radius
randomVec.multiplyScalar(randomRadius);
This method utilizes this approach internally to avoid density accumulation in the poles.
To distribute points inside a sphere evenly, having direction and radius, the radius computes with Math.sqrt( r * r * Math.random());
In the snippet, the red point cloud utilizes simple r * Math.random(), the aqua one utilizes that I wrote above:
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three#0.136.0/examples/jsm/controls/OrbitControls";
let scene = new THREE.Scene();
scene.background = new THREE.Color(0x160016);
let camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 8);
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
})
let controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = false;
let pts = new Array(1000).fill().map(p => {
let rMax = 2 * Math.random();
return new THREE.Vector3().randomDirection().multiplyScalar(rMax);
})
let g = new THREE.BufferGeometry().setFromPoints(pts);
let m = new THREE.PointsMaterial({size: 0.1, color: "red"})
let p = new THREE.Points(g, m);
p.position.x = -2;
scene.add(p)
let pts2 = new Array(1000).fill().map(p => {
let rMax = 2;
let r = Math.sqrt(rMax * rMax * Math.random());
return new THREE.Vector3().randomDirection().multiplyScalar(r);
})
let g2 = new THREE.BufferGeometry().setFromPoints(pts2);
let m2 = new THREE.PointsMaterial({size: 0.1, color: "aqua"})
let p2 = new THREE.Points(g2, m2);
p2.position.x = 2;
scene.add(p2)
renderer.setAnimationLoop(() => {
controls.update();
renderer.render(scene, camera);
});
</script>
For reference: https://discourse.threejs.org/t/random-points-on-surfaces/34153

How to project a texture/shape to specific part of a mesh in Three.js?

I’d like to project a texture or some shape ( transparent - ring, circle) to a mesh (but to a specific part). For example, in games we select/click an enemy or NPC then we see some circle under the character which indicates a selection. That circle changes its shape based on the mesh (height, slope), you can check the following images.
I’d like to do that, but I’m not sure how to do it, perfectly - so far I tried to raycast a mesh and got the vertices normal and applied the rotation but when it comes to more complex part of the mesh this does not work well enough. I think I need to use shaders? Is there any resource I can check?
Not as difficult as it seems.
Modify the ground material with .onBeforeCompile, passing position of the selected object in a uniform, and then process it in shaders.
In the code snippet, click a button to select the respective object, so the selection mark will follow it on the ground:
body{
overflow: hidden;
margin: 0;
}
#selections {
width: 100px;
display: flex;
flex-direction: column;
}
button.selected{
color: #00ff32;
background: blue;
}
<div id="selections" style="position: absolute;border: 1px solid yellow;"></div>
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.133";
import {
OrbitControls
} from "https://cdn.skypack.dev/three#0.133/examples/jsm/controls/OrbitControls.js";
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 5, 8);
camera.lookAt(scene.position);
let renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(innerWidth, innerHeight);
renderer.setClearColor(0x404040);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.DirectionalLight(0xffffff, 1);
light.position.setScalar(1);
scene.add(
light,
new THREE.AmbientLight(0xffffff, 0.5)
);
let objects = new Array(5).fill(0).map((p,idx)=>{return setObject(idx)});
//console.log(objects);
let selected = objects[0];
let g = new THREE.PlaneGeometry(10, 10, 5, 5);
g.rotateX(-Math.PI * 0.5);
for(let i = 0; i < g.attributes.position.count; i++){
g.attributes.position.setY(i, (Math.random() * 2 - 1) * 0.75);
}
g.computeVertexNormals();
let uniforms = {
selection: {value: new THREE.Vector3()}
}
let m = new THREE.MeshLambertMaterial({
color: 0x003264,
map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/water.jpg"),
onBeforeCompile: shader => {
shader.uniforms.selection = uniforms.selection;
shader.vertexShader = `
varying vec3 vPos;
${shader.vertexShader}
`.replace(
`#include <begin_vertex>`,
`#include <begin_vertex>
vPos = transformed;
`
);
shader.fragmentShader = `
#define ss(a, b, c) smoothstep(a, b, c)
uniform vec3 selection;
varying vec3 vPos;
${shader.fragmentShader}
`.replace(
`#include <dithering_fragment>`,
`#include <dithering_fragment>
// shape
float dist = distance(selection.xz, vPos.xz);
float r = 0.25;
float shape = (ss(r-0.1, r, dist)*0.75 + 0.25) - ss(r, r + 0.1, dist);
vec3 col = mix(gl_FragColor.rgb, vec3(0, 1, 0.25), shape);
gl_FragColor = vec4(col, gl_FragColor.a);
`
);
//console.log(shader.fragmentShader)
}
});
let o = new THREE.Mesh(g, m);
scene.add(o);
window.addEventListener("resize", onResize);
let clock = new THREE.Clock();
renderer.setAnimationLoop(_ => {
let t = clock.getElapsedTime() * 0.5;
objects.forEach(obj => {
let ud = obj.userData;
obj.position.x = Math.cos(t * ud.scaleX + ud.initPhase) * 4.75;
obj.position.y = 1;
obj.position.z = Math.sin(t * ud.scaleZ + ud.initPhase) * 4.75;
})
o.worldToLocal(uniforms.selection.value.copy(selected.position));
renderer.render(scene, camera);
})
function setObject(idx){
let g = new THREE.SphereGeometry(0.25);
let m = new THREE.MeshLambertMaterial({color: 0x7f7f7f * Math.random() + 0x7f7f7f});
let o = new THREE.Mesh(g, m);
o.userData = {
initPhase: Math.PI * 2 * Math.random(),
scaleX: Math.random() * 0.5 + 0.5,
scaleZ: Math.random() * 0.5 + 0.5
}
scene.add(o);
let btn = document.createElement("button");
btn.innerText = "Object " + idx;
selections.appendChild(btn);
btn.addEventListener("click", event => {
selections.querySelectorAll("button").forEach(b => {b.classList.remove("selected")});
btn.classList.add("selected");
selected = o
});
return o;
}
function onResize(event) {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
}
</script>

Three.js OrbitControls with azimuth close to +/-180 degrees

I have a situation where I use an OrbitControls to have a limited view in a room/space. The OrbitControls gets min/max values for azimuth and polar angles to control the view.
The OrbitControls' target is close by the camera to achieve the correct view, compare to the "panorama / cube" example (https://threejs.org/examples/?q=cube#webgl_panorama_cube).
In one situation this works fine. In an other situation this does not work. The reason is that because of the placement of objects, the starting azimuth is -179.999 degrees.
I have not found a way to tell the orbitcontrol to have the azimuth between -179.999 +/- 20 degrees.
I have experimented a little with the algorithm of #Αλέκος (Is angle in between two angles) and it looks like I can calculate the correct angles (not fully implemented). For that I would have set an azimuth and a delta in stead of min/max (and change the OrbitControls code).
Any suggestions for an easier solution? Thanks!
Test code:
var scene = new THREE.Scene();
var orbitControls;
var camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var material = new THREE.MeshBasicMaterial({
color: 0xffffff,
vertexColors: THREE.FaceColors
});
var geometry = new THREE.BoxGeometry(1, 1, 1);
// colors
red = new THREE.Color(1, 0, 0);
green = new THREE.Color(0, 1, 0);
blue = new THREE.Color(0, 0, 1);
var colors = [red, green, blue];
console.log("FACES", geometry.faces.length)
for (var i = 0; i < 3; i++) {
geometry.faces[4 * i].color = colors[i];
geometry.faces[4 * i + 1].color = colors[i];
geometry.faces[4 * i + 2].color = colors[i];
geometry.faces[4 * i + 3].color = colors[i];
}
geometry.faces[0].color = new THREE.Color(1, 1, 1);
geometry.faces[4].color = new THREE.Color(1, 1, 1);
geometry.faces[8].color = new THREE.Color(1, 1, 1);
var cube = new THREE.Mesh(geometry, material);
cube.position.x = 0;
cube.position.y = 4;
cube.position.z = 44;
console.log("CUBE", cube.position);
var cubeAxis = new THREE.AxesHelper(20);
cube.add(cubeAxis);
scene.add(cube);
camera.position.x = 0.8;
camera.position.y = 4.5;
camera.position.z = 33;
orbitControls = new THREE.OrbitControls(camera, renderer.domElement);
orbitControls.enablePan = false;
orbitControls.enableZoom = false;
orbitControls.minPolarAngle = (90 - 10) * Math.PI / 180;
orbitControls.maxPolarAngle = (90 + 10) * Math.PI / 180;
// These values do not work:
orbitControls.maxAzimuthAngle = 200 * Math.PI / 180;
orbitControls.minAzimuthAngle = 160 * Math.PI / 180;
orbitControls.target.x = 0.8;
orbitControls.target.y = 4.5;
orbitControls.target.z = 33.1;
orbitControls.enabled = true;
var animate = function () {
requestAnimationFrame(animate);
if (orbitControls) {
orbitControls.update();
}
renderer.render(scene, camera);
// console.log("orbitControls", "azi", orbitControls.getAzimuthalAngle() * 180 / Math.PI);
};
animate();

Draw Point GeoJSON in Three.js and D3.js

I want to overlay points from a GeoJSON file onto the surface of my Mars basemap using D3.js, similar to what Mike Bostock has done with a MultiLineString, as well as match the rotation angle and speed:
https://bl.ocks.org/mbostock/2b85250396c17a79155302f91ec21224
I am completely new to Three.js, but have been learning D3.js, so I am not sure how to mix the two together. Any help would be much appreciated.
var renderer, scene, camera;
var control;
var stats;
var cameraControl;
var radius = 15;
// Initialize the scene, camera and objects.
function init() {
// To display anything, you need 3 things: (1) Scene, (2) Camera, (3) Renderer
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x000000, 1.0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
// Mars needs (1) geometry, (2) material, (3) mesh
var sphereGeometry = new THREE.SphereGeometry(15, 60, 60);
var sphereMaterial = createMarsMaterial();
var marsMesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
marsMesh.name = 'mars';
scene.add(marsMesh);
// position and point the camera to the center of the scene
camera.position.x = 25;
camera.position.y = 26;
camera.position.z = 23;
camera.lookAt(scene.position);
// add controls
cameraControl = new THREE.OrbitControls(camera);
// setup the control object for the control gui
control = new function () {
this.rotationSpeed = 0.001;
};
// add extras
addControlGui(control);
addStatsObject();
// add the output of the renderer to the html element
document.body.appendChild(renderer.domElement);
// start animating
render();
}
function createMarsMaterial() {
// 4096 is the maximum width for maps
var marsTexture = THREE.ImageUtils;
marsTexture.crossOrigin = "";
marsTexture = THREE.ImageUtils.loadTexture("https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/mars.jpg");
var marsMaterial = new THREE.MeshBasicMaterial();
marsMaterial.map = marsTexture;
return marsMaterial;
}
function addControlGui(controlObject) {
var gui = new dat.GUI();
gui.add(controlObject, 'rotationSpeed', -0.01, 0.01);
}
function addStatsObject() {
stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild(stats.domElement);
}
function render() {
stats.update();
cameraControl.update();
scene.getObjectByName('mars').rotation.y += control.rotationSpeed;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function handleResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.onload = init;
window.addEventListener('resize', handleResize, false);
d3.json("https://tatornator12.github.io/classes/final-project/Mars_LandingSites.json", function(error, topology) {
if (error) throw error;
scene.add(graticule = wireframe(graticule10(), new THREE.LineBasicMaterial({color: 0xaaaaaa})));
scene.add(mesh = wireframe(topojson.mesh(topology, topology.features), new THREE.LineBasicMaterial({color: 0xff0000})));
d3.timer(function(t) {
graticule.rotation.x = mesh.rotation.x = Math.sin(t / 11000) * Math.PI / 3 - Math.PI / 2;
graticule.rotation.z = mesh.rotation.z = t / 10000;
renderer.render(scene, camera);
});
});
// Converts a point [longitude, latitude] in degrees to a THREE.Vector3.
function vertex(point) {
var lambda = point[0] * Math.PI / 180,
phi = point[1] * Math.PI / 180,
cosPhi = Math.cos(phi);
return new THREE.Vector3(
radius * cosPhi * Math.cos(lambda),
radius * cosPhi * Math.sin(lambda),
radius * Math.sin(phi)
);
}
// Converts a GeoJSON MultiLineString in spherical coordinates to a THREE.LineSegments.
function wireframe(multilinestring, material) {
var geometry = new THREE.Geometry;
multilinestring.coordinates.forEach(function(line) {
d3.pairs(line.map(vertex), function(a, b) {
geometry.vertices.push(a, b);
});
});
return new THREE.LineSegments(geometry, material);
}
// See https://github.com/d3/d3-geo/issues/95
function graticule10() {
var epsilon = 1e-6,
x1 = 180, x0 = -x1, y1 = 80, y0 = -y1, dx = 10, dy = 10,
X1 = 180, X0 = -X1, Y1 = 90, Y0 = -Y1, DX = 90, DY = 360,
x = graticuleX(y0, y1, 2.5), y = graticuleY(x0, x1, 2.5),
X = graticuleX(Y0, Y1, 2.5), Y = graticuleY(X0, X1, 2.5);
function graticuleX(y0, y1, dy) {
var y = d3.range(y0, y1 - epsilon, dy).concat(y1);
return function(x) { return y.map(function(y) { return [x, y]; }); };
}
function graticuleY(x0, x1, dx) {
var x = d3.range(x0, x1 - epsilon, dx).concat(x1);
return function(y) { return x.map(function(x) { return [x, y]; }); };
}
return {
type: "MultiPoint",
coordinates: d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X)
.concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y))
.concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return Math.abs(x % DX) > epsilon; }).map(x))
.concat(d3.range(Math.ceil(y0 / dy) * dy, y1 + epsilon, dy).filter(function(y) { return Math.abs(y % DY) > epsilon; }).map(y))
};
}
body {
/* set margin to 0 and overflow to hidden, to go fullscreen */
margin: 0;
overflow: hidden;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/three.js"></script>
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/OrbitControls.js"></script>
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/dat.gui.min.js"></script>
<script src="https://tatornator12.github.io/classes/final-project/Using_Three_-_D3/stats.min.js"></script>

Three js Object 3D rotation

Hy!
I'm facing a strange problem in THREE JS(r71) / THREEx (THREEx.LaserBeam). I'm having problems with rotation of Object 3D.
I'm calculating latitude, attitude points into phi,theta like this:
(Or any other variables for 50/-51)
var phi = (90 - 50) * Math.PI / 180;
var theta = (-51) * Math.PI / 180;
After this I drop a sphere on the location with the following Code:
var geometry = new THREE.SphereGeometry( 0.005, 15, 15 );
var material = new THREE.MeshBasicMaterial( {color: 0x0000ff} );
var sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
sphere.position.x = 0.5 * Math.sin(phi) * Math.cos(theta);
sphere.position.y = 0.5 * Math.cos(phi);
sphere.position.z = 0.5 * Math.sin(phi) * Math.sin(theta);
Then I rotate my ray to the same position with the following code:
laserBeam.rotation.y = -theta
laserBeam.rotation.z = phi
The laserBeam is actually acts as "line", in an Object3D. The Origin of the ray is at (0,0). So I haven't got a faintest idea why it is not going trough the sphere (See screenshot).
Any ideas?
---EDIT---
or here is the example with a simple line
var phi = (90 - 50) * Math.PI / 180;
var theta = (-51) * Math.PI / 180;
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, 0, 0));
geometry.vertices.push(new THREE.Vector3(1 * Math.sin(phi) * Math.cos(theta), 1* Math.cos(phi), 1 * Math.sin(phi) * Math.sin(theta)));
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var line = new THREE.Line(geometry, material);
containerLine = new THREE.Object3D();
containerLine.add( line );
scene.add(containerLine);
You incorrectly calculates a small radius and y-coordinates:
var rm = R * Math.cos(phi); // vs `R * Math.sin(phi)`
sphere.position.x = rm * Math.cos(theta);
sphere.position.y = R * Math.sin(phi); // vs `R * Math.cos(phi)`
sphere.position.z = rm * Math.sin(theta);
http://jsfiddle.net/sxen2kLd/
Ah finaly.... Dunno how and why I'm too tired to undestand now, but posting it
function latLongToVector3(lat, lon, radius, heigth) {
var phi = (lat)*Math.PI/180;
var theta = (lon-180)*Math.PI/180;
var x = -(radius+heigth) * Math.cos(phi) * Math.cos(theta);
var y = (radius+heigth) * Math.sin(phi);
var z = (radius+heigth) * Math.cos(phi) * Math.sin(theta);
return new THREE.Vector3(x,y,z);
}
var helper = latLongToVector3(51.227821,51.3865431,0.5,0);
var geometry = new THREE.SphereGeometry( 0.005, 15, 15 );
var material = new THREE.MeshBasicMaterial( {color: 0x0000ff} );
var sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
sphere.position.x = helper.x
sphere.position.y = helper.y
sphere.position.z = helper.z
----------------------------------------------------
var helper = latLongToVector3(51.227821,51.3865431,0.5,0);
function rotateAroundWorldAxis(object, axis, radians) {
rotWorldMatrix = new THREE.Matrix4();
rotWorldMatrix.makeRotationAxis(axis.normalize(), radians);
rotWorldMatrix.multiply(object.matrix);
object.matrix = rotWorldMatrix;
//object.rotation.setEulerFromRotationMatrix(object.matrix);
object.rotation.setFromRotationMatrix(object.matrix);
}
laserBeam.useQuaternion = true;
var origVec = new THREE.Vector3(1, 0, 0);
var targetVec = helper;
targetVec.normalize();
var rotateQuaternion = new THREE.Quaternion();
var axis = new THREE.Vector3(0, 0, 0);
var angle = Math.acos(origVec.dot(targetVec));
axis.cross(origVec, targetVec);
axis.normalize();
rotateAroundWorldAxis(laserBeam,axis,angle);

Categories

Resources