OnDocumentMouseMove three.js not working - javascript

I am not at all experienced with three.js but I am trying to create a camera effect equal to this one: https://threejs.org/examples/#webgl_geometry_colors
I was trying to use the following code to read out the mouse positions and apply those, (they do it the same way in the example).
For the sake of trying to find out where the problem is I put in "camera.positon.x = 1000" to see if it works, which it does not. Now I don't know where the problem lies but I just can't get the mouse to work.
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
camera.position.x = 10000;
}
(I don't want to use Orbit Controls by the way)
Thanks in advance
Below is the entire code
<script>
var renderer, camera, controls, scene, mesh1, mesh2;
function init(){
renderer = new THREE.WebGLRenderer({canvas: document.getElementById('myCanvas'), antialias: true});
renderer.setClearColor(0x000044);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(15, window.innerWidth/window.innerHeight, 0.1, 3000);
camera.position.set(0,0,750);
resize();
window.onresize = resize;
var light = new THREE.AmbientLight(0xFFFFFF, 0.9);
scene.add(light);
var light2 = new THREE.PointLight(0xFFFFFF, 1);
scene.add(light2);
light2.position.set(0,8,75);
var geometry = new THREE.BoxGeometry(30, 30, 1);
var material = new THREE.MeshPhongMaterial({
color: 0xFF1111,
});
mesh1 = new THREE.Mesh(geometry,material);
mesh1.rotation.x = -0.05;
scene.add(mesh1);
mesh1.position.set(0,0,50);
var geometry = new THREE.BoxGeometry(30, 30, 1);
var material = new THREE.MeshPhongMaterial({
color: 0x11FF11,
});
mesh2 = new THREE.Mesh(geometry,material);
mesh2.rotation.x = -0.05;
scene.add(mesh2);
mesh2.position.set(0,0,0);
var geometry = new THREE.BoxGeometry(30, 30, 1);
var material = new THREE.MeshPhongMaterial({
color: 0x1111FF,
});
mesh3 = new THREE.Mesh(geometry,material);
mesh3.rotation.x = -0.05;
scene.add(mesh3);
mesh3.position.set(0,0, -50);
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
}
function resize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
camera.position.x = 10000;
}
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
camera.position.x += 0.5;
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
init(); render();
</script>

The variables windowHalfX and windowHalfY are not defined in your code.
If the position of the camera should depend on the mouse position, then you have to manipulate the camera position by the change of the mouse position. This means you have to calculate the difference of the current mouse position and the previous mouse position.
If you want to calculate a manipulation of the position, dependent on the position of the mouse in relation to the center of the canvas, then the code should look somehow like this:
var prevDeltaX = 0, prevDeltaY = 0;
function onDocumentMouseMove( event ) {
var mouseX = event.clientX;
var mouseY = event.clientY;
var deltaX = (window.innerWidth / 2 - mouseX);
var deltaY = (mouseY - window.innerHeight / 2);
camera.position.x += deltaX - prevDeltaX;
camera.position.y += deltaY - prevDeltaY;
prevDeltaX = deltaX; prevDeltaY = deltaY;
}
See the snippet:
var renderer, camera, controls, scene, mesh1, mesh2;
function init(){
renderer = new THREE.WebGLRenderer({canvas: document.getElementById('myCanvas'), antialias: true});
renderer.setClearColor(0x000044);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(15, window.innerWidth/window.innerHeight, 0.1, 3000);
camera.position.set(0,0,750);
resize();
window.onresize = resize;
var light = new THREE.AmbientLight(0xFFFFFF, 0.9);
scene.add(light);
var light2 = new THREE.PointLight(0xFFFFFF, 1);
scene.add(light2);
light2.position.set(0,8,75);
var geometry = new THREE.BoxGeometry(30, 30, 1);
var material = new THREE.MeshPhongMaterial({
color: 0xFF1111,
});
mesh1 = new THREE.Mesh(geometry,material);
mesh1.rotation.x = -0.05;
scene.add(mesh1);
mesh1.position.set(0,0,50);
var geometry = new THREE.BoxGeometry(30, 30, 1);
var material = new THREE.MeshPhongMaterial({
color: 0x11FF11,
});
mesh2 = new THREE.Mesh(geometry,material);
mesh2.rotation.x = -0.05;
scene.add(mesh2);
mesh2.position.set(0,0,0);
var geometry = new THREE.BoxGeometry(30, 30, 1);
var material = new THREE.MeshPhongMaterial({
color: 0x1111FF,
});
mesh3 = new THREE.Mesh(geometry,material);
mesh3.rotation.x = -0.05;
scene.add(mesh3);
mesh3.position.set(0,0, -50);
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
}
function resize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
var prevDeltaX = 0, prevDeltaY = 0;
function onDocumentMouseMove( event ) {
var mouseX = event.clientX;
var mouseY = event.clientY;
var deltaX = (window.innerWidth / 2 - mouseX);
var deltaY = (mouseY - window.innerHeight / 2);
camera.position.x += deltaX - prevDeltaX;
camera.position.y += deltaY - prevDeltaY;
prevDeltaX = deltaX; prevDeltaY = deltaY;
}
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
//camera.position.x += 0.5;
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
init(); render();
<script src="https://threejs.org/build/three.min.js"></script>
<canvas id="myCanvas"></canvas>

