three.js - Cannot call method 'loadTexture' of undefined - loading

Sorry for my English.
I've got a problem while working with Three.js.
In every example of loading a texture I see this code:
var map = THREE.ImageUtils.loadTexture( "obj/textures/textures38.jpg" );
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.repeat.set( 3, 3 );
Could you tell me, why can i get messages like
Uncaught TypeError: Cannot call method 'loadTexture' of undefined
This works well:
var material=new THREE.MeshPhongMaterial({color:16777215,map:ImageUtils.loadTexture("obj/textures/textures38.jpg")});
P.S. Three.js version that I currently use is not last
Thank you.

P.S. Three.js version that I currently use is not last
You just answered your own question. Probably that version didn't have ImageUtils namespaced yet. Always recommended using the latest version.

I used
import { BasisTextureLoader } from './jsm/loaders.basisTexureLoader.js';
const loadersvariable = BasisTextureLoader.load("img.jpg");
You need to change permissions on the folder and file or you will get a 403 forbidden error. Point the import path to the dependency to the three.js loader folder but it all has to be together cause all the file link together then you have to call the variable from the file for it to be live without calling the variable from the file you get uncaught referenceError: BasisTextureLoader is not defined
or you can do
<script type="module"> import { TextureLoader } from './src/loaders/TextureLoader.js';
const imagevariablename = new Textureloader.load("image.jpg");
also the displacementmap of examples folder in three.js has a working texture.loader already to copy

Related

How do I get a gltfpack-processed model to appear in A-Frame?

