WebGL viewer using Three.js + ColladaLoader.js - javascript

I am using the following code to implement WebGL viewer:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(100, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(0, 4, 0);
var loader = new THREE.ColladaLoader();
loader.load("b.dae", function (result) {
scene.add(result.scene);
render();
});
var light = new THREE.AmbientLight( 0x404040 );
scene.add( light );
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
But when I load the my own model using colladaloader, there's a error message:
Uncaught TypeError: Cannot read property 'input' of null
And I find that error occur on this line in ColladaLoader.js
var vertexData = sources[ this.vertices.input['POSITION'].source ].data;
I don't know is this a problem in my model?
I use SketchUp to create the model and export to .dae format.

Related

Three.js texture does not load

I'm trying to make a model of planet Earth, but the texture doesn't load and I don't know why this happens, I tried to change the image format and also use it as an export link and it still doesn't work.
my code:
import * as THREE from 'https://cdn.skypack.dev/three#0.134.0'
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);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(5, 50, 50),
new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load('.img/global.jpeg')
})
);
scene.add(sphere);
camera.position.z = 15;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
My first suggestion is for you to split up your code into individual steps so you can pinpoint where the error is taking place. Additionally, TextureLoader.load() has a few callback functions that you can help you determine if loading was successful or if it failed:
const geom = new THREE.SphereGeometry(5, 50, 50);
const texLoader = new THREE.TextureLoader();
const texture = texLoader.load(
// Location
'.img/global.jpeg',
// On success
function(texture) {
console.log("Success!");
console.log(texture);
},
// Progress (ignored)
undefined,
// On error
function(err) {
console.log("Error");
console.log(err);
}
);
const mat = new THREE.MeshBasicMaterial({map: texture});
const sphere = new THREE.Mesh(geom, mat);
Then you can check your console to see what the logs are displaying.

Add OrbitalControl to Three.js results in TypeError

I am trying to add OrbitalControls to a Three.js Script.
The Code should just add two spheres to an empty space and let the user look around the spheres with the OrbitalControls, but whenever I run the code, I get the following error:
three.js:5353 Uncaught TypeError: Cannot read property 'center' of undefined
at Sphere.copy (three.js:5353)
at Frustum.intersectsObject (three.js:5792)
at projectObject (three.js:22427)
at projectObject (three.js:22472)
at WebGLRenderer.render (three.js:22230)
at animate (index.html:50)
Here is the code I wrote:
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var scope = this;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var controls = new THREE.OrbitControls( camera );
camera.position.z = 5;
scope.controls.addEventListener( 'change', function(){scope.render} );
controls.update();
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var v = new THREE.Vector3(1,1,1);
var v0 = new THREE.Vector3(2,2,2);
var sphere = new THREE.Sphere(v, .1);
var sphere0 = new THREE.Sphere(v0, .1);
var m = new THREE.Mesh(sphere, material);
var m0 = new THREE.Mesh(sphere0, material);
scene.add(m);
scene.add(m0);
animate();
function animate() {
requestAnimationFrame( animate );
scope.controls.update();
scope.renderer.render( scope.scene, scope.camera );
}
I have already looked at the following resources but couldn't figure out how to solve the problem:
Threejs and orbitcontrol
Three.js + OrbitControls - Uncaught TypeError: Cannot read property 'render' of undefined
three.js TypeError: Cannot read property 'center' of undefined (with that one I am not sure if it is related to the problem.)
https://threejs.org/docs/index.html#examples/controls/OrbitControls
Can you please tell me where my error is and how a possible solution could look like?
THREE.Sphere represents a bounding sphere whereas THREE.SphereGeometry or THREE.SphereBufferGeometry represents geometries. Since you create a mesh always with a geometry and not with a bounding volume, just switch to THREE.SphereBufferGeometry to solve the problem.

Three.js Fail to Load a large 3D model with JSONLoader

So I'm trying to load a 3D model(file.json) with JSONLoader. It's about 40mb, but the model doesn't show up on the webpage, and my laptop starts to heat up. The console doesn't tell any error or warning, I wonder what should I do to load my model.
// ----------- render --------------
var renderer = new THREE.WebGLRenderer({canvas:document.getElementById('myCanvas'), antialias:true});
renderer.setClearColor(0x000000);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// ----------- camera --------------
var camera = new THREE.PerspectiveCamera(35, window.innerWidth/ window.innerHeight, 0.1, 3000);
// ----------- scene --------------
var scene = new THREE.Scene();
// create light
var light = new THREE.AmbientLight(0xC2ffe3, 0.5);
scene.add(light);
var light1 = new THREE.PointLight(0xffffff,0.5);
scene.add(light1);
var loader = new THREE.JSONLoader();
// load a resource
loader.load(
// resource URL
'untitled.json',
// onLoad callback
function ( geometry, materials ) {
var mesh = new THREE.Mesh( geometry, materials);
scene.add( mesh );
mesh.position.z = -10;
},
);
render();
function render(){
renderer.render(scene, camera);
requestAnimationFrame(render);
}
</script>enter code here