Related

Three.js: How to change "diffuseMap" and "roughnessMap" to "cubeMap"?

This is the code I would like to work with:
var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function() {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
const textureLoader = new THREE.TextureLoader();
const diffuseMap = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
const roughnessMap = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 1.0,
metalness: 0.5,
envMapIntensity: 5.0
});
child.material.envMap = newEnvMap;
child.material.map = diffuseMap;
child.material.roughnessMap = roughnessMap;
child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
new THREE.EXRLoader()
.setDataType(THREE.UnsignedByteType)
.load(
"https://threejs.org/examples/textures/piz_compressed.exr",
function(texture) {
exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
exrBackground = exrCubeRenderTarget.texture;
newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded
texture.dispose();
}
);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function(obj) {
object = obj;
}
);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, 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 onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
scene.background = exrBackground;
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/OBJLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/EXRLoader.js"></script>
Instead of the existing material, I would like to have a metallic material like here.
For this, I have tried to delete diffuseMap and roughnessMap, and add cubeMap.
That's my not working result:
var container;
var camera, scene, renderer;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function() {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
const textureLoader = new THREE.TextureLoader();
textureLoader.load('https://threejs.org/examples/textures/2294472375_24a3b8ef46_o.jpg', function(texture) {
texture.encoding = THREE.sRGBEncoding;
texture.mapping = THREE.EquirectangularReflectionMapping;
init(texture);
animate();
});
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 1.0,
metalness: 0.5,
envMapIntensity: 5.0
});
child.material.envMap = newEnvMap;
child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function(obj) {
object = obj;
}
);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, 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 onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/OBJLoader.js"></script>
The background should be transparent in the end, only the OBJ object should be visible.
Could somebody help me please? Would be soooo happy about it!
There's not much you need to change to make it metallic:
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 0.0, // <- roughness 0
metalness: 1.0, // <- metalness 1
envMapIntensity: 1.0
});
child.material.envMap = newEnvMap;
// Then you only need the envMap, remove the other stuff
//child.material.map = diffuseMap;
//child.material.roughnessMap = roughnessMap;
//child.material.needsUpdate = true;
And finally, if you don't want the background, remove it from the Render loop:
//scene.background = exrBackground;
Live demo:
var container;
var camera, scene, renderer;
let exrCubeRenderTarget, exrBackground;
let newEnvMap;
let torusMesh, planeMesh;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var object;
init();
animate();
function init() {
container = document.createElement("div");
container.className = "object";
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
1,
2000
);
camera.position.z = 250;
// scene
scene = new THREE.Scene();
scene.add(camera);
// manager
function loadModel() {
THREE.DefaultLoadingManager.onLoad = function() {
pmremGenerator.dispose();
};
// -----------------
function loadObjectAndAndEnvMap() {
const textureLoader = new THREE.TextureLoader();
const diffuseMap = textureLoader.load('https://threejs.org/examples/textures/brick_diffuse.jpg');
const roughnessMap = textureLoader.load('https://threejs.org/examples/textures/brick_roughness.jpg');
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material = new THREE.MeshStandardMaterial({
color: "#555",
roughness: 0.0,
metalness: 1.0,
envMapIntensity: 5.0
});
child.material.envMap = newEnvMap;
//child.material.map = diffuseMap;
//child.material.roughnessMap = roughnessMap;
//child.material.needsUpdate = true;
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
}
});
object.position.y = -90;
scene.add(object);
}
const pmremGenerator = new THREE.PMREMGenerator(renderer);
pmremGenerator.compileEquirectangularShader();
new THREE.EXRLoader()
.setDataType(THREE.UnsignedByteType)
.load(
"https://threejs.org/examples/textures/piz_compressed.exr",
function(texture) {
exrCubeRenderTarget = pmremGenerator.fromEquirectangular(texture);
exrBackground = exrCubeRenderTarget.texture;
newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
loadObjectAndAndEnvMap(); // Add envmap once the texture has been loaded
texture.dispose();
}
);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
}
var manager = new THREE.LoadingManager(loadModel);
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};
var loader = new THREE.OBJLoader(manager);
loader.load(
"https://threejs.org/examples/models/obj/female02/female02.obj",
function(obj) {
object = obj;
}
);
//
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
document.addEventListener("mousemove", onDocumentMouseMove, 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 onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}
//
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);
//scene.background = exrBackground;
renderer.toneMappingExposure = 1.0;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/OBJLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.125.2/examples/js/loaders/EXRLoader.js"></script>

