Hi all.
First to thank for the great support you allways have provided me.
I have modified the SelectionBox and SelectionHelper modules published in threejs in order to work with instances.
The point is that if I try to use it with an orthographic camera the selection is not accurate. It works properly with a perspective camera.
Note:
In order to enable|disable area picking just double click left mouse button.
In order to test the code with an orthographic camera just comment perspective camera initialization and uncomment orthographic camera initialization in init function.
Here the code:
<!DOCTYPE html>
<html lang="en">
<head><base href="./three.js/examples/" target="_blank">
<title>three.js webgl - scene animation</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 {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
.selectBox {
border: 1px solid #55aaff;
background-color: rgba(75, 160, 255, 0.3);
position: fixed;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> webgl - scene animation - <a href="https://clara.io/view/96106133-2e99-40cf-8abd-64defd153e61">Three Gears Scene</a> courtesy of David Sarno</div>
<script type="text/javascript" src="https://threejs.org/build/three.js"></script>
<script type="text/javascript" src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script id="vertInstanced" type="x-shader/x-vertex">
precision highp float;
float EPSILON = 0.3421;
in float visible;
in float selected;
in vec4 lodInfo;
in vec3 mcol0;
in vec3 mcol1;
in vec3 mcol2;
in vec3 mcol3;
#ifdef PICKING
in float pn_UUID;
#else
in vec4 color;
#endif
out vec3 vPosition;
out float vFragDepth;
out float intensity;
out vec4 vColor;
out float vVisible;
uniform float logDepthBufFC;
vec3 lightDirection;
void main() {
vVisible = visible;
if (vVisible > 0.0) {
mat4 matrix = mat4(
vec4( mcol0, 0 ),
vec4( mcol1, 0 ),
vec4( mcol2, 0 ),
vec4( mcol3, 1 )
);
vec3 tPosition = (matrix * vec4(position, 1.0)).xyz;
vec3 positionEye = vec3( modelViewMatrix * vec4(tPosition, 1.0 ) ).xyz;
//vec3 positionEye = ( modelViewMatrix * matrix * vec4( position, 1.0 ) ).xyz;
vec3 cameraPos1 =vec3( modelViewMatrix * vec4(cameraPosition, 1.0 ) ).xyz;
gl_Position = projectionMatrix * vec4( positionEye, 1.0 );
vec3 cameraP = (projectionMatrix * vec4(cameraPos1, 1.0)).xyz;
vFragDepth = 1.0 + gl_Position.w;
gl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;
lightDirection = normalize(vec3(cameraPosition.x-gl_Position.x, cameraPosition.y-gl_Position.y, cameraPosition.z-gl_Position.z));
intensity = pow( 1.0 - dot (normal, lightDirection), 1.0);
vPosition = vec3(gl_Position.x, gl_Position.y, gl_Position.z);
//if ( distance(cameraPos1, positionEye) > lodInfo.a ) {
// vVisible = 0.0;
//}
#ifdef PICKING
vColor = vec4(tPosition, pn_UUID);
#else
if ( selected > 0.0 ) {
vColor = vec4(1.0, color.g, color.b, 0.5);
} else {
vColor = color;
}
#endif
}
}
</script>
<script id="fragInstanced" type="x-shader/x-fragment">
precision highp float;
in float vFragDepth;
in float intensity;
in float vVisible;
in vec4 vColor;
in vec3 vPosition;
out vec4 myColor;
uniform float logDepthBufFC;
void main() {
if ( vVisible > 0.0) {
#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)
gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;
#endif
#ifdef PICKING
myColor = vColor;
#else
myColor = vColor;
myColor.rgb *= intensity * 0.65;
#endif
} else {
discard;
}
}
</script>
<script>
var container, stats;
var selectionBox, helper;
var isSelecting = false;
var camera, controls, scene, renderer;
var objects = [];
var materialList = [];
var geometryList = [];
var dummyVector = new THREE.Vector3();
//var instanceCount = 10;
var objectCount = 0;
var vert = document.getElementById( 'vertInstanced' ).textContent;
var frag = document.getElementById( 'fragInstanced' ).textContent;
var material = new THREE.ShaderMaterial( {
vertexShader: "#version 300 es\n" + vert,
fragmentShader: "#version 300 es\n" +frag,
transparent: true,
side: THREE.DoubleSide,
clipping: true,
clipShadows: false
} );
materialList.push( material );
var pickingMaterial = new THREE.ShaderMaterial( {
vertexShader: "#version 300 es\n" +"#define PICKING\n" + vert,
fragmentShader: "#version 300 es\n" +"#define PICKING\n" + frag,
clipping: true,
clipShadows: false
} );
materialList.push( pickingMaterial );
console.log(materialList);
// Internal Functions:
var SelectionHelper = function( selectionBox, renderer, cssClassName ) {
var selectionHelper = this;
selectionHelper.isEnabled = isSelecting;
selectionHelper.element = document.createElement( "div" );
selectionHelper.element.classList.add( cssClassName );
selectionHelper.element.style.pointerEvents = "none";
selectionHelper.renderer = renderer;
selectionHelper.startPoint = { x: 0, y: 0 };
selectionHelper.pointTopLeft = { x: 0, y: 0 };
selectionHelper.pointBottomRight = { x: 0, y: 0 };
selectionHelper.isDown = false;
selectionHelper.renderer.domElement.addEventListener( "mousedown", function ( event ) {
selectionHelper.isDown = true;
selectionHelper.onSelectStart( event );
}.bind( selectionHelper ), false );
selectionHelper.renderer.domElement.addEventListener( "mousemove", function ( event ) {
if ( selectionHelper.isDown ) {
selectionHelper.onSelectMove( event );
}
}.bind( selectionHelper ), false );
selectionHelper.renderer.domElement.addEventListener( "mouseup", function ( event ) {
selectionHelper.isDown = false;
selectionHelper.onSelectOver( event );
}.bind( selectionHelper ), false );
selectionHelper.onSelectStart = function ( event ) {
if (isSelecting == true) {
selectionHelper.renderer.domElement.parentElement.appendChild( selectionHelper.element );
selectionHelper.element.style.left = event.clientX + "px";
selectionHelper.element.style.top = event.clientY + "px";
selectionHelper.element.style.width = "0px";
selectionHelper.element.style.height = "0px";
selectionHelper.startPoint.x = event.clientX;
selectionHelper.startPoint.y = event.clientY;
}
}
selectionHelper.onSelectMove = function ( event ) {
if (isSelecting == true) {
selectionHelper.pointBottomRight.x = Math.max( selectionHelper.startPoint.x, event.clientX );
selectionHelper.pointBottomRight.y = Math.max( selectionHelper.startPoint.y, event.clientY );
selectionHelper.pointTopLeft.x = Math.min( selectionHelper.startPoint.x, event.clientX );
selectionHelper.pointTopLeft.y = Math.min( selectionHelper.startPoint.y, event.clientY );
selectionHelper.element.style.left = selectionHelper.pointTopLeft.x + "px";
selectionHelper.element.style.top = selectionHelper.pointTopLeft.y + "px";
selectionHelper.element.style.width = ( selectionHelper.pointBottomRight.x - selectionHelper.pointTopLeft.x ) + "px";
selectionHelper.element.style.height = ( selectionHelper.pointBottomRight.y - selectionHelper.pointTopLeft.y ) + "px";
}
}
selectionHelper.onSelectOver = function ( event ) {
if (isSelecting == true) {
selectionHelper.element.parentElement.removeChild( selectionHelper.element );
}
}
}
var SelectionBox = function( camera, scene, deep ) {
var selectionBox = this;
selectionBox.camera = camera;
selectionBox.scene = scene;
selectionBox.startPoint = new THREE.Vector3();
selectionBox.endPoint = new THREE.Vector3();
selectionBox.collection = [];
selectionBox.deep = deep || Number.MAX_VALUE;
selectionBox.select = function ( startPoint, endPoint ) {
selectionBox.startPoint = startPoint || selectionBox.startPoint;
selectionBox.endPoint = endPoint || selectionBox.endPoint;
selectionBox.collection = [];
var boxSelectionFrustum = selectionBox.createFrustum( selectionBox.startPoint, selectionBox.endPoint );
console.log(boxSelectionFrustum);
selectionBox.searchChildInFrustum( boxSelectionFrustum, selectionBox.scene );
console.log("selectionBox.collection:", selectionBox.collection);
return selectionBox.collection;
}
selectionBox.createFrustum = function ( startPoint, endPoint ) {
console.log("startPoint", startPoint, "endPoint", endPoint);
startPoint = startPoint || selectionBox.startPoint;
endPoint = endPoint || selectionBox.endPoint
selectionBox.camera.updateProjectionMatrix();
selectionBox.camera.updateMatrixWorld();
selectionBox.camera.updateMatrix();
var tmpPoint = startPoint.clone();
tmpPoint.x = Math.min( startPoint.x, endPoint.x );
tmpPoint.y = Math.max( startPoint.y, endPoint.y );
endPoint.x = Math.max( startPoint.x, endPoint.x );
endPoint.y = Math.min( startPoint.y, endPoint.y );
var vecNear = selectionBox.camera.position.clone();
var vecTopLeft = tmpPoint.clone();
var vecTopRight = new THREE.Vector3( endPoint.x, tmpPoint.y, 0 );
var vecDownRight = endPoint.clone();
var vecDownLeft = new THREE.Vector3( tmpPoint.x, endPoint.y, 0 );
vecTopLeft.unproject( selectionBox.camera );
vecTopRight.unproject( selectionBox.camera );
vecDownRight.unproject( selectionBox.camera );
vecDownLeft.unproject( selectionBox.camera );
var vectemp1 = vecTopLeft.clone().sub( vecNear );
var vectemp2 = vecTopRight.clone().sub( vecNear );
var vectemp3 = vecDownRight.clone().sub( vecNear );
vectemp1.normalize();
vectemp2.normalize();
vectemp3.normalize();
vectemp1.multiplyScalar( selectionBox.deep );
vectemp2.multiplyScalar( selectionBox.deep );
vectemp3.multiplyScalar( selectionBox.deep );
vectemp1.add( vecNear );
vectemp2.add( vecNear );
vectemp3.add( vecNear );
var planeTop = new THREE.Plane();
planeTop.setFromCoplanarPoints( vecNear, vecTopLeft, vecTopRight );
var planeRight = new THREE.Plane();
planeRight.setFromCoplanarPoints( vecNear, vecTopRight, vecDownRight );
var planeDown = new THREE.Plane();
planeDown.setFromCoplanarPoints( vecDownRight, vecDownLeft, vecNear );
var planeLeft = new THREE.Plane();
planeLeft.setFromCoplanarPoints( vecDownLeft, vecTopLeft, vecNear );
var planeFront = new THREE.Plane();
planeFront.setFromCoplanarPoints( vecTopRight, vecDownRight, vecDownLeft );
var planeBack = new THREE.Plane();
planeBack.setFromCoplanarPoints( vectemp3, vectemp2, vectemp1 );
planeBack.normal = planeBack.normal.multiplyScalar( -1 );
return new THREE.Frustum( planeTop, planeRight, planeDown, planeLeft, planeFront, planeBack );
}
selectionBox.searchChildInFrustum = function ( frustum, scene ) {
var geometry
selectionBox.collection = [];
scene.traverse(function(object) {
if ( object.geometry != undefined ) {
//console.log(object.geometry);
object.geometry.name = object.geometry.uuid;
object.geometry.computeBoundingSphere();
object.geometry.computeBoundingBox();
if (object.geometry.attributes.pn_UUID != undefined) {
var uuidArray = [];
var colorArray = [];
var matrixArray = [];
for (var i in object.geometry.attributes.pn_UUID.array) {
var matrix = new THREE.Matrix4();
matrix.elements = [
object.geometry.attributes.mcol0.array[i*3], object.geometry.attributes.mcol0.array[(i*3)+1], object.geometry.attributes.mcol0.array[(i*3)+2], 0,
object.geometry.attributes.mcol1.array[i*3], object.geometry.attributes.mcol1.array[(i*3)+1], object.geometry.attributes.mcol1.array[(i*3)+2], 0,
object.geometry.attributes.mcol2.array[i*3], object.geometry.attributes.mcol2.array[(i*3)+1], object.geometry.attributes.mcol2.array[(i*3)+2], 0,
object.geometry.attributes.mcol3.array[i*3], object.geometry.attributes.mcol3.array[(i*3)+1], object.geometry.attributes.mcol3.array[(i*3)+2], 1
];
var center = object.geometry.boundingSphere.center.clone().applyMatrix4( matrix );
//console.log("i:", i, "pn_UUID:", object.geometry.attributes.pn_UUID.array[i]);
if ( frustum.containsPoint( center ) ) {
//console.log("frustum.containsPoint:" + object.geometry.attributes.pn_UUID.array[i]);
uuidArray.push(object.geometry.userData.uuid2IdArray[object.geometry.attributes.pn_UUID.array[i]]);
colorArray.push([
object.geometry.attributes.color.array[i*4],
object.geometry.attributes.color.array[(i*4)+1],
object.geometry.attributes.color.array[(i*4)+2],
object.geometry.attributes.color.array[(i*4)+3]
]);
var matrix = new THREE.Matrix4();
matrix.elements = [
object.geometry.attributes.mcol0.array[i*3], object.geometry.attributes.mcol0.array[(i*3)+1], object.geometry.attributes.mcol0.array[(i*3)+2], 0,
object.geometry.attributes.mcol1.array[i*3], object.geometry.attributes.mcol1.array[(i*3)+1], object.geometry.attributes.mcol1.array[(i*3)+2], 0,
object.geometry.attributes.mcol2.array[i*3], object.geometry.attributes.mcol2.array[(i*3)+1], object.geometry.attributes.mcol2.array[(i*3)+2], 0,
object.geometry.attributes.mcol3.array[i*3], object.geometry.attributes.mcol3.array[(i*3)+1], object.geometry.attributes.mcol3.array[(i*3)+2], 0,
];
matrixArray.push(matrix);
//console.log("object.geometry.attributes.pn_UUID.array[i]", object.geometry.attributes.pn_UUID.array[i]);
}
}
if (uuidArray.length > 0) {
selectionBox.collection.push( {
geo: object.geometry,
id:object.geometry.name,
uuidArray: uuidArray,
colorArray: colorArray,
matrixArray: matrixArray
});
console.log(selectionBox.collection);
}
}
}
});
}
}
var randomizeMatrix = function() {
var position = new THREE.Vector3();
var rotation = new THREE.Euler();
var quaternion = new THREE.Quaternion();
var scale = new THREE.Vector3();
return function( matrix ) {
position.x = Math.random() * 800 - 90;
position.y = Math.random() * 800 - 90;
position.z = Math.random() * 800 - 90;
rotation.x = Math.random() * 2 * Math.PI;
rotation.y = Math.random() * 2 * Math.PI;
rotation.z = Math.random() * 2 * Math.PI;
quaternion.setFromEuler( rotation, false );
scale.x = scale.y = scale.z = 1;
matrix.compose( position, quaternion, scale );
};
}();
// BEGIN:
init();
animate();
function makeInstanced( geo, instanceCount ) {
// geometry
geometryList.push( geo );
geo.computeBoundingSphere();
geo.computeBoundingBox();
geometrySize = geo.boundingBox.getSize(dummyVector);
console.log("geometrySize:", geometrySize);
var sizeArray = [geometrySize.x, geometrySize.y, geometrySize.z].sort((a, b) => b - a);
var occlussionDistance = (sizeArray[0]+ sizeArray[1]) * 0.5 * 500;
//console.log("occlussionDistance:", occlussionDistance);
geometryCenter = geo.boundingBox.getCenter(dummyVector);
//console.log("geometryCenter:", geometryCenter);
var igeo = new THREE.InstancedBufferGeometry();
igeo.index = geo.index;
igeo.attributes.position = geo.attributes.position;
igeo.attributes.normal = geo.attributes.normal;
igeo.attributes.uv = geo.attributes.uv;
geometryList.push( igeo );
igeo.userData = {
uuid2IdArray: []
}
// Instanced Attributes Definition:
// Visible:
var visible = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 1 ), 1, true, 1 );
// Selected:
var selected = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 1 ), 1, true, 1 );
// Absolute Transformation Matrix:
var mcol0 = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 3 ), 3, true, 1 );
var mcol1 = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 3 ), 3, true, 1 );
var mcol2 = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 3 ), 3, true, 1 );
var mcol3 = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 3 ), 3, true, 1 );
// Center and Occlussion Distance of object from camera position:
var lodInfo = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 4 ), 4,true, 1 );
// Scene Colors:
var colors = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 4 ), 4, true, 1 );
// UUID information
var pn_UUID = new THREE.InstancedBufferAttribute( new Float32Array( instanceCount * 1 ), 1 ,true, 1 );
// Instanced Attributes Assignation:
var matrix = new THREE.Matrix4();
var me = matrix.elements;
console.log(instanceCount);
for ( var i=0; i < instanceCount; i ++ ) {
objectCount ++;
visible.array[i] = 1;
selected.array[i] = 0;
randomizeMatrix( matrix );
var instanceCenter = geometryCenter.applyMatrix4(matrix);
//console.log("instanceCenter:", instanceCenter);
mcol0.setXYZ( i, me[ 0 ], me[ 1 ], me[ 2 ] );
mcol1.setXYZ( i, me[ 4 ], me[ 5 ], me[ 6 ] );
mcol2.setXYZ( i, me[ 8 ], me[ 9 ], me[ 10 ] );
mcol3.setXYZ( i, me[ 12 ], me[ 13 ], me[ 14 ] );
lodInfo.array[i*4] = instanceCenter.x;
lodInfo.array[(i*4) + 1] = instanceCenter.y;
lodInfo.array[(i*4) + 2] = instanceCenter.z;
lodInfo.array[(i*4) + 3] = occlussionDistance;
colors.array[i*4] = Math.random();
colors.array[(i*4) + 1] = Math.random();
colors.array[(i*4) + 2] = Math.random();
colors.array[(i*4) + 3] = Math.random();
//colors.array[i*4] = 0.0;
//colors.array[(i*4) + 1] = 0.0;
//colors.array[(i*4) + 2] = 1.0;
//colors.array[(i*4) + 3] = 1.0;
igeo.userData.uuid2IdArray[objectCount] = i;
pn_UUID.array[i] = objectCount;
}
// Instanced Attributes addition:
igeo.addAttribute( 'visible', visible );
igeo.addAttribute( 'selected', selected );
igeo.addAttribute( 'mcol0', mcol0 );
igeo.addAttribute( 'mcol1', mcol1 );
igeo.addAttribute( 'mcol2', mcol2 );
igeo.addAttribute( 'mcol3', mcol3 );
igeo.addAttribute( 'lodInfo', lodInfo );
igeo.addAttribute( 'color', colors );
igeo.addAttribute( 'pn_UUID', pn_UUID );
// mesh
mesh = new THREE.Mesh( igeo, material );
mesh.frustumCulled = false;
console.log(mesh);
scene.add( mesh );
}
function updateInstances(geometry, uuidArray, attribute, value) {
//console.log("geometry 1:", geometry);
for (var i in uuidArray) {
var uuid = uuidArray[i];
switch (attribute) {
case "color": // Replaces color in instanced attributes
if (value.length == 1) {
geometry.attributes.color.array[uuid*4] = value[0][0];
geometry.attributes.color.array[(uuid*4)+1] = value[0][1];
geometry.attributes.color.array[(uuid*4)+2] = value[0][2];
geometry.attributes.color.array[(uuid*4)+3] = value[0][3];
} else {
geometry.attributes.color.array[uuid*4] = value[i][0];
geometry.attributes.color.array[(uuid*4)+1] = value[i][1];
geometry.attributes.color.array[(uuid*4)+2] = value[i][2];
geometry.attributes.color.array[(uuid*4)+3] = value[i][3];
}
geometry.attributes.color.needsUpdate = true;
break;
case "visible": // Replaces visible in instanced attributes
if (value.length == 1) {
geometry.attributes.visible.array[uuid] = value[0];
} else {
geometry.attributes.visible.array[uuid] = value[i];
}
geometry.attributes.visible.needsUpdate = true;
break;
case "tMatrix": // multiplies absmatrix in instanced attributes by passed matrix
break;
case "rMatrix": // Replaces absmatrix in instanced attributes
break;
case "selected": // Replaces selected in instanced attributes
if (value.length == 1) {
geometry.attributes.selected.array[uuid] = value[0];
} else {
geometry.attributes.selected.array[uuid] = value[i];
}
geometry.attributes.selected.needsUpdate = true;
break;
case "pickable": // Replaces color in instanced attributes
if (value.length == 1) {
geometry.attributes.pickable.array[uuid] = value[0];
} else {
geometry.attributes.pickable.array[uuid] = value[i];
}
geometry.attributes.pickable.needsUpdate = true;
break;
}
}
}
function switchCamera() {
if (camera instanceof THREE.PerspectiveCamera) {
camera = new THREE.OrthographicCamera(
window.innerWidth / - 16, window.innerWidth / 16,window.innerHeight / 16, window.innerHeight / - 16, -200, 500 );
camera.position.x = 2;
camera.position.y = 1;
camera.position.z = 3;
camera.lookAt(scene.position);
this.perspective = "Orthographic";
} else {
camera = new THREE.PerspectiveCamera(45,
window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 120;
camera.position.y = 60;
camera.position.z = 180;
camera.lookAt(scene.position);
this.perspective = "Perspective";
}
}
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 5000 );
//frustumSize = 1000;
//var aspect = window.innerWidth / window.innerHeight;
//camera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 0.1, 1000 );
camera.position.z = 1000;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf0f0f0 );
var geometry1 = new THREE.BoxBufferGeometry( 20, 20, 20 );
makeInstanced( geometry1, 500 )
var geometry2 = new THREE.SphereBufferGeometry( 10, 8, 6 );
makeInstanced( geometry2, 500 )
var geometry3 = new THREE.CylinderBufferGeometry( 10, 5, 20, 32 );
makeInstanced( geometry3, 500 )
var geometry4 = new THREE.CylinderBufferGeometry( 10, 10, 20, 32 );
makeInstanced( geometry4, 500 )
container = document.getElementById( "container" );
var canvas = document.createElement( 'canvas' );
gl = canvas.getContext( 'webgl2', { antialias: true } );
gl.getExtension('EXT_color_buffer_float');
gl.enable(gl.SAMPLE_ALPHA_TO_COVERAGE);
renderer = new THREE.WebGLRenderer( {
logarithmicDepthBuffer: true,
canvas: canvas, context: gl
} );
renderer.setClearColor( 0xffffff );
renderer.autoClear = true;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = true;
container.appendChild( renderer.domElement );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '0px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - box selection';
container.appendChild( info );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render );
renderer.domElement.addEventListener('dblclick', onDblclickGl, false);
window.addEventListener( 'resize', onWindowResize, false );
}
function onDblclickGl(e){
console.log(e);
if (isSelecting == false) {
isSelecting =true;
if (controls != undefined) {
console.log("removing Listener in controls");
controls.enabled = false;
}
selectionBox = new SelectionBox( camera, scene );
helper = new SelectionHelper( selectionBox, renderer, "selectBox" );
} else {
isSelecting = false;
if (selectionBox != undefined && helper != undefined) {
console.log(selectionBox, helper);
}
selectionBox = undefined;
helper = undefined;
controls.enabled = true;
}
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
//stats.update();
//rendererStats.update(renderer);
}
function render() {
renderer.render( scene, camera );
}
// Events:
document.addEventListener("mousedown", function ( event ) {
console.log("mousedown",isSelecting);
console.log("geometries:", renderer.info.memory.geometries,
"calls:", renderer.info.render.calls,
"frame:", renderer.info.render.frame,
"lines:", renderer.info.render.lines,
"points:", renderer.info.render.points,
"triangles:", renderer.info.render.triangles
);
if (isSelecting == true) {
for ( var i in selectionBox.collection ) {
// Change attributes
//updateInstances(selectionBox.collection[i].geo, selectionBox.collection[i].uuidArray, "color", [[1,0,0,1]])
updateInstances(selectionBox.collection[i].geo, selectionBox.collection[i].uuidArray, "selected", [1])
}
selectionBox.startPoint.set(
( event.clientX / window.innerWidth ) * 2 - 1,
-( event.clientY / window.innerHeight ) * 2 + 1,
0.01 );
}
} );
document.addEventListener( "mousemove", function ( event ) {
if (isSelecting == true) {
if ( helper.isDown ) {
for ( var i = 0; i < selectionBox.collection.length; i++ ) {
// Reset all objects:
updateInstances(selectionBox.collection[i].geo, selectionBox.collection[i].uuidArray, "selected", [0])
}
selectionBox.endPoint.set(
( event.clientX / window.innerWidth ) * 2 - 1,
-( event.clientY / window.innerHeight ) * 2 + 1,
0.5 );
var allSelected = selectionBox.select();
for ( var i = 0; i < allSelected.length; i++ ) {
// Change attributes
updateInstances(selectionBox.collection[i].geo, selectionBox.collection[i].uuidArray, "selected", [1])
}
}
}
} );
document.addEventListener("mouseup", function ( event ) {
if (isSelecting == true) {
selectionBox.endPoint.set(
(event.clientX / window.innerWidth) * 2 - 1,
-(event.clientY / window.innerHeight) * 2 + 1,
0.5 );
var allSelected = selectionBox.select();
for ( var i = 0; i < allSelected.length; i++ ) {
// Finally change attrs
updateInstances(selectionBox.collection[i].geo, selectionBox.collection[i].uuidArray, "selected", [1])
}
}
});
</script>
</body>
</html>
Best regards