How to use THREE.MeshLine in my javascript project? - javascript

When looking for a way to create a three.js line with a changed width I came across this article which suggests to use a THREE.MeshLine class from here. However, when trying to follow the documentation on how to use it in my script I got an error:
require.js:5 Uncaught Error: Module name "three" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
at makeError (require.js:5)
at Object.o [as require] (require.js:5)
at requirejs (require.js:5)
at test_line.html:13
Here are the lines of code I used in my script:
<html>
<head>
<script src="https://requirejs.org/docs/release/2.3.5/minified/require.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<script src="https://raw.githubusercontent.com/spite/THREE.MeshLine/master/src/THREE.MeshLine.js"></script>
<title>Test</title>
</head>
<body>
<script>
var THREE = require( 'three' );
var MeshLine = require( 'three.meshline' );
...
Do I miss something? (Hint: I am a beginner with javascript)
I also tried to follow the suggestions HERE, but as soon as I added type="module" in the script part I got an error container is not defined.
Here is a complete, stand-alone, static, easy, direct working html example of a single line in a browser window. I'd appreciate if the answer could contain a complete, stand-alone, static, easy, direct working example of the code fixed!
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<title>Test</title>
</head>
<body>
<script>
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 150);
scene = new THREE.Scene();
scene.add(camera);
renderer = new THREE.WebGLRenderer({
clearAlpha: 1
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xcaffee, 1);
document.body.appendChild(renderer.domElement);
var material = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 10000000 } );
var points = [];
points.push( new THREE.Vector3(-50, 0, 0 ) );
points.push( new THREE.Vector3( 50, 0, 0 ) );
var geometry = new THREE.BufferGeometry().setFromPoints( points );
var line = new THREE.Line( geometry, material );
scene.add( line );
renderer.render( scene, camera );
animate();
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
</script>
</body>
</html>

Edit 2: As #user2589273 mentioned in the comment, this answer is no longer relevant, as the original repository (https://github.com/spite/THREE.MeshLine) has merged the below fork into the main repo. I will leave the answer below for posterity.
The Meshline repository you linked is not maintained any more and does not work with current three.js releases.
Here is the maintained fork that I currently use:
https://github.com/ryanking1809/threejs-meshline
It should work if you replace the link in your question with:
https://unpkg.com/threejs-meshline#2.0.11/src/index.js
Edit: with full working example:
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<script src="https://unpkg.com/threejs-meshline#2.0.11/src/index.js"></script>
<title>Test</title>
</head>
<body>
<script>
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 150);
scene = new THREE.Scene();
scene.add(camera);
renderer = new THREE.WebGLRenderer({
clearAlpha: 1
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xcaffee, 1);
document.body.appendChild(renderer.domElement);
let points = [];
points.push( new THREE.Vector3(-50, 0, 0 ) );
points.push( new THREE.Vector3( 50, 0, 0 ) );
const line = new MeshLine();
line.setVertices(points);
const material = new MeshLineMaterial();
const mesh = new THREE.Mesh( line, material );
scene.add( mesh );
renderer.render( scene, camera );
animate();
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
</script>
</body>
</html>

Related

I don't know why this three.js example doesn't work

I installed three.js through npm with the command: npm install --save three
I'm currently using VS-Code & have two files : index.html and index.js
By copying a simple example from threejs.org I can't seem to get three.js to work,because i only get a blank screen after running a live server,instead of a rotating cube.
Here's the code to both files:
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight,
0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material);
scene.add(cube);
camera.position.z = 5;
function animate() {
requestAnimationFrame(animate)
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera )
}
animate();
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" href = "index.css">
<script src = "index.js"></script>
<title >Title</title>
</head>
<body style = "margin: 0px;">
</body>
</html>
If you open the page in a browser and take a look at the dev tools menu, you'll find the following error:.
If you modify the script tag with type="module" to resolve this error, you get a new error: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".
Basically, the browser isn't able to find the three.js JavaScript library.
One easy fix is to just tell the browser to load the library from a web url when the page loads instead of installing it through npm and then loading those installed npm files into the web page:
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" href = "index.css">
<!-- This script tag loads the three.js library via url -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<title >Title</title>
</head>
<body style = "margin: 0px;">
<script src = "index.js"></script>
</body>
</html>
// import is no longer needed since the added script tag loads the library and adds the global THREE variable into the page
// import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight,
0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material);
scene.add(cube);
camera.position.z = 5;
function animate() {
requestAnimationFrame(animate)
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera )
}
animate();
Also note that document.body.appendChild will only work once the document has loaded (which doesn't necessarily happen before your script is executed). This issue was fixed by adding your <script> tag below the <body> tag in the html.

Error Importing three.js through npm and browserify

i'm very new to npms and i'm trying to import three.js into my scene but it is coming up with this error despite stating the type = "module" in my script tag in my html
I installed it through an npm and here is my javascript:
var $ = require('jquery');
var three = require('three');
import * as THREE from 'three';
import OrbitControls from 'three/examples/jsm/controls/OrbitControls';
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
material = new THREE.MeshNormalMaterial();
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 );
}
Here is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="#"/>
<title>Document</title>
<script type = "module" src="/bundle.js"></script>
</head>
<body>
</body>
</html>
Sorry if the answer is obvious, using browserify and module files is very new territory for me.
Edit: So in the official documentation, it says to do this :
var THREE = require('three');
var scene = new THREE.Scene();
...
which works except I want to use
import { MapControls } from 'three/examples/jsm/controls/OrbitControls.js';
which is only available through extracting it from the orbitcontrols library. Is there a way to do this without ES6 imports and using require() instead?

