Draw 3D object axes threejs - three.js

How can i draw object axes. I am refering at the mesh local axes and not the world axes. I know that using:
function drawlines(){
var material = new THREE.LineBasicMaterial({
color: 0x0000ff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( 100, 0, 0 ),
new THREE.Vector3( 0, 0, 0 )
);
var line = new THREE.Line( geometry, material );
scene.add( line );
var material = new THREE.LineBasicMaterial({
color: 0x00ff00
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( 0, 100, 0 ),
new THREE.Vector3( 0, 0, 0 )
);
var line = new THREE.Line( geometry, material );
scene.add( line );
var material = new THREE.LineBasicMaterial({
color: 0xff0000
});
var geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( 0, 0, 100 ),
new THREE.Vector3( 0, 0, 0 )
);
var line = new THREE.Line( geometry, material );
scene.add( line );
}
draws lines at XYZ respectively. What i need is to draw the XYZ axis of the model. How can i do that. I load the model with this code
var loader = new THREE.JSONLoader();
loader.load( "https://threejs.org/examples/models/animated/horse.js", function ( geometry ) {
var material = new THREE.MeshLambertMaterial( {
vertexColors: THREE.FaceColors,
morphTargets: true,
overdraw: 0.5
} );
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set( 1.5, 1.5, 1.5 );
scene.add( mesh );
mixer = new THREE.AnimationMixer( mesh );
var clip = THREE.AnimationClip.CreateFromMorphTargetSequence( 'gallop', geometry.morphTargets, 30 );
mixer.clipAction( clip ).setDuration( 1 ).play();
} );

If I get you correctly, you can use THREE.AxisHelper(). Just create an instance of it and then add it to your model.
jsfiddle example.
var camera, scene, renderer, controls;
var sphere, cube;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 5, 1.5).setLength(100);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
//renderer.setClearColor(0xcccccc);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var plane = new THREE.GridHelper(100, 10);
scene.add(plane);
sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 16, 8), new THREE.MeshBasicMaterial({color: "red", wireframe: true}));
sphere.position.set(-20, 0, 0);
cube = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10), new THREE.MeshBasicMaterial({color: "green", wireframe: true}));
cube.position.set(20, 0, 0);
var worldAxis = new THREE.AxesHelper(20);
scene.add(worldAxis);
scene.add(sphere);
scene.add(cube);
var sphereAxis = new THREE.AxesHelper(20);
sphere.add(sphereAxis);
var cubeAxis = new THREE.AxesHelper(20);
cube.add(cubeAxis);
}
var delta;
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}

Related

How to change three.js THREE.Face3 color

I've just create a sample which draw a triangle using THREE.Face3 with three.js.
Here is my code snippet
var scene, camera, renderer;
var cube;
var controls;
function initScene() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 30;
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
controls = new THREE.OrbitControls(camera);
controls.update();
document.body.appendChild(renderer.domElement);
}
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function draw() {
var material = new THREE.MeshStandardMaterial( { color : 0x00cc00, side: THREE.DoubleSide } );
//create a triangular geometry
var geometry = new THREE.Geometry();
geometry.vertices.push( new THREE.Vector3( -5, -5, 0 ) );
geometry.vertices.push( new THREE.Vector3( 5, -5, 0 ) );
geometry.vertices.push( new THREE.Vector3( 5, 5, 0 ) );
//create a new face using vertices 0, 1, 2
var normal = new THREE.Vector3( 0, 1, 0 ); //optional
var color = new THREE.Color( 0xffaa00 ); //optional
var materialIndex = 0; //optional
var face = new THREE.Face3( 0, 1, 2);
//add the face to the geometry's faces array
geometry.faces.push( face );
//the face normals and vertex normals can be calculated automatically if not supplied above
geometry.computeFaceNormals();
geometry.computeVertexNormals();
scene.add( new THREE.Mesh( geometry, material ) );
}
initScene();
draw();
render();
body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
I've refered the sample code in three.js Face3 documentation, I think the sample code try to set color is 0x00cc00 or 0xffaa00, but the color of triangle in my sample is black.
How to change it?

