Dear Mugen.
Many thanks for your response.
Finally I got Selection working with instances but for perspective camera.
The point is that I need to make Selection Box working also for ortographic camera.
I attach an example in order you see the problem, as you will see when you double click you activa selection area but with an ortographic camera it is not working.
I think the problem is on the createFrustum function but I am not an exapert like you.
COuld you give a clue?
Many thanks in advanced for your support.
Best regards
Here the code:
three.js webgl - scene animation
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 src="https://threejs.org/build/three.js"></script>
<script src="/libs/Detector.js"></script>
<script src="https://threejs.org/examples/js/libs/stats.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="/libs/threex.rendererstats.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 rendererStats = new THREEx.RendererStats()
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] = 1.0;
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() {
//container = document.createElement( 'div' );
//document.body.appendChild( container );
//camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 5000 );
//camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 5000 );
//camera = new THREE.OrthographicCamera( 0, window.innerWidth, window.innerHeight,0, 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 );
//var w = window.clientWidth;
//var h = window.clientHeight;
//var viewSize = h;
//var aspectRatio = w / h;
//
//var _viewport = {
// viewSize: viewSize,
// aspectRatio: aspectRatio,
// left: (-aspectRatio * viewSize) / 2,
// right: (aspectRatio * viewSize) / 2,
// top: viewSize / 2,
// bottom: -viewSize / 2,
// near: 0.1,
// far: 10000
//}
//
//camera = new THREE.OrthographicCamera (
// _viewport.left,
// _viewport.right,
// _viewport.top,
// _viewport.bottom,
// _viewport.near,
// _viewport.far
//);
camera.position.z = 1000;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf0f0f0 );
//scene.add( new THREE.AmbientLight( 0x505050 ) );
//var light = new THREE.SpotLight( 0xffffff, 1.5 );
//light.position.set( 0, 500, 2000 );
//light.angle = Math.PI / 9;
//light.castShadow = true;
//light.shadow.camera.near = 1000;
//light.shadow.camera.far = 4000;
//light.shadow.mapSize.width = 1024;
//light.shadow.mapSize.height = 1024;
//scene.add( light );
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 );
//stats = new Stats();
//container.appendChild( stats.dom );
rendererStats.domElement.style.position = 'absolute'
rendererStats.domElement.style.left = '0px'
rendererStats.domElement.style.bottom = '0px'
document.body.appendChild( rendererStats.domElement )
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.removeEventListener( 'change', render );
//controls = undefined;
controls.enabled = false;
}
selectionBox = new SelectionBox( camera, scene );
helper = new SelectionHelper( selectionBox, renderer, "selectBox" );
} else {
isSelecting = false;
if (selectionBox != undefined && helper != undefined) {
console.log("aqui");
console.log(selectionBox, helper);
//helper.destroy();
//helper.element = undefined;
}
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, "color", selectionBox.collection[i].colorArray);
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, "color", [[1,0,0,1]]);
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, "color", [[1,0,0,1]])
updateInstances(selectionBox.collection[i].geo, selectionBox.collection[i].uuidArray, "selected", [0])
}
}
});
</script>
</body>