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>
Related
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;
}
I am working towards this:
Here is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<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: #000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../build/three.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/ClearPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/Detector.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var composer, renderer;
var box_mask, box_1, box_2;
init();
animate();
function init() {
var camera_mask = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera_mask.position.z = 6;
var camera_1 = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera_1.position.z = 6;
var camera_2 = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera_2.position.z = 6;
var scene_mask = new THREE.Scene();
var scene_1 = new THREE.Scene();
var scene_2 = new THREE.Scene();
scene_mask.background = new THREE.Color( 0x000000 );
scene_1.background = new THREE.Color( 0xffffff );
scene_2.background = new THREE.Color( 0x000000 );
var box_mask_1 = new THREE.CircleGeometry( 2, 4 );
var box_mask_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_mask = new THREE.Geometry();
var boxMesh_mask_1 = new THREE.Mesh(box_mask_1);
boxMesh_mask_1.position.z = 1;
var boxMesh_mask_2 = new THREE.Mesh(box_mask_2);
boxMesh_mask_2.rotation.y = Math.PI;
boxMesh_mask_2.position.z = -1;
boxMesh_mask_1.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_1.geometry, boxMesh_mask_1.matrix);
boxMesh_mask_2.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_2.geometry, boxMesh_mask_2.matrix);
var material_mask = new THREE.MeshBasicMaterial({color: 0xffffff});
box_mask = new THREE.Mesh(singleGeometry_mask, material_mask);
scene_mask.add( box_mask );
var box_1_1 = new THREE.CircleGeometry( 2, 4 );
var box_1_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_1 = new THREE.Geometry();
var boxMesh_1_1 = new THREE.Mesh(box_1_1);
boxMesh_1_1.position.z = -1;
var boxMesh_1_2 = new THREE.Mesh(box_1_2);
boxMesh_1_2.rotation.y = Math.PI;
boxMesh_1_2.position.z = 1;
boxMesh_1_1.updateMatrix();
singleGeometry_1.merge(boxMesh_1_1.geometry, boxMesh_1_1.matrix);
boxMesh_1_2.updateMatrix();
singleGeometry_1.merge(boxMesh_1_2.geometry, boxMesh_1_2.matrix);
var material_1 = new THREE.MeshBasicMaterial({color: 0x000000});
box_1 = new THREE.Mesh(singleGeometry_1, material_1);
scene_1.add( box_1 );
var box_2_1 = new THREE.CircleGeometry( 2, 4 );
var box_2_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_2 = new THREE.Geometry();
var boxMesh_2_1 = new THREE.Mesh(box_2_1);
boxMesh_2_1.position.z = -1;
var boxMesh_2_2 = new THREE.Mesh(box_2_2);
boxMesh_2_2.rotation.y = Math.PI;
boxMesh_2_2.position.z = 1;
boxMesh_2_1.updateMatrix();
singleGeometry_2.merge(boxMesh_2_1.geometry, boxMesh_2_1.matrix);
boxMesh_2_2.updateMatrix();
singleGeometry_2.merge(boxMesh_2_2.geometry, boxMesh_2_2.matrix);
var material_2 = new THREE.MeshBasicMaterial({color: 0xffffff});
box_2 = new THREE.Mesh(singleGeometry_2, material_2);
scene_2.add( box_2 );
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.autoClear = false;
document.body.appendChild( renderer.domElement );
var clearPass = new THREE.ClearPass();
var clearMaskPass = new THREE.ClearMaskPass();
var maskPass = new THREE.MaskPass( scene_mask, camera_mask );
var renderPass_1 = new THREE.RenderPass( scene_1, camera_1 );
var renderPass_2 = new THREE.RenderPass( scene_2, camera_2 );
var outputPass = new THREE.ShaderPass( THREE.CopyShader );
outputPass.renderToScreen = true;
var parameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBFormat,
stencilBuffer: true
};
var renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, parameters );
composer = new THREE.EffectComposer( renderer , renderTarget );
composer.addPass( clearPass );
composer.addPass( renderPass_1 );
composer.addPass( maskPass );
composer.addPass( renderPass_2 );
composer.addPass( clearMaskPass );
composer.addPass( outputPass );
}
function animate() {
requestAnimationFrame( animate );
var time = performance.now() * 0.001 * 2;
box_mask.rotation.y = time;
box_1.rotation.y = time;
box_2.rotation.y = time;
renderer.clear();
composer.render( time );
}
</script>
</body>
</html>
this never works:
composer.addPass( clearPass );
composer.addPass( renderPass_1 );
composer.addPass( maskPass );
composer.addPass( renderPass_2 );
composer.addPass( clearMaskPass );
composer.addPass( outputPass );
if i switch out "renderPass_2" with a THREE.TexturePass it works, but it's not what I want.
Here is the codepen:
https://codepen.io/oxbits/pen/yEQLGK?editors=0010
Anyone able to combine two renderPasses with a mask?
Should I be using a different approach?
I finally got it to work! Though I'm not sure how...
Take a look:
https://codepen.io/anon/pen/PyJObz
One trick was not using a scene background in the 2nd render. Instead I had to create a background mesh.
Code below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
html, body, canvas {
margin: 0px;
overflow: hidden;
}
#fps {
position: absolute;
top: 0px;
left: 0px;
color: #fff;
z-index: 50;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../build/three.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/postprocessing/EffectComposer.js"></script>
<script src="js/postprocessing/ClearPass.js"></script>
<script src="js/postprocessing/ShaderPass.js"></script>
<script src="js/postprocessing/MaskPass.js"></script>
<script src="js/postprocessing/RenderPass.js"></script>
<script src="js/Detector.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
// if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
let scene = null;
let normal = null;
let outline = null;
let outScene = null;
let maskScene = null;
let light = null;
let renderer = null;
let composer = null;
let camera1 = null;
let camera2 = null;
let camera3 = null;
let mesh1 = null;
let mesh2 = null;
let mesh3 = null;
let bg_mesh = null;
let renderTarget = null;
let screenWidth = window.innerWidth;
let screenHeight = window.innerHeight;
const clock = new THREE.Clock;
let elapsedTime = 0;
let frameCount = 0;
const init = function() {
// SCENE
scene = new THREE.Scene;
maskScene = new THREE.Scene;
outScene = new THREE.Scene;
setModel();
// SCENE CAMERA
camera1 = new THREE.PerspectiveCamera(40, screenWidth/screenHeight, 1, 1000);
camera1.position.set(0, 0, 10);
scene.add(camera1);
camera2 = new THREE.PerspectiveCamera(40, screenWidth/screenHeight, 1, 1000);
camera2.position.set(0, 0, 10);
outScene.add(camera2);
camera3 = new THREE.PerspectiveCamera(40, screenWidth/screenHeight, 1, 1000);
camera3.position.set(0, 0, 10);
maskScene.add(camera3);
scene.background = new THREE.Color( 0xffffff );
// RENDERER
renderer = new THREE.WebGLRenderer({
width: screenWidth,
height: screenHeight,
antialias: true
});
renderer.setSize(screenWidth, screenHeight);
renderer.setClearColor(0x000000);
renderer.autoClear = false;
renderer.gammaInput = true;
renderer.gammaOutput = true;
document.body.appendChild(renderer.domElement);
// POSTPROCESSING
const renderTargetParameters = {
minFilter: THREE.LinearFilter,
magFilter: THREE.LinearFilter,
format: THREE.RGBAFormat,
stencilBuffer: true
};
renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters);
composer = new THREE.EffectComposer(renderer);
composer.renderTarget1.stencilBuffer = true;
composer.renderTarget2.stencilBuffer = true;
normal = new THREE.RenderPass(scene, camera1);
outline = new THREE.RenderPass(outScene, camera2);
outline.clear = false;
const mask = new THREE.MaskPass(maskScene, camera3);
mask.inverse = false;
const clearMask = new THREE.ClearMaskPass;
const copyPass = new THREE.ShaderPass(THREE.CopyShader);
copyPass.renderToScreen = true;
composer.addPass(normal);
composer.addPass(mask);
composer.addPass(outline);
composer.addPass(clearMask);
composer.addPass(copyPass);
// EVENTS
return window.addEventListener('resize', onWindowResize, false);
};
var setModel = function() {
var box_mask_1 = new THREE.CircleGeometry( 2, 4 );
var box_mask_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_mask = new THREE.Geometry();
var boxMesh_mask_1 = new THREE.Mesh(box_mask_1);
boxMesh_mask_1.position.z = 1;
var boxMesh_mask_2 = new THREE.Mesh(box_mask_2);
boxMesh_mask_2.rotation.y = Math.PI;
boxMesh_mask_2.position.z = -1;
boxMesh_mask_1.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_1.geometry, boxMesh_mask_1.matrix);
boxMesh_mask_2.updateMatrix(); // as needed
singleGeometry_mask.merge(boxMesh_mask_2.geometry, boxMesh_mask_2.matrix);
var box_1_1 = new THREE.CircleGeometry( 2, 4 );
var box_1_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_1 = new THREE.Geometry();
var boxMesh_1_1 = new THREE.Mesh(box_1_1);
boxMesh_1_1.position.z = -1;
var boxMesh_1_2 = new THREE.Mesh(box_1_2);
boxMesh_1_2.rotation.y = Math.PI;
boxMesh_1_2.position.z = 1;
boxMesh_1_1.updateMatrix();
singleGeometry_1.merge(boxMesh_1_1.geometry, boxMesh_1_1.matrix);
boxMesh_1_2.updateMatrix();
singleGeometry_1.merge(boxMesh_1_2.geometry, boxMesh_1_2.matrix);
var box_2_1 = new THREE.CircleGeometry( 2, 4 );
var box_2_2 = new THREE.CircleGeometry( 2, 4 );
var singleGeometry_2 = new THREE.Geometry();
var boxMesh_2_1 = new THREE.Mesh(box_2_1);
boxMesh_2_1.position.z = -1;
var boxMesh_2_2 = new THREE.Mesh(box_2_2);
boxMesh_2_2.rotation.y = Math.PI;
boxMesh_2_2.position.z = 1;
boxMesh_2_1.updateMatrix();
singleGeometry_2.merge(boxMesh_2_1.geometry, boxMesh_2_1.matrix);
boxMesh_2_2.updateMatrix();
singleGeometry_2.merge(boxMesh_2_2.geometry, boxMesh_2_2.matrix);
const matColor = new THREE.MeshBasicMaterial({
color: 0x000000});
mesh1 = new THREE.Mesh(singleGeometry_1, matColor); // geometry, matColor);
scene.add(mesh1);
// flat mask
const matFlat = new THREE.MeshBasicMaterial({
color: 0x000000});
mesh2 = new THREE.Mesh(singleGeometry_mask, matFlat);
maskScene.add(mesh2);
const matColor2 = new THREE.MeshBasicMaterial({
color: 0xffffff});
mesh3 = new THREE.Mesh(singleGeometry_2, matColor2);
outScene.add(mesh3);
const matColor3 = new THREE.MeshBasicMaterial({
color: 0x000000});
bg_mesh = new THREE.Mesh(new THREE.CircleGeometry( 100, 4 ), matColor3);
outScene.add(bg_mesh);
bg_mesh.position.set(0, 0, -10);
};
var onWindowResize = function() {
screenWidth = window.innerWidth;
screenHeight = window.innerHeight;
camera1.aspect = screenWidth / screenHeight;
camera2.aspect = camera1.aspect;
camera3.aspect = camera1.aspect;
camera1.updateProjectionMatrix();
camera2.updateProjectionMatrix();
camera3.updateProjectionMatrix();
return renderer.setSize(screenWidth, screenHeight);
};
var animate = function() {
updateFps();
requestAnimationFrame(animate);
return render();
};
var render = function() {
const now = Date.now();
const delta = clock.getDelta();
if (mesh1) {
mesh1.rotation.y += 0.015;
mesh2.rotation.y = mesh1.rotation.y;
mesh3.rotation.y = mesh1.rotation.y;
}
return composer.render();
};
var updateFps = function() {
elapsedTime += clock.getDelta();
frameCount++;
if (elapsedTime >= 1) {
$('#fps').html(frameCount);
frameCount = 0;
return elapsedTime = 0;
}
};
init();
animate();
</script>
</body>
</html>
Just chiming in because I don't know the specifics of your situation but I have used the composer before...
What if you just add the texturePass after the maskPass and leave the renderPass1 as the next one after that?
The composer works by applying operations through a succession of buffers, so in between operations you sometimes have to do a texturePass to copy the current output back to the input for the next pass...
But this is just a guess, in case nobody else answers....
I am trying to make the game brickbreaker with Three.js and Physi.js objects. So far I have the bricks and the paddle working. However, when I create a bouncy ball, it seems to be jumping all over the place instead of simply up and down at different angles. It also seems like the ball keeps bouncing even if it isn't hitting the paddle. Can any one help with my code?
var scene, camera, renderer;
var wall, brick, ball;
var npc;
var controls =
{ left:false, right:false,
speed:10,}
var counter=0;
var ball;
console.log("Checking!");
init();
animate();
/****************************************************************
To initialize the scene, we initialize each of its components *
****************************************************************/
function init(){
initPhysijs();
scene = initScene();
initRenderer();
initControls();
addLight();
camera = addCamera();
addBricks();
addWalls();
addNPC();
var ball = createBall();
ball.position.set(0,-10,0);
scene.add(ball)
}
function initScene(){
var scene = new Physijs.Scene();
return scene;
}
function initPhysijs(){
Physijs.scripts.worker = '../js/physijs_worker.js';
Physijs.scripts.ammo = '../js/ammo.js';
}
function initRenderer(){
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0xF7F9F9));
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
}
function initControls(){
// here is where we create the eventListeners to respond to operations
//create a clock for the time-based animation ...
clock = new THREE.Clock();
clock.start();
window.addEventListener( 'keydown', keydown);
window.addEventListener( 'keyup', keyup );
}
function keydown(event){
console.dir(event);
console.log("Keydown: '"+event.key+"'");
// this is the regular scene
switch (event.key){
// change the way the avatar is moving
case "ArrowRight": controls.right = true;console.log("coneAvatar moving forward"); break;
case "ArrowLeft": controls.left = true; break;
}
}
function keyup(event){
//console.log("Keydown:"+event.key);
//console.dir(event);
switch (event.key){
case "ArrowRight": controls.right = false; break;
case "ArrowLeft": controls.left = false; break;
}
}
function updateNPC(npc,controls){
var forward = npc.getWorldDirection();
if (controls.left){
npc.position.set(counter-.2,-15,0)
npc._dirtyPosition=true;
// npc.position.x+=1;
counter=counter-.2;
} else if (controls.right){
npc.position.set(counter+.2,-15,0)
npc._dirtyPosition=true;
// npc.position.x=npc.position-1;
counter=counter+.2;
}
else{
npc.position.set(counter,-15,0);
}
}
function addLight() {
var spotLight = new THREE.DirectionalLight(0xffffff);
spotLight.position.set(30, 40, 50);
spotLight.intensity = 1;
scene.add(spotLight);
}
function addCamera(){
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.z=24;
camera.position.y=0;
camera.position.x=0;
camera.lookAt(0,0,0);
return camera;
}
function createBall(){
//var geometry = new THREE.SphereGeometry( 4, 20, 20);
var geometry = new THREE.SphereGeometry( 1, 16, 16);
var material = new THREE.MeshLambertMaterial( { color: 0x444444} );
var pmaterial = new Physijs.createMaterial(material,0.9,3);
var mesh = new Physijs.BoxMesh( geometry, pmaterial );
mesh.setDamping(0.01,0.01);
mesh.castShadow = true;
return mesh;
}
/* Adds the bricks to the scene to form the wall the player will try to break down
Added by Allison Regna */
function addBricks() {
var yPos = 0;
var zPos = 0;
var colors = [0x1DD3B0, 0xAFFC41, 0xB2FF9E, 0x75B9BE, 0x7D82B8, 0x00A5CF, 0x987284, 0xAAEFDF, 0xAED6F1];
for(var i= 1; i <= 8 ; i++){
xPos = -30.5;
for(var j= 1; j <=16; j++){
color = colors[getRandomInt(9)];
brick = createBrick(color);
brick.position.set(xPos, yPos, zPos);
scene.add(brick);
brick.addEventListener('collision',
function( other_object, relative_velocity, relative_rotation, contact_normal ) {
if (other_object == ball){
console.log("The ball broke the brick!");
// make the brick drop below the scene ..
this.position.y = this.position.y - 100;
this.__dirtyPosition = true;
}
}
)
xPos += 4.10;
}
yPos += 2.10;
}
}
/* Returns a random integer between 0 inclusive and maxInt noninclusive
Added by Allison Regna */
function getRandomInt(maxInt) {
return Math.floor(Math.random() * Math.floor(maxInt));
}
function addNPC(){
npc = createBoxMesh(0x0000ff);
npc.position.set(0,-15,0);
npc.scale.set(5,2,1);
npc.rotateY(100)
scene.add(npc);
console.dir(npc);
}
/* Adds walls to the scene so the ball can bounce off back into the players view
Added by Allison Regna */
function addWalls(){
var topWall = createWall();
topWall.position.set(0, 18, 0);
scene.add(topWall);
var leftWall = createWall();
leftWall.position.set(-39, 0, 0);
leftWall.rotateZ(Math.PI/2);
scene.add(leftWall);
var rightWall = createWall();
rightWall.position.set(39, 0, 0);
rightWall.rotateZ(Math.PI/2);
scene.add(rightWall);
}
function createBoxMesh(color){
var geometry = new THREE.BoxGeometry( 2, .1, .1);
var material = new THREE.MeshLambertMaterial( { color: color} );
var pmaterial= new Physijs.createMaterial( material, 0.9, .95 );
mesh = new Physijs.BoxMesh( geometry, pmaterial, 0);
mesh.castShadow = true;
mesh.float=true;
return mesh;
}
/* Creates a brick mesh
Added by Allison Regna */
function createBrick(color){
var geometry = new THREE.PlaneGeometry( 4, 2, 4 );
var material = new THREE.MeshBasicMaterial( { color: color, wireframe: false } );
var pmaterial= new Physijs.createMaterial( material, 0.9, 0.05 );
brickMesh = new Physijs.BoxMesh( geometry, pmaterial, 0 );
brickMesh.castShadow = true;
return brickMesh;
}
/* Creates a wall mesh that will keep the ball inside the scene
Added by Allison Regna */
function createWall(){
var geometry = new THREE.PlaneGeometry( 100, 1, 1 );
var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
var pmaterial = new Physijs.createMaterial ( material, .9, 0.05 );
var wall = new THREE.Mesh( geometry, material, 0 );
return wall;
}
function animate() {
requestAnimationFrame( animate );
updateNPC(npc,controls);
renderer.render( scene, camera );
scene.simulate();
}
<!DOCTYPE html>
<!--
PA03 Group J-Crew
-->
<html>
<head>
<meta charset=utf-8>
<title>Game 0</title>
<style>
body { margin: 0;}
canvas { width: 100%; height: 100%;}
</style>
</head>
<body>
<script src="https://github.com/mrdoob/three.js/"></script>
<script src="https://github.com/chandlerprall/Physijs"></script>
<script src="https://github.com/dataarts/dat.gui"></script>
<script src="https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js"></script>
<script src="Final_project.js"></script>
<div id="info"></div>
</body>
</html>
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):
I've just started the book Games Development with Three.js (https://www.packtpub.com/game-development/game-development-threejs)
I have built an example (see code below).
It is supposed to show a cityscape. This displays just fine when viewed using Chrome (version 43.0.2357.124 m) on a Windows 7 machine. It also displays fine using Chrome on an Android tablet (version 43.0.2357.93).
However, when I try it from a Chromebook (version 43.0.2357.81 (stable-channel)), I just get a black page (and that is black as in "noir" not blank).
Can anyone suggest how I can get the Chromebook to display the city?
Part 1: HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script src="http://threejs.org/build/three.min.js"></script>
<script src="city.js"></script>
</body>
</html>
Part 2: JavaScript code "city.js"
// GLOBALS ======================================================
var camera, scene, renderer;
// SETUP ========================================================
function animate() {
draw();
update();
requestAnimationFrame( animate );
}
function setup() {
document.body.style.backgroundColor = '#d7f0f7';
setupThreeJS();
setupWorld();
requestAnimationFrame( animate );
}
function setupThreeJS() {
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x9db3b5, 0.002);
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.y = 400;
camera.position.z = 400;
camera.rotation.x = -45 * Math.PI / 180;
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMapEnabled = true;
document.body.appendChild( renderer.domElement );
}
function setupWorld() {
var geo = new THREE.PlaneGeometry(2000, 2000, 40, 40);
var mat = new THREE.MeshPhongMaterial({color: 0x9db3b5, overdraw: true});
var floor = new THREE.Mesh(geo, mat);
floor.rotation.x = -0.5 * Math.PI;
floor.receiveShadow = true;
scene.add(floor);
var geometry = new THREE.CubeGeometry( 1, 1, 1 );
geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, 0.5, 0 ) );
var material = new THREE.MeshPhongMaterial({overdraw: true, color: 0xcccccc});
var cityGeometry = new THREE.Geometry();
for (var i = 0; i < 300; i++) {
var building = new THREE.Mesh(geometry.clone());
building.position.x = Math.floor( Math.random() * 200 - 100 ) * 4;
building.position.z = Math.floor( Math.random() * 200 - 100 ) * 4;
building.scale.x = /**/Math.random()/*Math.pow(Math.random(), 2)/**/ * 50 + 10;
building.scale.y = /**/Math.random()/*Math.pow(Math.random(), 3)/**/ * building.scale.x * 8 + 8;
building.scale.z = building.scale.x;
THREE.GeometryUtils.merge(cityGeometry, building);
}
var city = new THREE.Mesh(cityGeometry, material);
city.castShadow = true;
city.receiveShadow = true;
scene.add(city);
var light = new THREE.DirectionalLight(0xf9f1c2, 1);
light.position.set(500, 1500, 1000);
light.castShadow = true;
light.shadowMapWidth = 2048;
light.shadowMapHeight = 2048;
var d = 1000;
light.shadowCameraLeft = d;
light.shadowCameraRight = -d;
light.shadowCameraTop = d;
light.shadowCameraBottom = -d;
light.shadowCameraFar = 2500;
scene.add(light);
}
// DRAW =========================================================
function draw() {
renderer.render( scene, camera );
}
// RUN ==========================================================
setup();
#Crush_157 I have faced a similar problem. I am using shaders from ShaderLib. Anyways, in my case I have 2 DirectionalLight on my scene. All works fine in most browsers/devices except on chromeOS. And guess what, If I remove one of the DirectionalLight, my objects start showing up :). Not sure why