How to draw Shape geometry with 3d points(x,y,z) using threejs which is not flat shape(surface)

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 10, 300);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.TrackballControls(camera, renderer.domElement);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
var closedSpline = new THREE.CatmullRomCurve3([
new THREE.Vector3(-60, -100, -10),
new THREE.Vector3(-60, 20, 0),
new THREE.Vector3(-60, 120, -20),
new THREE.Vector3(60, 120, 0),
new THREE.Vector3(60, -100, 10)
]);
closedSpline.curveType = 'catmullrom';
closedSpline.closed = true;
var closedSpline1 = new THREE.CatmullRomCurve3([
new THREE.Vector3(-50, -90, -10),
new THREE.Vector3(-50, 10, 0),
new THREE.Vector3(-50, 110, -20),
new THREE.Vector3(50, 110, 0),
new THREE.Vector3(50, -90, 10)
]);
closedSpline1.curveType = 'catmullrom';
closedSpline1.closed = true;
var tubeGeometry = new THREE.TubeBufferGeometry(closedSpline, 100, 1, 5, true);
var material = new THREE.MeshLambertMaterial({
color: 0xb00000,
wireframe: false
});
var mesh = new THREE.Mesh(tubeGeometry, material);
scene.add(mesh);
var tubeGeometry1 = new THREE.TubeBufferGeometry(closedSpline1, 100, 1, 5,true);
var material1 = new THREE.MeshLambertMaterial({
color: 0xb00000,
wireframe: false
});
var mesh1 = new THREE.Mesh(tubeGeometry1, material1);
scene.add(mesh1);
// magic starts here
var shape = new THREE.Shape(closedSpline1.getPoints(100)); // make a shape
shape.holes.push(new THREE.Path(closedSpline1.getPoints(100))); // add a hole
var shapeGeometry = new THREE.ShapeGeometry(shape); // create a geometry
var track = new THREE.Mesh(shapeGeometry, new THREE.MeshLambertMaterial({
color: "yellow",
side:THREE.DoubleSide,
})); // create a track from the geometry
scene.add(track);
render();
function render() {
requestAnimationFrame(render);
controls.update();
renderer.render(scene, camera);
}
Above is my code which draw two tube geometry using THREE.CatmullRomCurve3 points and surface between those two tubes. Issue i am facing is surface between those two tubes(Track in above code) is always flat(2d) instead of 3d. I think THREE.Shape() are not using z axis values to draw surface. Can anybody guide me to right direction or some related samples. Thanks
You can do the trick, using concatenated sets of points from curves and THREE.PlaneGeometry():
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 10, 300);
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);
var light = new THREE.DirectionalLight(0xffffff, 0.5);
light.position.setScalar(100);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
var closedSpline = new THREE.CatmullRomCurve3([
new THREE.Vector3(-60, -100, -10),
new THREE.Vector3(-60, 20, 0),
new THREE.Vector3(-60, 120, -20),
new THREE.Vector3(60, 120, 0),
new THREE.Vector3(60, -100, 10)
]);
closedSpline.curveType = 'catmullrom';
closedSpline.closed = true;
var closedSpline1 = new THREE.CatmullRomCurve3([
new THREE.Vector3(-50, -90, -10),
new THREE.Vector3(-50, 10, 0),
new THREE.Vector3(-50, 110, -20),
new THREE.Vector3(50, 110, 0),
new THREE.Vector3(50, -90, 10)
]);
closedSpline1.curveType = 'catmullrom';
closedSpline1.closed = true;
var tubeGeometry = new THREE.TubeBufferGeometry(closedSpline, 100, 1, 5, true);
var material = new THREE.MeshLambertMaterial({
color: 0xb00000,
wireframe: false
});
var mesh = new THREE.Mesh(tubeGeometry, material);
scene.add(mesh);
var tubeGeometry1 = new THREE.TubeBufferGeometry(closedSpline1, 100, 1, 5,
true);
var material1 = new THREE.MeshLambertMaterial({
color: 0xb00000,
wireframe: false
});
var mesh1 = new THREE.Mesh(tubeGeometry1, material1);
scene.add(mesh1);
// magic starts here
var points1 = closedSpline.getPoints(100); // get the first set of points
var points2 = closedSpline1.getPoints(100); // get the second set of points
var allPoints = points1.concat(points2); // concatenate them
var planeGeom = new THREE.PlaneGeometry(1, 1, 100, 1); // create a plane geometry
planeGeom.vertices = allPoints; // replace its vertices with the previously concatenated array of points
planeGeom.computeFaceNormals();
planeGeom.computeVertexNormals();
var track = new THREE.Mesh(planeGeom, new THREE.MeshLambertMaterial({
color: "yellow",
wireframe: false
}));
scene.add(track);
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>

