Three.js add a rotating camera - javascript

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();

Related

Three.js: Smoothing normals on non indexed BufferGeometry

I'm trying to smooth the normals of a mesh starting from a non indexed BufferGeometry.
This question has been answered before however the Three.js api has changed substantially since and I can't get it to work on r130
From what I've understood, I need to first merge the vertices to get an indexed BufferGeometry then re-compute the normals, but it doesn't seem to work.
Here is a minimal example using the defaulf cube :
// Scene
const scene = new THREE.Scene();
// Geometry
const boxGeometry = new THREE.BoxGeometry(.7,.7,.7);
// Materials
const shadedMaterial = new THREE.MeshStandardMaterial();
shadedMaterial.metalness = 0.4;
shadedMaterial.roughness = 0.4;
shadedMaterial.color = new THREE.Color(0xffffff);
// Mesh
const smoothBoxGeometry=BufferGeometryUtils
.mergeVertices(new THREE.BufferGeometry().copy(boxGeometry))
smoothBoxGeometry.computeVertexNormals();
smoothBoxGeometry.computeBoundingBox();
smoothBoxGeometry.normalizeNormals();
const box = new THREE.Mesh(smoothBoxGeometry, shadedMaterial);
scene.add(box);
flat shaded cube instead of expected smooth shaded cube
What am I missing ?
Try it like so:
let camera, scene, renderer;
let mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 4;
scene = new THREE.Scene();
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
hemiLight.position.set(0, 20, 0);
scene.add(hemiLight);
const dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(-3, 10, -10);
scene.add(dirLight);
let geometry = new THREE.BoxGeometry();
geometry.deleteAttribute('normal');
geometry.deleteAttribute('uv');
geometry = THREE.BufferGeometryUtils.mergeVertices(geometry);
geometry.computeVertexNormals();
const material = new THREE.MeshStandardMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.130.1/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.130.1/examples/js/utils/BufferGeometryUtils.js"></script>
BufferGeometryUtils.mergeVertices() can only perform the merge if vertex data are identical. To ensure this, it is necessary to remove the existing normal and uv attribute.

Three.Js positioning problem and coneGeometry error

I am trying to build a rocketship model by add different shapes to a large group and position them at specific axis.
When I try to use
rocketConeMesh.position.y = 15;
The shape does not move at all, I am trying to put the rocketCone (The nose of the rocket ship) on top of the rocketBody and then have them under the same group.
I get the followig error message
"THREE.Object3D.add: object not an instance of THREE.Object3D. "
for the coneGeometry object.
my code is as follows:
<script type="text/javascript">
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', function()
{
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
} );
controls = new THREE.OrbitControls(camera, renderer.domElement);
// create the object group that contains all the sub-shapes
var rocketGroup = new THREE.Object3D();
scene.add(rocketGroup);
//The object below is the top cone of the rocket
var rocketCone = new THREE.ConeGeometry(6, 10, 6);
var material = new THREE.MeshBasicMaterial({color: 0xcccccc, wireframe: true});
var cone = new THREE.Mesh(rocketCone, material);
rocketConeMesh = new THREE.Mesh(rocketCone,new THREE.MeshPhongMaterial())
scene.add(cone);
//Specify the position of the rocket cone
rocketConeMesh.position.y = 15;
//Add the rocketCone to the lowpolyRocket group
rocketGroup.add(rocketCone);
/******************************************************************************************************************/
//var rocketBody = new THREE.CylinderGeometry( 5, 5, 20, 32 );
//var material = new THREE.MeshBasicMaterial({color: 0xcccccc, wireframe:false});
//var cylinder = new THREE.Mesh(rocketBody, material);
//scene.add(cylinder);
// position and point the camera to the center of the scene
camera.position.x = -30;
camera.position.y = 20;
camera.position.z = 30;
camera.lookAt(scene.position);
// game logic
var update = function ( )
{
//cone.rotation.x += 0.01;
//cone.rotation.y += 0.005;
};
// draw scene
var render = function ( )
{
renderer.render(scene, camera);
};
// run game loop (update, render, repeat)
var GameLoop = function ( )
{
requestAnimationFrame(GameLoop);
update( );
render( );
};
GameLoop( );
</script>
rocketGroup.add(rocketCone);
This code is not valid since it's not possible to add an instance of ConeGeometry to an Object3D. Try to change your code to the following:
rocketGroup.add(rocketConeMesh);
Now you add the mesh (which is derived from THREE.Object3D) to rocketGroup. It's now part of the scene graph and changing its transformation should work.
BTW: I don't understand why you create two meshes with your rocketCone geometry. I guess you can remove the cone variable.

