I am trying to rotate the model. However, I have no idea why my model is not rotating because there is no error shown on the developer tools. Therefore I can not identify what causes the error. I might be missing something in my code but I'm not sure where about. Please, if anyone has any solution on this, thank you for your advice.
let scene, camera, renderer, controls, car;
function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 5000);
camera.rotation.y = 45 / 180 * Math.PI;
camera.position.x = 40;
camera.position.y = 0;
camera.position.z = 40;
hlight = new THREE.AmbientLight(0x404040, 0.001);
scene.add(hlight);
directionalLight = new THREE.DirectionalLight(0x333333, 10);
directionalLight.position.set(1, 1, 0);
directionalLight.castShadow = true;
scene.add(directionalLight);
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener('change');
let loader = new THREE.GLTFLoader();
loader.load('./5/3D_model.gltf', function (gltf) {
car = gltf.scene.children[0];
car.scale.set(10, 10, 10);
scene.add(gltf.scene);
renderer.render(scene, camera);
animate();
});
}
function animate() {
if (car) car.rotation.y += 0.3;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
animate();
There are a couple of issues in your code:
You are setting an undefined event listener to the change event of OrbitControls. Please remove this line.
You start the animation loop twice. Remove one call of animate();.
Rotating the asset 0.3 per animation step is quite a lot. The model might rotate so fast that you don't see it. Use 0.01 for now.
The intensity of the directional light is too high. Just use the default value for now. Besides, setting castShadow to true has no effect with your current scene setup.
Related
I'm rotating a PerspectiveCamera with orbitControls around an object. Now I want to move the camera closer to the object but keep the actual rotation.
My coordinate to set the distance to the objects are output as [0,0,100].
But my CameraPosition is [-500, 96, 1772]. How can I keep the "rotation" but move the camera closer to the object to a distance of 100.
Do I need to use getAzimuthalAngle() or getPolarAngle()?
For example, like this, if you object is not in the center of a scene:
camera.position.sub(obj.position).setLength(100).add(obj.position);
If the object is in the center:
camera.position.setLength(100);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(25, 0, 100);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
scene.add(new THREE.GridHelper(100, 100));
var obj = new THREE.Mesh(new THREE.CubeGeometry(10, 10, 10), new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
}));
obj.position.set(25, 0, 0);
scene.add(obj);
controls.target.copy(obj.position);
controls.update();
stepCloser.addEventListener("click", onClick, false);
function onClick() {
camera.position.sub(obj.position).setLength(100).add(obj.position);
}
render();
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<button id="stepCloser" style="position: absolute;">
100 units to the object
</button>
this will work. I was trying to load the GLTF model through this code snippet.
loader.load('./demo-models/model-1/scene.gltf', function (gltf) {
gltf.position.x -= 60
scene.add(gltf.scene);
});
But that didn't work out. So after debugging for a while, I realized I could play around with some parameters of the Perspective Camera. Well initially the first argument was 75 units which made my object way too far from the screen, I had to zoom in until I could get a clear view. Some code tweaks, it works the best when I set it to 1.
var camera = new THREE.PerspectiveCamera(1, window.innerWidth / window.innerHeight, 0.1, 1000);
I'm new to three js and webgl. I have a complicated solar system I'm building and it all works great until I want to animate anything. Here is a very stripped down version to show the problem (with sun in low res). If I add the line sun.rotate.y += 1; it wont load or run anything at all. I have looked around a lot and can't figure out why. I'm sure it is something stupid I'm missing. Thanks for any help.
<script>
// SETUP SCENE
var camera, controls, scene, renderer;
var container
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 90000 );
camera.position.z = 100;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = .2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = true;
controls.staticMoving = false;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
scene = new THREE.Scene();
// ADD THE SUN PHYSICAL LOCATION
var geometry = new THREE.SphereGeometry(5, 3, 3, 0, Math.PI * 2, 0, Math.PI * 2);
var material = new THREE.MeshBasicMaterial({color: "Yellow"});
var sun = new THREE.Mesh(geometry, material);
scene.add(sun);
//RENDER
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.getElementById( 'container' );
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
render();
animate();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
render();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
render();
}
function render() {
sun.rotate.y +=1; // Problem animating?
renderer.render( scene, camera );
}
</script>
You need to define sun as a global variable because currently it is not visible in the render() scope.
Also, I think to rotate a mesh you call "rotateX(), rotateY() or rotateZ()" so it is sun.rotateY(0.01)
Edit: I realized you can rotate the mesh by modifying its rotation rather than its rotate property.
You have a scope issue ( well it's complicated depending on what you are using es6 or es5), these are the offending bits:
Declare your global(or not Js will add it) to the global space :
var container, sun;
And refer to it inside the init function:
this.sun = new THREE.Mesh(geometry, material);
Working Pen:
Scope Issue in Three.js
Also, TrackballControls is not part of Three.js, you have to import it, check the pen.
Also, Also,for the rotation you might want to use:
sun.rotation.y += 0.003;
jsfiddle: http://jsfiddle.net/VsWb9/2151/
After a reading a few articles i am at a loss.
Rotate camera around object with Three.js
Below is simple code for a cube rotating with a floor. This should hopefully be a simple example to follow.
I am trying to add a camera so on click and drag it rotates around the scene. Similar to this http://threejs.org/examples/#misc_controls_trackball
For anyone with the same quesiton lets get you to my point below:
Download three.js here:
http://threejs.org/
You need to have something call orbit controls in your js folder. You will find a link to orbitcontrols to download here:
https://dl.dropboxusercontent.com/u/3587259/Code/Threejs/OrbitControls.js
Copy this and put it in your site folder.
You then need to link to orbit control and three.js it in your html. Like the below:
<script src="js/OrbitControls.js"></script>
<script src="js/three.min.js"></script>
Then see below for a simple wireframe cube with a floor.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 0.1, 1000);
var axisHelper = new THREE.AxisHelper( 5 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//This breaks it?
//controls = new THREE.OrbitControls( camera, renderer.domElement );
var geometry = new THREE.CubeGeometry(2,1,1);
var material = new THREE.MeshBasicMaterial({wireframe: true});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var floorMaterial = new THREE.MeshBasicMaterial( {wireframe: true} );
var floorGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
var floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.position.y = -50.0;
floor.rotation.x = Math.PI / 2;
scene.add(floor);
camera.position.z = 3;
var render = function () {
requestAnimationFrame(render);
cube.rotation.z += 0.005;
cube.rotation.x += 0.005;
renderer.render(scene, camera);
};
render();
I'm adding sprites in a 3d scene using three.js and I want to know distance between the camera and sprite when I click on screen. So I use a Raycater.
But if I click on the sprite, the distance property of intersection object is always "wrong" (someting like 0.3), or maybe I don't know how to read and understand the result. I thought "distance" value of intersection is the distance from camera to sprite (so, in my case something like 5).
Here is a shortened version of my code :
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sprite = new THREE.Sprite(new THREE.SpriteMaterial({color: 0x00ff00}));
scene.add(sprite);
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
render();
window.addEventListener('mousedown', function (e) {
if (e.target == renderer.domElement) {
var vector = new THREE.Vector3((e.clientX / window.innerWidth) * 2 - 1, -(e.clientY / window.innerHeight) * 2 + 1, 0.5);
var projector = new THREE.Projector();
projector.unprojectVector(vector, camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects([sprite]);
console.log(intersects[0]);
}
}, false);
You can see it in action here : http://jsfiddle.net/pWr57/
So how can I have the distance form camera to a sprite ?
three.js r66
Do this, instead
console.log( raycaster.ray.origin.distanceTo( intersects[0].point ) );
Tip: Read the source code, Raycaster.js, so you know what it is doing. It is currently returning the perpendicular distance from the sprite center to the ray.
In this case, I agree that it would be better to return the distance from the camera.
three.js r.66
I loaded the script in index.html but when I open the page it shows the rendered but nothing inside, nothing renderer, I can't find the problem
Here is the code of external .js:
var wdt = $('.design').width();
var hgh = $('.design').height();
var scene = new THREE.Scene();
var camera = new THREE.Camera(75, wdt/hgh, 0.1, 1000);
var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(wdt, hgh);
document.getElementById('designer').appendChild(renderer.domElement);
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
Can anybody help please?
Camera issues
Here's a jsfiddle of a working version.
Camera in Three.js is abstract, so I picked the common one to construct:
var camera = new THREE.PerspectiveCamera (75, wdt / hgh, 0.1, 1000);
The camera's viewpoint doesn't line up by default, so explicit calls eliminate confusion:
camera.lookAt(cube.position);
And adding the camera to the scene:
scene.add(camera);