How to make TextGeometry in THREE JS follow mouse?

This is my source code. I am trying to make the text rotate according to mouse position.
// Initialization
const scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
let renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
let body = document.getElementsByTagName("body");
let pageX = 0.5;
let pageY = 0.5;
renderer.setSize( window.innerWidth, window.innerHeight );
document.getElementById("board").appendChild(renderer.domElement);
// Handle resize event
window.addEventListener('resize', () => {
renderer.setSize( window.innerWidth, window.innerHeight );
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
camera.position.z = 20;
// Create light
let directLight = new THREE.DirectionalLight('#fff', 4);
directLight.position.set(0, 7, 5);
scene.add(directLight);
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
function animate (){
requestAnimationFrame( animate );
var loader = new THREE.FontLoader();
loader.load( 'https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Hello three.js!', {
font: font,
size: 3,
height: 0.5,
curveSegments: 4,
bevelEnabled: true,
bevelThickness: 0.02,
bevelSize: 0.05,
bevelSegments: 3
} );
geometry.center();
var material = new THREE.MeshPhongMaterial(
{ color: '#dbe4eb', specular: '#dbe4eb' }
);
var mesh = new THREE.Mesh( geometry, material );
mesh.rotation.x = (pageY - 0.5) * 2;
mesh.rotation.y = (pageX - 0.5) * 2;
scene.add( mesh );
} );
renderer.render(scene, camera);
}
animate();
// Get mouse coordinates inside the browser
document.body.addEventListener('mousemove', (event) => {
pageX = event.pageX / window.innerWidth;
pageY = event.pageY / window.innerHeight;
});
renderer.render(scene, camera);
</script>
This is the best I could get. The problem is that each time I move the mouse, it instantiates a new mesh and rotates it accordingly, and I only need one mesh to follow the mouse. Can anyone help?
Thanks in advance!
As you already figured out, each frame you're reloading the font and ultimately recreating the mesh each time.
To get around this you need to move the font loading and object creation inside some initialization function, so it just happens once.
The only part of code you want to keep inside the render loop is the updating of the text's rotation according to the mouse movement:
mesh.rotation.x = (pageY - 0.5) * 2;
mesh.rotation.y = (pageX - 0.5) * 2;
This will bring up another problem though. Since mesh is a local object defined inside the callback function of the font loader, it won't be accessible outside. Luckily three.js offers a property called .name which you can use to give your object a name.
e.g.
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "myText";
scene.add(mesh);
Later on you can get a reference to this object using:
scene.getObjectByName("myText")
Here's an example:
var container, scene, camera, renderer, pageX, pageY;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
pageX = 0.5;
pageY = 0.5;
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById("container").appendChild(renderer.domElement);
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
camera.position.z = 20;
let directLight = new THREE.DirectionalLight('#fff', 4);
directLight.position.set(0, 7, 5);
scene.add(directLight);
var light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
var loader = new THREE.FontLoader();
loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function(font) {
var geometry = new THREE.TextGeometry('Hello three.js!', {
font: font,
size: 3,
height: 0.5,
curveSegments: 4,
bevelEnabled: true,
bevelThickness: 0.02,
bevelSize: 0.05,
bevelSegments: 3
});
geometry.center();
var material = new THREE.MeshPhongMaterial({
color: '#dbe4eb',
specular: '#dbe4eb'
});
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "myText";
scene.add(mesh);
animate();
});
document.body.addEventListener('mousemove', (event) => {
pageX = event.pageX / window.innerWidth;
pageY = event.pageY / window.innerHeight;
});
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
scene.getObjectByName("myText").rotation.x = (pageY - 0.5) * 2;
scene.getObjectByName("myText").rotation.y = (pageX - 0.5) * 2;
renderer.render(scene, camera);
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r120/three.min.js"></script>
<div id="container"></div>

