level - Combine LOD and Octree for select meshes -
i have prepared simple pieze of code mixing concepts.
in example load geometry (buffergeometry) coming gltf file.
i using lod feature combined simplifymesh function in order have 5 level of details.
i using octree object push lods.
it seems working fine.
my problema want able pick meses mouse middle button, raycaster.intersectoctreeobjects function not working. function expects array of meses , not array of lods passing.
could me addapt code ver able pick lod meses in octree?
here full code.
<!doctype html> <html lang="en"> <head> <title>three.js webgl - level-of-details</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { background:#000; color:#fff; padding:0; margin:0; font-weight: bold; overflow:hidden; } #info { position: absolute; top: 0px; width: 100%; color: #ffffff; padding: 5px; font-family: monospace; font-size: 13px; text-align: center; z-index:100; } { color:red } </style> </head> <body> <div id="info"> <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - level-of-details webgl example </div> <script src="../build/three.js"></script> <script type="text/javascript" src="js/octree.js"></script> <script type="text/javascript" src="js/controls/orbitcontrols.js"></script> <script src="js/controls/flycontrols.js"></script> <script type="text/javascript" src="js/loaders/gltfloader.js"></script> <script src="js/modifiers/simplifymodifier.js"></script> <script src="js/detector.js"></script> <script src="js/libs/stats.min.js"></script> <script> if ( ! detector.webgl ) detector.addgetwebglmessage(); var container, stats; var camera, scene, renderer; var octree; /*var material = new three.meshbasicmaterial({ color: math.random() * 0xffffff, wireframe: false });*/ var objects = []; var material1 = new three.meshbasicmaterial({ side: three.doubleside, //flatshading: true, fog: false, //color: math.random() * 0xffffff, color: 0xff0000, wireframe: true, }); var material2 = new three.meshbasicmaterial({ side: three.doubleside, //flatshading: true, fog: false, //color: math.random() * 0xffffff, color: 0x00ff00, wireframe: true, }); var material3 = new three.meshbasicmaterial({ side: three.doubleside, //flatshading: true, fog: false, //color: math.random() * 0xffffff, color: 0x0000ff, wireframe: true, }); var material4 = new three.meshbasicmaterial({ side: three.doubleside, //flatshading: true, fog: false, //color: math.random() * 0xffffff, color: 0x00ffff, wireframe: true, }); var material5 = new three.meshbasicmaterial({ side: three.doubleside, //flatshading: true, fog: false, //color: math.random() * 0xffffff, color: 0xff00ff, wireframe: true, }); var materials = [ material1, material2, material3, material4]; var geometry, objects; var controls, clock = new three.clock(); var raycaster = new three.raycaster(); var mouse = new three.vector2(); var intersected; init(); animate(); function init() { container = document.createelement( 'div' ); document.body.appendchild( container ); camera = new three.perspectivecamera( 45, window.innerwidth / window.innerheight, 1, 150000 ); camera.position.z = 1000; //controls = new three.flycontrols( camera ); //controls.movementspeed = 1000; //controls.rollspeed = math.pi / 10; scene = new three.scene(); scene.fog = new three.fog( 0x000000, 1, 15000 ); scene.autoupdate = false; var light = new three.pointlight( 0xff2200 ); light.position.set( 0, 0, 0 ); scene.add( light ); var light = new three.directionallight( 0xffffff ); light.position.set( 0, 0, 1 ).normalize(); scene.add( light ); var manager = new three.loadingmanager(); manager.onprogress = function( item, loaded, total ) { console.log( item, loaded, total ); }; 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 ) { console.error( xhr ); }; var loader = new three.gltfloader( manager ); var filename = "mdex-mira/out/glb/part/0177b1200160006_000.gltf"; //var filename = "mdex-mira/out/glb/part/cms-f000a0003000-90.gltf"; octree = new three.octree( { // uncomment below see octree (may kill fps) //scene: scene, // when undeferred = true, objects inserted // instead of being deferred until next octree.update() call // may decrease performance forces matrix update undeferred: false, // set max depth of tree depthmax: infinity, // max number of objects before nodes split or merge objectsthreshold: 8, // percent between 0 , 1 nodes overlap each other // helps insert objects lie on more 1 node overlappct: 0.15 } ); loader.load( filename, function( data ) { console.log(data); var name = data.scene.children[0].children[0].name; var gltf_geom = data.scene.children[0].children[0].geometry; console.log("gltf_geom"); console.log(gltf_geom); var modifer = new three.simplifymodifier(); console.log(modifer); console.log("materials:"); console.log(materials); var gltf_sgeom1 = modifer.modify( gltf_geom,5 ); console.log("conversion 1"); var gltf_sgeom2 = modifer.modify( gltf_geom,10 ); console.log("conversion 2"); var gltf_sgeom3 = modifer.modify( gltf_geom,50 ); console.log("conversion 3"); gltf_sgeom1.dynamic = true; gltf_sgeom2.dynamic = true; gltf_sgeom3.dynamic = true; console.log("simplified"); //console.log(gltf_sgeom); var geometry = [ [ gltf_geom, 100 ], [ gltf_sgeom1, 500], [ gltf_sgeom2, 1000], [ gltf_sgeom3, 2000], [ new three.geometry(), 8000 ] ]; ( j = 0; j < 100; j ++ ) { lod = new three.lod(); ( = 0; < geometry.length; ++ ) { mesh = new three.mesh( geometry[ ][ 0 ], materials[i] ); mesh.scale.set( 1.5, 1.5, 1.5 ); mesh.updatematrix(); mesh.matrixautoupdate = false; lod.addlevel( mesh, geometry[ ][ 1 ] ); } lod.name = name; lod.position.x = 10000 * ( 0.5 - math.random() ); lod.position.y = 7500 * ( 0.5 - math.random() ); lod.position.z = 10000 * ( 0.5 - math.random() ); lod.updatematrix(); lod.matrixautoupdate = false; var w_matrix = lod.matrixworld; console.log("here!!!"); modifyoctree( lod, false ); //scene.add( lod ); } }, onprogress, onerror ); renderer = new three.webglrenderer(); renderer.setpixelratio( window.devicepixelratio ); renderer.setsize( window.innerwidth, window.innerheight ); container.appendchild( renderer.domelement ); controls = new three.orbitcontrols( camera, renderer.domelement ); // window.addeventlistener( 'resize', onwindowresize, false ); } renderer.domelement.addeventlistener('mousedown', ondocumentmousedown, false); function ondocumentmousedown(event) { var button; switch ( event.button ) { case 0: // left button = "left"; break; case 1: // middle //alert("middle"); button = "middle"; var selected_mesh = pick(event) break; case 2: // right button = "right"; break; } //alert("button=" + button); } function pick(event){ event.preventdefault(); switch ( event.button ) { case 0: // left console.log("left"); break; case 1: // middle console.log("middle"); mouse.x = ( event.clientx / window.innerwidth ) * 2 - 1; mouse.y = - ( event.clienty / window.innerheight ) * 2 + 1; raycaster.setfromcamera( mouse, camera ); var octreeobjects; var numobjects; var numfaces = 0; var intersections; octreeobjects = octree.search( raycaster.ray.origin, raycaster.ray.far, true, raycaster.ray.direction ); console.log("octreeobjects"); console.log(octreeobjects); intersections = raycaster.intersectoctreeobjects( octreeobjects ); console.log("number of intersections"); console.log(intersections); numobjects = octreeobjects.length; ( var = 0, il = numobjects; < il; i++ ) { numfaces += octreeobjects[ ].faces.length; } console.log("numfaces:" + numfaces); if ( intersections.length > 0 ) { // selected var distance_array = []; var min_distance = infinity; var index = 0; (i=0; i<intersections.length; i++){ var point = "(" + intersections[i].point.x + "," + intersections[i].point.y + "," + intersections[i].point.z + ")"; var distance = intersections[i].distance; if ( distance < min_distance){ min_distance = distance; index = i; } distance_array.push(distance); var mesh_name = intersections[i].object.name; console.log("mesh [" + + "] name:" + mesh_name + "; position point:" + point + "; distance:" + distance); } console.log("min_distance:" + min_distance + "; index:" + index); console.log("intersections.length > 0"); if ( intersected != intersections[index].object ) { // current selection different previus 1 currentselectedcolor = intersections[index].object.material.color.gethex(); //console.log("intersected != intersections[index].object"); //console.log("currentselectedcolor:" + currentselectedcolor + "; currentselectedcolor:" + currentselectedcolor); if ( intersected ) { // reset previous selection if not null //console.log("intersected1"); intersected.material.color.sethex( previousselectedcolor ); //console.log("currentselectedcolor:" + currentselectedcolor + "; currentselectedcolor:" + currentselectedcolor); } // set new color selection intersected = intersections[index].object; intersected.material.color.sethex( intersectcolor ); previousselectedcolor = currentselectedcolor; //console.log(intersected.name); //console.log("currentselectedcolor:" + currentselectedcolor + "; currentselectedcolor:" + currentselectedcolor); controls.target.copy(intersections[index].point); console.log(raycaster); } //document.body.style.cursor = 'pointer'; } else if ( intersected ) { // nothing has been selected , reset previous selection if not null //console.log("intersected2"); //console.log("currentselectedcolor:" + currentselectedcolor + "; currentselectedcolor:" + currentselectedcolor); intersected.material.color.sethex( previousselectedcolor ); intersected = null; //document.body.style.cursor = 'auto'; } break; } } function modifyoctree( lod, usefaces ) { console.log("modifyoctree_1"); if ( lod ) { console.log("modifyoctree_2"); octree.add( lod, { usefaces: usefaces } ); console.log("modifyoctree_3"); scene.add( lod ); console.log("modifyoctree_4"); objects.push( lod ); console.log("modifyoctree_5"); } } function onwindowresize() { camera.aspect = window.innerwidth / window.innerheight; camera.updateprojectionmatrix(); renderer.setsize( window.innerwidth, window.innerheight ); } function animate() { requestanimationframe( animate ); render(); } function render() { controls.update( clock.getdelta() ); scene.updatematrixworld(); scene.traverse( function ( object ) { if ( object instanceof three.lod ) { object.update( camera ); } } ); octree.update(); renderer.render( scene, camera ); } </script> </body> </html>
best regards
wiki
Comments
Post a Comment