Exception when running three.js example using iewebgl - javascript

I'm trying to use the iewebgl and having trouble running one of the examples from three.js, the webgl_loader_obj. I am getting the following error:
SCRIPT445: Object doesn't support this action
iewebgl.html, line 134 character 5
which points to this line
// texture
var manager = new THREE.LoadingManager(); <!-- here -->
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
I also tried commenting out the texture and model portions and loading the object without the manager but I would receive the following error:
SCRIPT445: Object doesn't support this action
OBJLoader.js, line 19 character 3
which points to this line
THREE.OBJLoader.prototype = {
constructor: THREE.OBJLoader,
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var loader = new THREE.XHRLoader( scope.manager ); <!-- here-->
loader.setCrossOrigin( this.crossOrigin );
I tried both creating canvas and getting WebGL context from JavaScript and creating WebGL context with helper.
I'm using ie 10 with r.46 of three.js. When I use r.61 of three.js I get the following exception
SCRIPT5007: Unable to get property 'getExtension' of undefined or null reference
three.min.js, line 8322 character 2
which is
} catch (Zb) {
console.error(Zb)
}
Na = j.getExtension("OES_texture_float"); <!-- here -->
j.getExtension("OES_texture_float_linear");
va = j.getExtension("OES_standard_derivatives");
Any idea what may be causing it?

I was able to solve my issue using the Creating canvas and getting WebGL context from JavaScript example
<div id="container">
<script id="WebGLCanvasCreationScript" type="text/javascript">WebGLHelper.CreateGLCanvasInline('renderCanvas', onLoad)</script>
</div>
I then placed both the init() and animate() calls in the following block leaving out the global vars
var container, stats;
var camera, cameraTarget, scene, renderer;
function onLoad() {
<!-- require(["js/Three.js"], function () { -->
init();
animate();
<!-- }); -->
}
I didn't use the require code, but included it in case anyone else runs into a similar problem and finds they need it.
Finally, had to change the render code to the following. (I left the original commented)
var externalCanvas = document.getElementById('renderCanvas');
renderer = new THREE.WebGLRenderer({ 'canvas': externalCanvas, 'clearColor': 0xffffff });
<!-- renderer = new THREE.WebGLRenderer(); -->
<!-- renderer = new THREE.WebGLRenderer( { antialias: true, alpha: false } ); -->

If you use the un-minified version of three.js, I think you'll see the problem is the _gl object (j in the minified version) is null. It also looks to me as if three.js will throw an exception, log the message "Error creating WebGL context" and then proceed to try to use the _gl object. :)
Did you see that message in your console? Here's the un-minified source where I think your error occurs.
function initGL() {
try {
var attributes = {
alpha: _alpha,
premultipliedAlpha: _premultipliedAlpha,
antialias: _antialias,
stencil: _stencil,
preserveDrawingBuffer: _preserveDrawingBuffer
};
_gl = _canvas.getContext( 'webgl', attributes ) || _canvas.getContext( 'experimental-webgl', attributes );
if ( _gl === null ) {
throw 'Error creating WebGL context.';
}
} catch ( error ) {
console.error( error );
}
_glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
_glExtensionTextureFloatLinear = _gl.getExtension( 'OES_texture_float_linear' );
_glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );
Is WebGL supported on your IE? Do other webgl tests work? I don't have IE Win8.1 preview but I am curious to know if three.js works with it.

Related

THREE.js CSS2DRenderer - How to save ordinary and CSS2D image as a single .jpg file?