three.js - object look at mouse

Ok I understand it seems I did not try hard enough but I am really new to this
and I get no errors what so ever in Dreamweaver.
I deleted my old example and this is what I have now, trying to integrate
the look at function with the OBJ loader, camera and lights.
I think I understand what is happening more or less in the code,
but it's still not working, I assume it's because there is a code for
window resize but the look at function dose not take that into account,
thus it's not working since the function assume a fixed window size,
Am I right here?
Also I am not sure I need the two commented lines in the obj loader
object.rotateX(Math.PI / 2); and object.lookAt(new THREE.Vector3(0, 0, 0));
since this is just to get the starting position?
if I put these tow lines back, it will just rotate the object into an initial pose but the object will not turn relative to mouse position.
I am really not sure what is conflicting here
I changed the code now to this:
<script>
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var camera, scene;
var canvasRenderer, webglRenderer;
var container, mesh, geometry, plane;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1500);
camera.position.x = 0;
camera.position.z = 100;
camera.position.y = 0;
camera.lookAt({
x: 0,
y: 0,
z: 0,
});
scene = new THREE.Scene();
// LIGHTS
scene.add(new THREE.AmbientLight(0x666666, 0.23));
var light;
light = new THREE.DirectionalLight(0xffc1c1, 2.20);
light.position.set(0, 100, 0);
light.position.multiplyScalar(1.2);
light.castShadow = true;
light.shadowCameraVisible = true;
light.shadowMapWidth = 512;
light.shadowMapHeight = 512;
var d = 50000;
light.shadowCameraLeft = -d;
light.shadowCameraRight = d;
light.shadowCameraTop = d;
light.shadowCameraBottom = -d;
light.shadowcameranear = 0.5;
light.shadowCameraFar = 1000;
//light.shadowcamerafov = 30;
light.shadowDarkness = 0.1;
scene.add(light);
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( 'model/' );
mtlLoader.load( 'rope.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'model/' );
objLoader.load( 'rope.obj', function ( object ) {
var positionX = 0;
var positionY = 0;
var positionZ = 0;
object.position.x = positionX;
object.position.y = positionY;
object.position.z = positionZ;
object.scale.x = 1;
object.scale.y = 1;
object.scale.z = 1;
//object.rotateX(Math.PI / 2);
//object.lookAt(new THREE.Vector3(0, 0, 0));
// castshow setting for object loaded by THREE.OBJLoader()
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.castShadow = true;
child.receiveShadow = true;
}
});
scene.add(object);
});
});
// RENDERER
//webglRenderer = new THREE.WebGLRenderer();
webglRenderer = new THREE.WebGLRenderer({
antialias: true
});
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
webglRenderer.domElement.style.position = "relative";
webglRenderer.shadowMapEnabled = true;
webglRenderer.shadowMapSoft = true;
//webglRenderer.antialias: true;
container.appendChild(webglRenderer.domElement);
window.addEventListener('resize', onWindowResize, false);
}
window.addEventListener("mousemove", onmousemove, false);
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 0), 0);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersectPoint = new THREE.Vector3();
function onmousemove(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
raycaster.ray.intersectPlane(plane, intersectPoint);
object.lookAt(intersectPoint);
}
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
webglRenderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.lookAt(scene.position);
webglRenderer.render(scene, camera);
}
</script>
I took your code and adapted so it doesn't require a obj and put it into this codepen. The main problem seems to be that your intersection plane was defined incorrectly. The first argument is the normal vector which needs to be of length 1. Yours is 0. Therefore there are no meaningful intersections.
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 0), 0);
If you change it to
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 10);
the intersections are more meaningful and the object actually rotates.

