I am attempting to load a collada file using three.js and the collada loader. I am leveraging the three.js documentation, but can't seem to get the file to render on screen. What I want to achieve is a very basic import of the collada file into a scene, no animation required. The errors I am receiving are as follows:
unhandled Surface prop: format_hint
Can not convert Transform of type lookat
The XHR output is showing 100% load of the .dae file, and I can browse to the location of the stored file in a browser and view it as XML. I currently have the mime type set to application/xml in IIS.
Here is my current code. What am I missing?:
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - loaders - collada loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<script src="scripts/three.min.js"></script>
<script src="scripts/ColladaLoader.js"></script>
<script src="scripts/jquery-2.1.4.min.js"></script>
<script src="scripts/bootstrap.min.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<h1>Box Example</h1>
<p>This example loads an collada file</p>
<div id="webGL-container"></div>
<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.setClearColor(0xff0000);
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.x = 40;
camera.position.y = 40;
camera.position.z = 40;
// instantiate a loader
var loader = new THREE.ColladaLoader();
loader.load(
// resource URL
'models/box.dae',
// Function when resource is loaded
function (collada) {
scene.add(collada.scene);
},
// Function called when download progresses
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
}
);
camera.lookAt(scene.position);
renderer.render(scene, camera);
$("#webGL-container").append(renderer.domElement);
</script>
</body>
</html>
Per the advice offered, here is version 2:
var scene;;
var camera;
var renderer;
var loader;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor();
renderer.setSize(window.innerWidth, window.innerHeight);
camera.position.x = 40;
camera.position.y = 40;
camera.position.z = 40;
// instantiate a loader
loader = new THREE.ColladaLoader();
loader.load(
// resource URL
'models/box.dae',
// Function when resource is loaded
function (collada) {
scene.add(collada.scene);
},
// Function called when download progresses
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
}
);
camera.lookAt(scene.position);
$("#webGL-container").append(renderer.domElement);
};
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
init();
animate();
Update 3: I have been able to get the core .DAE file to render, but it is missing the texture (currently showing the box as all black):
var scene;
var camera;
var renderer;
var box;
// instantiate a loader
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load('models//box.dae', function (collada) {
box = collada.scene;
box.traverse(function (child) {
if (child instanceof THREE.SkinnedMesh) {
var animation = new THREE.Animation(child, child.geometry.animation);
animation.play();
}
});
box.scale.x = box.scale.y = box.scale.z = .2;
box.updateMatrix();
init();
animate();
});
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xdddddd);
renderer.setSize(window.innerWidth, window.innerHeight);
scene.add(box);
camera.position.x = 40;
camera.position.y = 40;
camera.position.z = 40;
camera.lookAt(scene.position);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
$("#webGL-container").append(renderer.domElement);
}
You are hitting the asynchronous loading of javascript. When you call renderer.render() your scene is still empty because the model has not downloaded yet. Put the code you have in an init() function and then create an animate() function and call them as such:
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
init();
animate();
The variables scene, camera, renderer you should make global.
Related
I am trying to display a model which is gltf but it doesn't come up. I'm running of a http server as without so it is causing more errors now this "Error: Could not establish connection. Receiving end does not exist." comes up
<html><head>
<title>My first three.js app</title>
<style>
body {
margin: 0;
}
canvas {
display: block;
}
</style></head>[enter image description here][1]<body>
<script src="js/three.js"></script>
<script src="js/GLTFLoader.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 loader = new THREE.GLTFLoader();
loader.load("LegoEv3.glb", handle_load);
var mesh;
function handle_load(gltf) {
mesh = gltf.scene.children[0];
scene.add(mesh);
mesh.position, (z = -1000);
}
renderer.render(scene, camera);
</script>
you render only once before the model is loaded.
Try rendering again after the model is loaded and added to the scene
function handle_load(gltf) {
mesh = gltf.scene.children[0];
scene.add(mesh);
mesh.position, (z = -1000);
renderer.render(scene, camera); // You need to render after model is added
}
I'm trying to upload a 3D model to my scene in three.js however I have trouble doing this.
I decided to recreate an example to practice which is shown below but I still get error and it doesn't work.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Website first attempt</title>
<script src="js/three.min.js"></script>
<script type = "module"src="js/OrbitControls.js"></script>
<script type = "module" src="js/GLTFLoader.js"></script>
<style>
body { margin: 0;}
canvas { display: block; }
</style>
</head>
<body>
<div class = "wave"></div>
<script type = "module">
var scene, camera, renderer, controls;
var hlight,directionalLight, light, light2, light3, light4;
function init () {
//scene
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xdddddd );
//camera
camera = new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,5000);
camera.rotation.y = 45/180*Math.PI;
camera.position.x = 800;
camera.position.y = 100;
camera.position.z = 1000;
//render
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
hlight = new THREE.AmbientLight (0x404040,100);
scene.add(hlight);
directionalLight = new THREE.DirectionalLight(0xffffff,100);
directionalLight.position.set(0,1,0);
directionalLight.castShadow = true;
scene.add(directionalLight);
light = new THREE.PointLight(0xc4c4c4,10);
light.position.set(0,300,500);
scene.add(light);
light2 = new THREE.PointLight(0xc4c4c4,10);
light2.position.set(500,100,0);
scene.add(light2);
light3 = new THREE.PointLight(0xc4c4c4,10);
light3.position.set(0,100,-500);
scene.add(light3);
light4 = new THREE.PointLight(0xc4c4c4,10);
light4.position.set(-500,300,500);
scene.add(light4);
var loader = new THREE.GLTFLoader();
loader.load('scene.gltf', function(gltf){
car = gltf.scene.children[0];
car.scale.set(0.5,0.5,0.5);
scene.add(gltf.scene);
animate();
});
}
function onWindowResize () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener('resize', onWindowResize, false);
function animate () {
requestAnimationFrame(animate);
controls.update();
render();
}
function render() {
renderer.render( scene, camera );
}
init ();
animate();
</script>
</body>
</html>
Comes with an error:
GET http://127.0.0.1:5500/build/three.module.js net::ERR_ABORTED 404
(Not Found) index4.html:78 Uncaught TypeError: THREE.GLTFLoader is not
a constructor
at init (index4.html:78)
at index4.html:122
I think easier to stick to the example's code style and organize your imports like so:
<script type = "module">
import * as THREE from '../build/three.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
var scene, camera, renderer, controls;
Meaning three.module.js, OrbitControls and GLTFLoader are ES6 modules. In this case, you can create an instance of GLTFLoader without the THREE namespace. Same for OrbitControls.
Notice that it's no good approach to mix ES6 modules with non-ES6 modules. If you do so, you will be inevitably faced with issues which are really hard to track down. E.g. libraries like three.js get included twice.
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!
I try to do a 3D animation with Three.js controls. During the execution of my code in Firefox, a have this error :
EDIT
SyntaxError: import declarations may only appear at top level of a module
And here is my code, simplified :
<!DOCTYPE html>
<head>
<title>Three.js Test</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100%;};
</style>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script type="module">
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);
//keep the scene in center of the page
window.addEventListener('resize', function() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width,height);
//prevent distortion
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
controls = new THREE.OrbitControls(camera, renderer.domElement);
// create the shape
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0xFF0080 } );
var 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;
cube.rotation.z += 0.01;*/
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
I don't understand where the error came from and I don't know how to fix it.
I now run my code on a wamp server.
Thanks for your help !
import * as THREE from './jsthree.module.js';
It seems there is a typo. It should be ./js/three.module.js.
In any event, ensure to run your code on a local web server in order to avoid any security issues. More information about this topic in the following guide:
https://threejs.org/docs/index.html#manual/en/introduction/How-to-run-things-locally
I'm trying to load a model that I created in blender using the three.js exporter addon. However I'm a reoccurring error even if I change around the loading property, and I would like to know the correct way to format it.
<html>
<head>
<title>three.js</title>
<meta charset="utf-8">
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="js/three.min.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/renderers/CanvasRenderer.js"></script>
<script>
// Setup a new scene
var scene = new THREE.Scene();
// Setup the camera
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 5;
camera.position.y = 1;
// Setup the renderer
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Add the lights
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
var light = new THREE.PointLight( 0xFFFFDD );
light.position.set( -15, 10, 15 );
scene.add( light );
// Models
var model;
var theaterModel;
// instantiate a loader
var loader = new THREE.JSONLoader();
// load a resource
loader.load(
// resource URL
'models/Theater-of-PalmyraNEW.json',
// Function when resource is loaded
function ( geometry, materials ) {
var material = new THREE.MultiMaterial( materials );
var object = new THREE.Mesh( geometry, material );
scene.add( object );
}
);
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .05;
camera.position.y += ( - mouseY + 200 - camera.position.y ) * .05;
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
</script>
</body>
</html>
The error of which is, uncaught Type Errors in the three.js file and three.min.js files.
Uncaught TypeError: Cannot read property 'length' of undefined
at three.min.js:658
at Jd.parse (three.min.js:661)
at three.min.js:657
at XMLHttpRequest.<anonymous> (three.min.js:605)
This may just be a simple error that I'm not seeing - and that I've seen other's having problems with this.