I want to get the name of an object i clicked at. The model is loaded into the Scene with ColladaLoader.js.
My Problem is, i just get the THREE.Mesh object but i need the THREE.Object3D object, because the Mesh doesn't contain the name.
If i use the following code:
scene.traverse (function (object){
console.log(object);
});
I get:
THREE.Object3D {uuid: "085928DC-5493-4C57-B142-51D2A95F27B6", name: "Schraube_M4x16_002", type: "Object3D", parent: THREE.Object3D, children: Array[1]…}
THREE.Mesh {uuid: "1AD3D989-CEB7-4B89-BE88-6D58C1C24AD6", name: "", type: "Mesh", parent: THREE.Object3D, children: Array[0]…}
The Object3D has a name the Mesh not. But Raycast only returns meshes How to fix that?
I finally modifyed the ColladaLoader and added the node's name to the mesh.
function createSceneGraph( node, parent ) {
...
// geometries
...
} else {
if ( geom.isLineStrip === true ) {
mesh = new THREE.Line ( geom );
} else {
mesh = new THREE.Mesh ( geom, material );
}
mesh.name = node.name;
}
...
}
Related
I'm hoping to get some help using geometry instancing with A-Frame. I was trying to figure out the bottleneck for my web app and after implementing pooling for physics objects being created in the scene, saw that the number of draw calls was increasing with each new object -- I had thought that by utilizing the asset management system in A-Frame my models were automatically cached, but I think I was mistaken.
I was wondering, if I register the geometry of the model using AFRAME.registerGeometry, would I be able to utilize geometry instancing? I saw that creating from a pool of object using the A-Frame geometry primitives did not increase the geometry count of the scene on a per-entity basis. I took a shot at loading my GLTF and registering the geometry from the mesh, but I'm getting an error from a-node that I don't understand:
<script>
AFRAME.registerGeometry('ramshorn', {
schema: {
depth: {default: 1, min: 0},
height: {default: 1, min: 0},
width: {default: 1, min: 0},
},
init: function(data) {
var model = null;
var geometry = null;
var manager = new THREE.LoadingManager();
manager.onLoad = function () {
console.log(geometry);
this.geometry = geometry;
console.log(this.geometry);
}
var gltfLoader = new THREE.GLTFLoader(manager);
gltfLoader.setCrossOrigin('anonymous');
const src = "./assets/ramsHorn/Ram's Horn 2.gltf";
gltfLoader.load(src, function ( gltf ) {
console.log("Gltf: " + gltf);
model = gltf.scene;
console.log("Model: " + model)
model.children.forEach((child) => {
console.log(child);
});
gltf.scene.traverse(function (o) {
if (o.isMesh) {
geometry = o.geometry;
//console.log(geometry);
//tried assigning "this.geometry" here
}
});
}, undefined, function ( error ) {
console.error(error);
});
//tried assigning "this.geometry" here
}
});
</script>
Error:
core:a-node:error Failure loading node: TypeError: "t is undefined"
aframe-master.min.js:19:658
Any help with this would be appreciated! Thanks
The code at 19:658 in aframe-master.min.js is trying to run something with a variable t but it has not been declared.
By using aframe-master.js it would be possible to get a more meaningful error.
I am trying to remove the point light (or preferrably any light source), but I am new to ThreeJS... I tried babylonScene.remove(object); but I get an error that "cannot call traverse on undefined" or something to that affect. Happy to post the error if that is the suggested approach.
The code below is taken from the ThreeJS example code with the additional removal code.
https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_babylon.html
var loader = new THREE.BabylonLoader( manager );
loader.load( data.src, function ( babylonScene ) {
babylonScene.traverse( function ( object ) {
if ( object instanceof THREE.Mesh ) {
object.material = new THREE.MeshPhongMaterial( {
color: Math.random() * 0xffffff
});
}
else if(object instanceof THREE.PointLight){
console.log("Removing PointLight");
object.remove();
}
});
...
}, onProgress, onError );
The best idea would be to set the light intensity at 0, this means you won't see it anymore:
var loader = new THREE.BabylonLoader( manager );
loader.load( data.src, function ( babylonScene ) {
babylonScene.traverse( function ( object ) {
if ( object instanceof THREE.Mesh ) {
object.material = new THREE.MeshPhongMaterial( {
color: Math.random() * 0xffffff
});
}
else if(object instanceof THREE.PointLight){
console.log("Removing PointLight");
object.intensity = 0
}
});
...
}, onProgress, onError );
Hope this helps!
I have an stl file of the gold ring mesh exported from the blender. When I imported it into three JS and add image texture to get the gold metal effect, the texture is not getting applied properly.
Any suggestions?
Here is the code,
loader.load( objaddress, stladdress, function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
material = new THREE.MeshPhongMaterial({map: new THREE.ImageUtils.loadTexture("Gold.jpg")});
child.material = material;
}
} );
This is the jpg file url I've used:
http://cdn.designbeep.com/wp-content/uploads/2012/10/7.gold-textures.jpg
Once the geometry is loaded from the external file, use THREE js ShaderMaterial to create the material for the loaded geometry. Inside the ShaderMaterial specify the image texture along with the smoothness, noise, wrapping to get a better look and feel.
For reference: http://threejs.org/docs/#Reference/Materials/ShaderMaterial
Here is the code to create the Shader material for the geometry,
var material = new THREE.ShaderMaterial({
uniforms: {
tMatCap: {
type: 't',
value: THREE.ImageUtils.loadTexture('Gold.jpg')
},
time: {
type: 'f',
value: 0
},
bump: {
type: 'f',
value: 0
},
noise: {
type: 'f',
value: .04
},
useNormal: {
type: 'f',
value: 0
},
normalScale: {
type: 'f',
value: .5
},
normalRepeat: {
type: 'f',
value: 1
} });
I am trying to load an object with OBJLoader and subdivide every geometry, so it would look smoother... but when I do so, texture is being ruined. How to avoid that?
var modifier = new THREE.SubdivisionModifier(4);
var loader = new THREE.OBJLoader( manager );
loader.load( 'obj/'+model+'.obj', function ( object ) {
var reflection = THREE.ImageUtils.loadTextureCube( [ 'additional/background.jpg', 'additional/background.jpg', 'additional/background_top.jpg', 'additional/background_down.jpg', 'additional/background.jpg', 'additional/background.jpg' ] );
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.geometry.mergeVertices()
child.geometry.computeFaceNormals();
child.geometry.computeVertexNormals();
child.material.map = texture;
if(reflex){
child.material.envMap = reflection;
child.material.reflectivity = reflex;
}
modifier.modify(child.geometry);
}
} );
I'm trying to select a particular material in the imported model (via Collada loader) in Three.js. I know this can be done with the getChildByName method but it just doesn't work for me. I couldn't find any working example with this method included, either.
What am I doing wrong here?
loader = new THREE.ColladaLoader();
loader.load('myModel.dae', function ( collada ) {
model = collada.scene;
var myMaterial = model.getChildByName( 'materialName', true );
myMaterial.material = new THREE.MeshBasicMaterial( { wireframe: true } );
});
I think this is what you're after.
collada.scene.traverse( function ( child ) {
if ( child.material && child.material.name === 'materialName' ) {
child.material = new THREE.MeshBasicMaterial( { wireframe: true } );
}
} );