threejs how to get geometry of loaded models using OBJMTLloder on callback - three.js

How to get the geometry of loaded models using OBJMTLloder on callback, i can't get the geometry of the loaded object, if i get it with the object traverse can get the only one portion of the object, i want to get the geometry of the object dynamically to scale the object into center of the scene
object.traverse( function ( child ) {
if (child instanceof THREE.Mesh) {
var geometry = child.geometry;
material = child.material;
child.material.needsUpdate = true;
}
});

If you want to scale the object you dont need to use the traverse() method. You can do:
object.scale.x = x_scale;
object.scale.y = y_scale;
object.scale.z = z_scale;
You can also use the BoundingBoxHelper() method to find the approximate size of the object.

Related

How textureLoader.load for more than 1 texture and assigning map names to each texture?

How can I call textureLoader.load only once and assign a map name to each texture and so that it I can call creating the material when all the textures have loaded?
Otherwise I can't control when to create the material and assign the textures correctly.
I am working with obj without loading mtl.
Thank you for your help
This is the code I'm asking to replace for one function textureLoader.load
var textureLoader = new THREE.TextureLoader(manager);
var albedoM = textureLoader.load( "vaseTextures/albedo.png", onLoad, onProgress, onError );
var normalMap = textureLoader.load( "vaseTextures/normal.png", onLoad, onProgress, onError );
var aoMap = textureLoader.load( "vaseTextures/cavity.png", onLoad, onProgress, onError );
Expected result: I call once function onLoad( texture) after the textures are loaded and saving a name for each texture, and so that I can then create one material that holds each texture and assign the textures to it.
In this case, it's best to use the onLoad() callback of THREE.LoadingManager. It will be executed as soon as all resources are loaded. Since you already pass an instance of THREE.LoadingManager to your texture loader, you just have to implement onLoad(). For example like so:
manager.onLoad = function ( ) {
const material = new THREE.MeshPhongMaterial();
material.map = albedoM;
material.normalMap = normalMap;
material.aoMap = aoMap;
// do something with your material
};
three.js R103

three.js GPU Instantiation with custom mesh and material

Trying to implement GPU instantiation, following the instances/gpu three.js example.
However, somehow nothing seems to be loading in my attempt: http://designs.playgami.com/webgl_loader_fbx3.html
(here is the non-gpu instantiation version - http://designs.playgami.com/webgl_loader_fbx2.1.html)
Here's specifically where I am trying to load the fbx model just once, and then instantiate. I'm trying to instantiate using var object = new THREE.Mesh( geo );, but somehow that does not work?
function CreateCraneScape(texturearray,squareside,armyside){
var total = texturearray.length;
var halfside = Math.floor(squareside*0.5);
loader.load( '/11272018-crane.fbx', function ( geo ) {
var k = 0;
// create cranes
for(var i=-halfside;i<=halfside;i++){
for(var j=-halfside;j<=halfside;j++){
var object = new THREE.Mesh( geo );
CraneApplyTexture(object,texturearray[k]);
CranePosRot(object,i,j);
k++;
}
}
// create army
for(var i=-(halfside+armyside);i<=(halfside+armyside);i++){
for(var j=-(halfside+armyside);j<=(halfside+armyside);j++){
if(j<-halfside||j>halfside || (i<-halfside||i>halfside)){
var object = new THREE.Mesh( geo );
CraneApplyTexture(object,'');
CreatePosRot(object,i,j);
}
}
}
});
}
Apparently FBXLoader does not load just the mesh geometry but actually the entire three.js game object. So, the mesh instantiation needed to reference the geometry of the first child.
geo = geo.children[0].geometry;

Three.js: Do I have to set up the anisotropic texture filtering for each texture?

Do I have to set up the anisotropic texture filtering for each texture?
I think it would be cool If you can set the anisotropic level for a material or even for the global scene. Any Ideas?
maxA = renderer.getMaxAnisotropy();
var texture1 = THREE.ImageUtils.loadTexture('models/folder/m67/o1.jpg');
texture1.anisotropy = maxA;
var texture2 = THREE.ImageUtils.loadTexture('models/folder/m67/o2.jpg');
texture2.anisotropy = maxA;
var texture3 = THREE.ImageUtils.loadTexture('models/folder/m67/c1.jpg');
texture3.anisotropy = maxA;
var texture4 = THREE.ImageUtils.loadTexture('models/folder/m67/c2.jpg');
texture4.anisotropy = maxA;
var material = {
"logoprint": new THREE.MeshPhongMaterial({
map: texture1
}),
}
you can wrap the load into a function, imageutils just gives you another utility function
function loadTexture( url ){
var tex = THREE.ImageUtils.loadTexture(url);
tex.anisotropy = MAXANISO;
return tex;
}
To clarify what's happening here, and what to do about the ImageUtils depreciation warning:
var tl = new THREE.TextureLoader();
//calling load on it immediately returns a THREE.Texture object
var myTexture = tl.load( 'name.jpg' );
//you can also pass a callback
function onTextureLoaded( tex ){
//tex.image contains data, because textureLoader updated it, before passing it to the callback
handleTexture( tex )...
}
var myTexture = tl.load( 'name.jpg' , onTextureLoaded );
// myTexture is now an instance of THREE.Texture
// myTexture.image contains no data
myTexture.aniso = ...; //texture is configured , but probably waiting for data
The texture object itself holds all these 3d properties like wrapping, mapping type and filtering. The image data itself has nothing to do with this, it stays the same regardless of how you use it.
When you call load on the texture loader, it gives you back a proxy - a reference to an object that can be configured, manipulated, and passed to other objects (like materials) to be used.
A material can render an empty texture. When the image data is loaded, the texture is updated and the very next frame will reflect that.
var tl = new THREE.TextureLoader()
function myCustomLoad( url ){
var newTex = tl.load(url); //make the proxy
newTex.prop = ... ;//config
return newTex; //return configured texture, it will update itself
}

.vertices array does not give the vertices in THREE.js

I am using OBJloader to load an .obj file in WEBGL , Three.js.
I want to access the vertices and faces of the objects but the geometry.vertices does not return the vertices positions and it gives me undefined.
Here is a piece of code:
var tool= new THREE.OBJLoader();
tool.load( '../obj/tool.obj', function ( object ) {
var material = new THREE.MeshLambertMaterial({color:0xA0A0A0});
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material = material;
console.log( "child" + child.geometry.vertices);} }
r.70
I am thankful for your helps in advance.
This answer only applies to versions of three.js prior to r.125.
If the loader you are using is returning BufferGeometry, you can convert the returned geometry to Geometry in the loader callback using a pattern like so:
var geometry = new THREE.Geometry().fromBufferGeometry( bufferGeometry );
three.js r.124

threejs wireframe helper with object traverse

i want to apply the WireframeHelper to the object that is loaded using OBJMTLLoder objects, i know that i must do the traverse the mesh to apply it on the entire object, so here i tried like below
mesh.traverse ( function (child) {
if (child instanceof THREE.Mesh)
{
wfh = new THREE.WireframeHelper( mesh,whfcolor );
wfh.material.depthTest = false;
wfh.material.opacity = 0.25;
wfh.material.transparent = true;
scene.add( wfh );
}
});
but it is not working the wireframe is only apply on the some part of the object only, not the entire object, it is working fine with the OBJLoader alone

Resources