How to control fps with requestAnimationFrame?

I have used FBX format with three js. It seems like requestAnimationFrame is the de facto way to animate things now. The animation was working very speed, Like lightening. Can't find any solutions to control the fps.
See the below image.
Source code:
if (!Detector.webgl)
Detector.addGetWebGLMessage();
var container, stats, controls;
var camera, scene, renderer, light, mesh;
var clock = new THREE.Clock();
var mixers = [];
var mouseX = 0, mouseY = 0;
var spdx = 0, spdy = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 2000);
scene = new THREE.Scene();
// grid
var gridHelper = new THREE.GridHelper(28, 28, 0x303030, 0x303030);
gridHelper.position.set(0, -0.04, 0);
scene.add(gridHelper);
// stats
stats = new Stats();
container.appendChild(stats.dom);
// model
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var onProgress = function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}
};
var onError = function (xhr) {
console.error(xhr);
};
var loader = new THREE.FBXLoader(manager);
loader.load('assests/JetEngine_Ani.fbx', function (object) {
object.mixer = new THREE.AnimationMixer(object);
mixers.push(object.mixer);
var action = object.mixer.clipAction(object.animations[ 0 ]);
action.play();
scene.add(object);
}, onProgress, onError);
renderer = new THREE.WebGLRenderer({alpha: true});
renderer.setClearColor(0xdddddd, 1);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0, 12, 0);
camera.position.z = 850;
controls.update();
window.addEventListener('resize', onWindowResize, false);
light = new THREE.HemisphereLight(0xffffff, 0x444444, 1.0);
light.position.set(0, 1, 0);
scene.add(light);
light = new THREE.DirectionalLight(0xffffff, 1.0);
light.position.set(0, 1, 0);
scene.add(light); }
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;
mouseY = event.clientY;
}
function animate() {
requestAnimationFrame(animate);
if (mixers.length > 0) {
for (var i = 0; i < mixers.length; i++) {
mixers[ i ].update(clock.getDelta());
}
}
stats.update();
render();
}
function render() {
renderer.render(scene, camera);
}
How to control the animation speed. Is there have other ways or only through fps(frames per second).
How can I reduce the animation speed??..
You want to control the duration of your AnimationAction loop. To do so, you can use this pattern:
action.setDuration( 10 ).play();
three.js r.87

How to click and slide into three js cube?

