three.js change object distance dynamically - three.js

I'm using three.js for graphical website.
It's concept is universe that has many text.
If I click the text, Regardless of it's distance, object have to move to fixed position(or camera's front)
So I wrote the code like this.
[index.html]
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://gitcdn.xyz/repo/thesmart/jquery-scrollspy/0.1.3/scrollspy.js"></script>
<script src="./src/WOW.js"></script>
<script src="./src/three.js"></script>
<script src="//cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/ColladaLoader.js"></script>
<script src="https://unpkg.com/three.texttexture"></script>
<script src="https://unpkg.com/three.textsprite"></script>
<script src="./src/DeviceOrientationControls.js"></script>
<script src="./src/hammer.js"></script>
<script src="./src/Detector.js"></script>
<script src="./src/perlin.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" href="animate.css">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
<meta charset="UTF-8">
</head>
<body>
<header>
<div class="header-left">
MAIN
</div>
<div class="header-right">
MISSION
PRODUCT
CULTURE
STORY
</div>
</header>
<main>
<!-- Universe -->
<section id="universe" class="wow" data-wow-duration="0.5s"></section>
<!-- Main -->
<section class="main" id="main">
</section>
<script src="./src/src.js"></script>
</main>
</body>
</html>
[src.js]
// VARIABLES
let clock, camera, scene, renderer, mixer;
const sleep = ms => new Promise(res => setTimeout(res, ms));
var myElement = document.getElementById("threejs");
const mouse = new THREE.Vector2();
const clicked = new THREE.Vector2();
const target = new THREE.Vector2();
const windowHalf = new THREE.Vector2( window.innerWidth / 2, window.innerHeight / 2 );
const moveState = {forward: 0, back: 0};
var isMobile = false;
var textCount = 500;
var firstTime = true;
var fontFamily = '"Courier New", Courier, monospace';
var lock = true;
var group = new THREE.Group();
const scrollPosition = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop;
checkMobile()
// WOW.js
var wow = new WOW();
wow.init();
init();
async function init() {
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
scene = new THREE.Scene();
// CAMERA
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2100 );
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 1200;
camera.lookAt(scene.position);
clock = new THREE.Clock();
// HELPER
const gridHelper = new THREE.PolarGridHelper( 8, 16 );
scene.add( gridHelper );
// LIGHT
const ambientLight = new THREE.AmbientLight( 0xffffff, 0.2 );
scene.add( ambientLight );
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
directionalLight.position.set( 1, 1, - 1 );
scene.add( directionalLight );
// CONTROLS
if(isMobile) { // 모바일이면
var controls = new THREE.DeviceOrientationControls(camera);
console.log('isMobile true');
} else {
console.log('isMobile false');
}
// SATISFY THE DESIRES OF LOVE
let sprite = new THREE.TextSprite({
textSize: 5,
redrawInterval: 250,
texture: {
text: 'MAIN TEST',
fontFamily: fontFamily,
},
material: {
color: 'white',
},
});
sprite.position.x = 0;
sprite.position.y = 0;
sprite.position.z = 10;
scene.add(sprite);
// ADD MESH
var size = ( isMobile ? 2 : 2 );
var starsLights = new THREE.Group();
var starGeometry = new THREE.SphereGeometry(0.3, 16, 16);
var emptyGeometry = new THREE.Geometry();
for ( let i = 0; i < textCount; i ++ ) {
var lod = new THREE.LOD();
// Text
let sprite = new THREE.TextSprite({
textSize: size,
redrawInterval: 250,
texture: {
text: 'For Test',
fontFamily: fontFamily,
},
material: {
color: 'white',
transparent: true,
},
});
// Star
var starMaterial = new THREE.MeshBasicMaterial({color: 0xffffff, transparent: true});
var star = new THREE.Mesh(starGeometry, starMaterial);
// Dummy
var dummy = new THREE.Mesh(emptyGeometry, new THREE.MeshBasicMaterial());
// Add
lod.addLevel(sprite, 1);
lod.addLevel(star, 100, 240);
lod.addLevel(dummy, 200, 300);
lod.position.x = (Math.random() * 180-100);
lod.position.y = Math.random() * 180-100;
lod.position.z = Math.random() * 1000-40;
group.add(lod);
}
scene.add(group);
// Renderer
renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById("universe").appendChild(renderer.domElement);
// Event handler
window.addEventListener('load', refreshCheck, false);
window.addEventListener('resize', onWindowResize, false);
document.addEventListener('mousemove', onMouseMove, false);
document.addEventListener('mousewheel', onMouseWheel, false);
document.addEventListener('contextmenu', onContextMenu, false);
document.addEventListener('mouseup', onMouseClick, false);
function animate() {
target.x = ( 1 - mouse.x ) * 0.002;
target.y = ( 1 - mouse.y ) * 0.002;
camera.rotation.x += 0.05 * ( target.y - camera.rotation.x );
camera.rotation.y += 0.05 * ( target.x - camera.rotation.y );
if(isMobile) {
controls.update();
}
// Object change related to distance
group.children.forEach(function(child) {
child.update(camera);
})
// Render
requestAnimationFrame( animate );
render(scene, camera);
}
animate();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onMouseWheel(event) {
event.preventDefault();
camera.position.z -= event.deltaY * 0.2;
}
function render() {
const delta = clock.getDelta();
if ( mixer !== undefined ) mixer.update( delta );
renderer.render( scene, camera );
}
function onTransitionEnd( event ) {
console.log("Loading Complete");
event.target.remove();
}
// Exist functions
function checkMobile() {
var UserAgent = navigator.userAgent;
if (UserAgent.match(/iPhone|iPod|Android|Windows CE|BlackBerry|Symbian|Windows Phone|webOS|Opera Mini|Opera Mobi|POLARIS|IEMobile|lgtelecom|nokia|SonyEricsson/i) != null || UserAgent.match(/LG|SAMSUNG|Samsung/) != null) {
isMobile = true;
} else {
isMobile = false;
}
}
var raycaster = new THREE.Raycaster();
var mouseVector = new THREE.Vector3();
function getIntersects( x, y ) {
x = ( x / window.innerWidth ) * 2 - 1;
y = - ( y / window.innerHeight ) * 2 + 1;
mouseVector.set( x, y, 0.5 );
raycaster.setFromCamera( mouseVector, camera );
return raycaster.intersectObject( group, true );
}
var selectedObject = null;
var intersects;
function onMouseMove(event) {
event.preventDefault();
mouse.x = ( (event.clientX/2) - (windowHalf.x/2) );
mouse.y = ( (event.clientY/2) - (windowHalf.y/2) );
clicked.x = ( event.clientX / window.innerWidth ) * 2 - 1;
clicked.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
// Select object
if ( selectedObject ) {
selectedObject.material.color.set( '#ffffff' );
selectedObject = null;
}
intersects = getIntersects( event.layerX, event.layerY );
if ( intersects.length > 0 ) {
var res = intersects.filter( function ( res ) {
return res && res.object;
} )[ 0 ];
if ( res && res.object ) {
selectedObject = res.object;
selectedObject.material.color.set( '#f00' );
}
}
}
function onMouseClick() {
if(intersects[0]) {
console.log(intersects[0].point);
intersects[0].object.position.z += intersects[0].distance-70;
intersects[0].object.position.x = 0;
intersects[0].object.position.y = 0;
}
}
function onResize(event) {
const width = window.innerWidth;
const height = window.innerHeight;
windowHalf.set( width / 2, height / 2 );
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize( width, height );
}
function onContextMenu(event) { // Mouse right click
event.preventDefault();
}
function refreshCheck() {
if(window.performance) {
if(performance.navigation.type === 1) {
setTimeout(() => {
document.body.scrollTop = 0; // Other Browser
document.documentElement.scrollTop = 0; // IE
}, 0);
}
}
}
In the onMouseWheel() function, I detect current cursor point to object or not.
So, object's information will be stored in var intersects.
Also add onMouseClick(). And inside that function, I change object's position like this.
if(intersects[0]) {
console.log(intersects[0].point);
intersects[0].object.position.z += intersects[0].distance-70;
intersects[0].object.position.x = 0;
intersects[0].object.position.y = 0;
}
So if you click the object, object's x,y,z coordinate will be changed to, 0, 0, distance-70.
But it doesn't apply to the scene.
Refer to this site https://50-jahre-hitparade.ch/
If you click the text, text will be move to front of camera.
My goal is made it like above site.
(like this)
Why it doesn't work in my code?
Any solution here?
Thanks.
(Maybe I have to update into animate()?)
Source : https://github.com/teamhide/raycast
Launch : https://teamhide.github.io/raycast/