Three js in a class

I tried to set all the necessary functionality into one class in order to create a simple three.js scene with a cube. I don't get any errors, but the scene stays black when I open it in the browser.
Here is my code:
class SceneInit {
constructor(fov = 45,camera,scene,controls,renderer)
{
this.camera = camera;
this.scene = scene;
this.controls = controls;
this.renderer = renderer;
this.fov = fov;
}
initScene() {
this.camera = new THREE.PerspectiveCamera(this.fov, window.innerWidth / window.innerHeight, 1, 1000);
this.camera.position.z = 15;
this.controls = new THREE.TrackballControls( this.camera );
//this.controls.addEventListener('change', this.renderScene);
this.scene = new THREE.Scene();
//specify a canvas which is already created in the HTML file and tagged by an id //aliasing enabled
this.renderer = new THREE.WebGLRenderer({canvas: document.getElementById('myThreeJsCanvas') , antialias: true});
this.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.renderer.domElement);
//ambient light which is for the whole scene
let ambientLight = new THREE.AmbientLight(0xffffff, 0.7);
ambientLight.castShadow = false;
this.scene.add(ambientLight);
//spot light which is illuminating the chart directly
let spotLight = new THREE.SpotLight(0xffffff, 0.55);
spotLight.castShadow = true;
spotLight.position.set(0,40,10);
this.scene.add(spotLight);
//if window resizes
window.addEventListener('resize', this.onWindowResize, false);
}
animate(){
requestAnimationFrame( this.animate.bind(this) );
this.render();
this.controls.update();
}
render(){
this.renderer.render( this.scene, this.camera );
}
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize( window.innerWidth, window.innerHeight );
}
}
And then I try to instantiate a new object and add an object to the scene. When I try to print the children of the scene, it returns me the right objects, but as I mentioned before the scene stays black. Only the renderer window is getting drawed in the browser.
let test = new SceneInit(45);
test.initScene();
test.animate();
let geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
let material = new THREE.MeshBasicMaterial();
let mesh = new THREE.Mesh( geometry, material );
test.scene.add(mesh);
console.log(test.scene.children); //returns 3 objects (ambientLight, spotLight, mesh)
I got the answer.
The problem in the code was that the BoxGeometry was too big and the camera was inside the box. With the clipping set to 1 it wouldn't even render it.
So the solution is to set a smaller BoxGeometry. or to move the camera away!

THREE.FileLoader is not a constructor(…)

I'm trying to load a model into my scene.
I've included these files at the top of my project:
<script src="js/build/three.min.js"></script>
<script src="js/loaders/OBJLoader.js"></script>
This is my code
var loader = new THREE.OBJLoader();
loader.load( "res/rose/ModelsAndTextures/rose.obj", function ( object ) {
scene.add( object );
} );
But I get error: OBJLoader.js:46 Uncaught TypeError: THREE.FileLoader is not a constructor(…)
I looked in the OBJLoader.js file and to find THREE.FileLoader - this is the line the error is on:
var loader = new THREE.FileLoader( scope.manager );
Other peoples examples of this work fine
Check out if you're using the right OBJLoader.js.
Take a look at an example that shows how to use this object properly:
var scene = new THREE.Scene();
var renderer, camera, banana;
var ww = window.innerWidth,
wh = window.innerHeight;
renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('scene')
});
renderer.setSize(ww, wh);
camera = new THREE.PerspectiveCamera(50, ww / wh, 0.1, 10000);
camera.position.set(0, 0, 500);
scene.add(camera);
//Add a light in the scene
directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(0, 0, 350);
directionalLight.lookAt(new THREE.Vector3(0, 0, 0));
scene.add(directionalLight);
var render = function() {
requestAnimationFrame(render);
banana.rotation.z += .01;
renderer.render(scene, camera);
};
var loadOBJ = function() {
//Manager from ThreeJs to track a loader and its status
var manager = new THREE.LoadingManager();
//Loader for Obj from Three.js
var loader = new THREE.OBJLoader(manager);
//Launch loading of the obj file, addBananaInScene is the callback when it's ready
loader.load('http://mamboleoo.be/learnThree/demos/banana.obj', function(object) {
banana = object;
//Move the banana in the scene
banana.rotation.x = Math.PI / 2;
banana.position.y = -200;
banana.position.z = 50;
//Go through all children of the loaded object and search for a Mesh
object.traverse(function(child) {
//This allow us to check if the children is an instance of the Mesh constructor
if (child instanceof THREE.Mesh) {
child.material.color = new THREE.Color(0X00FF00);
//Sometimes there are some vertex normals missing in the .obj files, ThreeJs will compute them
child.geometry.computeVertexNormals();
}
});
scene.add(banana);
render();
});
};
loadOBJ();
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script src="http://mamboleoo.be/learnThree/demos/OBJLoader.js"></script>
<canvas id="scene"></canvas>
I had this issue and realized I used an old version of the three.js file. I replaced it with the three.js in the build folder of the three.js download where I took the OBJLoader from.

Categories

Resources