Three.js load Image as texture not render

The g.png success loaded,but it not render.
Is it not loaded but render first?
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
material = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("g.png") });
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
Full code
https://gist.github.com/EasonWang01/410046ababc1af4f7f2db4b294b591ca
I write a sample based on your code, hope that will help you.
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js"> </script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.lookAt(new THREE.Vector3(0, 0, 0));
var renderer = new THREE.WebGLRenderer({ alpha: false });
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry1 = new THREE.BoxGeometry( 12, 1, 1 );
var material1 = new THREE.MeshBasicMaterial( { color: 0x00FFCC } );
var cube1 = new THREE.Mesh( geometry1, material1 );
scene.add( cube1 );
var geometry2 = new THREE.BoxGeometry( 10, 1, 1 );
var material2 = new THREE.MeshBasicMaterial( { color: 0xCCFF33 } );
var cube2 = new THREE.Mesh( geometry2, material2 );
scene.add( cube2 );
var geometry3 = new THREE.CircleBufferGeometry( 3, 32 );
var material3 = new THREE.MeshBasicMaterial( { color: 0xCCFFCC } );
var circle3 = new THREE.Mesh( geometry3, material3 );
scene.add( circle3 );
var geometry4 = new THREE.BoxBufferGeometry( 10, 1, 1 );
material4 = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("img/g.png") });
var cube4 = new THREE.Mesh( geometry4, material4 );
scene.add( cube4 );
var geometry = new THREE.CubeGeometry(150, 200, 150, 2, 2, 2);
var materials = [];
cube = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials));
cube.position.y = 150;
scene.add(cube);
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
camera.position.z = 5;
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
material = new THREE.MeshLambertMaterial({ map: new THREE.TextureLoader().load("img/g.png") });
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
cube1.rotation.x += 0.02;
cube1.rotation.y += 0.02;
cube2.rotation.x += 0.03;
cube2.rotation.y += 0.03;
renderer.render(scene, camera);
};
setTimeout(() => {render();},500)
</script>
</body>
</html>

three.js transparent sphere glitch

I have a transparent sphere and a spot light and that's about it. My sphere displays visual glitches, like striations.
see: http://jsfiddle.net/blwoodley/tvcogqkg/3/
(Note the grid is not necessary to manifest the bug. I just put it in there to show that transparency is working otherwise fine).
Any thoughts on how to get rid of these glitches? They seem to depend on the relative position of the camera and spot light.
Using three.js, r71.
Here is the code from the fiddle since SO seems to want it:
var SCREEN_WIDTH = window.innerWidth - 100;
var SCREEN_HEIGHT = window.innerHeight - 100;
var camera, scene, _planeMesh;
var canvasRenderer, webglRenderer;
var container, mesh, geometry, plane;
container = document.createElement('div');
document.body.appendChild(container);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 100000);
camera.position.set( 380, 80, 100 );
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 180, 160, 0 );
var grid = new THREE.GridHelper(400, 40);
grid.position.y = -20;
scene.add(grid);
scene.add(spotLight);
camera.lookAt( scene.position );
var material = new THREE.MeshPhongMaterial( {
color: 0xaaaa00,
emissive: 0xaa0000,
specular: 0xaa00aa,
shininess: 10,
side: THREE.DoubleSide,
shading: THREE.SmoothShading,
opacity: .8, transparent: true } );
var size = 16.0;
var sphereGeo = new THREE.SphereGeometry( size, 32, 16 );
var mesh = new THREE.Mesh( sphereGeo, material);
scene.add(mesh);
var mesh = new THREE.Mesh( sphereGeo, material);
mesh.position.y = 40;
scene.add(mesh);
var mesh = new THREE.Mesh( sphereGeo, material);
mesh.position.x = 60;
scene.add(mesh);
// RENDERER
webglRenderer = new THREE.WebGLRenderer();
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
webglRenderer.domElement.style.position = "relative";
container.appendChild(webglRenderer.domElement);
animate();
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
webglRenderer.render(scene, camera);
}
Remove the attribute side: THREE.DoubleSide. Since you are drawing spheres, you don't need it.