How to create a 3D star view in three.js given the x,y and z coordinates?

I am trying to create a 3d star view, with a movable camera to traverse stars (js objects) using three.js. In searching for something to get me going/started, I found some code (below) and modified it to what seemed 'logically' correct. The code:
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 500);
camera.position.set(0, 0, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));
var scene = new THREE.Scene();
var geometry = new THREE.Geometry();
// Starlist contains 1600+ stars
for (var i=0;i<oldstarlist.length;i++)
{
// Convert RA/DEC to x,y,z coordinates
var s0 = new Star(oldstarlist[i]['starname'], oldstarlist[i]['constellation'], oldstarlist[i]['RA'], oldstarlist[i]['DEC'], oldstarlist[i]['lightyears']);
var star = new THREE.Vector3();
star.x = s0.coordinates.X;
star.y = s0.coordinates.Y;
star.z = s0.coordinates.Z;
console.log(star.x,star.y,star.z);
geometry.vertices.push( star );
}
var starsMaterial = new THREE.PointsMaterial( { color: 0x888888 } );
var starField = new THREE.Points( geometry, starsMaterial );
scene.add( starField );
renderer.render(scene, camera);
I presumed the 'Points' was correct, and I am still not sure where to place the camera. To be sure, I checked around for any examples and tutorials I could find but found nothing similar to what I am looking for.
A working example can be found on my test site area at this address:
http://theangelfallseries.com/stars/sp/test3js.html
Any help is appreciated.

Three.js wont render on canvas

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);

THREE.js Triangle is Black

So i was using THREE.JS and created a triangle. But even though i gave it color: 0xFF0000, it appears black on Screen.
Here is my Script:
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);
var geometry = new THREE.Geometry(200,200,200);
var v1 = new THREE.Vector3(200,0,0); // Vector3 used to specify position
var v2 = new THREE.Vector3(-100,0,0);
var v3 = new THREE.Vector3(0,50,0); // 2d = all vertices in the same plane.. z = 0
// Push vertices represented by position vectors
geometry.vertices.push(v1);
geometry.vertices.push(v2);
geometry.vertices.push(v3);
// Push face, defined with vertices in counter clock-wise order
geometry.faces.push(new THREE.Face3(0, 2, 1));
// Create a material and combine with geometry to create our mesh
var redMat = new THREE.MeshLambertMaterial({color: 0xFF0000});
var triangle = new THREE.Mesh(geometry, redMat);
scene.add(triangle);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
Hope you can find the mistake i made. I am sure it's just something really stupid.
late to the party...but for all who come after me.
The issue here is the type of material used
change
new THREE.MeshLambertMaterial({color: 0xFF0000});
to
new THREE.MeshBasicMaterial({color: 0xFF0000});
and it will show up red
Even I've struggled from this problem for sometime. The solution for me was to add an ambient light to the scene if you're using Lambert Material.
Just add:
var light = new THREE.AmbientLight(0xffffff);
scene.add(light);
Try add computeFaceNormals call upon geometry object:
geometry.computeFaceNormals();
*from https://stackoverflow.com/a/49226898/2154075

Categories