Instead of
if(intersects[0]) {
intersects[0].point.z = 100;
intersects[0].point.x = 100;
intersects[0].point.y = 100;
}
Try changing the position of the intersects[0].object.position like this,
if(intersects[0]) {
intersects[0].object.position.z = 100;
intersects[0].object.position.x = 100;
intersects[0].object.position.y = 100;
}

Related

Using THREE.Raycaster - I get always the id 8?

I would like to create a dashboard on which a certain number of "THREE.Meshes" appear. When I click on one of them with the mouse, I want to call a function that recognizes what I clicked on.
My problem:
I always get the ID:8 back from the "callFromTitleWithId" function. It doesn´t matter which one I selected with the mouseclick.
Maybe someone can help, I could not find the error :(
Here is the complete Example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TEST</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style>
body { margin: 0;
background: black; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<!-- Bibs -->
<script src="../extlib/webthree/build/three.js"></script>
<script>
document.addEventListener('mousedown', onDocumentMouseDown, false);
var arrayTiles = [];
//[SCREEN]
var SCREEN_WIDTH = window.innerWidth - 5;
var SCREEN_HEIGHT = window.innerHeight - 5;
screenOrientationValue=0;
//RayCaster für Objekte
var raycaster2 = new THREE.Raycaster(new THREE.Vector3(0,0,35),new THREE.Vector3(0,0,1));
var mouse2 = new THREE.Vector2();
var renderer = new THREE.WebGLRenderer();
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
document.body.appendChild( renderer.domElement );
var sceneWorld = new THREE.Scene();
sceneWorld.add( new THREE.AxesHelper(50) );
createTiles(sceneWorld);
var camera= new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(0,0,35);
var light2 = new THREE.AmbientLight( 0x20202A, 20, 100 );
light2.position.set( 30, -10, 30 );
sceneWorld.add( light2 );
var animate = function () {
requestAnimationFrame( animate );
renderer.render( sceneWorld, camera);
sceneUpdate();
};
animate();
function sceneUpdate()
{
//Update
}
function callFromTitleWithId(titleId)
{
console.log("ID:"+titleId);
}
function onDocumentMouseDown(event)
{
event.preventDefault();
mouse2.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1;
mouse2.y = - (event.clientY / renderer.domElement.clientHeight) * 2 + 1;
raycaster2.setFromCamera(mouse2, camera);
var intersects2 = raycaster2.intersectObjects(arrayTiles,true);
if (intersects2.length > 0) {
console.log('Maus: X:'+mouse2.x+' Y:'+mouse2.y);
console.log("intersects:" + intersects2[0].object);
console.log("distance:" + intersects2[0].distance);
console.log("face:" + intersects2[0].face);
console.log("faceIndex:" + intersects2[0].faceIndex);
console.log("faceIndex y:" + intersects2[0].point.y);
console.log("faceIndex x:" + intersects2[0].point.x);
intersects2[0].object.callback();
}
}
function createTiles(sceneWorld)
{
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
var materialSide = new THREE.MeshBasicMaterial( {color: 0xffff00} );
var materialsTiles = [materialSide, // Left side
materialSide, // Right side
materialSide, // Top side ---> THIS IS THE FRONT
materialSide, // Bottom side --> THIS IS THE BACK
material, // Front side
materialSide // Back side
];
var maxTileSizeWidth=11;
var maxTileSizeHeight=8;
var distanceBetween=2;
var distanceBorderLeft=-1;
var countInColumns=2;
var countInRow = 4;
var startCoordinatesX = ((((countInColumns * maxTileSizeWidth)+(countInColumns-6.5)*distanceBetween)/2))*-1;
var startCoordinatesY = 20;
var actualCoordinatesX = startCoordinatesX;
var actualCoordinatesY = startCoordinatesY;
//id for test
var idNumberForTest=0;
let r;
for(r=1; r<=countInRow; r++ )
{
let i;
for(i=1; i<=countInColumns; i++ )
{
var geometry = new THREE.BoxGeometry(maxTileSizeWidth, maxTileSizeHeight, 1 );
var tileX = new THREE.Mesh( geometry, materialsTiles );
tileX.position.set(actualCoordinatesX,actualCoordinatesY,0);
//Change actualCoordinates X
actualCoordinatesX = actualCoordinatesX + maxTileSizeWidth + distanceBetween;
idNumberForTest=idNumberForTest + 1;
tileX.callback = function(){callFromTitleWithId(idNumberForTest+'')};
arrayTiles.push(tileX);
sceneWorld.add( tileX );
}
actualCoordinatesY = actualCoordinatesY - (maxTileSizeHeight+1);
actualCoordinatesX = startCoordinatesX;
}
}
</script>
</body>
</html>
`
The problem is that idNumberForTest is equal for all objects. The callback functions always refer to the same variable. Instead of using a callback function, you can store the ID for the clicked mesh like so:
tileX.userData.id = idNumberForTest;
In this way, the correct ID is assigned to the respective object. Check out the following live example to see this approach in action.
document.addEventListener('mousedown', onDocumentMouseDown, false);
var arrayTiles = [];
//[SCREEN]
var SCREEN_WIDTH = window.innerWidth - 5;
var SCREEN_HEIGHT = window.innerHeight - 5;
screenOrientationValue=0;
//RayCaster für Objekte
var raycaster2 = new THREE.Raycaster(new THREE.Vector3(0,0,35),new THREE.Vector3(0,0,1));
var mouse2 = new THREE.Vector2();
var renderer = new THREE.WebGLRenderer();
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
document.body.appendChild( renderer.domElement );
var sceneWorld = new THREE.Scene();
sceneWorld.add( new THREE.AxesHelper(50) );
createTiles(sceneWorld);
var camera= new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(0,0,35);
var light2 = new THREE.AmbientLight( 0x20202A, 20, 100 );
light2.position.set( 30, -10, 30 );
sceneWorld.add( light2 );
var animate = function () {
requestAnimationFrame( animate );
renderer.render( sceneWorld, camera);
sceneUpdate();
};
animate();
function sceneUpdate()
{
//Update
}
function callFromTitleWithId(titleId)
{
console.log("ID:"+titleId);
}
function onDocumentMouseDown(event)
{
event.preventDefault();
mouse2.x = (event.clientX / renderer.domElement.clientWidth) * 2 - 1;
mouse2.y = - (event.clientY / renderer.domElement.clientHeight) * 2 + 1;
raycaster2.setFromCamera(mouse2, camera);
console.log( arrayTiles );
var intersects2 = raycaster2.intersectObjects(arrayTiles,true);
if (intersects2.length > 0) {
console.log('Maus: X:'+mouse2.x+' Y:'+mouse2.y);
console.log("intersects:" + intersects2[0].object);
console.log("distance:" + intersects2[0].distance);
console.log("face:" + intersects2[0].face);
console.log("faceIndex:" + intersects2[0].faceIndex);
console.log("faceIndex y:" + intersects2[0].point.y);
console.log("faceIndex x:" + intersects2[0].point.x);
console.log("ID:", intersects2[0].object.userData.id);
}
}
function createTiles(sceneWorld)
{
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
var materialSide = new THREE.MeshBasicMaterial( {color: 0xffff00} );
var materialsTiles = [materialSide, // Left side
materialSide, // Right side
materialSide, // Top side ---> THIS IS THE FRONT
materialSide, // Bottom side --> THIS IS THE BACK
material, // Front side
materialSide // Back side
];
var maxTileSizeWidth=11;
var maxTileSizeHeight=8;
var distanceBetween=2;
var distanceBorderLeft=-1;
var countInColumns=2;
var countInRow = 4;
var startCoordinatesX = ((((countInColumns * maxTileSizeWidth)+(countInColumns-6.5)*distanceBetween)/2))*-1;
var startCoordinatesY = 20;
var actualCoordinatesX = startCoordinatesX;
var actualCoordinatesY = startCoordinatesY;
//id for test
var idNumberForTest=0;
let r;
for(r=1; r<=countInRow; r++ )
{
let i;
for(i=1; i<=countInColumns; i++ )
{
var geometry = new THREE.BoxGeometry(maxTileSizeWidth, maxTileSizeHeight, 1 );
var tileX = new THREE.Mesh( geometry, materialsTiles );
tileX.position.set(actualCoordinatesX,actualCoordinatesY,0);
//Change actualCoordinates X
actualCoordinatesX = actualCoordinatesX + maxTileSizeWidth + distanceBetween;
idNumberForTest=idNumberForTest + 1;
arrayTiles.push(tileX);
tileX.userData.id = idNumberForTest;
sceneWorld.add( tileX );
}
actualCoordinatesY = actualCoordinatesY - (maxTileSizeHeight+1);
actualCoordinatesX = startCoordinatesX;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>

Regarding electric field lines in three js

I would like to illustrate coulomb's law.I want to do 2 things.
1.I would like to show the force between any charge and resultant force.
2.And I want to show the electric field due to one charge on other.
I am done with the first one.So,how can I do the second one using three js?
<html>
<head>
<title>My first three.js app</title>
<meta charset="UTF-8">
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
<script src="DragControls.js"></script>
<script src="TrackballControls.js"></script>
<script src= "ThreeCSG.js"></script>
<script src="ObjectControls.js"></script>
<script src="stats.min.js"></script>
<script src="dat.gui.min.js"></script>
<script src = "object.js"></script>
<script>
objects=[]
var gui;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 );
var IsDragRunning=false;
var objectDragging;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// var controls = new THREE.OrbitControls(camera,renderer.domElement);
camera.position.z = 60;
var dragElements = [];
var dragControls = new THREE.DragControls( dragElements, camera, renderer.domElement );
dragControls.addEventListener( 'dragstart', function ( event ) { /*controls.enabled = false;*/
IsDragRunning=true;} );
dragControls.addEventListener( 'dragend', function ( event ) {
IsDragRunning=false;
/*controls.enabled = true;*/ } );
scene.background = new THREE.Color("#FDF6D5");
var groundMaterial = new THREE.MeshBasicMaterial( );
//text geometry
var myfont;
function text(object,text1){
if(!myfont){
var loader = new THREE.FontLoader();
loader.load( 'optimer_regular.typeface.json', function ( font ) {
var count = 0;
myfont = font;
});
}
if(myfont){
var textGeometry = new THREE.TextGeometry( text1, {
font: myfont,
size: 1,
height:0,
curveSegments: 12,
bevelThickness: 0.1,
bevelSize: 0.1,
bevelEnabled: false
});
var textMaterial = new THREE.MeshPhongMaterial(
{ color: "black",transparent:true,opacity:1.0,specular:"#B6C015"}
);
numberText = new THREE.Mesh( textGeometry, textMaterial );
numberText.position.set(2,1,1);
object.add(numberText);
}
}
var ambientLight;
var spotLight;
ambientLight = new THREE.AmbientLight(16777215, 0.5);
ambientLight.position.set(-100,0,0);
scene.add(ambientLight);
spotLight = new THREE.PointLight(16777215);
spotLight.position.set(60,10,40);
spotLight.castShadow = true;
scene.add(spotLight);
ambientLight = new THREE.AmbientLight(16777215, 0.5);
ambientLight.position.set(-100,100,100);
scene.add(ambientLight);
//dat gui
gui = new dat.GUI();
parameters =
{
//x: 0, y: 30, z: 0,
Charge:0,
Er:1,
//color: "#ff0000", // color (change "#" to "0x")
//opacity: 1,
visible: true,
material: "Phong",
charge: function() { charge_create(mag) ;
findForce();}
};
var cubeX = gui.add( parameters, 'Charge' ).min(-10).max(10).step(1).listen();
//var epsilon = gui.add( parameters, 'Er' ).min(0).max(2).step(0.01).listen();
var mag=0;
var e=1;
cubeX.onChange(function(value)
{ mag = value; });
//epsilon.onChange(function(value)
//{ e = value;
//findForce(test.position);
//});
gui.add( parameters, 'charge' ).name("Add Charge");
gui.open();
//columns law code
charge=[];
function charge_create(magnitude){
var t;
var geometry = new THREE.SphereGeometry( 0.5, 32, 32 );
if(magnitude>=0){
var material = new THREE.MeshPhongMaterial( {color: 0xff0000} );
t="+";
}
else{
var material = new THREE.MeshPhongMaterial( {color: 0x000000} );
t="-";
}
var sphere = new THREE.Mesh( geometry, material );
text(sphere,t);
scene.add( sphere );
sphere.position.set(Math.random()*40-20,0,0);
sphere.magnitude=magnitude;
charge.push(sphere);
dragElements.push(sphere);
return sphere;
}
var geometry = new THREE.SphereGeometry( 0.5, 32, 32 );
var material = new THREE.MeshPhongMaterial( {color: 0x0000ff} );
var test = new THREE.Mesh( geometry, material );
scene.add( test );
test.forceX=0;
test.forceY=0;
dragElements.push(test);
test.position.set(0,0,0);
text(test,"Test Charge");
/*charge_create(+1);
console.log(charge[0].magnitude);
charge_create(-1);
console.log(charge[1].magnitude);*/
//negative_charge=[];
var arr=new Array(20);
var resultant=null;
findForce(test.position);
function findForce(){
var fx=0;
var fy=0;
for(var i=0;i<charge.length;i++){
//console.log(position.x);
var r_square=Math.pow(Math.abs(test.position.x-charge[i].position.x),2)+Math.pow(Math.abs(test.position.y-charge[i].position.y),2);
var k=9*Math.pow(10,9)/e;
var force=k*charge[i].magnitude/(r_square);
force=force/1000000;
var y=test.position.y-charge[i].position.y;
var x=test.position.x-charge[i].position.x;
var angle =Math.atan(Math.abs(y/x));
if(y<0 && x>0)angle=-angle;
if(x<0 && y>0)angle=Math.PI-angle;
if(x<0 && y<0)angle=Math.PI+angle;
var force_x=force*(Math.cos(angle));
var force_y=force*(Math.sin(angle));
//arrowHelper
var dir = new THREE.Vector3( force_x, force_y, 0 );
//normalize the direction vector (convert to vector of length 1)
dir.normalize();
var origin = new THREE.Vector3( test.position.x, test.position.y, 0 );
var length = Math.abs(force);
if(charge[i].magnitude>=0)
var hex = 0xff0000;
else{
var hex=0x000000;
}
var arrowHelper = new THREE.ArrowHelper( dir, origin, length, hex );
//text(arrowHelper.line,force);
//scene.add( arrowHelper );
//arr.push(arrowHelper);
if(arr[i]){
//console.log("asdas");
scene.remove(arr[i]);
arr[i]=arrowHelper;
scene.add( arrowHelper );
}
else{
//console.log("a");
arr[i]=arrowHelper;
scene.add( arrowHelper );
}
fx=fx+force_x;
fy=fy+force_y;
//console.log("force x"+fx+" "+"force_y"+fy);
}
var net_force=Math.sqrt(Math.pow(force_x,2)+Math.pow(force_y,2))
var dir = new THREE.Vector3( fx, fy, 0 );
//normalize the direction vector (convert to vector of length 1)
dir.normalize();
var origin = new THREE.Vector3( test.position.x, test.position.y, 0 );
var length = Math.abs(net_force);
var hex = 0x0000ff;
var arrowHelper = new THREE.ArrowHelper( dir, origin, length, hex );
//text(arrowHelper.line,force);
if(resultant==null){
resultant=arrowHelper;
scene.add(resultant);
}
else{
//console.log()
scene.remove(resultant);
resultant=arrowHelper;
scene.add(resultant);
}
}
document.addEventListener("mousedown",onDocumentMouseDown);
var raycaster;
function onDocumentMouseDown(event) {
// event.preventDefault();
var mouse;
mouse = new THREE.Vector2();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects, true);
if (intersects.length > 0) {
if(IsDragRunning == true){
objectDragging = intersects[0].object;
}
}
console.log(IsDragRunning );
if(objectDragging)
console.log(objectDragging.name);
}
document.addEventListener("mousemove",onDocumentMouseMove);
var raycaster;
function onDocumentMouseMove(event) {
// event.preventDefault();
if(IsDragRunning){
console.log("asd");
findForce(test.position);
//render();
}
}
//findForce();
var count=false;
var render = function () {
requestAnimationFrame(render);
if(myfont && !count){
text(test,"Test Charge");
console.log("hello");
count=true;
}
//findForce(test.position);
renderer.render(scene,camera);
};
render();
</script>
</body>
This is not the ultimate solution, this is just the point where you can start from.
So, you can use a grid of THREE.ArrowHelper()
and then, when you add a charge in this field:
function setCharge(val) {
var chargeGeom = new THREE.SphereGeometry(0.25, 16, 12);
var chargeMat = new THREE.MeshBasicMaterial({
color: val == 1 ? 0xff0000 : 0x0000ff
});
var charge = new THREE.Mesh(chargeGeom, chargeMat);
charge.position.set(THREE.Math.randFloatSpread(cubeDim), THREE.Math.randFloatSpread(cubeDim), THREE.Math.randFloatSpread(cubeDim));
charge.userData.charge = val;
charges.push(charge);
scene.add(charge);
arrangeArrows();
}
and its usage is like:
chargePositive.addEventListener("click", function() {
setCharge(1)
});
chargeNegative.addEventListener("click", function() {
setCharge(-1)
});
So, when you add a charge, you arrange your grid arrows, using the superposition principle for each arrow, counting forces from all charges in the field:
var direction = new THREE.Vector3();
var normal = new THREE.Vector3();
var forceVector = new THREE.Vector3();
var directions = [];
var result = new THREE.Vector3();
function arrangeArrows() {
arrows.forEach((arrow) => {
directions = [];
charges.forEach((charge, index) => {
direction.subVectors(arrow.position, charge.position)
normal.copy(direction).normalize();
directions.push({
dir: (charge.userData.charge == -1 ? normal.negate() : normal).clone(),
force: 1 / Math.pow(forceVector.subVectors(arrow.position, charge.position).length(), 2)
});
});
result.set(0, 0, 0);
directions.forEach((dir) => {
result.addScaledVector(dir.dir, dir.force);
})
arrow.setDirection(result.normalize());
});
};
jsfiddle example.
Also, you can use THREE.LineSegments() with THREE.BufferGeometry() andTHREE.ShaderMaterial(), and do the same calculation on a GPU (with cooler visual effects):

having trouble with Three.js .Json Loader (importing 3d models)

This is a skull i found on clara.io , i downloaded the .obj, and uploaded into the three.js editor, and proceeded to export it as Json.. Now I have been trying to add it to some of the three.js examples. What am I doing wrong. I notice the examples have different scripts linked, but most tutorials show people only linking the build. I love this stuff so much, I really wanna learn...
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - panorama fisheye demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: rgb(200,200,200);
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
color: #ffffff;
padding: 5px;
font-family:Monospace;
font-size:13px;
font-weight: bold;
text-align:center;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">three.js - panorama fisheye demo. cubemap by Jochum Skoglund. (mousewheel: change fov)</div>
<script src="../build/three.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/CanvasRenderer.js"></script>
<script>
var camera, scene, renderer;
var texture_placeholder,
isUserInteracting = false,
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 90, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0,
target = new THREE.Vector3();
init();
animate();
function init() {
var container, mesh;
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1100 );
scene = new THREE.Scene();
texture_placeholder = document.createElement( 'canvas' );
texture_placeholder.width = 128;
texture_placeholder.height = 128;
var context = texture_placeholder.getContext( '2d' );
context.fillStyle = 'rgb( 200, 200, 200 )';
context.fillRect( 0, 0, texture_placeholder.width, texture_placeholder.height );
var materials = [
loadTexture( 'textures/cube/skybox/px.jpg' ), // right
loadTexture( 'textures/cube/skybox/nx.jpg' ), // left
loadTexture( 'textures/cube/skybox/py.jpg' ), // top
loadTexture( 'textures/cube/skybox/ny.jpg' ), // bottom
loadTexture( 'textures/cube/skybox/pz.jpg' ), // back
loadTexture( 'textures/cube/skybox/nz.jpg' ) // front
];
mesh = new THREE.Mesh( new THREE.BoxGeometry( 300, 300, 300, 7, 7, 7 ), new THREE.MultiMaterial( materials ) );
mesh.scale.x = - 1;
scene.add( mesh );
for ( var i = 0, l = mesh.geometry.vertices.length; i < l; i ++ ) {
var vertex = mesh.geometry.vertices[ i ];
vertex.normalize();
vertex.multiplyScalar( 550 );
}
var particleMaterial = new THREE.MeshBasicMaterial();
particleMaterial.map = THREE.ImageUtils.loadTexture ('');
particleMaterial.side = THREE.DoubleSide;
var itmArr = []
var loader = new THREE.JSONLoader();
loader.load('models/json/skull.json', function (geometry) {
for (var i = 0; i < 20; i++) {
var mesh = new THREE.Mesh(geometry, particleMaterial);
mesh.position.z = (Math.random()-Math.random())*100;
mesh.position.x = (Math.random()-Math.random())*100;
mesh.position.y = (Math.random()-Math.random())*100;
mesh.dir = (Math.random()-Math.random())*.01;
scene.add(mesh);
itmArr.push(mesh);
}
});
renderer = new THREE.CanvasRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'wheel', onDocumentMouseWheel, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function loadTexture( path ) {
var texture = new THREE.Texture( texture_placeholder );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
var image = new Image();
image.onload = function () {
texture.image = this;
texture.needsUpdate = true;
};
image.src = path;
return material;
}
function onDocumentMouseDown( event ) {
event.preventDefault();
isUserInteracting = true;
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
function onDocumentMouseMove( event ) {
if ( isUserInteracting === true ) {
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
}
function onDocumentMouseUp( event ) {
isUserInteracting = false;
}
function onDocumentMouseWheel( event ) {
camera.fov += event.deltaY * 0.05;
camera.updateProjectionMatrix();
}
function onDocumentTouchStart( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
onPointerDownPointerX = event.touches[ 0 ].pageX;
onPointerDownPointerY = event.touches[ 0 ].pageY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
lon = ( onPointerDownPointerX - event.touches[0].pageX ) * 0.1 + onPointerDownLon;
lat = ( event.touches[0].pageY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
}
function animate() {
requestAnimationFrame( animate );
update();
}
function update() {
if ( isUserInteracting === false ) {
lon += 0.1;
}
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = THREE.Math.degToRad( 90 - lat );
theta = THREE.Math.degToRad( lon );
target.x = 500 * Math.sin( phi ) * Math.cos( theta );
target.y = 500 * Math.cos( phi );
target.z = 500 * Math.sin( phi ) * Math.sin( theta );
camera.position.copy( target ).negate();
camera.lookAt( target );
renderer.render( scene, camera );
}
</script>
</body>
</html>

How to control the data.gui.js that do not affect the object(Three.js r66)

I write a trackball to control the object rotation, everything goes fine. However, when I add the gui component to the program, and when I put the mouse to change the gui, the object is moving. Because my trackball project the screen coordinate to the virtual ball, when my mouse is on the gui component, it is still in the screen, and it makes the object move. How to avoid that? I try t find the reason about the trackball three.js has, and do not find the a result. Why his trackball do not affact the gui object?
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - geometry - cube</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
var cube, plane;
var mouseDown = false;
var rotateStartP = new THREE.Vector3(0,0,1);
var rotateEndP = new THREE.Vector3(0,0,1);
var lastPosX;
var lastPosY;
var targetRotationY = 0;
var targetRotationX = 0;
var quater;
//var rotateQuaternion = new THREE.Quaternion();
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = 'Drag to spin the cube';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
scene = new THREE.Scene();
// Cube
var geometry = new THREE.CubeGeometry( 200, 200, 200 );
for ( var i = 0; i < geometry.faces.length; i += 2 ) {
var hex = Math.random() * 0xffffff;
geometry.faces[ i ].color.setHex( hex );
geometry.faces[ i + 1 ].color.setHex( hex );
}
var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
cube = new THREE.Mesh( geometry, material );
cube.position.y = 150;
scene.add( cube );
// Plane
var geometry = new THREE.PlaneGeometry( 200, 200 );
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );
plane = new THREE.Mesh( geometry, material );
scene.add( plane );
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//GUI
var controls = new function () {
this.xx = false;
this.yy = 512;
this.onChange = function () {
}
};
var gui = new dat.GUI();
gui.add(controls, 'xx').onChange(controls.onChange);
gui.add(controls, 'yy', 1, 10).step(1).onChange(controls.onChange);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function onDocumentMouseDown( event ) {
event.preventDefault();
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mouseout', onDocumentMouseOut, false );
mouseDown = true;
rotateStartP = projectOnTrackball(event.clientX, event.clientY);
}
function onDocumentMouseMove( event ) {
if(!mouseDown)
{
return;
}
rotateEndP = projectOnTrackball(event.clientX, event.clientY);
}
function getMouseOnScreen( pageX, pageY) {
return new THREE.Vector2.set(pageX / window.innerWidth ,pageY / window.innerHeight);
}
function projectOnTrackball(pageX, pageY) // The screen coordinate[(0,0)on the left-top] convert to the
//trackball coordinate [(0,0) on the center of the page]
{
var mouseOnBall = new THREE.Vector3();
mouseOnBall.set(
( pageX - window.innerWidth * 0.5 ) / (window.innerWidth * .5),
( window.innerHeight * 0.5 - pageY ) / ( window.innerHeight * .5),
0.0
);
var length = mouseOnBall.length();
if (length > 1.0) {
mouseOnBall.normalize();
}
else {
mouseOnBall.z = Math.sqrt(1.0 - length * length);
}
return mouseOnBall;
}
function rotateMatrix(rotateStart, rotateEnd)
{
var axis = new THREE.Vector3(),
quaternion = new THREE.Quaternion();
var angle = Math.acos( rotateStart.dot( rotateEnd ) / rotateStart.length() / rotateEnd.length() );
if ( angle )
{
axis.crossVectors( rotateStart, rotateEnd ).normalize();
angle *= 0.01; //Here we could define rotate speed
quaternion.setFromAxisAngle( axis, angle );
}
return quaternion;
}
function onDocumentMouseUp( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
mouseDown = false;
rotateStartP = rotateEndP;
}
function onDocumentMouseOut( event ) {
document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentTouchStart( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
/*
mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
targetRotationOnMouseDownX = targetRotationX;
mouseYOnMouseDown = event.touches[ 0 ].pageY - windowHalfY;
targetRotationOnMouseDownY = targetRotationY; */
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length === 1 ) {
event.preventDefault();
/*
mouseX = event.touches[ 0 ].pageX - windowHalfX;
targetRotationX = targetRotationOnMouseDownX + ( mouseX - mouseXOnMouseDown ) * 0.05;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
targetRotationY = targetRotationOnMouseDownY + ( mouseY - mouseYOnMouseDown ) * 0.05; */
}
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
//if(rotateStartP != rotateEndP) {
//rotateQuaternion = rotateMatrix(rotateStartP, rotateEndP);
//quater=cube.quaternion;
//quater.multiplyQuaternions(rotateQuaternion, quater);
//quater.multiply(rotateQuaternion);
//quater.normalize();
var rotateQuaternion = rotateMatrix(rotateStartP, rotateEndP);
quater=cube.quaternion;
quater.multiplyQuaternions(rotateQuaternion,quater);
quater.normalize();
cube.setRotationFromQuaternion(quater);
// }
renderer.render( scene, camera );
}
</script>
</body>
</html>
Change my code to ObjectTrackball.js
The code is as follows:
TrackballControls = function ( object, domElement ) {
var _this = this;
_this.quater = object.quaternion;
_this.object = object;
_this.domElement = ( domElement !== undefined ) ? domElement : document;
_this.zoomValue = 0;
_this.mouseDown = true;
_this.rotateStartP = new THREE.Vector3();
_this.rotateEndP = new THREE.Vector3();
// events
var changeEvent = { type: 'change' };
// methods
this.handleEvent = function ( event ) {
if ( typeof this[ event.type ] == 'function' ) {
this[ event.type ]( event );
}
};
this.update = function () {
var rotateQuaternion = rotateMatrix(_this.rotateStartP, _this.rotateEndP);
_this.quater = _this.object.quaternion;
_this.quater.multiplyQuaternions(rotateQuaternion,_this.quater);
_this.quater.normalize();
_this.object.setRotationFromQuaternion(_this.quater);
_this.object.position.z += _this.zoomValue;
_this.zoomValue = 0;
};
function mousedown( event ) {
event.preventDefault();
_this.mouseDown = true;
_this.rotateStartP = projectOnTrackball(event.clientX, event.clientY);
document.addEventListener( 'mousemove', mousemove, false );
document.addEventListener( 'mouseup', mouseup, false );
}
function getMouseOnScreen( pageX, pageY) {
return new THREE.Vector2.set(pageX / window.innerWidth ,pageY / window.innerHeight);
}
function projectOnTrackball(pageX, pageY) // The screen coordinate[(0,0)on the left-top] convert to the
//trackball coordinate [(0,0) on the center of the page]
{
var mouseOnBall = new THREE.Vector3();
mouseOnBall.set(
( pageX - window.innerWidth * 0.5 ) / (window.innerWidth * .5),
( window.innerHeight * 0.5 - pageY ) / ( window.innerHeight * .5),
0.0
);
var length = mouseOnBall.length();
if (length > 1.0) {
mouseOnBall.normalize();
}
else {
mouseOnBall.z = Math.sqrt(1.0 - length * length);
}
return mouseOnBall;
}
function rotateMatrix(rotateStart, rotateEnd)
{
var axis = new THREE.Vector3(),
quaternion = new THREE.Quaternion();
var angle = Math.acos( rotateStart.dot( rotateEnd ) / rotateStart.length() / rotateEnd.length() );
if ( angle )
{
axis.crossVectors( rotateStart, rotateEnd ).normalize();
angle *= 0.01; //Here we could define rotate speed
quaternion.setFromAxisAngle( axis, angle );
}
return quaternion;
}
function mousemove( event ) {
if(!_this.mouseDown)
{
return;
}
_this.rotateEndP = projectOnTrackball(event.clientX, event.clientY);
}
function mouseup( event ) {
_this.mouseDown = false;
_this.rotateStartP = _this.rotateEndP;
document.removeEventListener( 'mousemove', mousemove );
document.removeEventListener( 'mouseup', mouseup );
}
function mousewheel( event ) {
event.preventDefault();
event.stopPropagation();
var delta = 0;
if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
delta = event.wheelDelta / 40;
} else if ( event.detail ) { // Firefox
delta = - event.detail / 3;
}
_this.zoomValue += delta;
}
this.domElement.addEventListener( 'mousedown', mousedown, false );
this.domElement.addEventListener( 'mousewheel', mousewheel, false );
this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
};
TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
Code of The Object control application (Three.js r66)
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - geometry - cube</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/controls/ObjectTrackballControl.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
var cube, plane;
var control;
var mouseDown = false;
var rotateStartP = new THREE.Vector3(0,0,1);
var rotateEndP = new THREE.Vector3(0,0,1);
var lastPosX;
var lastPosY;
var targetRotationY = 0;
var targetRotationX = 0;
var quater;
//var rotateQuaternion = new THREE.Quaternion();
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = 'Drag to spin the cube';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.y = 150;
camera.position.z = 500;
scene = new THREE.Scene();
// Cube
var geometry = new THREE.CubeGeometry( 200, 200, 200 );
for ( var i = 0; i < geometry.faces.length; i += 2 ) {
var hex = Math.random() * 0xffffff;
geometry.faces[ i ].color.setHex( hex );
geometry.faces[ i + 1 ].color.setHex( hex );
}
var material = new THREE.MeshBasicMaterial( { vertexColors: THREE.FaceColors, overdraw: 0.5 } );
cube = new THREE.Mesh( geometry, material );
cube.position.y = 150;
scene.add( cube );
control = new TrackballControls(cube);
// Plane
var geometry = new THREE.PlaneGeometry( 200, 200 );
geometry.applyMatrix( new THREE.Matrix4().makeRotationX( - Math.PI / 2 ) );
var material = new THREE.MeshBasicMaterial( { color: 0xe0e0e0, overdraw: 0.5 } );
plane = new THREE.Mesh( geometry, material );
scene.add( plane );
renderer = new THREE.CanvasRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//GUI
var controls = new function () {
this.xx = false;
this.yy = 512;
this.onChange = function () {
}
};
var gui = new dat.GUI();
gui.add(controls, 'xx').onChange(controls.onChange);
gui.add(controls, 'yy', 1, 10).step(1).onChange(controls.onChange);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
control.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>

Why find intersections does not work with THREE.UTF8Loader?

I clone https://github.com/mrdoob/three.js.git, and I did 2 changes for sample webgl_loader_utf8.html
Add CubeGeometry
Support find intersections
When I clicked Cubes can find intersections, but clicked utf8 models(for instance, ben or hand models) can't find intersections. Any ideas about this? Many thanks!
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - io - UTF8 loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
</style>
</head>
<body>
<div id="info">
three.js -
UTF8 format loader test -
models from The Utah 3D Animation Repository
<div id="show"></div>
</div>
<script src="../build/three.min.js"></script>
<script src="js/loaders/UTF8Loader.js"></script>
<script src="js/loaders/MTLLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/tween.min.js"></script>
<script>
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var FLOOR = -150;
var container, stats;
var camera, scene, renderer;
var projector, raycaster;
var mouse = new THREE.Vector2();
var mesh, zmesh, geometry;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
var show = document.getElementById("show");
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 20, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 2000 );
camera.position.z = 800;
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x000000, 800, 2000 );
var path = "textures/cube/SwedishRoyalCastle/";
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
reflectionCube = THREE.ImageUtils.loadTextureCube( urls );
// LIGHTS
var ambient = new THREE.AmbientLight( 0x222222 );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffffff, 1.1 );
directionalLight.position.set( 0, 20, 300 );
scene.add( directionalLight );
directionalLight.castShadow = true;
//directionalLight.shadowCameraVisible = true;
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMaHeight = 2048;
var d = 150;
directionalLight.shadowCameraLeft = -d * 1.2;
directionalLight.shadowCameraRight = d * 1.2;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 200;
directionalLight.shadowCameraFar = 500;
// RENDERER
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
renderer.setClearColor( scene.fog.color, 1 );
renderer.domElement.style.position = "relative";
container.appendChild( renderer.domElement );
//
/**
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.physicallyBasedShading = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFShadowMap;
**/
// STATS
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
var start = Date.now();
var loader = new THREE.UTF8Loader();
loader.load( "models/utf8/hand.js", function ( object ) {
var end = Date.now();
console.log( "hand", end - start, "ms" );
var s = 350;
object.scale.set( s, s, s );
object.position.x = 125;
object.position.y = -125;
//scene.add( object );
object.traverse( function( node ) {
node.castShadow = true;
node.receiveShadow = true;
if ( node.material && node.material.name === "skin" ) {
node.material.wrapAround = true;
node.material.wrapRGB.set( 0.6, 0.2, 0.1 );
}
} );
}, { normalizeRGB: true } );
loader.load( "models/utf8/ben_dds.js", function ( object ) {
var end = Date.now();
console.log( "ben", end - start, "ms" );
var s = 350;
object.scale.set( s, s, s );
object.position.x = -125;
object.position.y = -125;
scene.add( object );
object.traverse( function( node ) {
node.castShadow = true;
node.receiveShadow = true;
if ( node.material && ( node.material.name === "head" || node.material.name === "skinbody" ) ) {
node.material.wrapAround = true;
node.material.wrapRGB.set( 0.6, 0.2, 0.1 );
}
} );
}, { normalizeRGB: true } );
var geometry = new THREE.CubeGeometry( 20, 20, 20 );
for ( var i = 0; i < 20; i ++ ) {
var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );
object.position.x = Math.random() * 800 - 400;
object.position.y = Math.random() * 800 - 400;
object.position.z = Math.random() * 800 - 400;
object.rotation.x = Math.random() * 2 * Math.PI;
object.rotation.y = Math.random() * 2 * Math.PI;
object.rotation.z = Math.random() * 2 * Math.PI;
object.scale.x = Math.random() + 0.5;
object.scale.y = Math.random() + 0.5;
object.scale.z = Math.random() + 0.5;
scene.add( object );
}
projector = new THREE.Projector();
raycaster = new THREE.Raycaster();
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY - camera.position.y ) * .05;
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
show.innerText = "";
var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
projector.unprojectVector( vector, camera );
var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
show.innerText = "intersects=" + intersects.length + " at " + Date.now();
console.log(intersects.length);
}
}
</script>
</body>
</html>
You need to add the recursive flag to raycaster.intersectObjects().
var intersects = raycaster.intersectObjects( scene.children, true );
three.js r.58

Resources