I compressed my models and textures with gltfpack and now they are invisible in A-Frame 1.1.0. In gltfpack, I used -tc to convert the texture files to BasisU and left everything else as is. When I loaded them in A-Frame, the models aren't there. Interestingly, the models work in Don McCurdy's viewer. Update: there is a relevant Javascript console message
THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2
textures.
So it appears I'm misusing Three.js.
Here is a bare Glitch showing the issue. There should be two models visible in the scene but only the unprocessed one is there. Anyone know I could fix it?
The models are working with Don's viewer because he isn't using the standard gltf-model component, but uses a raw threejs loader(with multiple extras):
const loader = new GLTFLoader().setCrossOrigin('anonymous');
loader.setDRACOLoader(new DRACOLoader().setDecoderPath('./wasm/'));
loader.setKTX2Loader(new KTX2Loader().detectSupport(renderer));
Afaik the KTX2Loader on the threejs repo is available only as a module (here), so I've managed to make it work by creating my own module which imports the KTX2Loader. In a nutshell:
// probably only need the KTX2Loader since aframe gives access to
// the GLTFLoader and DRACOLoader.
import { GLTFLoader } from './path_to_three/examples/jsm/loaders/GLTFLoader.js';
import { KTX2Loader } from './path_to_three/examples/jsm/loaders/KTX2Loader.js';
import { DRACOLoader } from './path_to_three/examples/jsm/loaders/DRACOLoader.js';
// this is a 'minimal' version of the gltf-component,
// a more faithful one is linked later on
module.exports.Component =
AFRAME.registerComponent("full-gltf-model",
schema: { type: 'model' },
init: function() {
const loader = new GLTFLoader().setCrossOrigin('anonymous')
.setDRACOLoader(new DRACOLoader().setDecoderPath('./wasm/'))
.setKTX2Loader(new KTX2Loader().detectSupport(renderer));
var src = this.data;
// load the model:
loader.load(src,
function gltfLoaded(gltfModel) {
let model = self.model = gltfModel.scene || gltfModel.scenes[0];
// assuming el is an entity;
el.setObject3D("mesh", model);
}, undefined /* in progress */,
function error(err) {
console.log("error:", err);
})
}
})
I've bundled it with browserify (browserify index.js -p esmify > dist/full-gltf-model.js), and used like this:
<!-- Somewhere in the scripts -->
<script src="dist/full-gltf-model.js>
<!-- Somewhere in the scene -->
<a-entity full-gltf-model="#model"></a-entity>
You can check it out here. The models are straight from Your glitch (credited to you ofc).
Feel free to check out the directory with the component and package.json. I'm pretty sure the bundle contains already defined stuff (1Mb even with only the KTX2Loader imported o.O), so there definitely is room for improvement. Still this seems like a good start :)
Just want to provide an updated answer to this--this is now natively supported in A-Frame. Just do the following:
<a-scene gltf-model="dracoDecoderPath: https://www.gstatic.com/draco/v1/decoders/;
basisTranscoderPath:https://cdn.jsdelivr.net/npm/super-three#0.141.0/examples/js/libs/basis/;;
meshoptDecoderPath: https://unpkg.com/meshoptimizer#~0.18.1/meshopt_decoder.js;">
Note: that basisTranscoderPath is only on master right now--so, not included yet in A-Frame 1.3.0, you'd have to pull master and run a build at the moment. Next release will have it, though. (see the PR)
See the docs on this: https://github.com/jameskane05/aframe/blob/9df1d2cb50ab12aa341cc250c703624510d25deb/docs/components/gltf-model.md
The official master build links are currently lagging behind, and using a github cdn won't work because dist files are not being committed in the last few months, but I made a build and put it on a glitch project of mine--you can use that file at this link if you need this if aframe 1.3.0 is still the most recent version out for you:
https://gltf-packed.glitch.me/aframe-diego.js
(this is a dev build of a particular branch of diego's fork as of oct 15 2022)

Using THREEJS OrbitControls with ES6 module import

When I'm trying to import OrbitControls from the ThreeJS examples, the following errors appear: Attempted import error: 'OrbitControls' is not exported from 'three' (imported as 'THREE').
Here is an example:
https://codesandbox.io/s/lyz5y4kq0z
There is now a very simple solution using the standard "three" npm package, just :
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
I think you're trying to access OrbitControls from the instance of THRRE like below
const controls = new THREE.OrbitControls();
But you should try to access the Orbitcontrols like following way
const controls = new OrbitControls();
You can't get rid of this error, if you try to initiate it from THREE. Thanks
DEPRECATED, PLEASE CHECK https://stackoverflow.com/a/65619187/7355534
I finally solved my issue with a simple solution: I removed the code example provided by ThreeJS and I replaced it with a fix.
I've published the corrective here (with some doc): https://gist.github.com/bastienrobert/f381d642da9abaaaf271866db9da59a7
If you have any recommandations, be free to comment!

Cannot read property 'object3D' of undefined error, when remove() of AFrame component is explicitly called

I am writing a custom timer component for AFrame. The timer is made using basic three.js by grouping multiple three.js object3D's and finally set to the entity (el) using
seconds = new THREE.Object3D();
parent1 = new THREE.Object3D();
seconds.add(parent1);
parent2 = new THREE.Object3D();
seconds.add(parent2);
this.el.setObject3D('Mesh', seconds);
The timer works fine. But when I call remove(), containing the following code.
this.el.removeObject3D('Mesh');
I get the error Uncaught TypeError: Cannot read property 'object3D' of undefined.
I logged el.object3D and the type was "Group" but seconds was "Object3D".
I need to remove the component from the scene. what can I do to fix this?
Please find the code to the component on glitch link
Thanks.
Two options:
Use the DOM API to remove the entity:
var clock=document.getElementById("timer");
document.querySelector("a-scene").removeChild(clock);
Modified glitch
You can also remove the component from the entity:
var clock=document.getElementById("timer");
clock.removeAttribute('timer-component');
glitch
The remove method is not meant to be called directly but a life cycle method invoked automatically when the component is detached from the entity or the entity is removed from the DOM.

How can I have a custom default scene in the three.js editor?

I'm trying to use the Three.js editor to have the population participate in the town planning process. For that, I would like the editor to load with a 3D Version of the town, without the user having to load it manually. Clicking on "New" should also load that default model again.
I already copied the code on our server, it works. Which part of that code should I modify to do have the town model already loaded on startup?
The source code for the threejs editor is available here , you can just download it from it here, add your code to display the default model at appropriate place and host it.
Update 1: Adding a custom model in the Editor's Scene
After reviewing the code of the Editor.js I found that you can add custom objects in the scenevariable defined in the Editor using the addObject() function
I am assuming that you need to add an object which is exported out of blender in .obj format, but using this addObject() function you can add any object/mesh into the editor.
So in index.html add the following lines of code to add a model manually.
var manager = new THREE.LoadingManager();
var loader = new THREE.OBJLoader( manager );
loader.load( '../obj/male02/male02.obj', function ( object ) {
object.position.y =0;
editor.addObject( object );// THIS WAY YOU CAN MANUALLY ADD ANY MESH/OBJECT3D IN THE EDITOR
});
I have made and hosted an example here you can visit it and look around line 123 to see the custom code.

canvas.drawImage(canvas, 0,0) getting Type Error

I am trying to copy the image from one canvas to another canvas. I have seen an answer saying that an easy way to do it is:
var Scanvas = $("#sourceCanvas");
var Scontext = Scanvas.get(0).getContext("2d");
var Dcanvas = $("#destinationCanvas");
var Dcontext = Scanvas.get(0).getContext("2d");
//draw something in Scanvas
Dcontext.drawImage(Scanvas, 0 ,0);
However, whenever I try this I keep getting a Type Error.
The browser I am using is an up-to-date version of Google Chrome, so I don't think that is the problem.
You are using a jQuery object as the first parameter of drawImage().
It needs to be a pure DOM object.
You can access the underlying DOM objects in jQuery by calling get() and specifically get(0) if there is only one object in jQuery selection, as mentioned in the comments.
DContext.drawImage(Scanvas.get(0),....)

Resources