Mercurial > hg > orthanc-stl
diff Resources/Nexus/js/nexus_three.js @ 45:967f947014ac nexus
adding experimental support for nexus models
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 09 Apr 2024 22:13:01 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Nexus/js/nexus_three.js Tue Apr 09 22:13:01 2024 +0200 @@ -0,0 +1,108 @@ +function NexusObject(url, renderer, render, material) { + var gl = renderer.context; + var geometry = new THREE.BufferGeometry(); + var positions = new Float32Array(3); + + + geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3)); + + + if(!material) + this.autoMaterial = true; + + THREE.Mesh.call( this, geometry, material); + this.frustumCulled = false; + + var mesh = this; + var instance = this.instance = new Nexus.Instance(gl); + instance.open(url); + instance.onLoad = function() { + var s = 1/instance.mesh.sphere.radius; + var pos = instance.mesh.sphere.center; + mesh.position.set(-pos[0]*s, -pos[1]*s, -pos[2]*s); + mesh.scale.set(s, s, s); + if(mesh.autoMaterial) + mesh.material = new THREE.MeshLambertMaterial( { color: 0xffffff } ); + + if(this.mesh.vertex.normal) { + var normals = new Float32Array(3); + geometry.addAttribute( 'normal', new THREE.BufferAttribute(normals, 3)); + } + if(this.mesh.vertex.color) { + var colors = new Float32Array(4); + geometry.addAttribute( 'color', new THREE.BufferAttribute(colors, 4)); + if(mesh.autoMaterial) + mesh.material = new THREE.MeshLambertMaterial({ vertexColors: THREE.VertexColors }); + } + + if(this.mesh.vertex.texCoord) { + var uv = new Float32Array(2); + geometry.addAttribute( 'uv', new THREE.BufferAttribute(uv, 2)); + if(mesh.autoMaterial) { + var texture = new THREE.DataTexture( new Uint8Array([1, 1, 1]), 1, 1, THREE.RGBFormat ); + texture.needsUpdate = true; + mesh.material = new THREE.MeshLambertMaterial( { color: 0xffffff, map: texture } ); + } + } + + if(this.mesh.face.index) { + var indices = new Uint32Array(3); + geometry.setIndex(new THREE.BufferAttribute( indices, 3) ); + } + render(); + }; + instance.onUpdate = function() { render(); } + + this.onAfterRender = function(renderer, scene, camera, geometry, material, group) { + if(!instance.isReady) return; + var s = renderer.getSize(); + instance.updateView([0, 0, s.width, s.height], + camera.projectionMatrix.elements, + mesh.modelViewMatrix.elements); + var program = renderer.context.getParameter(gl.CURRENT_PROGRAM); + instance.attributes['position'] = renderer.context.getAttribLocation(program, "position"); + instance.attributes['normal'] = renderer.context.getAttribLocation(program, "normal"); + instance.attributes['color'] = renderer.context.getAttribLocation(program, "color"); + instance.attributes['uv'] = renderer.context.getAttribLocation(program, "uv"); + + instance.render(); + } +} + +NexusObject.prototype = Object.create(THREE.Mesh.prototype); + +NexusObject.prototype.raycast = function(raycaster, intersects) { + var instance = this.instance; + var nexus = instance.mesh; + if(!nexus.sphere) return; + var sp = nexus.sphere; + var c = sp.center; + var center = new THREE.Vector3(c[0], c[1], c[2]); + var sphere = new THREE.Sphere(center, sp.radius); + sphere.applyMatrix4( this.matrixWorld ); + + if ( raycaster.ray.intersectsSphere( sphere ) === false ) return; + //just check the last level spheres. + if(!nexus.sink) return; + + var distance = -1.0; + for(var i = 0; i < nexus.sink; i++) { + var patch = nexus.nfirstpatch[i]; + if(nexus.patches[patch*3] != nexus.sink) + continue; + var x = nexus.nspheres[i*5]; + var y = nexus.nspheres[i*5+1]; + var z = nexus.nspheres[i*5+2]; + var r = nexus.nspheres[i*5+4]; //tight radius + var sphere = new THREE.Sphere(new THREE.Vector3(x, y, z), r); + sphere.applyMatrix4( this.matrixWorld ); + if ( raycaster.ray.intersectsSphere( sphere ) != false ) { + var d = sphere.center.lengthSq(); + if(distance == -1.0 || d < distance) + distance = d; + } + } + if(distance == -1.0) return; + + intersects.push({ distance: distance, object: this} ); +}