Using the code listed below...
(1) I have been able to save ordinary rendered THREE.js scenes as .jpg files;
(2) I have also been able to use CSS2DRenderer to "render" CSS2D labels on top of (not "onto") the canvas;
(3) Next I want to save the CSS2DRenderer-rendered overlay image as a second .jpg file;
But I get the error:- TypeError: labelRenderer.domElement.toDataURL is not a function.
I am thinking that maybe it is not possible to export from CSS2D?
(4) Ideally I want to save the combined (ordinary and CSS2D overlay) onscreen image as a single .jpg file.
Code:-
// GLOBALS
// INITIATION
var MyContainer = document.getElementById( "for_3JS" );
MyContainer.innerHTML = "";
renderer = new THREE.WebGLRenderer( {antialias:true , preserveDrawingBuffer: true} );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( wwww, hhhh );
MyContainer.appendChild( renderer.domElement );
var labelRenderer = new CSS2DRenderer();
labelRenderer.setSize( wwww, hhhh );
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
MyContainer.appendChild( labelRenderer.domElement );
// ANIMATION & RENDERING
renderer.render ( scene, camera );
labelRenderer.render( scene, camera );
// ONCLICK
var strMime = "image/jpg";
//... THIS WORKS OK (but NO LABELS):-
var imgDataA = renderer.domElement.toDataURL( strMime );
//... THIS FAILS with:- TypeError: labelRenderer.domElement.toDataURL is not a function.
var imgDataB = labelRenderer.domElement.toDataURL( strMime );
//... save as file (imgDataA only at present).
var fileURL = imgDataA;//imgDataB
//...from http://muaz-khan.blogspot.co.uk/2012/10/save-files-on-disk-using-javascript-or.html
var Fsave = document.createElement('a'); //... creates an html <a> anchor object.
document.body.appendChild( Fsave ); //... for Firefox, not needed in Opera (?)
Fsave.style = "display: none";
Fsave.href = fileURL;
Fsave.target = '_blank';
Fsave.download = filename || 'unknown';
Fsave.click();
document.body.removeChild( Fsave );
(2) I have also been able to use CSS2DRenderer to render CSS2D labels onto the canvas;
I'm afraid this formulation is not correct since your are not rendering "onto the canvas" when using CSS2DRenderer or CSS3DRenderer. You actually put HTML elements on top of the canvas and assign them a respective 2D or 3D transformation.
Hence, it is not possible to use toDataURL() to save the output of WebGLRenderer AND CSS2DRenderer into an image.
I have inspected .domElement in the debugger but cannot see toDataURL even for renderer.domElement.
The method definitely exists when using WebGLRenderer, see https://jsfiddle.net/dxmrvzw6/.

issue when real time updating a-sky src

I have simple python based websocket server which passes video frames as base64 string to client.
My client code
var ws = new WebSocket("ws://127.0.0.1:5678/")
ws.onmessage = function (event) {
console.log("Event received: ", event.data.length)
let data = event.data.slice(0, -1);
document.getElementById('sky').setAttribute('src', "data:image/jpg;base64," + data);
};
When I use
//html
<img id="sky" src="" >
as image container, a "video" is produced.
But when I swtich to
<a-scene>
<a-assets>
<img id="sky" src="sky.png">
</a-assets>
<a-sky src="#sky"></a-sky>
</a-scene>
the image container get stuck at first frame, and although the src attribute of img element is updated, the image on web page doesn't change.
I've looked documentation and weren't able to find anything. What should I give attention?
You should access the <a-sky>'s material and texture and set the needsUpdate flag.
For example in a custom component:
AFRAME.registerComponent('foo', {
init: function() {
// wait until the object is loaded
this.el.addEventListener("loaded", e => {
// grab the mesh
var mesh = this.el.getObject3D("mesh")
// expose the material
this.material = mesh.material
})
},
tick: function() {
// when the material is exposed - set the update flag on each tick
if (!this.material) return;
this.material.map.needsUpdate = true
}
}
Canvas texture example here.
Or you can do this with a more direct approach, by accessing the material component:
// Providing the a-sky entity is loaded and ready
a_sky.components.material.material.map.needsUpdate = true
// Untangling it from the left to right:
// entity -> component list -> material component ->
// THREE.js Material object -> texture -> needsUpdate flag

Three.js - TypeError: THREE.XLoader is not a constructor

So I decided to see if I could import a DirectX Model and found this XLoader. However I can't seem to initialize it at all. Now, I am the kind of guy who likes to link directly to the library so that whenever there is an update I don't have to re-download and re-upload. My test code looks like this:
<html>
<body>
<script src="https://threejs.org/build/three.js"></script>
<script type="module" src="https://threejs.org/examples/jsm/loaders/XLoader.js"></script>
<script>
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.001, 10000 );
var manager = new THREE.LoadingManager();
var Texloader = new THREE.TextureLoader();
var loader = new THREE.XLoader(manager, Texloader);
loader.load(['FrigateHull.x'], function (object) {
console.log(object);
},function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}},
function (xhr) {
console.log(xhr);
});
</script>
</body>
</html>
The error I am getting from this setup is this:
TypeError: THREE.XLoader is not a constructor
I have also tried the import method as described in the examples but still same error. I have also downloaded the git to the server and tried linking to that, but it said something about global is undefined.
What am I missing, or is there another DirectX Model Loader out there I could try?
Should be like this:
<script src="https://threejs.org/build/three.js"></script>
<script type="module">
import { XLoader } from "https://threejs.org/examples/jsm/loaders/XLoader.js";
// ....
var loader = new XLoader(manager, Texloader);
// ....
</script>
Although the TypeError: THREE.XLoader is not a constructor exception is resolved, there are still other problems.
Let's look at the source code of XLoader.js:
import {
AnimationClip,
AnimationMixer,
Bone,
BufferGeometry,
FileLoader,
Float32BufferAttribute,
FrontSide,
Loader,
LoaderUtils,
Matrix4,
Mesh,
MeshPhongMaterial,
Quaternion,
Skeleton,
SkinnedMesh,
TextureLoader,
Uint16BufferAttribute,
Vector2,
Vector3
} from "../../../build/three.module.js";
// ...
We don't have ../../../build/three.module.js code.
It is recommended that you clone the repository of three.js, and then npm install → npm start to start the project, instead of viewing it directly in the browser, which involves a lot of import and export of modules depends on front-end construction tools.

