I am building a 3D Visualization and Interactive application using threejs.
Following are the key functionalities I want to provide in this application:
In this User should be able to:
- Rotate and Scale the Obj. -- done
- Manipulate some certain parts of the Obj like, changing its color, replace that part with another. -- pending
I am following the vast threejs documentation and its list of examples, which really helped me a lot and I am able to achieve a little.
Also I have come across an useful threejs inspector Chrome Ext
This threejs inspector Chrome Ext all in all does everything what I want to achive, but unfortunately I am not able to understand that how does it work and how does it able to select and manipulate the parts of an Obj file.
I am using the following piece of code using threejs for now to just display, rotate and scale the Obj file.
if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); var container, camera, controls, scene, renderer; var mtlObject = {}; init(); animate(); function init() { camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.z = 500; controls = new THREE.TrackballControls( camera ); controls.rotateSpeed = 2.0; controls.zoomSpeed = 2.0; controls.panSpeed = 2.0; controls.noZoom = false; controls.noPan = false; controls.staticMoving = true; controls.dynamicDampingFactor = 0.3; controls.keys = [ 65, 83, 68 ]; controls.addEventListener( 'change', render ); // world scene = new THREE.Scene(); var ambient = new THREE.AmbientLight( 0x444444 ); scene.add( ambient ); var directionalLight = new THREE.DirectionalLight( 0xffeedd ); directionalLight.position.set( 0, 0, 1 ).normalize(); scene.add( directionalLight ); // model var onProgress = function ( xhr ) { if ( xhr.lengthComputable ) { var percentComplete = xhr.loaded / xhr.total * 100; console.log( Math.round(percentComplete, 2) + '% downloaded' ); } }; var onError = function ( xhr ) { }; //mtl loader THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() ); var mtlLoader = new THREE.MTLLoader(); mtlLoader.setPath( 'obj/' ); mtlLoader.load( 'bike.mtl', function( materials ) { materials.preload(); var objLoader = new THREE.OBJLoader(); objLoader.setMaterials( materials ); objLoader.setPath( 'obj/' ); objLoader.load( 'bike.obj', function ( object ) { object.position.y = - 95; scene.add( object ); }, onProgress, onError ); }); // lights var light = new THREE.DirectionalLight( 0xffffff ); light.position.set( 1, 1, 1 ); scene.add( light ); var light = new THREE.DirectionalLight( 0x002288 ); light.position.set( -1, -1, -1 ); scene.add( light ); var light = new THREE.AmbientLight( 0x222222 ); scene.add( light ); // renderer renderer = new THREE.WebGLRenderer( { antialias: false } ); //renderer.setClearColor( scene.fog.color ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); container = document.getElementById( 'container' ); container.appendChild( renderer.domElement ); // window.addEventListener( 'resize', onWindowResize, false ); // render(); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); controls.handleResize(); render(); } function animate() { requestAnimationFrame( animate ); controls.update(); } function render() { renderer.render( scene, camera ); }
Please if anyone can help me out in this. Thanks in advance and please comment if I am missing anything.
1 Answers
Answers 1
All three.js inspector is doing is parsing the scene, and displaying the various properties of the objects in an interactive UI.
Let's say you have an OBJ file arranged like this:
bike frame seat drive pedals frontSprocket chain rearSprocket rearWheel steering handlebars fork frontWheel
OBJLoader
would create a scene hierarchy like this:
bike // THREE.Group frame // THREE.Mesh seat // THREE.Mesh drive // THREE.Group pedals // THREE.Mesh frontSprocket // THREE.Mesh chain // THREE.Mesh rearSprocket // THREE.Mesh rearWheel // THREE.Mesh steering // THREE.Group handlebars // THREE.Mesh fork // THREE.Mesh frontWheel // THREE.Mesh
three.js inspector displays this same hierarchy, using the names of the objects. When you click on an object in its tree, it references the object in the scene, and grabs/displays its properties, such as its position
, rotation
, visible
state, etc. When you make a change in the three.js inspector UI, it sets the value on the object in the scene, resulting in the changes you see.
You can do all of this yourself, and you don't even need to be so general about it. Say you want to create a map of object name to the scene object for easier reference (searching the scene is fast enough, but it's recursive). So you could do this:
var nameToObject = {}; scene.traverse(function(node){ // watch out for duplicate empty names! nameToObject[node.name] = node; });
(That doesn't give you the hierarchy, but this is just an example.)
Now you can get and update any object by name:
// enlarge the rear tire nameToObject["rearTire"].scale.addScalar(0.1);
You can read and set all properties of the object. For example, if MTLLoader
created a basic material for the frame, you could do something like this:
// make the frame red nameToObject["frame"].material.color.setRGB(1.0, 0.0, 0.0);
Or you could outright replace the entire material.
For your example of replacing an object, let's say you already loaded a new Mesh
called newRearTire
...
// replace the rear tire var drive = nameToObject["drive"]; // the parent of rearTire drive.remove(nameToObject["rearTire"]); drive.add(newRearTire);
(Of course you would need to re-build your name map at this point.)
These are just very general examples, but should get you started. If you encounter any problems accessing your data, leave a comment and I'll try to clarify.
0 comments:
Post a Comment