How can I change the position of an imported model in Three.JS?

I'm trying to make a hologram with Three.JS (Pepperghost Effect) and for it to work I need 4 rotating models.
I have a working POC (https://gyazo.com/57da565593493a2c9971457632bb5552). This was an STL model, so I wasn't able to add textures to it. I did some research and gave gLTF's a shot. I got a model with textures and the importing all worked, but the rotation part was not working as I expected.
Here is a gif of the problem: https://gyazo.com/c5a1a8ee65f7da2cce1c83261d465b33
I want it to spin on its own axes instead of in circles. What I think is the problem, is that it doesn't import it centered, so it would be a problem with the model position and not the rotating part (which is mesh.rotation.y += 0.01; to be clear).
I tried moving the mesh with the mesh.position.set() function, but that moves the whole scene (I guess that's what you call it?).
Also, as you can see on the last gif, I have another problem where the chest is only displayed twice. Maybe this is tied to the other problem I have?
I tried putting it together in a jsfiddle, but since I cant upload the model that doesn't work. This is the 3D model I'm importing: https://sketchfab.com/3d-models/chest-92a8d45d2d5c43b8b0b5bf7d97816ada
The peppersghost file can be found here https://threejs.org/examples/jsm/effects/PeppersGhostEffect.js
<!DOCTYPE html>
<html lang="en">
<head>
<title>Three.js Hologram POC</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.js"></script>
<script src="peppersghost.js"></script>
<!-- <script charset="utf-8" src="STLLoader.js"></script> -->
<!-- <script src="three.module.js"></script> -->
<!-- <script src="http://threejs.org/build/three.min.js"></script> -->
<script src="http://threejs.org/examples/js/loaders/MTLLoader.js"></script>
<script src="http://threejs.org/examples/js/loaders/OBJLoader.js"></script>
<script src="http://threejs.org/examples/js/loaders/GLTFLoader.js"></script>
</head>
<body>
<script type="module">
var container;
var camera, scene, renderer, effect, mesh, cube;
var group;
// var cameraTarget = new THREE.Vector3( 0, - 0.25, 0 );
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
// console.log(window.innerWidth / window.innerHeight)
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 100000 );
scene = new THREE.Scene();
// scene.background = new THREE.Color( 0xffd300 );
var ambientLight = new THREE.AmbientLight(0xffffff);
var light = new THREE.PointLight(0xffffff, 2.0, 200);
camera.add(ambientLight);
camera.add(light);
scene.add(camera);
camera.position.z = 1100;
camera.lookAt(scene.position);
const gltfLoader = new THREE.GLTFLoader();
gltfLoader.load('/media/autoconvert/scene.gltf', (gltf) => {
mesh = gltf.scene;
// mesh.position.set(0, 100, 0)
// mesh.scale.set(3, 1, 1);
scene.add(mesh);
const box = new THREE.Box3().setFromObject(mesh);
const boxSize = box.getSize(new THREE.Vector3()).length();
const boxCenter = box.getCenter(new THREE.Vector3());
});
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
effect = new THREE.PeppersGhostEffect( renderer );
effect.setSize( window.innerWidth, window.innerHeight );
effect.cameraDistance = 5;
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
effect.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
// var timer = Date.now() * 0.0005;
// camera.position.x = Math.cos( timer ) * 3;
// camera.position.z = Math.sin( timer ) * 3;
// camera.lookAt( cameraTarget );
effect.render( scene, camera );
}
</script>
</body>
</html>
Thanks!
EDIT: Thanks for the help! I tried both solutions, but I am still encountering problems :(
First I tried getting the first child. Although it didnt spin in circles like it did before, it still rotates the wrong way and it only shows two models instead of four: https://gyazo.com/1da02beff790bbb440c42eec42540e56
Then I expanded and added a group like this:
group = new THREE.Group(); scene.add(group); and group.add(mesh) instead of scene.add(mesh).
This is what I got after that: https://gyazo.com/220f5eed04ec05c56000327b57837047
As you can see, it still isn't working. I am still trying to find a solution for my problem. Any other suggestions are welcome!

Three.js - Imported obj material not showing

I suppose my first question is - because most of the threads here I've found on the subject are 3-5 years old now - what is the best way to import 3dsmax models or scenes to use in three.js?
Currently I've made a quick coke can with a simple texture applied, however when I use the obj loader found under examples/js/loaders the texture does not load.
I've tried using the python script to convert obj files to js however given that there is an obj loader this seemed like an unnecessary additional step (I was not able to get the textures to work that way either). Am I correct in assuming the obj loader has made the python conversion script obsolete?
When I try to load the scene I get the following error in my console:
Not allowed to load local resource: file:///C:/wamp/www/gordon/skins/coke_uv_map.jpg
See the following code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
</body>
<script src="three.min.js"></script>
<script src="controls/OrbitControls.js"></script>
<script src="DDSLoader.js"></script>
<script src="MTLLoader.js"></script>
<script src="OBJMTLLoader.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 controls;
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'mousedown', render );
var hemiLight = new THREE.HemisphereLight( 0xa4cecb, 0xdae0e6, 1 );
scene.add(hemiLight);
var dirLight = new THREE.DirectionalLight( 0xFFA200, 1);
scene.add(dirLight);
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var loader = new THREE.OBJMTLLoader();
loader.load( 'cokecan.obj', 'cokecan.mtl', function ( object ) {
object.position.y = 0;
object.position.x = 0;
object.position.z = 0;
scene.add( object );
});
camera.position.z = 50;
camera.position.y = 25;
camera.position.x = 0;
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
</script>
</html>
Here's a comparison of what I want versus what I'm getting (ignore the lighting):
For anybody getting the same error - I resolved this by opening the .mtl file that came with the .obj in a text editor and changing the path to my image.

ThreeJS Getting Started code gives console error

I am trying to attempt to learn Three.js from their getting started guide: http://threejs.org/docs/index.html#Manual/Introduction/Creating_a_scene and I have the code as exactly from the site. I am using the latest code from their site, as for the library. The error in the console is as follows:
Uncaught TypeError: Object #<Object> has no method 'mergeVertices'
I am not really too sure on what the issue is
Here is the code that is from the site that I am using:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>First Three JS App</title>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
// To be able to view anything with Three.js we need a scene, a camera, and a renderer
// -> To render the scene with the camera
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 = THREE.BoxGeometry(10, 10, 10 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 });
var cube = new THREE.Mesh( geometry, material);
scene.add( cube );
camera.position.z = 5;
var render = function render() {
requestAnimationFrame( render )
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render( scene, camera );
};
render();
</script>
</body>
</html>
From what #WestLangley suggested, I needed to review my code. I was missing a new in geometry declaration, and my renderer.setSize call needed 2 params instead of 1 (I was using a ratio) and the final var render = function.... I needed to take out the second render
Sometimes it is good to have a second pair of eyes.. Thanks again #WestLangley

Categories

Resources