Three.js - OrbitControls doesn't work

If I run the script, the console displays me "THREE.OrbitControls is not a constructor".
What did I wrong? I used the same code from a manual.
var controls;
controls = new THREE.OrbitControls( camera );
controls.addEventListener( 'change', render );
var render = function () {
requestAnimationFrame( render );
renderer.render(scene, camera);
//Hier wird die Größe des Fensters manipuliert!
renderer.setSize(window.innerWidth - 20, window.innerHeight - 20);
};
var animate = function () {
requestAnimationFrame( animate );
controls.update();
};
var geometry1 = new THREE.BoxGeometry( 10, 10, 10);
var material = new THREE.MeshPhongMaterial( {specular: "#fdfb57", color: "#d8d613", emissive: "#6b6a0d", side: THREE.DoubleSide} );
var box = new THREE.Mesh(geometry1, material);
scene.add(box);
camera.position.z = 50;
render();
animate();
You must explicitly include OrbitControls in your application. For example:
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims#1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three/build/three.module.js",
"three/addons/": "https://unpkg.com/three/examples/jsm/"
}
}
</script>
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
Also, read the comments in the three.js OrbitControls example carefully so you understand when to use
controls.addEventListener( 'change', render ); // add this only if there is no animation loop (requestAnimationFrame)
and when to use
controls.update(); // required if controls.enableDamping = true, or if controls.autoRotate = true
https://github.com/mrdoob/three.js/blob/dev/examples/misc_controls_orbit.html
three.js r.147
I had the same issue with a webpack build of the three library
var THREE = require('three')
THREE.OrbitControls === undefined // true
Solution, install a 3rd party orbit control
npm install three-orbit-controls
details here: https://github.com/mattdesl/three-orbit-controls
then change the above code fragment to
var THREE = require('three')
var OrbitControls = require('three-orbit-controls')(THREE)
OrbitControls === undefined // false
ok, not the best example, but when applied in place of THREE.OrbitControls, it works just fine ;)
https://github.com/nicolaspanel/three-orbitcontrols-ts :
npm install --save three-orbitcontrols-ts
import { OrbitControls } from 'three-orbitcontrols-ts'
orbitcontrols should be installed separately in angular, this issue bothers me for several days.
I have a same problem too, it's because you put in wrong line.
you need to put it under of this line
document.body.appendChild( renderer.domElement );
then you add orbit controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', posUpdate );
controls.update();
if it wasn't work, add the script file download here
<script src="OrbitControls.js"></script>
I faced similar issue and after lot of research, the below thing worked
In your HTML the order matters when adding OrbitControls as it needs certain things from Three.js.
It should be
<script src="../build/three.min.js"></script>
<script src="js/controls/OrbitControls.js"></script>

Three.js Progress Loader not hiding when model loaded

I have a page based on this example, and using the relevant lines from the webgl_material_bumpmap example for implementing a loading progress Dom Element.
The page is (temporarily) here. If what I have included below is not enough information, please see the source for this page.
My problem is that the Loading text block does not disappear when the model is loaded.
I show it using:
function installModel(file) {
if (model) {**strong text**
scene.remove(model);
}
render();
var loader = new THREE.JSONLoader(true);
loader.load("obj/" + file, modelLoadedCallback);
document.body.appendChild( loader.statusDomElement );
}
The init function (without the error handling stuff) is
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, theCanvas.width/theCanvas.height, 0.1, 100);
camera.position.z = 30;
camera.lookAt( scene.position );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.damping = 0.3;
controls.addEventListener( 'change', render );
createWorld();
installModel("room1.json");
render();
loader.statusDomElement.style.display = "none";
}
Why does the Loading text remain visible?
You probably need to add:
loader.statusDomElement.style.display = "none";
in your callback function modelLoadedCallback() after you print to the console.
I worked it out.
I had to add another div element called "prog"
then
var show
function show() {
document.getElementById("prog").style.display = "inline";
}
and
var loader = new THREE.JSONLoader(true);
document.getElementById("prog").appendChild(loader.statusDomElement );
loader.load("obj/" + file, modelLoadedCallback);

Categories

Resources