i have this code which works nice and i want to add a situation that when i click on the red cube all the page "jump" closer to the cube. (maybe the camera ?).
i do not have any idea and i will hope you can help me.
In general, i want to learn how to click in one object in three js and move into a second object in my page.
this is my code :
<html>
<head>
<script src="js/three.js"></script>
</head>
<body>
<script>
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(document.body.clientWidth, document.body.clientHeight);
document.body.appendChild(renderer.domElement);
renderer.setClearColorHex(0xEEEEEE, 1.0);
renderer.clear();
renderer.shadowCameraFov = 50;
renderer.shadowMapWidth = 1024;;
renderer.shadowMapHeight = 1024;
var fov = 45; // camera field-of-view in degrees
var width = renderer.domElement.width;
var height = renderer.domElement.height;
var aspect = width / height; // view aspect ratio
var near = 1; // near clip plane
var far = 10000; // far clip plane
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = -400;
camera.position.x = 200;
camera.position.y = 350;
var scene = new THREE.Scene();
var cube = new THREE.Mesh(
new THREE.CubeGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({ color: 0xff0000 })
);
scene.add(cube);
cube.castShadow = true;
cube.receiveShadow = true;
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(400, 200, 10, 10),
new THREE.MeshLambertMaterial({ color: 0xffffff }));
plane.rotation.x = -Math.PI / 2;
plane.position.y = -25.1;
plane.receiveShadow = true;
scene.add(plane);
var light = new THREE.SpotLight();
light.castShadow = true;
light.position.set(170, 330, -160);
scene.add(light);
var litCube = new THREE.Mesh(
new THREE.CubeGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({ color: 0xffffff }));
litCube.position.y = 50;
litCube.castShadow = true;
scene.add(litCube);
renderer.shadowMapEnabled = true;
renderer.render(scene, camera);
var paused = false;
var last = new Date().getTime();
var down = false;
var sx = 0, sy = 0;
window.onmousedown = function (ev) {
down = true; sx = ev.clientX; sy = ev.clientY;
};
window.onmouseup = function () { down = false; };
window.onmousemove = function (ev) {
if (down) {
var dx = ev.clientX - sx;
var dy = ev.clientY - sy;
camera.position.x += dx;
camera.position.y += dy;
sx += dx;
sy += dy;
}
}
function animate(t) {
if (!paused) {
last = t;
litCube.position.y = 60 - Math.sin(t / 900) * 25;
litCube.position.x = Math.cos(t / 600) * 85;
litCube.position.z = Math.sin(t / 600) * 85;
litCube.rotation.x = t / 500;
litCube.rotation.y = t / 800;
renderer.clear();
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
window.requestAnimationFrame(animate, renderer.domElement);
};
animate(new Date().getTime());
onmessage = function (ev) {
paused = (ev.data == 'pause');
};
</script>
</body>
</html>
waiting for your replay,
thanks :)
You need to implement different and separated parts to do this:
Selecting an object can be done by using a Raycaster, you'll find many examples here on SO and in the three.js examples such as this one
Orienting the camera - see camera.lookAt( target.position ) - and zooming can be done in many ways, but you might want to use a kind of Control to ease the camera placement process, such as one of these. The TrackballControls for example seems appropriate.
One last bit, as your title says "sliding", is how the "camera jump" is done. If you want a smooth zoom, you'll need a kind of easing function. Have a look on Tween.js for this.
vincent wrote an excellent answer. I just want to add an example to help to understand.
Jsfiddle
<script>
var container, stats;
var camera, scene, projector, raycaster, renderer, selected;
var target, zoom=false;
var mouse = new THREE.Vector2(), INTERSECTED;
var radius = 100, theta = 0;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
scene = new THREE.Scene();
var light = new THREE.DirectionalLight( 0xffffff, 2 );
light.position.set( 1, 1, 1 ).normalize();
scene.add( light );
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( -1, -1, -1 ).normalize();
scene.add( light );
var geometry = new THREE.CubeGeometry( 20, 20, 20 );
var cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F3B557' } ) );
cube.rotation = new THREE.Euler(0,Math.PI/4,0);
cube.position = new THREE.Vector3(-20,0,0);
scene.add(cube);
cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F05B47' } ) );
cube.rotation = new THREE.Euler(0,Math.PI/4,0);
cube.position = new THREE.Vector3(20,0,0);
scene.add(cube);
projector = new THREE.Projector();
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
renderer.domElement.addEventListener( 'mousedown', onCanvasMouseDown, false);
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
// set lookAt position according to target position
if(target){
camera.lookAt( target.position );
}else{
camera.lookAt(new THREE.Vector3(0,0,0));
}
//zoom in and out
if(zoom && camera.fov>10){
camera.fov-=1;
camera.updateProjectionMatrix();
}else if(!zoom && camera.fov<70){
camera.fov+=1;
camera.updateProjectionMatrix();
}
camera.position = new THREE.Vector3(0,100,100);
// find intersections
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = intersects[ 0 ].object;
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex( 0xff0000 );
}
} else {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = null;
}
renderer.render( scene, camera );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
//detect selected cube
function onCanvasMouseDown( event ){
if(INTERSECTED){
target = INTERSECTED;
zoom = true;
}else{
zoom = false;
}
}
</script>

Categories

Resources