[three.js]THREE.Geometry : can't apply textured material

I created a hexagon with THREE.JS, it works with a basic material with a color, but i can't make it works with a texture... When i set up a textured material, the object isn't rendered at all.
I had the same problem with a bufferGeometry, but i solved the issue by setting geometry.addAttribute('uv'..., but this time, looks like it's not a uvs issue.
Here's the JS 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 );
// Adding light
scene.add( new THREE.AmbientLight( 0x444444 ) );
// SPOT LIGHT
var pXL1 = 3; var pYL1 = 1; var pZL1 = 2;
var LightGeometry1 = new THREE.BoxGeometry( 0.1, 0.1, 0.1 );
var LightMaterial1 = new THREE.MeshBasicMaterial( { map: new THREE.ImageUtils.loadTexture( "textures/default.jpg" ) } ); // this one is well textured !!!!
var LightCube1 = new THREE.Mesh( LightGeometry1, LightMaterial1 );
LightCube1.position.set(pXL1, pYL1, pZL1);
scene.add( LightCube1 );
var light1 = new THREE.DirectionalLight( 0xffffff );
light1.position.set( pXL1, pYL1, pZL1 ).normalize();
scene.add(light1);
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(-0.866 , 0.5,1));
geometry.vertices.push(new THREE.Vector3(-0.866 , -0.5 ,1));
geometry.vertices.push(new THREE.Vector3(0, -1 ,1));
geometry.vertices.push(new THREE.Vector3(0.866, -0.5 ,1));
geometry.vertices.push(new THREE.Vector3(0.866,0.5 ,1));
geometry.vertices.push(new THREE.Vector3(0, 1 ,1));
geometry.faces.push(new THREE.Face3(1, 2, 3, new THREE.Vector3(0, 0, 1)));
geometry.faces.push(new THREE.Face3(1, 3, 4, new THREE.Vector3(0, 0, 1)));
geometry.faces.push(new THREE.Face3(4, 0, 1, new THREE.Vector3(0, 0, 1)));
geometry.faces.push(new THREE.Face3(4, 5, 0, new THREE.Vector3(0, 0, 1)));
geometry.faceVertexUvs[0] = [];
geometry.faceVertexUvs[0].push( THREE.Vector2(0,5), THREE.Vector2(0.933,0.2835), THREE.Vector2(0.933,0.7165));
geometry.faceVertexUvs[0].push( THREE.Vector2(0,5), THREE.Vector2(0.933,0.7165), THREE.Vector2(0.5,1));
geometry.faceVertexUvs[0].push( THREE.Vector2(0.5,1), THREE.Vector2(0.067,0.2835), THREE.Vector2(0,5));
geometry.faceVertexUvs[0].push( THREE.Vector2(0.5,1), THREE.Vector2(0.067,7165), THREE.Vector2(0.067,0.2835));
var hexagon_texture = new THREE.ImageUtils.loadTexture( "textures/default.jpg" );
hexagon_texture.wrapS = THREE.RepeatWrapping;
hexagon_texture.wrapT = THREE.RepeatWrapping;
hexagon_texture.repeat.set(1,1);
var hexagon_material = new THREE.MeshBasicMaterial( { color: 0xff0000} );
//var hexagon_material = new THREE.MeshPhongMaterial( { ambient: 0xffffff, specular: 0x555555, shininess: 50, map:hexagon_texture, side: THREE.DoubleSide } );
//var hexagon_material = new THREE.MeshBasicMaterial( { map: new THREE.ImageUtils.loadTexture( "textures/default.jpg" ) } );
var hexagon = new THREE.Mesh( geometry,hexagon_material );
scene.add(hexagon);
camera.position.z = 5;
controls = new THREE.OrbitControls( camera, renderer.domElement );
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
};
render();
As it, it works and i have a red hexagon. But if i uncomment one of the var hexagon_materual = ..., then the hexagon isn't rendered.
What am i missing ?
Thank you

Resources