feat(viewer): various fixes, fiddles
This commit is contained in:
@@ -1,26 +1,31 @@
|
||||
import * as THREE from 'three'
|
||||
import Rainbow from 'rainbowvis.js'
|
||||
import { cloneUniforms } from 'three'
|
||||
|
||||
const WireframeMaterial = new THREE.MeshStandardMaterial( {
|
||||
color: 0x7080A0,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true,
|
||||
opacity: 0.04,
|
||||
wireframe: true
|
||||
} )
|
||||
export default class FilteringManager {
|
||||
|
||||
constructor( viewer ) {
|
||||
this.viewer = viewer
|
||||
this.WireframeMaterial = new THREE.MeshStandardMaterial( {
|
||||
color: 0x7080A0,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true,
|
||||
opacity: 0.04,
|
||||
wireframe: true,
|
||||
clippingPlanes: this.viewer.sectionBox.planes
|
||||
} )
|
||||
|
||||
this.ColoredMaterial = new THREE.MeshStandardMaterial( {
|
||||
color: 0x7080A0,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: false,
|
||||
clippingPlanes: this.viewer.sectionBox.planes
|
||||
} )
|
||||
}
|
||||
|
||||
const ColoredMaterial = new THREE.MeshStandardMaterial( {
|
||||
color: 0x7080A0,
|
||||
side: THREE.DoubleSide,
|
||||
transparent: false
|
||||
} )
|
||||
|
||||
|
||||
export function filterAndColorObject( obj, filter ) {
|
||||
filterAndColorObject( obj, filter ) {
|
||||
if ( !filter )
|
||||
return obj.clone()
|
||||
if ( !passesFilter( obj.userData, filter.filterBy ) )
|
||||
if ( !this.passesFilter( obj.userData, filter.filterBy ) )
|
||||
{
|
||||
if ( filter.ghostOthers && obj.type === 'Mesh' ) {
|
||||
let clone = obj.clone()
|
||||
@@ -37,104 +42,105 @@ export function filterAndColorObject( obj, filter ) {
|
||||
let clone = obj.clone()
|
||||
if ( filter.colorBy ) {
|
||||
if ( filter.colorBy.type === 'category' ) {
|
||||
clone.material = colorWithCategory( obj.userData, filter.colorBy )
|
||||
clone.material = this.colorWithCategory( obj.userData, filter.colorBy )
|
||||
} else if ( filter.colorBy.type === 'gradient' ) {
|
||||
clone.material = colorWithGradient( obj, filter.colorBy )
|
||||
clone.material = this.colorWithGradient( obj, filter.colorBy )
|
||||
}
|
||||
}
|
||||
|
||||
return clone
|
||||
}
|
||||
|
||||
function getObjectProperty( obj, property ) {
|
||||
if ( !property ) return
|
||||
let keyParts = property.split( '.' )
|
||||
let crtObj = obj
|
||||
for ( let i = 0; i < keyParts.length - 1; i++ ) {
|
||||
if ( !( keyParts[i] in crtObj ) ) return
|
||||
crtObj = crtObj[ keyParts[i] ]
|
||||
if ( crtObj.constructor !== Object ) return
|
||||
}
|
||||
let attributeName = keyParts[ keyParts.length - 1 ]
|
||||
return crtObj[ attributeName ]
|
||||
}
|
||||
|
||||
function colorWithCategory( obj, colors ) {
|
||||
let defaultValue = colors.default
|
||||
let color = defaultValue
|
||||
let objValue = getObjectProperty( obj, colors.property )
|
||||
let customPallete = colors.values || {}
|
||||
if ( objValue in customPallete ) {
|
||||
color = customPallete[ objValue ]
|
||||
}
|
||||
|
||||
if ( !color ) {
|
||||
// compute value hash
|
||||
let objValueAsString = '' + objValue
|
||||
let hash = 0
|
||||
for( let i = 0; i < objValueAsString.length; i++ ) {
|
||||
let chr = objValueAsString.charCodeAt( i )
|
||||
hash = ( ( hash << 5 ) - hash ) + chr
|
||||
hash |= 0 // Convert to 32bit integer
|
||||
}
|
||||
hash = Math.abs( hash )
|
||||
let colorHue = hash % 360
|
||||
color = `hsl(${colorHue}, 50%, 30%)`
|
||||
}
|
||||
|
||||
let material = ColoredMaterial.clone()
|
||||
material.color = new THREE.Color( color )
|
||||
return material
|
||||
}
|
||||
|
||||
function colorWithGradient( threejsObj, colors ) {
|
||||
let obj = threejsObj.userData
|
||||
let rainbow = new Rainbow( )
|
||||
if ( 'minValue' in colors && 'maxValue' in colors )
|
||||
rainbow.setNumberRange( colors.minValue, colors.maxValue )
|
||||
if ( 'gradientColors' in colors )
|
||||
rainbow.setSpectrum( ...colors.gradientColors )
|
||||
|
||||
let objValue = getObjectProperty( obj, colors.property )
|
||||
objValue = Number( objValue )
|
||||
if ( Number.isNaN( objValue ) ) {
|
||||
return WireframeMaterial
|
||||
getObjectProperty( obj, property ) {
|
||||
if ( !property ) return
|
||||
let keyParts = property.split( '.' )
|
||||
let crtObj = obj
|
||||
for ( let i = 0; i < keyParts.length - 1; i++ ) {
|
||||
if ( !( keyParts[i] in crtObj ) ) return
|
||||
crtObj = crtObj[ keyParts[i] ]
|
||||
if ( crtObj.constructor !== Object ) return
|
||||
}
|
||||
let attributeName = keyParts[ keyParts.length - 1 ]
|
||||
return crtObj[ attributeName ]
|
||||
}
|
||||
|
||||
let material = ColoredMaterial.clone()
|
||||
material.color = new THREE.Color( `#${rainbow.colourAt( objValue )}` )
|
||||
return material
|
||||
}
|
||||
|
||||
function passesFilter( obj, filterBy ) {
|
||||
if ( !filterBy ) return true
|
||||
for ( let filterKey in filterBy ) {
|
||||
let objValue = getObjectProperty( obj, filterKey )
|
||||
|
||||
let passesFilter = filterValue( objValue, filterBy[ filterKey ] )
|
||||
if ( !passesFilter ) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function filterValue( objValue, valueFilter ) {
|
||||
// Array value filter means it can be any value from the array
|
||||
if ( Array.isArray( valueFilter ) )
|
||||
return valueFilter.includes( objValue )
|
||||
|
||||
// Dictionary value filter can specify ranges with `lte` and `gte` fields (LowerThanOrEqual, GreaterThanOrEqual)
|
||||
if ( valueFilter.constructor === Object ) {
|
||||
if ( 'not' in valueFilter && Array.isArray( valueFilter.not ) ) {
|
||||
if ( valueFilter.not.includes( objValue ) )
|
||||
return false
|
||||
colorWithCategory( obj, colors ) {
|
||||
let defaultValue = colors.default
|
||||
let color = defaultValue
|
||||
let objValue = this.getObjectProperty( obj, colors.property )
|
||||
let customPallete = colors.values || {}
|
||||
if ( objValue in customPallete ) {
|
||||
color = customPallete[ objValue ]
|
||||
}
|
||||
|
||||
if ( !color ) {
|
||||
// compute value hash
|
||||
let objValueAsString = '' + objValue
|
||||
let hash = 0
|
||||
for( let i = 0; i < objValueAsString.length; i++ ) {
|
||||
let chr = objValueAsString.charCodeAt( i )
|
||||
hash = ( ( hash << 5 ) - hash ) + chr
|
||||
hash |= 0 // Convert to 32bit integer
|
||||
}
|
||||
hash = Math.abs( hash )
|
||||
let colorHue = hash % 360
|
||||
color = `hsl(${colorHue}, 50%, 30%)`
|
||||
}
|
||||
|
||||
let material = this.ColoredMaterial.clone()
|
||||
material.color = new THREE.Color( color )
|
||||
return material
|
||||
}
|
||||
|
||||
colorWithGradient( threejsObj, colors ) {
|
||||
let obj = threejsObj.userData
|
||||
let rainbow = new Rainbow( )
|
||||
if ( 'minValue' in colors && 'maxValue' in colors )
|
||||
rainbow.setNumberRange( colors.minValue, colors.maxValue )
|
||||
if ( 'gradientColors' in colors )
|
||||
rainbow.setSpectrum( ...colors.gradientColors )
|
||||
|
||||
let objValue = this.getObjectProperty( obj, colors.property )
|
||||
objValue = Number( objValue )
|
||||
if ( Number.isNaN( objValue ) ) {
|
||||
return this.WireframeMaterial
|
||||
}
|
||||
|
||||
let material = this.ColoredMaterial.clone()
|
||||
material.color = new THREE.Color( `#${rainbow.colourAt( objValue )}` )
|
||||
return material
|
||||
}
|
||||
|
||||
passesFilter( obj, filterBy ) {
|
||||
if ( !filterBy ) return true
|
||||
for ( let filterKey in filterBy ) {
|
||||
let objValue = this.getObjectProperty( obj, filterKey )
|
||||
|
||||
let passesFilter = this.filterValue( objValue, filterBy[ filterKey ] )
|
||||
if ( !passesFilter ) return false
|
||||
}
|
||||
if ( 'lte' in valueFilter && objValue > valueFilter.lte )
|
||||
return false
|
||||
if ( 'gte' in valueFilter && objValue < valueFilter.gte )
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
// Can also filter by specific value
|
||||
return objValue === valueFilter
|
||||
|
||||
filterValue( objValue, valueFilter ) {
|
||||
// Array value filter means it can be any value from the array
|
||||
if ( Array.isArray( valueFilter ) )
|
||||
return valueFilter.includes( objValue )
|
||||
|
||||
// Dictionary value filter can specify ranges with `lte` and `gte` fields (LowerThanOrEqual, GreaterThanOrEqual)
|
||||
if ( valueFilter.constructor === Object ) {
|
||||
if ( 'not' in valueFilter && Array.isArray( valueFilter.not ) ) {
|
||||
if ( valueFilter.not.includes( objValue ) )
|
||||
return false
|
||||
}
|
||||
if ( 'lte' in valueFilter && objValue > valueFilter.lte )
|
||||
return false
|
||||
if ( 'gte' in valueFilter && objValue < valueFilter.gte )
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
// Can also filter by specific value
|
||||
return objValue === valueFilter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import * as THREE from 'three'
|
||||
import SectionBox from './SectionBox'
|
||||
import SelectionHelper from './SelectionHelper'
|
||||
|
||||
export default class InteractionHandler {
|
||||
@@ -26,11 +25,11 @@ export default class InteractionHandler {
|
||||
this.selectionHelper.on( 'object-doubleclicked', this._handleDoubleClick.bind( this ) )
|
||||
this.selectionHelper.on( 'object-clicked', this._handleSelect.bind( this ) )
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if(e.key === 'Escape' && this.viewer.mouseOverRenderer){
|
||||
document.addEventListener( 'keydown', ( e ) => {
|
||||
if( e.key === 'Escape' && this.viewer.mouseOverRenderer ) {
|
||||
this.deselectObjects()
|
||||
}
|
||||
})
|
||||
} )
|
||||
}
|
||||
|
||||
_handleDoubleClick( objs ) {
|
||||
@@ -47,8 +46,8 @@ export default class InteractionHandler {
|
||||
}
|
||||
|
||||
_handleSelect( objs ) {
|
||||
console.log(this.viewer.cameraHandler.orbiting )
|
||||
if(this.viewer.cameraHandler.orbiting ) return
|
||||
console.log( this.viewer.cameraHandler.orbiting )
|
||||
if( this.viewer.cameraHandler.orbiting ) return
|
||||
if ( this.preventSelection ) return
|
||||
|
||||
if ( objs.length === 0 ) {
|
||||
@@ -100,34 +99,16 @@ export default class InteractionHandler {
|
||||
this.viewer.emit( 'select', this.selectedObjectsUserData )
|
||||
}
|
||||
|
||||
toggleSectionBox() {
|
||||
this.sectionBox.toggle()
|
||||
if ( this.sectionBox.display.visible ) {
|
||||
if ( this.selectedObjects.children.length === 0 ) {
|
||||
this.sectionBox.setBox( this.viewer.sceneManager.getSceneBoundingBox() )
|
||||
this.zoomExtents()
|
||||
}
|
||||
else {
|
||||
let box = new THREE.Box3().setFromObject( this.selectedObjects )
|
||||
this.sectionBox.setBox( box )
|
||||
this.zoomToBox( box )
|
||||
}
|
||||
} else {
|
||||
this.preventSelection = false
|
||||
}
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
zoomToObject( target, fit = 1.2, transition = true ) {
|
||||
const box = new THREE.Box3().setFromObject( target )
|
||||
this.zoomToBox( box, fit, transition )
|
||||
}
|
||||
|
||||
zoomExtents( fit = 1.2, transition = true ) {
|
||||
// if ( this.sectionBox.display.visible ) {
|
||||
// this.zoomToObject( this.sectionBox.boxMesh )
|
||||
// return
|
||||
// }
|
||||
if ( this.viewer.sectionBox.display.visible ) {
|
||||
this.zoomToObject( this.viewer.sectionBox.cube )
|
||||
return
|
||||
}
|
||||
if ( this.viewer.sceneManager.sceneObjects.allObjects.length === 0 ) {
|
||||
let box = new THREE.Box3( new THREE.Vector3( -1,-1,-1 ), new THREE.Vector3( 1,1,1 ) )
|
||||
this.zoomToBox( box, fit, transition )
|
||||
@@ -140,8 +121,8 @@ export default class InteractionHandler {
|
||||
}
|
||||
|
||||
zoomToBox( box, fit = 1.2, transition = true ) {
|
||||
if(box.max.x === Infinity || box.max.x === -Infinity) {
|
||||
box = new THREE.Box3( new THREE.Vector3( -10,-10,-10 ), new THREE.Vector3( 10,10,10 ) )
|
||||
if( box.max.x === Infinity || box.max.x === -Infinity ) {
|
||||
box = new THREE.Box3( new THREE.Vector3( -5,-5,-5 ), new THREE.Vector3( 5,5,5 ) )
|
||||
}
|
||||
const fitOffset = fit
|
||||
|
||||
@@ -167,15 +148,6 @@ export default class InteractionHandler {
|
||||
this.viewer.cameraHandler.orthoCamera.updateProjectionMatrix()
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows camera to go "underneath" or not. By default, this function will set
|
||||
* the max polar angle to Pi, allowing the camera to look from down upwards.
|
||||
* @param {[type]} angle [description]
|
||||
*/
|
||||
setMaxPolarAngle( angle = Math.PI ) {
|
||||
this.viewer.controls.maxPolarAngle = angle
|
||||
}
|
||||
|
||||
rotateCamera( azimuthAngle = 0.261799, polarAngle = 0, transition = true ) {
|
||||
this.viewer.controls.rotate( azimuthAngle, polarAngle, transition )
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ export default class SceneObjectManager {
|
||||
|
||||
}
|
||||
|
||||
addSolid( wrapper, addToScene = true ) {
|
||||
addSolid( wrapper, _addToScene = true ) {
|
||||
// Do we have a defined material?
|
||||
if ( wrapper.meta.renderMaterial ) {
|
||||
let renderMat = wrapper.meta.renderMaterial
|
||||
@@ -242,10 +242,6 @@ export default class SceneObjectManager {
|
||||
return group
|
||||
}
|
||||
|
||||
removeObject( id ) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
async removeImportedObject( importedUrl ) {
|
||||
for ( let objGroup of this.sceneObjects.allObjects.children ) {
|
||||
let toRemove = objGroup.children.filter( obj => obj.userData?.__importedUrl === importedUrl )
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as THREE from 'three'
|
||||
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils'
|
||||
// import { BufferGeometryUtils } from 'three/examples/jsm/utils/BufferGeometryUtils'
|
||||
import debounce from 'lodash.debounce'
|
||||
import { filterAndColorObject } from './Filtering'
|
||||
import FilteringManager from './Filtering'
|
||||
|
||||
/**
|
||||
* Container for the scene objects, to allow loading/unloading/filtering/coloring/grouping
|
||||
@@ -38,6 +38,7 @@ export default class SceneObjects {
|
||||
this.groupedSolidObjects.name = 'groupedSolidObjects'
|
||||
this.allObjects.add( this.groupedSolidObjects )
|
||||
|
||||
this.filteringManager = new FilteringManager( this.viewer )
|
||||
this.filteredObjects = null
|
||||
|
||||
this.appliedFilter = null
|
||||
@@ -125,7 +126,7 @@ export default class SceneObjects {
|
||||
|
||||
for ( let obj of threejsGroup.children ) {
|
||||
await this.asyncPause()
|
||||
let filteredObj = filterAndColorObject( obj, filter )
|
||||
let filteredObj = this.filteringManager.filterAndColorObject( obj, filter )
|
||||
if ( filteredObj )
|
||||
ret.add( filteredObj )
|
||||
}
|
||||
@@ -248,9 +249,6 @@ export default class SceneObjects {
|
||||
let groupGeometry = BufferGeometryUtils.mergeBufferGeometries( materialIdToBufferGeometry[ materialId ] )
|
||||
await this.asyncPause()
|
||||
let groupMaterial = materialIdToMaterial[ materialId ]
|
||||
// // console.log( this.viewer.sectionBox.planes )
|
||||
// // groupMaterial.clippingPlanes = [ this.viewer.sectionBox.planes[0], this.viewer.sectionBox.planes[1] ]
|
||||
// groupMaterial.clippingPlanes = [ ...this.viewer.sectionBox.planes ]
|
||||
let groupMesh = new THREE.Mesh( groupGeometry, groupMaterial )
|
||||
groupMesh.userData = null
|
||||
groupedObjects.add( groupMesh )
|
||||
|
||||
@@ -1,246 +1,371 @@
|
||||
import * as THREE from 'three'
|
||||
import SelectionHelper from './SelectionHelper'
|
||||
import { TransformControls } from './external/TransformControls.js'
|
||||
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'
|
||||
import { Box3 } from 'three'
|
||||
|
||||
export default class SectionBox {
|
||||
|
||||
constructor( viewer, bbox ) {
|
||||
constructor( viewer ) {
|
||||
this.viewer = viewer
|
||||
|
||||
this.orbiting = false
|
||||
this.viewer.renderer.localClippingEnabled = true
|
||||
|
||||
this.dragging = false
|
||||
this.display = new THREE.Group()
|
||||
this.viewer.controls.addEventListener( 'wake', () => { this.orbiting = true } )
|
||||
this.viewer.controls.addEventListener( 'controlend', () => { this.orbiting = false } )
|
||||
|
||||
this.box = bbox || this.viewer.sceneManager.getSceneBoundingBox()
|
||||
const dimensions = new THREE.Vector3().subVectors( this.box.max, this.box.min )
|
||||
this.boxGeo = new THREE.BoxGeometry( dimensions.x, dimensions.y, dimensions.z )
|
||||
|
||||
const matrix = new THREE.Matrix4().setPosition( dimensions.addVectors( this.box.min, this.box.max ).multiplyScalar( 0.5 ) )
|
||||
this.boxGeo.applyMatrix4( matrix )
|
||||
this.boxMesh = new THREE.Mesh( this.boxGeo, new THREE.MeshBasicMaterial() )
|
||||
|
||||
this.boxHelper = new THREE.BoxHelper( this.boxMesh, 0x0A66FF )
|
||||
|
||||
const plane = new THREE.PlaneGeometry( 1, 1 )
|
||||
this.hoverPlane = new THREE.Mesh( plane, new THREE.MeshStandardMaterial( {
|
||||
transparent: true,
|
||||
side: THREE.DoubleSide,
|
||||
opacity: 0.02,
|
||||
color: 0x0A66FF,
|
||||
metalness: 0.1,
|
||||
roughness: 0.75
|
||||
} ) )
|
||||
|
||||
this.display.add( this.boxHelper )
|
||||
this.display.add( this.hoverPlane )
|
||||
|
||||
this.viewer.scene.add( this.display )
|
||||
|
||||
this.boxMesh.userData.planes = []
|
||||
this.boxMesh.userData.indices = []
|
||||
this.planes = []
|
||||
// box
|
||||
this.boxGeometry = this._generateSimpleCube( 5, 5, 5 )
|
||||
this.material = new THREE.MeshStandardMaterial( { color: 0x00ffff, opacity:0, wireframe: false, side: THREE.DoubleSide } )
|
||||
this.cube = new THREE.Mesh( this.boxGeometry, this.material )
|
||||
this.cube.visible = false
|
||||
|
||||
// Gen box and planes
|
||||
this._generatePlanes()
|
||||
this.display.add( this.cube )
|
||||
|
||||
// Box face selection controls
|
||||
this.selectionHelper = new SelectionHelper( this.viewer, { subset: this.boxMesh, hover: true } )
|
||||
let targetFaceIndex = -1
|
||||
this.boxHelper = new THREE.BoxHelper( this.cube, 0x0A66FF )
|
||||
this.boxHelper.material.opacity = 0.4
|
||||
this.display.add( this.boxHelper )
|
||||
|
||||
this.selectionHelper.on( 'hovered', ( obj ) => {
|
||||
if ( obj.length === 0 && !this.dragging ) {
|
||||
this.hoverPlane.visible = false
|
||||
// we're attaching the gizmo mover to this sphere in the box centre
|
||||
let sphere = new THREE.SphereGeometry( 0.01, 10, 10 )
|
||||
this.sphere = new THREE.Mesh( sphere, new THREE.MeshStandardMaterial( { color:0x00ffff } ) )
|
||||
this.display.add( this.sphere )
|
||||
|
||||
// plane
|
||||
this.plane = new THREE.PlaneGeometry( 1, 1 )
|
||||
this.hoverPlane = new THREE.Mesh( this.plane, new THREE.MeshStandardMaterial( { transparent: true, side: THREE.DoubleSide, opacity: 0.1, wireframe: false, color: 0x0A66FF, metalness: 0.1, roughness: 0.75 } ) )
|
||||
this.hoverPlane.visible = false
|
||||
this.display.add( this.hoverPlane )
|
||||
|
||||
this.dragging = false
|
||||
this._setupControls()
|
||||
|
||||
this.sidesSimple = {
|
||||
'256': { verts: [ 1, 2, 5, 6 ], axis:'x' },
|
||||
'152': { verts: [ 1, 2, 5, 6 ], axis:'x' },
|
||||
'407': { verts: [ 0, 3, 4, 7 ], axis:'x' },
|
||||
'703': { verts: [ 0, 3, 4, 7 ], axis:'x' },
|
||||
'327': { verts: [ 2, 3, 6, 7 ], axis:'y' },
|
||||
'726': { verts: [ 2, 3, 6, 7 ], axis:'y' },
|
||||
'450': { verts: [ 0, 1, 4, 5 ], axis:'y' },
|
||||
'051': { verts: [ 0, 1, 4, 5 ], axis:'y' },
|
||||
'312': { verts: [ 0, 1, 3, 2 ], axis:'z' },
|
||||
'013': { verts: [ 0, 1, 3, 2 ], axis:'z' },
|
||||
'546': { verts: [ 4, 5, 7, 6 ], axis:'z' },
|
||||
'647': { verts: [ 4, 5, 7, 6 ], axis:'z' }
|
||||
}
|
||||
|
||||
this._generateOrUpdatePlanes()
|
||||
|
||||
this.currentRange = null
|
||||
this.prevPosition = null
|
||||
this.attachedToBox = true
|
||||
|
||||
this.selectionHelper = new SelectionHelper( this.viewer, { subset: this.cube, hover: true } )
|
||||
this.selectionHelper.on( 'object-clicked', this._clickHandler.bind( this ) )
|
||||
this.selectionHelper.on( 'hovered', ( objs ) =>{
|
||||
if( !this.attachedToBox ) return
|
||||
if( objs.length === 0 ) {
|
||||
this.controls.visible = false
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
else if( objs.length !== 0 ) {
|
||||
this.controls.visible = true
|
||||
this.planeControls.detach()
|
||||
this.viewer.controls.enabled = true
|
||||
this.viewer.interactions.preventSelection = false
|
||||
this.viewer.needsRender = true
|
||||
targetFaceIndex = -1
|
||||
return
|
||||
}
|
||||
if ( this.orbiting || this.dragging ) return
|
||||
|
||||
this.controls.visible = false
|
||||
this.hoverPlane.visible = true
|
||||
|
||||
let centre = new THREE.Vector3()
|
||||
for ( let i = 0; i < 4; i++ ) {
|
||||
centre.add( this.boxGeo.vertices[ obj[0].object.userData.indices[ obj[0].faceIndex ][i] ].clone().applyMatrix4( this.boxMesh.matrixWorld ) )
|
||||
}
|
||||
centre.multiplyScalar( 0.25 )
|
||||
this.hoverPlane.position.copy( centre )
|
||||
|
||||
for ( let i = 0; i < 4; i++ ) {
|
||||
let vertex = this.boxGeo.vertices[ obj[0].object.userData.indices[ obj[0].faceIndex ][i] ].clone().applyMatrix4( this.boxMesh.matrixWorld )
|
||||
this.hoverPlane.geometry.vertices[i].set( vertex.x - centre.x, vertex.y - centre.y , vertex.z - centre.z )
|
||||
}
|
||||
|
||||
this.hoverPlane.geometry.verticesNeedUpdate = true
|
||||
|
||||
let normal = obj[0].face.normal
|
||||
this.planeControls.showX = normal.x !== 0
|
||||
this.planeControls.showY = normal.y !== 0
|
||||
this.planeControls.showZ = normal.z !== 0
|
||||
|
||||
this.planeControls.attach( this.hoverPlane )
|
||||
|
||||
if ( obj[0].faceIndex !== targetFaceIndex ) {
|
||||
this.viewer.needsRender = true
|
||||
targetFaceIndex = obj[0].faceIndex
|
||||
}
|
||||
} )
|
||||
|
||||
// Whole box controls
|
||||
this._globalControlsTarget = new THREE.Mesh( new THREE.SphereGeometry( 0.0001 ), new THREE.MeshBasicMaterial( ) )
|
||||
this._globalControlsTarget.position.copy( this.boxGeo.vertices[ 5 ].clone().multiplyScalar( 1.1 ) )
|
||||
this.display.add( this._globalControlsTarget )
|
||||
document.addEventListener( 'keydown', ( e ) => {
|
||||
if( e.key === 'Escape' && this.viewer.mouseOverRenderer ) {
|
||||
this._attachControlsToBox()
|
||||
}
|
||||
} )
|
||||
|
||||
this.controls = new TransformControls( this.viewer.camera, this.viewer.renderer.domElement )
|
||||
this.controls.setSize( 0.5 )
|
||||
this.controls.attach( this._globalControlsTarget )
|
||||
this._attachControlsToBox()
|
||||
|
||||
this.viewer.on( 'projection-change', function() { this._setupControls(); this._attachControlsToBox() }.bind( this ) )
|
||||
}
|
||||
|
||||
_setupControls() {
|
||||
this.controls?.dispose()
|
||||
this.controls?.detach()
|
||||
this.controls = new TransformControls( this.viewer.cameraHandler.activeCam.camera, this.viewer.renderer.domElement )
|
||||
this.controls.setSize( 0.75 )
|
||||
this.display.add( this.controls )
|
||||
|
||||
// Section plane controls
|
||||
this.planeControls = new TransformControls( this.viewer.camera, this.viewer.renderer.domElement, true )
|
||||
this.display.add( this.planeControls )
|
||||
|
||||
this.prevGizmoPos = this._globalControlsTarget.position.clone()
|
||||
this.controls.addEventListener( 'change', ( ) => {
|
||||
this.prevGizmoPos.sub( this._globalControlsTarget.position )
|
||||
this.boxMesh.translateX( -this.prevGizmoPos.x )
|
||||
this.boxMesh.translateY( -this.prevGizmoPos.y )
|
||||
this.boxMesh.translateZ( -this.prevGizmoPos.z )
|
||||
|
||||
this.prevGizmoPos = this._globalControlsTarget.position.clone()
|
||||
this.setPlanesFromBox( new THREE.Box3().setFromObject( this.boxMesh ) )
|
||||
this.boxHelper.update()
|
||||
this.viewer.needsRender = true
|
||||
} )
|
||||
|
||||
this.controls.addEventListener( 'change', this._draggingChangeHandler.bind( this ) )
|
||||
this.controls.addEventListener( 'dragging-changed', ( event ) => {
|
||||
this.viewer.controls.enabled = !event.value
|
||||
this.viewer.interactions.preventSelection = !event.value
|
||||
if ( !event.value )
|
||||
this.viewer.interactions.zoomToObject( this.boxMesh )
|
||||
} )
|
||||
|
||||
let prevPlaneGizmoPos = null
|
||||
this.planeControls.addEventListener( 'change', ( ) => {
|
||||
if ( !this.dragging ) return
|
||||
if ( targetFaceIndex === -1 ) return
|
||||
if ( prevPlaneGizmoPos === null ) prevPlaneGizmoPos = this.hoverPlane.position.clone()
|
||||
prevPlaneGizmoPos.sub( this.hoverPlane.position )
|
||||
let plane = this.boxMesh.userData.planes[ targetFaceIndex ]
|
||||
|
||||
prevPlaneGizmoPos.negate()
|
||||
plane.translate( prevPlaneGizmoPos )
|
||||
let indices = this.boxMesh.userData.indices[ targetFaceIndex ]
|
||||
for ( let i = 0; i < 4; i++ ) {
|
||||
let index = indices[i]
|
||||
this.boxGeo.vertices[index].add( prevPlaneGizmoPos )
|
||||
let val = !!event.value
|
||||
if( val ) {
|
||||
this.dragging = val
|
||||
this.viewer.interactions.preventSelection = val
|
||||
this.viewer.cameraHandler.enabled = !val
|
||||
} else {
|
||||
setTimeout( ()=> {
|
||||
this.dragging = val
|
||||
this.viewer.interactions.preventSelection = val
|
||||
this.viewer.cameraHandler.enabled = !val
|
||||
}, 100 )
|
||||
}
|
||||
this.boxGeo.verticesNeedUpdate = true
|
||||
this.boxMesh.geometry.computeBoundingBox()
|
||||
this.boxMesh.geometry.computeBoundingSphere()
|
||||
|
||||
let gizmoPos = this.boxGeo.vertices[ 5 ].clone()
|
||||
gizmoPos.multiplyScalar( 1.1 )
|
||||
gizmoPos.applyMatrix4( this.boxMesh.matrixWorld )
|
||||
this._globalControlsTarget.position.copy( gizmoPos )
|
||||
this.prevGizmoPos = gizmoPos
|
||||
|
||||
prevPlaneGizmoPos = this.hoverPlane.position.clone()
|
||||
this.boxHelper.update()
|
||||
this.viewer.needsRender = true
|
||||
} )
|
||||
|
||||
this.planeControls.addEventListener( 'dragging-changed', ( event ) => {
|
||||
this.viewer.controls.enabled = !event.value
|
||||
this.viewer.interactions.preventSelection = !event.value
|
||||
this.dragging = !!event.value
|
||||
if ( !this.dragging ) {
|
||||
prevPlaneGizmoPos = null
|
||||
this.viewer.interactions.zoomToObject( this.boxMesh )
|
||||
targetFaceIndex = -1
|
||||
|
||||
}
|
||||
this.viewer.needsRender = true
|
||||
} )
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
_generatePlanes() {
|
||||
for ( let i = 0; i < this.boxGeo.faces.length; i += 2 ) {
|
||||
let face = this.boxGeo.faces[i]
|
||||
let pairFace = this.boxGeo.faces[i+1]
|
||||
let plane = new THREE.Plane()
|
||||
// inverting points so plane
|
||||
plane.setFromCoplanarPoints( this.boxGeo.vertices[face.c], this.boxGeo.vertices[face.b], this.boxGeo.vertices[face.a] )
|
||||
// adding it twice for ease of use
|
||||
this.boxMesh.userData.planes.push( plane )
|
||||
this.boxMesh.userData.planes.push( plane )
|
||||
|
||||
this.boxMesh.userData.indices.push( [ face.a, face.b, face.c, pairFace.b ] )
|
||||
this.boxMesh.userData.indices.push( [ face.a, face.b, face.c, pairFace.b ] )
|
||||
|
||||
this.planes.push( plane )
|
||||
}
|
||||
}
|
||||
|
||||
setPlanesFromBox( box ) {
|
||||
const dimensions = new THREE.Vector3().subVectors( box.max, box.min )
|
||||
let boxGeo = new THREE.BoxGeometry( dimensions.x, dimensions.y, dimensions.z )
|
||||
|
||||
const matrix = new THREE.Matrix4().setPosition( dimensions.addVectors( box.min, box.max ).multiplyScalar( 0.5 ) )
|
||||
boxGeo.applyMatrix4( matrix )
|
||||
|
||||
for ( let i = 0; i < this.boxGeo.faces.length; i += 2 ) {
|
||||
let face = boxGeo.faces[i]
|
||||
let plane = this.boxMesh.userData.planes[i]
|
||||
plane.setFromCoplanarPoints( boxGeo.vertices[face.c], boxGeo.vertices[face.b], boxGeo.vertices[face.a] ) // invert pts
|
||||
}
|
||||
}
|
||||
|
||||
setBox( box ) {
|
||||
box = box.clone().expandByScalar( 0.5 )
|
||||
const dimensions = new THREE.Vector3().subVectors( box.max, box.min )
|
||||
let boxGeo = new THREE.BoxGeometry( dimensions.x, dimensions.y, dimensions.z )
|
||||
|
||||
const matrix = new THREE.Matrix4().setPosition( dimensions.addVectors( box.min, box.max ).multiplyScalar( 0.5 ) )
|
||||
boxGeo.applyMatrix4( matrix )
|
||||
|
||||
for ( let i = 0; i < this.boxGeo.vertices.length; i++ ) {
|
||||
this.boxGeo.vertices[i].copy( boxGeo.vertices[i] )
|
||||
}
|
||||
|
||||
this._globalControlsTarget.position.copy( this.boxGeo.vertices[ 5 ].clone().multiplyScalar( 1.1 ) )
|
||||
this.prevGizmoPos = this._globalControlsTarget.position.clone()
|
||||
this.boxMesh.position.copy( new THREE.Vector3() )
|
||||
this.boxMesh.geometry.verticesNeedUpdate = true
|
||||
this.boxMesh.geometry.computeBoundingBox()
|
||||
this.boxMesh.geometry.computeBoundingSphere()
|
||||
_draggingChangeHandler( ) {
|
||||
this.boxHelper.update()
|
||||
this._generateOrUpdatePlanes()
|
||||
|
||||
// Dragging a side / plane
|
||||
if( this.dragging && this.currentRange ) {
|
||||
if( this.prevPosition === null ) this.prevPosition = this.hoverPlane.position.clone()
|
||||
this.prevPosition.sub( this.hoverPlane.position )
|
||||
this.prevPosition.negate()
|
||||
let boxArr = this.boxGeometry.attributes.position.array
|
||||
for( let i = 0; i < this.currentRange.length; i++ ) {
|
||||
let index = this.currentRange[i]
|
||||
boxArr[3 * index] += this.prevPosition.x
|
||||
boxArr[3 * index + 1] += this.prevPosition.y
|
||||
boxArr[3 * index + 2] += this.prevPosition.z
|
||||
}
|
||||
|
||||
this.prevPosition = this.hoverPlane.position.clone()
|
||||
this.boxGeometry.attributes.position.needsUpdate = true
|
||||
this.boxGeometry.computeVertexNormals()
|
||||
this.boxGeometry.computeBoundingBox()
|
||||
this.boxGeometry.computeBoundingSphere()
|
||||
}
|
||||
|
||||
// Dragging the whole section box
|
||||
if( this.dragging && !this.currentRange ) {
|
||||
if( this.prevPosition === null ) this.prevPosition = this.sphere.position.clone()
|
||||
this.prevPosition.sub( this.sphere.position )
|
||||
this.prevPosition.negate()
|
||||
|
||||
for( let i = 0; i < this.boxGeometry.attributes.position.array.length; i += 3 ) {
|
||||
this.boxGeometry.attributes.position.array[i] += this.prevPosition.x
|
||||
this.boxGeometry.attributes.position.array[i + 1] += this.prevPosition.y
|
||||
this.boxGeometry.attributes.position.array[i + 2] += this.prevPosition.z
|
||||
}
|
||||
this.boxGeometry.attributes.position.needsUpdate = true
|
||||
this.boxGeometry.computeVertexNormals()
|
||||
this.boxGeometry.computeBoundingBox()
|
||||
this.boxGeometry.computeBoundingSphere()
|
||||
|
||||
this.prevPosition = this.sphere.position.clone()
|
||||
}
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
_clickHandler( args ) {
|
||||
if( this.viewer.cameraHandler.orbiting || this.dragging ) return
|
||||
if( args.length === 0 && !this.dragging ) {
|
||||
this._attachControlsToBox()
|
||||
this.boxHelper.material.opacity = 0.5
|
||||
this.attachedToBox = true
|
||||
return
|
||||
}
|
||||
this.attachedToBox = false
|
||||
this.boxHelper.material.opacity = 0.3
|
||||
this.hoverPlane.visible = true
|
||||
let side = this.sidesSimple[`${args[0].face.a}${args[0].face.b}${args[0].face.c}`]
|
||||
this.controls.showX = side.axis === 'x'
|
||||
this.controls.showY = side.axis === 'y'
|
||||
this.controls.showZ = side.axis === 'z'
|
||||
|
||||
this.currentRange = side.verts
|
||||
|
||||
let boxArr = this.boxGeometry.attributes.position
|
||||
let index = 0
|
||||
let planeArr = this.plane.attributes.position.array
|
||||
let centre = new THREE.Vector3()
|
||||
|
||||
let tempArr = []
|
||||
for( let i = 0; i < planeArr.length; i++ ) {
|
||||
if( i % 3 === 0 ) {
|
||||
tempArr.push( boxArr.getX( this.currentRange[index] ) )
|
||||
}
|
||||
else if( i % 3 === 1 ) {
|
||||
tempArr.push( boxArr.getY( this.currentRange[index] ) )
|
||||
}
|
||||
else if( i % 3 === 2 ) {
|
||||
tempArr.push( boxArr.getZ( this.currentRange[index] ) )
|
||||
centre.add( new THREE.Vector3( tempArr[i - 2], tempArr[i - 1], tempArr[i] ) )
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
centre.multiplyScalar( 0.25 )
|
||||
this.hoverPlane.position.copy( centre.applyMatrix4( this.cube.matrixWorld ) )
|
||||
this.prevPosition = this.hoverPlane.position.clone()
|
||||
index = 0
|
||||
for( let i = 0; i < planeArr.length; i++ ) {
|
||||
if( i % 3 === 0 ) {
|
||||
planeArr[i] = boxArr.getX( this.currentRange[index] ) - centre.x
|
||||
}
|
||||
else if( i % 3 === 1 ) {
|
||||
planeArr[i] = boxArr.getY( this.currentRange[index] ) - centre.y
|
||||
}
|
||||
else if( i % 3 === 2 ) {
|
||||
planeArr[i] = boxArr.getZ( this.currentRange[index] ) - centre.z
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
this.plane.applyMatrix4( this.cube.matrixWorld )
|
||||
this.plane.attributes.position.needsUpdate = true
|
||||
this.plane.computeBoundingSphere()
|
||||
this.plane.computeBoundingBox()
|
||||
this.controls.detach()
|
||||
this.controls.attach( this.hoverPlane )
|
||||
this.controls.updateMatrixWorld()
|
||||
}
|
||||
|
||||
_generateSimpleCube( width = 0.5, depth = 0.5, height = 0.5 ) {
|
||||
const vertices = [
|
||||
[ -1 * width, -1 * depth, -1 * height ],
|
||||
[ 1 * width, -1 * depth, -1 * height ],
|
||||
[ 1 * width, 1 * depth, -1 * height ],
|
||||
[ -1 * width, 1 * depth, -1 * height ],
|
||||
[ -1 * width, -1 * depth, 1 * height ],
|
||||
[ 1 * width, -1 * depth, 1 * height ],
|
||||
[ 1 * width, 1 * depth, 1 * height ],
|
||||
[ -1 * width, 1 * depth, 1 * height ]
|
||||
]
|
||||
|
||||
const indexes = [
|
||||
0, 1, 3, 3, 1, 2,
|
||||
1, 5, 2, 2, 5, 6,
|
||||
5, 4, 6, 6, 4, 7,
|
||||
4, 0, 7, 7, 0, 3,
|
||||
3, 2, 7, 7, 2, 6,
|
||||
4, 5, 0, 0, 5, 1
|
||||
]
|
||||
|
||||
let positions = []
|
||||
for( let vert of vertices ) {
|
||||
positions.push( ...vert )
|
||||
}
|
||||
|
||||
let g = new THREE.BufferGeometry()
|
||||
g.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) )
|
||||
g.setIndex( indexes )
|
||||
g.computeVertexNormals()
|
||||
return g
|
||||
}
|
||||
|
||||
_generateOrUpdatePlanes() {
|
||||
this.planes = this.planes || [ new THREE.Plane(), new THREE.Plane(), new THREE.Plane(), new THREE.Plane(), new THREE.Plane(), new THREE.Plane() ]
|
||||
|
||||
let index = 0
|
||||
let boxArr = this.boxGeometry.attributes.position
|
||||
const indexes = [
|
||||
0, 1, 3, 3, 1, 2,
|
||||
1, 5, 2, 2, 5, 6,
|
||||
5, 4, 6, 6, 4, 7,
|
||||
4, 0, 7, 7, 0, 3,
|
||||
3, 2, 7, 7, 2, 6,
|
||||
4, 5, 0, 0, 5, 1
|
||||
]
|
||||
|
||||
for( let i = 0; i < indexes.length; i += 6 ) {
|
||||
let a = new THREE.Vector3( boxArr.getX( indexes[i] ), boxArr.getY( indexes[i] ), boxArr.getZ( indexes[i] ) )
|
||||
let b = new THREE.Vector3( boxArr.getX( indexes[i + 1] ), boxArr.getY( indexes[i + 1] ), boxArr.getZ( indexes[i + 1] ) )
|
||||
let c = new THREE.Vector3( boxArr.getX( indexes[i + 2] ), boxArr.getY( indexes[i + 2] ), boxArr.getZ( indexes[i + 2] ) )
|
||||
let plane = this.planes[index]
|
||||
plane.setFromCoplanarPoints( a, b, c )
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
_attachControlsToBox() {
|
||||
this.controls.detach()
|
||||
|
||||
let centre = new THREE.Vector3()
|
||||
let boxArr = this.boxGeometry.attributes.position.array
|
||||
for( let i = 0; i < boxArr.length; i += 3 ) {
|
||||
centre.add( new THREE.Vector3( boxArr[i], boxArr[i + 1], boxArr[i + 2] ) )
|
||||
}
|
||||
centre.multiplyScalar( 1 / 8 )
|
||||
this.sphere.position.copy( centre )
|
||||
|
||||
this.cube.geometry.computeBoundingSphere()
|
||||
this.cube.geometry.computeBoundingBox()
|
||||
this.controls.attach( this.sphere )
|
||||
this.currentRange = null
|
||||
this.prevPosition = null
|
||||
this.hoverPlane.visible = false
|
||||
this.controls.showX = true
|
||||
this.controls.showY = true
|
||||
this.controls.showZ = true
|
||||
}
|
||||
|
||||
setBox( targetBox, offset = 0.05 ) {
|
||||
let box
|
||||
|
||||
if( targetBox ) box = targetBox
|
||||
else {
|
||||
if( this.viewer.interactions.selectedObjects.children.length !== 0 ) {
|
||||
box = new THREE.Box3( ).setFromObject( this.viewer.interactions.selectedObjects )
|
||||
} else if( this.viewer.sceneManager.sceneObjects.allObjects.children.length !== 0 ) {
|
||||
box = new THREE.Box3( ).setFromObject( this.viewer.sceneManager.sceneObjects.allObjects )
|
||||
} else {
|
||||
box = new Box3( new THREE.Vector3( -1, -1, -1 ), new THREE.Vector3( 1, 1, 1 ) )
|
||||
}
|
||||
}
|
||||
|
||||
if( box.min.x === Infinity ) {
|
||||
box = new Box3( new THREE.Vector3( -1, -1, -1 ), new THREE.Vector3( 1, 1, 1 ) )
|
||||
}
|
||||
|
||||
const x1 = box.min.x - ( box.max.x - box.min.x ) * offset
|
||||
const y1 = box.min.y - ( box.max.y - box.min.y ) * offset
|
||||
const z1 = box.min.z - ( box.max.z - box.min.z ) * offset
|
||||
const x2 = box.max.x + ( box.max.x - box.min.x ) * offset
|
||||
const y2 = box.max.y + ( box.max.y - box.min.y ) * offset
|
||||
const z2 = box.max.z + ( box.max.z - box.min.z ) * offset
|
||||
|
||||
const newVertices = [
|
||||
x1, y1, z1,
|
||||
x2, y1, z1,
|
||||
x2, y2, z1,
|
||||
x1, y2, z1,
|
||||
x1, y1, z2,
|
||||
x2, y1, z2,
|
||||
x2, y2, z2,
|
||||
x1, y2, z2
|
||||
]
|
||||
|
||||
let boxVerts = this.boxGeometry.attributes.position.array
|
||||
for( let i = 0; i < newVertices.length; i++ ) {
|
||||
boxVerts[i] = newVertices[i]
|
||||
}
|
||||
|
||||
this.boxGeometry.attributes.position.needsUpdate = true
|
||||
this.boxGeometry.computeVertexNormals()
|
||||
this.boxGeometry.computeBoundingBox()
|
||||
this.boxGeometry.computeBoundingSphere()
|
||||
this._generateOrUpdatePlanes()
|
||||
this._attachControlsToBox()
|
||||
this.boxHelper.update()
|
||||
this.setPlanesFromBox( box )
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
toggle() {
|
||||
if ( this.display.visible ) {
|
||||
this.viewer.renderer.localClippingEnabled = false
|
||||
this.display.visible = false
|
||||
this.viewer.emit( 'section-box', false )
|
||||
} else {
|
||||
this.viewer.renderer.localClippingEnabled = true
|
||||
this.display.visible = true
|
||||
this.viewer.emit( 'section-box', true )
|
||||
}
|
||||
this.setBox()
|
||||
this.display.visible = !this.display.visible
|
||||
this.viewer.renderer.localClippingEnabled = this.display.visible
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.selectionHelper.dispose()
|
||||
this.controls.dispose()
|
||||
this.planeControls.dispose()
|
||||
this.display.clear()
|
||||
off() {
|
||||
this.display.visible = false
|
||||
this.viewer.renderer.localClippingEnabled = false
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
on() {
|
||||
this.display.visible = true
|
||||
this.viewer.renderer.localClippingEnabled = true
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,353 +0,0 @@
|
||||
import * as THREE from 'three'
|
||||
import SelectionHelper from './SelectionHelper'
|
||||
import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js'
|
||||
import { Box3 } from 'three'
|
||||
|
||||
export default class SectionBox {
|
||||
|
||||
constructor( viewer, bbox ) {
|
||||
this.viewer = viewer
|
||||
|
||||
this.viewer.renderer.localClippingEnabled = true
|
||||
|
||||
this.dragging = false
|
||||
this.display = new THREE.Group()
|
||||
this.viewer.scene.add( this.display )
|
||||
|
||||
// box
|
||||
this.boxGeometry = this._generateSimpleCube( 5, 5, 5 )
|
||||
this.material = new THREE.MeshStandardMaterial( { color: 0x00ffff, opacity:0, wireframe: false, side: THREE.DoubleSide } )
|
||||
this.cube = new THREE.Mesh( this.boxGeometry, this.material )
|
||||
this.cube.visible = false
|
||||
|
||||
this.display.add( this.cube )
|
||||
|
||||
this.boxHelper = new THREE.BoxHelper( this.cube, 0x0A66FF )
|
||||
this.boxHelper.material.opacity = 0.4
|
||||
this.display.add( this.boxHelper )
|
||||
|
||||
// we're attaching the gizmo mover to this sphere in the box centre
|
||||
let sphere = new THREE.SphereGeometry( 0.01, 10, 10 )
|
||||
this.sphere = new THREE.Mesh( sphere, new THREE.MeshStandardMaterial( { color:0x00ffff } ) )
|
||||
this.display.add( this.sphere )
|
||||
|
||||
// plane
|
||||
this.plane = new THREE.PlaneGeometry( 1, 1 )
|
||||
this.hoverPlane = new THREE.Mesh( this.plane, new THREE.MeshStandardMaterial( { transparent: true, side: THREE.DoubleSide, opacity: 0.1, wireframe: false, color: 0x0A66FF, metalness: 0.1, roughness: 0.75 } ) )
|
||||
this.hoverPlane.visible = false
|
||||
this.display.add( this.hoverPlane )
|
||||
|
||||
this.dragging = false
|
||||
this._setupControls()
|
||||
|
||||
this.sidesSimple = {
|
||||
'256': { verts: [ 1, 2, 5, 6 ], axis:'x' },
|
||||
'152': { verts: [ 1, 2, 5, 6 ], axis:'x' },
|
||||
'407': { verts: [ 0, 3, 4, 7 ], axis:'x' },
|
||||
'703': { verts: [ 0, 3, 4, 7 ], axis:'x' },
|
||||
'327': { verts: [ 2, 3, 6, 7 ], axis:'y' },
|
||||
'726': { verts: [ 2, 3, 6, 7 ], axis:'y' },
|
||||
'450': { verts: [ 0, 1, 4, 5 ], axis:'y' },
|
||||
'051': { verts: [ 0, 1, 4, 5 ], axis:'y' },
|
||||
'312': { verts: [ 0, 1, 3, 2 ], axis:'z' },
|
||||
'013': { verts: [ 0, 1, 3, 2 ], axis:'z' },
|
||||
'546': { verts: [ 4, 5, 7, 6 ], axis:'z' },
|
||||
'647': { verts: [ 4, 5, 7, 6 ], axis:'z' }
|
||||
}
|
||||
|
||||
this._generateOrUpdatePlanes()
|
||||
|
||||
this.currentRange = null
|
||||
this.prevPosition = null
|
||||
|
||||
this.selectionHelper = new SelectionHelper( this.viewer, { subset: this.cube, hover: true } )
|
||||
this.selectionHelper.on( 'object-clicked', this._clickHandler.bind( this ) )
|
||||
this._attachControlsToBox()
|
||||
|
||||
this.viewer.on('projection-change', function() { this._setupControls(); this._attachControlsToBox(); }.bind(this) )
|
||||
}
|
||||
|
||||
_setupControls() {
|
||||
this.controls?.dispose()
|
||||
this.controls?.detach()
|
||||
this.controls = new TransformControls( this.viewer.cameraHandler.activeCam.camera, this.viewer.renderer.domElement )
|
||||
this.controls.setSize( 0.75 )
|
||||
this.display.add( this.controls )
|
||||
this.controls.addEventListener( 'change', this._draggingChangeHandler.bind( this ) )
|
||||
this.controls.addEventListener( 'dragging-changed', ( event ) => {
|
||||
let val = !!event.value
|
||||
if( val ) {
|
||||
this.dragging = val
|
||||
this.viewer.interactions.preventSelection = val
|
||||
this.viewer.cameraHandler.enabled = !val
|
||||
} else {
|
||||
setTimeout( ()=> {
|
||||
this.dragging = val
|
||||
this.viewer.interactions.preventSelection = val
|
||||
this.viewer.cameraHandler.enabled = !val
|
||||
}, 100 )
|
||||
|
||||
}
|
||||
} )
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
_draggingChangeHandler( ) {
|
||||
this.boxHelper.update()
|
||||
this._generateOrUpdatePlanes()
|
||||
|
||||
// Dragging a side / plane
|
||||
if( this.dragging && this.currentRange ) {
|
||||
if( this.prevPosition === null ) this.prevPosition = this.hoverPlane.position.clone()
|
||||
this.prevPosition.sub( this.hoverPlane.position )
|
||||
this.prevPosition.negate()
|
||||
let boxArr = this.boxGeometry.attributes.position.array
|
||||
for( let i = 0; i < this.currentRange.length; i++ ) {
|
||||
let index = this.currentRange[i]
|
||||
boxArr[3 * index] += this.prevPosition.x
|
||||
boxArr[3 * index + 1] += this.prevPosition.y
|
||||
boxArr[3 * index + 2] += this.prevPosition.z
|
||||
}
|
||||
|
||||
this.prevPosition = this.hoverPlane.position.clone()
|
||||
this.boxGeometry.attributes.position.needsUpdate = true
|
||||
this.boxGeometry.computeVertexNormals()
|
||||
this.boxGeometry.computeBoundingBox()
|
||||
this.boxGeometry.computeBoundingSphere()
|
||||
}
|
||||
|
||||
// Dragging the whole section box
|
||||
if( this.dragging && !this.currentRange ) {
|
||||
if( this.prevPosition === null ) this.prevPosition = this.sphere.position.clone()
|
||||
this.prevPosition.sub( this.sphere.position )
|
||||
this.prevPosition.negate()
|
||||
|
||||
for( let i = 0; i < this.boxGeometry.attributes.position.array.length; i += 3 ) {
|
||||
this.boxGeometry.attributes.position.array[i] += this.prevPosition.x
|
||||
this.boxGeometry.attributes.position.array[i + 1] += this.prevPosition.y
|
||||
this.boxGeometry.attributes.position.array[i + 2] += this.prevPosition.z
|
||||
}
|
||||
this.boxGeometry.attributes.position.needsUpdate = true
|
||||
this.boxGeometry.computeVertexNormals()
|
||||
this.boxGeometry.computeBoundingBox()
|
||||
this.boxGeometry.computeBoundingSphere()
|
||||
|
||||
this.prevPosition = this.sphere.position.clone()
|
||||
}
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
_clickHandler( args ) {
|
||||
if( this.viewer.cameraHandler.orbiting || this.dragging ) return
|
||||
if( args.length === 0 && !this.dragging ) {
|
||||
this._attachControlsToBox()
|
||||
this.boxHelper.material.opacity = 0.5
|
||||
return
|
||||
}
|
||||
|
||||
this.boxHelper.material.opacity = 0.3
|
||||
this.hoverPlane.visible = true
|
||||
let side = this.sidesSimple[`${args[0].face.a}${args[0].face.b}${args[0].face.c}`]
|
||||
this.controls.showX = side.axis === 'x'
|
||||
this.controls.showY = side.axis === 'y'
|
||||
this.controls.showZ = side.axis === 'z'
|
||||
|
||||
this.currentRange = side.verts
|
||||
|
||||
let boxArr = this.boxGeometry.attributes.position
|
||||
let index = 0
|
||||
let planeArr = this.plane.attributes.position.array
|
||||
let centre = new THREE.Vector3()
|
||||
|
||||
let tempArr = []
|
||||
for( let i = 0; i < planeArr.length; i++ ) {
|
||||
if( i % 3 === 0 ) {
|
||||
tempArr.push( boxArr.getX( this.currentRange[index] ) )
|
||||
}
|
||||
else if( i % 3 === 1 ) {
|
||||
tempArr.push( boxArr.getY( this.currentRange[index] ) )
|
||||
}
|
||||
else if( i % 3 === 2 ) {
|
||||
tempArr.push( boxArr.getZ( this.currentRange[index] ) )
|
||||
centre.add( new THREE.Vector3( tempArr[i - 2], tempArr[i - 1], tempArr[i] ) )
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
centre.multiplyScalar( 0.25 )
|
||||
this.hoverPlane.position.copy( centre.applyMatrix4( this.cube.matrixWorld ) )
|
||||
this.prevPosition = this.hoverPlane.position.clone()
|
||||
index = 0
|
||||
for( let i = 0; i < planeArr.length; i++ ) {
|
||||
if( i % 3 === 0 ) {
|
||||
planeArr[i] = boxArr.getX( this.currentRange[index] ) - centre.x
|
||||
}
|
||||
else if( i % 3 === 1 ) {
|
||||
planeArr[i] = boxArr.getY( this.currentRange[index] ) - centre.y
|
||||
}
|
||||
else if( i % 3 === 2 ) {
|
||||
planeArr[i] = boxArr.getZ( this.currentRange[index] ) - centre.z
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
this.plane.applyMatrix4( this.cube.matrixWorld )
|
||||
this.plane.attributes.position.needsUpdate = true
|
||||
this.plane.computeBoundingSphere()
|
||||
this.plane.computeBoundingBox()
|
||||
this.controls.detach()
|
||||
this.controls.attach( this.hoverPlane )
|
||||
this.controls.updateMatrixWorld()
|
||||
}
|
||||
|
||||
_generateSimpleCube( width = 0.5, depth = 0.5, height = 0.5 ) {
|
||||
const vertices = [
|
||||
[ -1 * width, -1 * depth, -1 * height ],
|
||||
[ 1 * width, -1 * depth, -1 * height ],
|
||||
[ 1 * width, 1 * depth, -1 * height ],
|
||||
[ -1 * width, 1 * depth, -1 * height ],
|
||||
[ -1 * width, -1 * depth, 1 * height ],
|
||||
[ 1 * width, -1 * depth, 1 * height ],
|
||||
[ 1 * width, 1 * depth, 1 * height ],
|
||||
[ -1 * width, 1 * depth, 1 * height ]
|
||||
]
|
||||
|
||||
const indexes = [
|
||||
0, 1, 3, 3, 1, 2,
|
||||
1, 5, 2, 2, 5, 6,
|
||||
5, 4, 6, 6, 4, 7,
|
||||
4, 0, 7, 7, 0, 3,
|
||||
3, 2, 7, 7, 2, 6,
|
||||
4, 5, 0, 0, 5, 1
|
||||
]
|
||||
|
||||
let positions = []
|
||||
for( let vert of vertices ) {
|
||||
positions.push( ...vert )
|
||||
}
|
||||
|
||||
let g = new THREE.BufferGeometry()
|
||||
g.setAttribute( 'position', new THREE.BufferAttribute( new Float32Array( positions ), 3 ) )
|
||||
g.setIndex( indexes )
|
||||
g.computeVertexNormals()
|
||||
return g
|
||||
}
|
||||
|
||||
_generateOrUpdatePlanes() {
|
||||
this.planes = this.planes || [ new THREE.Plane(), new THREE.Plane(), new THREE.Plane(), new THREE.Plane(), new THREE.Plane(), new THREE.Plane() ]
|
||||
|
||||
let index = 0
|
||||
let boxArr = this.boxGeometry.attributes.position
|
||||
const indexes = [
|
||||
0, 1, 3, 3, 1, 2,
|
||||
1, 5, 2, 2, 5, 6,
|
||||
5, 4, 6, 6, 4, 7,
|
||||
4, 0, 7, 7, 0, 3,
|
||||
3, 2, 7, 7, 2, 6,
|
||||
4, 5, 0, 0, 5, 1
|
||||
]
|
||||
|
||||
for( let i = 0; i < indexes.length; i += 6 ) {
|
||||
let a = new THREE.Vector3( boxArr.getX( indexes[i] ), boxArr.getY( indexes[i] ), boxArr.getZ( indexes[i] ) )
|
||||
let b = new THREE.Vector3( boxArr.getX( indexes[i + 1] ), boxArr.getY( indexes[i + 1] ), boxArr.getZ( indexes[i + 1] ) )
|
||||
let c = new THREE.Vector3( boxArr.getX( indexes[i + 2] ), boxArr.getY( indexes[i + 2] ), boxArr.getZ( indexes[i + 2] ) )
|
||||
let plane = this.planes[index]
|
||||
plane.setFromCoplanarPoints( a, b, c )
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
_attachControlsToBox() {
|
||||
this.controls.detach()
|
||||
|
||||
let centre = new THREE.Vector3()
|
||||
let boxArr = this.boxGeometry.attributes.position.array
|
||||
for( let i = 0; i < boxArr.length; i += 3 ) {
|
||||
centre.add( new THREE.Vector3( boxArr[i], boxArr[i + 1], boxArr[i + 2] ) )
|
||||
}
|
||||
centre.multiplyScalar( 1 / 8 )
|
||||
this.sphere.position.copy( centre )
|
||||
|
||||
this.cube.geometry.computeBoundingSphere()
|
||||
this.cube.geometry.computeBoundingBox()
|
||||
this.controls.attach( this.sphere )
|
||||
this.currentRange = null
|
||||
this.prevPosition = null
|
||||
this.hoverPlane.visible = false
|
||||
this.controls.showX = true
|
||||
this.controls.showY = true
|
||||
this.controls.showZ = true
|
||||
}
|
||||
|
||||
setBox( ) {
|
||||
let box = null
|
||||
console.log(this.viewer.interactions.selectedObjects.children.length )
|
||||
console.log(this.viewer.sceneManager.sceneObjects.allObjects.children.length )
|
||||
if( this.viewer.interactions.selectedObjects.children.length !== 0 ) {
|
||||
box = new THREE.Box3( ).setFromObject(this.viewer.interactions.selectedObjects)
|
||||
} else if( this.viewer.sceneManager.sceneObjects.allObjects.children.length !== 0 ){
|
||||
box = new THREE.Box3( ).setFromObject(this.viewer.sceneManager.sceneObjects.allObjects)
|
||||
} else {
|
||||
box = new Box3( new THREE.Vector3(-1, -1, -1), new THREE.Vector3(1, 1, 1))
|
||||
}
|
||||
if(box.min.x === Infinity) {
|
||||
box = new Box3( new THREE.Vector3(-1, -1, -1), new THREE.Vector3(1, 1, 1))
|
||||
}
|
||||
const dist = box.min.distanceTo(box.max)
|
||||
|
||||
const x1 = box.min.x - (box.max.x-box.min.x) * 0.05 // - dist * 0.05
|
||||
const y1 = box.min.y - (box.max.y-box.min.y) * 0.05 // - dist * 0.05
|
||||
const z1 = box.min.z - (box.max.z-box.min.z) * 0.05 // - dist * 0.05
|
||||
const x2 = box.max.x + (box.max.x-box.min.x) * 0.05 // + dist * 0.05
|
||||
const y2 = box.max.y + (box.max.y-box.min.y) * 0.05 // + dist * 0.05
|
||||
const z2 = box.max.z + (box.max.z-box.min.z) * 0.05 // + dist * 0.05
|
||||
|
||||
const newVertices = [
|
||||
x1, y1, z1,
|
||||
x2, y1, z1,
|
||||
x2, y2, z1,
|
||||
x1, y2, z1,
|
||||
x1, y1, z2,
|
||||
x2, y1, z2,
|
||||
x2, y2, z2,
|
||||
x1, y2, z2,
|
||||
]
|
||||
|
||||
let boxVerts = this.boxGeometry.attributes.position.array
|
||||
for(let i = 0; i < newVertices.length; i++) {
|
||||
boxVerts[i] = newVertices[i]
|
||||
}
|
||||
|
||||
this.boxGeometry.attributes.position.needsUpdate = true
|
||||
this.boxGeometry.computeVertexNormals()
|
||||
this.boxGeometry.computeBoundingBox()
|
||||
this.boxGeometry.computeBoundingSphere()
|
||||
this._generateOrUpdatePlanes()
|
||||
this._attachControlsToBox()
|
||||
this.boxHelper.update()
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setBox()
|
||||
this.display.visible = !this.display.visible
|
||||
this.viewer.renderer.localClippingEnabled = this.display.visible
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
off() {
|
||||
this.display.visible = false
|
||||
this.viewer.renderer.localClippingEnabled = false
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
on() {
|
||||
this.display.visible = true
|
||||
this.viewer.renderer.localClippingEnabled = true
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,14 @@
|
||||
import * as THREE from 'three'
|
||||
|
||||
import CameraControls from 'camera-controls'
|
||||
import { HOLD_EVENT_TYPE, ElementHold, KeyboardKeyHold } from 'hold-event'
|
||||
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
|
||||
import { SSAOPass } from 'three/examples/jsm/postprocessing/SSAOPass.js'
|
||||
import Stats from 'three/examples/jsm/libs/stats.module.js'
|
||||
|
||||
import ObjectManager from './SceneObjectManager'
|
||||
import ViewerObjectLoader from './ViewerObjectLoader'
|
||||
import EventEmitter from './EventEmitter'
|
||||
import InteractionHandler from './InteractionHandler'
|
||||
import CameraHandler from './context/cameras'
|
||||
import CameraHandler from './context/CameraHanlder'
|
||||
|
||||
import SectionBox from './SectionBoxNew'
|
||||
import SectionBox from './SectionBox'
|
||||
|
||||
export default class Viewer extends EventEmitter {
|
||||
|
||||
@@ -64,6 +60,7 @@ export default class Viewer extends EventEmitter {
|
||||
this.sceneLights()
|
||||
this.animate()
|
||||
this.onWindowResize()
|
||||
this.interactions.zoomExtents()
|
||||
this.needsRender = true
|
||||
}
|
||||
|
||||
|
||||
+34
-44
@@ -1,9 +1,9 @@
|
||||
import * as THREE from 'three'
|
||||
import CameraControls from 'camera-controls'
|
||||
import { HOLD_EVENT_TYPE, ElementHold, KeyboardKeyHold } from 'hold-event'
|
||||
import { KeyboardKeyHold } from 'hold-event'
|
||||
|
||||
export default class CameraHandler {
|
||||
constructor(viewer) {
|
||||
constructor( viewer ) {
|
||||
this.viewer = viewer
|
||||
|
||||
this.camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight )
|
||||
@@ -13,7 +13,7 @@ export default class CameraHandler {
|
||||
|
||||
let aspect = this.viewer.container.offsetWidth / this.viewer.container.offsetHeight
|
||||
let fustrumSize = 50
|
||||
this.orthoCamera = new THREE.OrthographicCamera( (-fustrumSize * aspect ) / 2, (fustrumSize * aspect ) / 2, fustrumSize / 2, -fustrumSize/ 2, 0.001, 1000)
|
||||
this.orthoCamera = new THREE.OrthographicCamera( ( -fustrumSize * aspect ) / 2, ( fustrumSize * aspect ) / 2, fustrumSize / 2, -fustrumSize / 2, 0.001, 10000 )
|
||||
this.orthoCamera.up.set( 0, 0, 1 )
|
||||
this.orthoCamera.position.set( 100, 100, 100 )
|
||||
this.orthoCamera.updateProjectionMatrix()
|
||||
@@ -39,20 +39,10 @@ export default class CameraHandler {
|
||||
]
|
||||
|
||||
this.orbiting = false
|
||||
this.controls.addEventListener('wake', () => {
|
||||
// console.log( 'orbiting')
|
||||
this.orbiting = true
|
||||
} )
|
||||
|
||||
this.controls.addEventListener('controlend', () => {
|
||||
// console.log( 'controlend')
|
||||
// this.orbiting = false
|
||||
} )
|
||||
|
||||
this.controls.addEventListener('rest', () => {
|
||||
// console.log( 'rest')
|
||||
setTimeout( () => { this.orbiting = false }, 400 )
|
||||
} )
|
||||
this.controls.addEventListener( 'wake', () => { this.orbiting = true } )
|
||||
// note: moved to new controls event called "rest"
|
||||
this.controls.addEventListener( 'controlend', () => { } )
|
||||
this.controls.addEventListener( 'rest', () => { setTimeout( () => { this.orbiting = false }, 400 ) } )
|
||||
|
||||
window.addEventListener( 'resize', this.onWindowResize.bind( this ), false )
|
||||
this.onWindowResize()
|
||||
@@ -64,17 +54,17 @@ export default class CameraHandler {
|
||||
|
||||
set activeCam( val ) {
|
||||
if( val === 'perspective' )
|
||||
return this.setPerspectiveCameraOn()
|
||||
this.setPerspectiveCameraOn()
|
||||
if( val === 'ortho' )
|
||||
return this.setOrthoCameraOn()
|
||||
this.setOrthoCameraOn()
|
||||
}
|
||||
|
||||
set enabled( val ) {
|
||||
this.controls.enabled = val
|
||||
}
|
||||
|
||||
setPerspectiveCameraOn(){
|
||||
if(this.cameras[0].active) return
|
||||
setPerspectiveCameraOn() {
|
||||
if( this.cameras[0].active ) return
|
||||
this.cameras[0].active = true
|
||||
this.cameras[1].active = false
|
||||
|
||||
@@ -82,8 +72,8 @@ export default class CameraHandler {
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
setOrthoCameraOn(){
|
||||
if(this.cameras[1].active) return
|
||||
setOrthoCameraOn() {
|
||||
if( this.cameras[1].active ) return
|
||||
this.cameras[0].active = false
|
||||
this.cameras[1].active = true
|
||||
|
||||
@@ -91,8 +81,8 @@ export default class CameraHandler {
|
||||
this.viewer.needsRender = true
|
||||
}
|
||||
|
||||
toggleCameras(){
|
||||
if(this.cameras[0].active) this.setOrthoCameraOn()
|
||||
toggleCameras() {
|
||||
if( this.cameras[0].active ) this.setOrthoCameraOn()
|
||||
else this.setPerspectiveCameraOn()
|
||||
}
|
||||
|
||||
@@ -101,15 +91,15 @@ export default class CameraHandler {
|
||||
this.controls.mouseButtons.wheel = CameraControls.ACTION.ZOOM
|
||||
|
||||
const lineOfSight = new THREE.Vector3()
|
||||
this.camera.getWorldDirection(lineOfSight)
|
||||
this.camera.getWorldDirection( lineOfSight )
|
||||
const target = new THREE.Vector3()
|
||||
this.controls.getTarget(target)
|
||||
const distance = target.clone().sub(this.camera.position)
|
||||
const depth = distance.dot(lineOfSight)
|
||||
this.controls.getTarget( target )
|
||||
const distance = target.clone().sub( this.camera.position )
|
||||
const depth = distance.dot( lineOfSight )
|
||||
const dims = { x: this.viewer.container.offsetWidth, y: this.viewer.container.offsetHeight }
|
||||
const aspect = dims.x / dims.y
|
||||
const fov = this.camera.fov
|
||||
const height = depth * 2 * Math.atan((fov * (Math.PI / 180)) / 2)
|
||||
const height = depth * 2 * Math.atan( ( fov * ( Math.PI / 180 ) ) / 2 )
|
||||
const width = height * aspect
|
||||
|
||||
this.orthoCamera.zoom = 1
|
||||
@@ -119,21 +109,21 @@ export default class CameraHandler {
|
||||
this.orthoCamera.bottom = height / -2
|
||||
this.orthoCamera.far = this.camera.far
|
||||
this.orthoCamera.updateProjectionMatrix()
|
||||
this.orthoCamera.position.copy(this.camera.position)
|
||||
this.orthoCamera.quaternion.copy(this.camera.quaternion)
|
||||
this.orthoCamera.position.copy( this.camera.position )
|
||||
this.orthoCamera.quaternion.copy( this.camera.quaternion )
|
||||
this.controls.camera = this.orthoCamera
|
||||
this.viewer.emit('projection-change', 'ortho' )
|
||||
this.viewer.emit( 'projection-change', 'ortho' )
|
||||
}
|
||||
|
||||
setupPerspectiveCamera() {
|
||||
this.controls.mouseButtons.wheel = CameraControls.ACTION.DOLLY
|
||||
this.camera.position.copy(this.orthoCamera.position)
|
||||
this.camera.quaternion.copy(this.orthoCamera.quaternion)
|
||||
this.camera.position.copy( this.orthoCamera.position )
|
||||
this.camera.quaternion.copy( this.orthoCamera.quaternion )
|
||||
this.camera.updateProjectionMatrix()
|
||||
this.controls.distance = this.previousDistance
|
||||
this.controls.camera = this.camera
|
||||
this.controls.zoomTo(1)
|
||||
this.viewer.emit('projection-change', 'perspective' )
|
||||
this.controls.zoomTo( 1 )
|
||||
this.viewer.emit( 'projection-change', 'perspective' )
|
||||
}
|
||||
|
||||
setupWASDControls() {
|
||||
@@ -143,10 +133,10 @@ export default class CameraHandler {
|
||||
const aKey = new KeyboardKeyHold( KEYCODE.A, 16.666 )
|
||||
const sKey = new KeyboardKeyHold( KEYCODE.S, 16.666 )
|
||||
const dKey = new KeyboardKeyHold( KEYCODE.D, 16.666 )
|
||||
aKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.truck( -0.01 * event.deltaTime, 0, false ); return; }.bind( this ) )
|
||||
dKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.truck( 0.01 * event.deltaTime, 0, false ); return;}.bind( this ) )
|
||||
wKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.forward( 0.01 * event.deltaTime, false ); return; }.bind( this ) )
|
||||
sKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.forward( -0.01 * event.deltaTime, false ); return; }.bind( this ) )
|
||||
aKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.truck( -0.01 * event.deltaTime, 0, false ); return }.bind( this ) )
|
||||
dKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.truck( 0.01 * event.deltaTime, 0, false ); return}.bind( this ) )
|
||||
wKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.forward( 0.01 * event.deltaTime, false ); return }.bind( this ) )
|
||||
sKey.addEventListener( 'holding', function( event ) { if( this.viewer.mouseOverRenderer === false ) return; this.controls.forward( -0.01 * event.deltaTime, false ); return }.bind( this ) )
|
||||
}
|
||||
|
||||
onWindowResize() {
|
||||
@@ -155,10 +145,10 @@ export default class CameraHandler {
|
||||
|
||||
let aspect = this.viewer.container.offsetWidth / this.viewer.container.offsetHeight
|
||||
let fustrumSize = 50
|
||||
this.orthoCamera.left = (-fustrumSize * aspect ) / 2
|
||||
this.orthoCamera.right = (fustrumSize * aspect ) / 2
|
||||
this.orthoCamera.left = ( -fustrumSize * aspect ) / 2
|
||||
this.orthoCamera.right = ( fustrumSize * aspect ) / 2
|
||||
this.orthoCamera.top = fustrumSize / 2
|
||||
this.orthoCamera.bottom = -fustrumSize/2
|
||||
this.orthoCamera.bottom = -fustrumSize / 2
|
||||
this.orthoCamera.updateProjectionMatrix()
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user