How does one go about creating an ellipse in three.js?
I've looked at this:
Drawing an ellipse in THREE.js
But it would be cool if someone could provide a working example.
I've tried this:
ellipse = new THREE.EllipseCurve(0,0,200,400,45,45,10);
but that's not working for me. I have no idea what the parameters mean so I'm just blindly going about it.
edit: I am getting the error "defined is not a function" when I try to create an ellipse curve.
edit2: Figured out I had to include Curves.js for it to work but having a working example somewhere would still be really nice for me and other people since the stackoverflow link I pasted earlier doesn't have an example.
I am unfamiliar with THREE.js, but looking at the code the parameters seem to be
(Center_Xpos, Center_Ypos, Xradius, Yradius, StartAngle, EndAngle, isClockwise)
so a reason your definition isn't working is because you're setting the start and end angles both to the same thing.
There is an example here, and below is my example:
var scene = new THREE.Scene();
var material = new THREE.LineBasicMaterial({color:0x000000, opacity:1});
var ellipse = new THREE.EllipseCurve(0, 0, 1, 5, 0, 2.0 * Math.PI, false);
var ellipsePath = new THREE.CurvePath();
ellipsePath.add(ellipse);
var ellipseGeometry = ellipsePath.createPointsGeometry(100);
ellipseGeometry.computeTangents();
var line = new THREE.Line(ellipseGeometry, material);
scene.add( line );
Notice: this is not a complete example, you should add the rest code like <script src="js/three.min.js"></script> if you want to view the result.
You can directly set a circle geometry and set its scale as: object.scale.setY(2.5);
This could easily form an oval without using any shape or curve.
Here is a complete working example.
<!doctype html>
<html>
<head>
<title>example</title>
<script src="threejs/build/three.min.js"></script>
<script src="threejs/src/core/Curve.js"></script>
<script src="threejs/examples/js/controls/OrbitControls.js"></script>
</head>
<body>
<script>
var parent, renderer, scene, camera, controls, pivot1, pivot2, pivot3;
init();
animate();
function init() {
// info
info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '30px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.style.color = '#fff';
info.style.fontWeight = 'bold';
info.style.backgroundColor = 'transparent';
info.style.zIndex = '1';
info.style.fontFamily = 'Monospace';
info.innerHTML = 'Drag your cursor to rotate camera';
document.body.appendChild( info );
// renderer
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.physicallyBasedShading = true;
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 0.1, 100 );
camera.position.set( 20, 20, 20 );
// controls
controls = new THREE.OrbitControls( camera );
// axes
scene.add( new THREE.AxisHelper( 20 ) );
var material = new THREE.LineBasicMaterial({color:0x000000, opacity:1});
var ellipse = new THREE.EllipseCurve(0, 0, 1, 4, 0, 2.0 * Math.PI, false);
var ellipsePath = new THREE.CurvePath();
ellipsePath.add(ellipse);
var ellipseGeometry = ellipsePath.createPointsGeometry(100);
ellipseGeometry.computeTangents();
var line = new THREE.Line(ellipseGeometry, material);
scene.add( line );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
</script>
</body>
</html>
Related
I'm new to three.js and need to make a project for school. For this project I need a texture on my cube. But the screen stays black.. and there are no console errors! I did everything I can so this is kinda my last change haha.
My code:
<script src="js/three.min.js"></script>
<script>
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 geometry = new THREE.BoxGeometry( 1, 1, 1 );
// +
var material = new THREE.MeshLambertMaterial({
map: THREE.ImageUtils.loadTexture('images/crate2.jpg')
})
// =
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.05;
renderer.render(scene, camera);
};
render();
</script>
You do not have a light in your scene.
Adding one like below should work
// Create ambient light and add to scene.
var light = new THREE.AmbientLight(0xffffff); // white light
scene.add(light);
I would add a link to a js fiddle but it seems they have changed and I can not longer find where to get the link.
Anyway, just ad some sort of light.
Perhaps adding a light would help? That or try using THREE.MeshBasicMaterial
I am trying to customize a shape by a slider, and then the shape is extruded by ExtrudeGeometry. First, I created 4 points as in "pts", and then created a "shape" with them, and finally, created a geomtery by extrude it through a line. However, I cannot make it works. My HTML code is as below:
<head>
<script src="three.min.js"> </script>
<script src="three.js"> </script>
<script src="TrackballControls.js"></script>
<script src="main.js"> </script>
</head>
<body onload="start()">
<div id="s"> </div>
</body>
</html>
and the "main" js file is as follows:
var camera, scene, renderer, phone, material, mesh;
var shape, extrudeSettings, randomSpline, controls;
var pts = [];
var randomPoints = [];
var v;
function start() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,1,10000);
camera.position.set( 0, 0, 500 );
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0x222222 );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.minDistance = 100;
controls.maxDistance = 600;
scene.add(camera);
pts.push( new THREE.Vector3 (100,1,0));
pts.push( new THREE.Vector3 (-100,1,0));
pts.push( new THREE.Vector3 (-100,-1,0));
pts.push( new THREE.Vector3 (100,-1,0));
randomPoints.push( new THREE.Vector3 (0,0,10));
randomPoints.push( new THREE.Vector3 (0,0,-10));
randomSpline = new THREE.SplineCurve3( randomPoints );
extrudeSettings = {
steps : 200,
bevelEnabled : false,
extrudePath : randomSpline
};
shape = new THREE.Shape(pts);
phone = new THREE.ExtrudeGeometry(shape, extrudeSettings);
material = new THREE.MeshBasicMaterial({color:0x0000FF, wireframe:true});
mesh = new THREE.Mesh(phone,material);
scene.add(mesh);
var slider = document.createElement("input");
slider.setAttribute("type", "range");
slider.setAttribute("value", 90);
slider.setAttribute("id", "sliding");
document.getElementById("s").appendChild(slider);
document.getElementById("s").style.position = "absolute";
document.getElementById("s").style.zIndex="1";
animate();
}
function animate() {
requestAnimationFrame(animate);
v = document.getElementById("sliding").value;
pts[0].x = v;
pts[1].x = -v;
pts[2].x = -v;
pts[3].x = v;
shape.needsUpdate = true;
phone.verticesNeedUpdate = true;
phone.dynamic=true;
controls.update();
renderer.render( scene, camera );
}
When you create an ExtrudeGeometry, it creates the geometry based on the parameter, but it doesn't store the object you created it from. You'll need to create a new ExtrudeGeometry each time you want to update it, or you may be able to simply adjust phone.scale, depending on your needs.
I'm just beginning to experiment with THREE.js. I'm trying different combinations of renderers and cameras.
I can render a simple animation using the WebGLRenderer and the OrthographicCamera or the CanvasRenderer and the PerspectiveCamera. But if I use the CanvasRenderer with the OrthographicCamera I don't see any image rendered.
Should the CanvasRenderer work with the OrthographicCamera? Fiddles that work are here:
http://jsfiddle.net/PXxLq/ - WebGL/Orthographic - OK
http://jsfiddle.net/fXsKq/ - Canvas/Perspective - OK
This is the code that fails:
<html>
<head>
<script src="https://raw.github.com/mrdoob/three.js/master/build/three.js"></script>
</head>
<body>
<script>
SCREEN_WIDTH = 200;
SCREEN_HEIGHT = 200;
var ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 1000;
var scene = new THREE.Scene();
// PerspectiveCamera good with CanvasRenderer
//var camera = new THREE.PerspectiveCamera(75, ASPECT, NEAR, FAR);
var camera = new THREE.OrthographicCamera( -SCREEN_WIDTH / 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, -SCREEN_HEIGHT / 2, NEAR, FAR );
var renderer = new THREE.CanvasRenderer();
// WebGLRenderer good with OrthographicCamera
//var renderer = new THREE.WebGLRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.CubeGeometry(50,50,50);
var material = new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 100;
function render() {
requestAnimationFrame(render);
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
render();
</script>
</body>
</html>
For CanvasRenderer, when using OrthographicCamera, the near plane must be negative.
This appears to be a bug.
EDIT: This bug has been fixed. The near plane should always be positive now.
three.js r.55
Reference : WebGLRenderer() & PerspectiveCamera()
List item
<script src="build/three.min.js"></script>
<script>
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 geometry = new THREE.BoxGeometry( 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();
</script>
I want to create a skydome and made the shpere, texture loading also fine but I cannot move the camera inside the sphere.
The sphere disappears. I know it is an amateur issue but cannot see the inside of the sphere.
Is it some kind of cutting or Z-buffer issue?
How can I fix it?
My code:
<html>
<head>
<script src="js/jquery-1.8.3.min.js"></script>
<script src="js/three.min.js"></script>
</head>
<body>
<div id="container">
</div>
<script>
function addSpaceSphere( ){
// set up the sphere vars
var radius = 200,
segments = 16,
rings = 16;
var material = new THREE.MeshPhongMaterial({
color:0xFFFFFF,
map: THREE.ImageUtils.loadTexture( 'textures/SPACE014SX.png' )
});
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(
radius,
segments,
rings
),
material
);
// add the sphere to the scene
scene.add(sphere);
}
function addLights(){
// create a point light
var ambient = new THREE.AmbientLight( 0xFFFFFF );
scene.add( ambient );
}
function render() {
camera.lookAt( focus );
camera.updateProjectionMatrix();
renderer.render( scene, camera );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function createScene(){
// add the camera to the scene
scene.add(camera);
// the camera starts at 0,0,0
// so pull it back
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 300;
// start the renderer
renderer.setSize(WIDTH, HEIGHT);
$container.append(renderer.domElement);
addSpaceSphere( );
addLights();
animate();
}
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.01,
FAR = 10000;
var focus = new THREE.Vector3( 0, 0, 0 );
var isUserInteracting = false,
onPointerDownPointerX = 0, onPointerDownPointerY = 0,
lon = 0, onPointerDownLon = 0,
lat = 0, onPointerDownLat = 0,
phi = 0, theta = 0;
var $container = $('#container');
// create a WebGL renderer, camera
// and a scene
//var renderer = new THREE.CanvasRenderer();
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
VIEW_ANGLE, ASPECT, NEAR, FAR
);
var scene = new THREE.Scene();
createScene();
</script>
</body>
make the skydome material double-sided -- it's being culled. Set the 'side' attribute to THREE.DoubleSide
(or THREE.BackSide should work too, if the camera is ONLY inside the sphere)
I'm struggleing with texture load issues.
All I see is a black sphere. :(
Any help would be awesome! Do i make something wrong?
Browser downloads the image, no issues on the console.
Checked in every browser with the same result.
OS: Mac 10.8.2
Here is my code:
<html>
<head>
<script src="js/jquery-1.8.3.min.js"></script>
<script src="js/three.min.js"></script>
</head>
<body>
<div id="container">
</div>
<script>
function addSpaceSphere( ){
// set up the sphere vars
var radius = 125,
segments = 16,
rings = 16;
var material = new THREE.MeshPhongMaterial({
color:0xFFFFFF,
map: THREE.ImageUtils.loadTexture( 'textures/SPACE014S.png' ) ,
});
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(
radius,
segments,
rings
),
material
);
// add the sphere to the scene
scene.add(sphere);
}
function addLights(){
// create a point light
var ambient = new THREE.AmbientLight( 0xFFFFFF );
scene.add( ambient );
// create a point light
var pointLight = new THREE.PointLight(0xFFFFFF);
// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
// add to the scene
scene.add(pointLight);
}
function createScene(){
// add the camera to the scene
scene.add(camera);
// the camera starts at 0,0,0
// so pull it back
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 300;
// start the renderer
renderer.setSize(WIDTH, HEIGHT);
$container.append(renderer.domElement);
addSpaceSphere( );
addLights();
renderer.render(scene, camera);
}
function onWindowResize( event ) {
var newEarthContainerWidth = earthContainer.offsetWidth;
var newWindowHeight = window.innerHeight;
var newScale = newEarthContainerWidth / earthContainerWidth;
sphere.geometry.__dirtyVertices = true;
sphere.scale.x = sphere.scale.y = sphere.scale.z = newScale;
renderer.setSize( newEarthContainerWidth, newWindowHeight );
camera.aspect = newEarthContainerWidth / newWindowHeight;
camera.updateProjectionMatrix();
camera.radius = ( newEarthContainerWidth + newWindowHeight ) / 4;
}
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;
var $container = $('#container');
// create a WebGL renderer, camera
// and a scene
//var renderer = new THREE.CanvasRenderer();
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
VIEW_ANGLE, ASPECT, NEAR, FAR
);
var scene = new THREE.Scene();
createScene();
window.addEventListener( 'resize', onWindowResize, false );
</script>
</body>
You are calling
renderer.render( scene, camera );
only once, and probably before the texture completes loading.
Add an animation loop.
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
animate();