I'm working on a Web Service which main funcionality resolves around displaying binary .ply files. To open and visualize the point cloud I'm using PLYLoader from Three.js. I used it to present example files from the internet and it worked. But when I'm trying to attach my .ply file it doesn't. I'm using Three.js because I need my display to be optimal, my files are at least 70mb.
Example .ply file here:
https://onedrive.live.com/redir?resid=7DDB287362EDFD5A!761&authkey=!AOHxkZk-6etH--0&ithint=file%2cply
I noticed that the .ply files that i have are a bit different from .ply files i displayed before. In my files there are no faces only points.
So basically my question is "Is it possible to display point cloud using Three.js? or should I use other library? If this is possible can someone help me with configuring my code to work properly?
Here it is my script in which I'm supporting .ply files:
var cameraControls;
var container = document.getElementById("three");
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, container.offsetWidth / container.offsetHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( container.offsetWidth, container.offsetHeight );
document.getElementById("three").appendChild( renderer.domElement );
cameraControls = new THREE.OrbitControls( camera, renderer.domElement );
cameraControls.target.set( 0, 0, 0 );
cameraControls.addEventListener( 'change', render );
var geometry = new THREE.BoxGeometry( 3, 3, 3 );
var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
var loader = new THREE.PLYLoader();
loader.load( 'resources/cube.ply', function ( geometry ) {
geometry.computeFaceNormals();
var material = new THREE.MeshStandardMaterial( { color: 0x0055ff } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 0.25;
mesh.rotation.x = - Math.PI / 2;
mesh.scale.multiplyScalar( 1 );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add( mesh );
} );
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
var light = new THREE.AmbientLight( 0x404040 ); // soft white light
scene.add( light );
directionalLight.position.set( 0, 1, 0 );
scene.add( directionalLight );
camera.position.z = 5;
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
Use THREE.MeshNormalMaterial. It loads the textures with MeshNormalMaterial for some odd reason
Use PointMaterials and Points
const loader = new PLYLoader();
loader.load('00000012.ply', function (geometry) {
var material = new THREE.PointsMaterial( { size: 0.005 } );
material.vertexColors = true //if has colors
var mesh = new THREE.Points(geometry, material)
scene.add(mesh)
} );
Related
I need to place a number of objects on the canvas, using three js. I'm getting stuck at the point of trying to change the location of the objects. My code is as below:
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( 2, 1, 1 );
//geometry.position.x = 1;
//geometry.position.y = 1;
//geometry.position.z = 1;
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
//scene.children[1].position.set(0, 0, 0);
var cube = new THREE.Mesh(geometry, material);
scene.add( cube );
camera.position.z = 5;
renderer.render( scene, camera );
I've commented out the two different ways I tried to achieve this (both failed). Can anyone suggest a solution?
You have to set position to a mesh, not a geometry:
var geometry = new THREE.BoxGeometry( 2, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh(geometry, material);
cube.position.set(1, 1, 1);
scene.add( cube );
I have a problem with CanvasRenderer rendering a Mesh that has multiple materials applied to a BoxBufferGeometry. It renders a Mesh with no materials applied. This is only problem with CanvasRenderer, when I use the same Mesh with WebGLRenderer all works as expected.
Here's an example code:
// three.js: multiple materials on a single mesh
var renderer, scene, camera, mesh;
init();
render();
function init() {
// renderer
renderer = new THREE.CanvasRenderer( { alpha: true } );
renderer.setSize( window.innerWidth / 2, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, (window.innerWidth / 2) / window.innerHeight, 1, 1000 );
camera.position.set( 15, 20, 30 );
camera.lookAt(scene.position);
scene.add( camera );
// ambient
scene.add( new THREE.AmbientLight( 0xffffff, 0.1 ) );
// light
camera.add( new THREE.PointLight( 0xffffff, 1 ) );
// geometry
var geometry = new THREE.BoxBufferGeometry( 10, 10, 10 );
// materials
var material0 = new THREE.MeshBasicMaterial({ color: 0xff0000 });
var material1 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var material2 = new THREE.MeshBasicMaterial({ color: 0x0000ff });
var material3 = new THREE.MeshBasicMaterial({ color: 0xffff00 });
var material4 = new THREE.MeshBasicMaterial({ color: 0x00ffff });
var material5 = new THREE.MeshBasicMaterial({ color: 0xff00ff });
var materials = [ material0, material1, material2, material3, material4, material5 ];
// mesh
mesh = new THREE.Mesh( geometry, materials );
scene.add( mesh );
}
function render() {
requestAnimationFrame(render);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
I've also made this fiddle
Where you can see exactly what I'm talking about. In the fiddle there's a Mesh(cube) that has all 6 groups(sides) in different material(color), and that same Mesh is rendered with WebGLRenderer(left) and CanvasRenderer(right).
Can someone with more experience help me understand this.
Am I doing something wrong?
Is there some limitation with CanvasRenderer that disables it to render such a Mesh, and if so, how would I achieve this effect in some other way?
Is this a bug, and should I report it as an issue on three.js repository?
Thanks for your help!
Note:
I'm new to Three.js, so I apologize if I made some obvious mistake.
CanvasRenderer is crucial for me as I use phantom.js to capture some screenshots.
Three.js r93
CanvasRenderer does not appear to support BufferGeometry and multi-materials.
A work-around is to use Geometry, instead.
var geometry = new THREE.BoxGeometry( 10, 10, 10 );
three.js r.93
I have downloaded the following model from TF3DM : http://tf3dm.com/3d-model/sprite-bottle-91563.html
And i'm trying to display it in a scene with threeJS.
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 light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 10, 10, 10 );
scene.add( light );
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 );
var mtlLoader = new THREE.MTLLoader();
// mtlLoader.setBaseUrl( '' );
mtlLoader.setPath( './' );
var url = "SpriteBottle.mtl";
mtlLoader.load( url, function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( './' );
objLoader.load( 'SpriteBottle.obj', function ( object ) {
object.position.y = - 95;
scene.add( object );
}, function() {}, function() {} );
});
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
With this code, nothing appears but the cube. I sometimes manage to display the bottle but the texture is not set.
EDIT: I have also tried to convert the obj file to JSON using the python script, and then applied the texture on it, it displays but not at the right spot.
What am i doing wrong ?
Three.js Version: 82
I'm looking at this example here: https://threejs.org/examples/#webgl_helpers
Notice that there are yellow boxes around the models. I was using version 79 and was using THREE.EdgesHelper to outline my 3D objects I made in Blender, but THREE.EdgesHelper was replaced by THREE.EdgesGeometry. I wanted to see an example of this, and the only one I could find is linked above.
I dove into the line and BoxHelper objects, but I didn't notice anything that would allow me to get rid of those yellow boxes.
JSFiddle: https://jsfiddle.net/4nbjvmpe/
Here is the code from the JSFiddle:
HTML
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
CSS
body {
background-color: #000;
margin: 0px;
overflow: hidden;
}
JavaScript
var mesh, renderer, scene, camera, controls;
init();
animate();
function init() {
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 20, 20, 20 );
// controls
controls = new THREE.OrbitControls( camera );
// ambient
scene.add( new THREE.AmbientLight( 0x222222 ) );
// light
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 20, 20, 0 );
scene.add( light );
// geometry
var geometry = new THREE.SphereGeometry( 5, 12, 8 );
// material
var material = new THREE.MeshPhongMaterial( {
color: 0x00ffff,
shading: THREE.FlatShading,
transparent: true,
opacity: 0.7,
} );
// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
// CUSTOM
// This is where I create the outline mesh.
var group = new THREE.Group();
scene.add( group );
group.updateMatrixWorld(true);
var edges = new THREE.EdgesGeometry(geometry);
var line = new THREE.LineSegments(edges);
group.add(line);
line.material.depthTest = true;
line.material.opacity = 0.25;
line.material.transparent = false;
this.outlineMesh = new THREE.BoxHelper(line);
scene.add(this.outlineMesh);
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
Simply comment this.outlineMesh = new THREE.BoxHelper(line); and scene.add(this.outlineMesh);. you will get want you want.
I am using three.js and the scene is not rendering. I am getting following errors in console:
THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.
Uncaught SecurityError: Failed to execute 'texImage2D' on 'WebGLRenderingContext': The cross-origin image at file:///F:/Study/3rd%20Sem/ES%20XXX%20-20Intro%20to%20Computer%20Graphics/Stick%20Baddy/images/crate.jpg may not be loaded.
Here are some of my code snippets:
Camera:
var scene = new THREE.Scene(); // Create a Three.js scene object
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
Light:
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 1 ).normalize();
scene.add(light);
Adding a cube:
var geometry = new THREE.CubeGeometry(stickLenX, 20, 20);
var material = new THREE.MeshPhongMaterial( { map: THREE.ImageUtils.loadTexture('images/crate.jpg', {}, function() { renderer.render(scene); }) } );
var myStick = new THREE.Mesh(geometry, material); // Create a mesh based on the specified geometry (myStick) and material (normal).
scene.add(myStick); // at (0,0,0)
Rendering:
var render = function () {
document.addEventListener('mousemove', onDocumentMouseMove, false);
move();
renderer.render(scene, camera); // Each time we change the position of the cube object, we must re-render it.
requestAnimationFrame(render);
};
render();
It works fine with THREE.MeshNormalMaterial()
Like
var material = new THREE.MeshNormalMaterial();
In my code, there are other cubes and spheres, too. Could any of them be causing the problem? Please can anybody mention what could be the problem?
--------UPDATE:----------
Running the file with Wampserver worked. What is the reason for that and how to make it work without server?
I solved it by using ImageUtils.loadTexture and PlaneGeometry.
var geometry = new THREE.PlaneGeometry( 500, 300, 1, 1 );
geometry.vertices[0].uv = new THREE.Vector2( 0 , 0 );
geometry.vertices[1].uv = new THREE.Vector2( 2, 0 );
geometry.vertices[2].uv = new THREE.Vector2( 2, 2 );
geometry.vertices[3].uv = new THREE.Vector2( 0, 2 );
texture = THREE.ImageUtils.loadTexture("text.png",null,function(t){
});
var material = new THREE.MeshBasicMaterial ( {map: texture} );
var mesh = new THREE.Mesh ( geometry, material );
scene.add( mesh );
Maybe you can replace the material.map with:
map: THREE.ImageUtils.loadTexture('images/crate.jpg')