lxc
2 years ago
54 changed files with 101520 additions and 10 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -0,0 +1,46 @@ |
|||
/** |
|||
* @author alteredq / http://alteredqualia.com/
|
|||
* |
|||
* Full-screen textured quad shader |
|||
*/ |
|||
|
|||
THREE.CopyShader = { |
|||
|
|||
uniforms: { |
|||
|
|||
"tDiffuse": { value: null }, |
|||
"opacity": { value: 1.0 } |
|||
|
|||
}, |
|||
|
|||
vertexShader: [ |
|||
|
|||
"varying vec2 vUv;", |
|||
|
|||
"void main() {", |
|||
|
|||
"vUv = uv;", |
|||
"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", |
|||
|
|||
"}" |
|||
|
|||
].join( "\n" ), |
|||
|
|||
fragmentShader: [ |
|||
|
|||
"uniform float opacity;", |
|||
|
|||
"uniform sampler2D tDiffuse;", |
|||
|
|||
"varying vec2 vUv;", |
|||
|
|||
"void main() {", |
|||
|
|||
"vec4 texel = texture2D( tDiffuse, vUv );", |
|||
"gl_FragColor = opacity * texel;", |
|||
|
|||
"}" |
|||
|
|||
].join( "\n" ) |
|||
|
|||
}; |
@ -0,0 +1,282 @@ |
|||
/* |
|||
* @author zz85 / https://github.com/zz85
|
|||
* @author mrdoob / http://mrdoob.com
|
|||
* Running this will allow you to drag three.js objects around the screen. |
|||
*/ |
|||
|
|||
THREE.DragControls = function ( _objects, _camera, _domElement ) { |
|||
|
|||
if ( _objects instanceof THREE.Camera ) { |
|||
|
|||
console.warn( 'THREE.DragControls: Constructor now expects ( objects, camera, domElement )' ); |
|||
var temp = _objects; _objects = _camera; _camera = temp; |
|||
|
|||
} |
|||
|
|||
var _plane = new THREE.Plane(); |
|||
var _raycaster = new THREE.Raycaster(); |
|||
|
|||
var _mouse = new THREE.Vector2(); |
|||
var _offset = new THREE.Vector3(); |
|||
var _intersection = new THREE.Vector3(); |
|||
|
|||
var _selected = null, _hovered = null; |
|||
|
|||
//
|
|||
|
|||
var scope = this; |
|||
|
|||
function activate() { |
|||
|
|||
_domElement.addEventListener( 'mousemove', onDocumentMouseMove, false ); |
|||
_domElement.addEventListener( 'mousedown', onDocumentMouseDown, false ); |
|||
_domElement.addEventListener( 'mouseup', onDocumentMouseCancel, false ); |
|||
_domElement.addEventListener( 'mouseleave', onDocumentMouseCancel, false ); |
|||
_domElement.addEventListener( 'touchmove', onDocumentTouchMove, false ); |
|||
_domElement.addEventListener( 'touchstart', onDocumentTouchStart, false ); |
|||
_domElement.addEventListener( 'touchend', onDocumentTouchEnd, false ); |
|||
|
|||
} |
|||
|
|||
function deactivate() { |
|||
|
|||
_domElement.removeEventListener( 'mousemove', onDocumentMouseMove, false ); |
|||
_domElement.removeEventListener( 'mousedown', onDocumentMouseDown, false ); |
|||
_domElement.removeEventListener( 'mouseup', onDocumentMouseCancel, false ); |
|||
_domElement.removeEventListener( 'mouseleave', onDocumentMouseCancel, false ); |
|||
_domElement.removeEventListener( 'touchmove', onDocumentTouchMove, false ); |
|||
_domElement.removeEventListener( 'touchstart', onDocumentTouchStart, false ); |
|||
_domElement.removeEventListener( 'touchend', onDocumentTouchEnd, false ); |
|||
|
|||
} |
|||
|
|||
function dispose() { |
|||
|
|||
deactivate(); |
|||
|
|||
} |
|||
|
|||
function onDocumentMouseMove( event ) { |
|||
|
|||
event.preventDefault(); |
|||
|
|||
var rect = _domElement.getBoundingClientRect(); |
|||
|
|||
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1; |
|||
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; |
|||
|
|||
_raycaster.setFromCamera( _mouse, _camera ); |
|||
|
|||
if ( _selected && scope.enabled ) { |
|||
|
|||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { |
|||
|
|||
_selected.position.copy( _intersection.sub( _offset ) ); |
|||
|
|||
} |
|||
|
|||
scope.dispatchEvent( { type: 'drag', object: _selected } ); |
|||
|
|||
return; |
|||
|
|||
} |
|||
|
|||
_raycaster.setFromCamera( _mouse, _camera ); |
|||
|
|||
var intersects = _raycaster.intersectObjects( _objects ); |
|||
|
|||
if ( intersects.length > 0 ) { |
|||
|
|||
var object = intersects[ 0 ].object; |
|||
|
|||
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), object.position ); |
|||
|
|||
if ( _hovered !== object ) { |
|||
|
|||
scope.dispatchEvent( { type: 'hoveron', object: object } ); |
|||
|
|||
_domElement.style.cursor = 'pointer'; |
|||
_hovered = object; |
|||
|
|||
} |
|||
|
|||
} else { |
|||
|
|||
if ( _hovered !== null ) { |
|||
|
|||
scope.dispatchEvent( { type: 'hoveroff', object: _hovered } ); |
|||
|
|||
_domElement.style.cursor = 'auto'; |
|||
_hovered = null; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
function onDocumentMouseDown( event ) { |
|||
|
|||
event.preventDefault(); |
|||
|
|||
_raycaster.setFromCamera( _mouse, _camera ); |
|||
|
|||
var intersects = _raycaster.intersectObjects( _objects ); |
|||
|
|||
if ( intersects.length > 0 ) { |
|||
|
|||
_selected = intersects[ 0 ].object; |
|||
|
|||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { |
|||
|
|||
_offset.copy( _intersection ).sub( _selected.position ); |
|||
|
|||
} |
|||
|
|||
_domElement.style.cursor = 'move'; |
|||
|
|||
scope.dispatchEvent( { type: 'dragstart', object: _selected } ); |
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
function onDocumentMouseCancel( event ) { |
|||
|
|||
event.preventDefault(); |
|||
|
|||
if ( _selected ) { |
|||
|
|||
scope.dispatchEvent( { type: 'dragend', object: _selected } ); |
|||
|
|||
_selected = null; |
|||
|
|||
} |
|||
|
|||
_domElement.style.cursor = 'auto'; |
|||
|
|||
} |
|||
|
|||
function onDocumentTouchMove( event ) { |
|||
|
|||
event.preventDefault(); |
|||
event = event.changedTouches[ 0 ]; |
|||
|
|||
var rect = _domElement.getBoundingClientRect(); |
|||
|
|||
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1; |
|||
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; |
|||
|
|||
_raycaster.setFromCamera( _mouse, _camera ); |
|||
|
|||
if ( _selected && scope.enabled ) { |
|||
|
|||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { |
|||
|
|||
_selected.position.copy( _intersection.sub( _offset ) ); |
|||
|
|||
} |
|||
|
|||
scope.dispatchEvent( { type: 'drag', object: _selected } ); |
|||
|
|||
return; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
function onDocumentTouchStart( event ) { |
|||
|
|||
event.preventDefault(); |
|||
event = event.changedTouches[ 0 ]; |
|||
|
|||
var rect = _domElement.getBoundingClientRect(); |
|||
|
|||
_mouse.x = ( ( event.clientX - rect.left ) / rect.width ) * 2 - 1; |
|||
_mouse.y = - ( ( event.clientY - rect.top ) / rect.height ) * 2 + 1; |
|||
|
|||
_raycaster.setFromCamera( _mouse, _camera ); |
|||
|
|||
var intersects = _raycaster.intersectObjects( _objects ); |
|||
|
|||
if ( intersects.length > 0 ) { |
|||
|
|||
_selected = intersects[ 0 ].object; |
|||
|
|||
_plane.setFromNormalAndCoplanarPoint( _camera.getWorldDirection( _plane.normal ), _selected.position ); |
|||
|
|||
if ( _raycaster.ray.intersectPlane( _plane, _intersection ) ) { |
|||
|
|||
_offset.copy( _intersection ).sub( _selected.position ); |
|||
|
|||
} |
|||
|
|||
_domElement.style.cursor = 'move'; |
|||
|
|||
scope.dispatchEvent( { type: 'dragstart', object: _selected } ); |
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
|
|||
function onDocumentTouchEnd( event ) { |
|||
|
|||
event.preventDefault(); |
|||
|
|||
if ( _selected ) { |
|||
|
|||
scope.dispatchEvent( { type: 'dragend', object: _selected } ); |
|||
|
|||
_selected = null; |
|||
|
|||
} |
|||
|
|||
_domElement.style.cursor = 'auto'; |
|||
|
|||
} |
|||
|
|||
activate(); |
|||
|
|||
// API
|
|||
|
|||
this.enabled = true; |
|||
|
|||
this.activate = activate; |
|||
this.deactivate = deactivate; |
|||
this.dispose = dispose; |
|||
|
|||
// Backward compatibility
|
|||
|
|||
this.setObjects = function () { |
|||
|
|||
console.error( 'THREE.DragControls: setObjects() has been removed.' ); |
|||
|
|||
}; |
|||
|
|||
this.on = function ( type, listener ) { |
|||
|
|||
console.warn( 'THREE.DragControls: on() has been deprecated. Use addEventListener() instead.' ); |
|||
scope.addEventListener( type, listener ); |
|||
|
|||
}; |
|||
|
|||
this.off = function ( type, listener ) { |
|||
|
|||
console.warn( 'THREE.DragControls: off() has been deprecated. Use removeEventListener() instead.' ); |
|||
scope.removeEventListener( type, listener ); |
|||
|
|||
}; |
|||
|
|||
this.notify = function ( type ) { |
|||
|
|||
console.error( 'THREE.DragControls: notify() has been deprecated. Use dispatchEvent() instead.' ); |
|||
scope.dispatchEvent( { type: type } ); |
|||
|
|||
}; |
|||
|
|||
}; |
|||
|
|||
THREE.DragControls.prototype = Object.create( THREE.EventDispatcher.prototype ); |
|||
THREE.DragControls.prototype.constructor = THREE.DragControls; |
@ -0,0 +1,189 @@ |
|||
/** |
|||
* @author alteredq / http://alteredqualia.com/
|
|||
*/ |
|||
|
|||
THREE.EffectComposer = function ( renderer, renderTarget ) { |
|||
|
|||
this.renderer = renderer; |
|||
|
|||
if ( renderTarget === undefined ) { |
|||
|
|||
var parameters = { |
|||
minFilter: THREE.LinearFilter, |
|||
magFilter: THREE.LinearFilter, |
|||
format: THREE.RGBAFormat, |
|||
stencilBuffer: false |
|||
}; |
|||
|
|||
var size = renderer.getDrawingBufferSize(); |
|||
renderTarget = new THREE.WebGLRenderTarget( size.width, size.height, parameters ); |
|||
renderTarget.texture.name = 'EffectComposer.rt1'; |
|||
|
|||
} |
|||
|
|||
this.renderTarget1 = renderTarget; |
|||
this.renderTarget2 = renderTarget.clone(); |
|||
this.renderTarget2.texture.name = 'EffectComposer.rt2'; |
|||
|
|||
this.writeBuffer = this.renderTarget1; |
|||
this.readBuffer = this.renderTarget2; |
|||
|
|||
this.passes = []; |
|||
|
|||
// dependencies
|
|||
|
|||
if ( THREE.CopyShader === undefined ) { |
|||
|
|||
console.error( 'THREE.EffectComposer relies on THREE.CopyShader' ); |
|||
|
|||
} |
|||
|
|||
if ( THREE.ShaderPass === undefined ) { |
|||
|
|||
console.error( 'THREE.EffectComposer relies on THREE.ShaderPass' ); |
|||
|
|||
} |
|||
|
|||
this.copyPass = new THREE.ShaderPass( THREE.CopyShader ); |
|||
|
|||
}; |
|||
|
|||
Object.assign( THREE.EffectComposer.prototype, { |
|||
|
|||
swapBuffers: function () { |
|||
|
|||
var tmp = this.readBuffer; |
|||
this.readBuffer = this.writeBuffer; |
|||
this.writeBuffer = tmp; |
|||
|
|||
}, |
|||
|
|||
addPass: function ( pass ) { |
|||
|
|||
this.passes.push( pass ); |
|||
|
|||
var size = this.renderer.getDrawingBufferSize(); |
|||
pass.setSize( size.width, size.height ); |
|||
|
|||
}, |
|||
|
|||
insertPass: function ( pass, index ) { |
|||
|
|||
this.passes.splice( index, 0, pass ); |
|||
|
|||
}, |
|||
|
|||
render: function ( delta ) { |
|||
|
|||
var maskActive = false; |
|||
|
|||
var pass, i, il = this.passes.length; |
|||
|
|||
for ( i = 0; i < il; i ++ ) { |
|||
|
|||
pass = this.passes[ i ]; |
|||
|
|||
if ( pass.enabled === false ) continue; |
|||
|
|||
pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); |
|||
|
|||
if ( pass.needsSwap ) { |
|||
|
|||
if ( maskActive ) { |
|||
|
|||
var context = this.renderer.context; |
|||
|
|||
context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); |
|||
|
|||
this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); |
|||
|
|||
context.stencilFunc( context.EQUAL, 1, 0xffffffff ); |
|||
|
|||
} |
|||
|
|||
this.swapBuffers(); |
|||
|
|||
} |
|||
|
|||
if ( THREE.MaskPass !== undefined ) { |
|||
|
|||
if ( pass instanceof THREE.MaskPass ) { |
|||
|
|||
maskActive = true; |
|||
|
|||
} else if ( pass instanceof THREE.ClearMaskPass ) { |
|||
|
|||
maskActive = false; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
reset: function ( renderTarget ) { |
|||
|
|||
if ( renderTarget === undefined ) { |
|||
|
|||
var size = this.renderer.getDrawingBufferSize(); |
|||
|
|||
renderTarget = this.renderTarget1.clone(); |
|||
renderTarget.setSize( size.width, size.height ); |
|||
|
|||
} |
|||
|
|||
this.renderTarget1.dispose(); |
|||
this.renderTarget2.dispose(); |
|||
this.renderTarget1 = renderTarget; |
|||
this.renderTarget2 = renderTarget.clone(); |
|||
|
|||
this.writeBuffer = this.renderTarget1; |
|||
this.readBuffer = this.renderTarget2; |
|||
|
|||
}, |
|||
|
|||
setSize: function ( width, height ) { |
|||
|
|||
this.renderTarget1.setSize( width, height ); |
|||
this.renderTarget2.setSize( width, height ); |
|||
|
|||
for ( var i = 0; i < this.passes.length; i ++ ) { |
|||
|
|||
this.passes[ i ].setSize( width, height ); |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} ); |
|||
|
|||
|
|||
THREE.Pass = function () { |
|||
|
|||
// if set to true, the pass is processed by the composer
|
|||
this.enabled = true; |
|||
|
|||
// if set to true, the pass indicates to swap read and write buffer after rendering
|
|||
this.needsSwap = true; |
|||
|
|||
// if set to true, the pass clears its buffer before rendering
|
|||
this.clear = false; |
|||
|
|||
// if set to true, the result of the pass is rendered to screen
|
|||
this.renderToScreen = false; |
|||
|
|||
}; |
|||
|
|||
Object.assign( THREE.Pass.prototype, { |
|||
|
|||
setSize: function ( width, height ) {}, |
|||
|
|||
render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { |
|||
|
|||
console.error( 'THREE.Pass: .render() must be implemented in derived pass.' ); |
|||
|
|||
} |
|||
|
|||
} ); |
File diff suppressed because it is too large
@ -0,0 +1,300 @@ |
|||
/** |
|||
* @author mrdoob / http://mrdoob.com/
|
|||
* @author alteredq / http://alteredqualia.com/
|
|||
* @author paulirish / http://paulirish.com/
|
|||
*/ |
|||
|
|||
THREE.FirstPersonControls = function ( object, domElement ) { |
|||
|
|||
this.object = object; |
|||
this.target = new THREE.Vector3( 0, 0, 0 ); |
|||
|
|||
this.domElement = ( domElement !== undefined ) ? domElement : document; |
|||
|
|||
this.enabled = true; |
|||
|
|||
this.movementSpeed = 1.0; |
|||
this.lookSpeed = 0.005; |
|||
|
|||
this.lookVertical = true; |
|||
this.autoForward = false; |
|||
|
|||
this.activeLook = true; |
|||
|
|||
this.heightSpeed = false; |
|||
this.heightCoef = 1.0; |
|||
this.heightMin = 0.0; |
|||
this.heightMax = 1.0; |
|||
|
|||
this.constrainVertical = false; |
|||
this.verticalMin = 0; |
|||
this.verticalMax = Math.PI; |
|||
|
|||
this.autoSpeedFactor = 0.0; |
|||
|
|||
this.mouseX = 0; |
|||
this.mouseY = 0; |
|||
|
|||
this.lat = 0; |
|||
this.lon = 0; |
|||
this.phi = 0; |
|||
this.theta = 0; |
|||
|
|||
this.moveForward = false; |
|||
this.moveBackward = false; |
|||
this.moveLeft = false; |
|||
this.moveRight = false; |
|||
|
|||
this.mouseDragOn = false; |
|||
|
|||
this.viewHalfX = 0; |
|||
this.viewHalfY = 0; |
|||
|
|||
if ( this.domElement !== document ) { |
|||
|
|||
this.domElement.setAttribute( 'tabindex', - 1 ); |
|||
|
|||
} |
|||
|
|||
//
|
|||
|
|||
this.handleResize = function () { |
|||
|
|||
if ( this.domElement === document ) { |
|||
|
|||
this.viewHalfX = window.innerWidth / 2; |
|||
this.viewHalfY = window.innerHeight / 2; |
|||
|
|||
} else { |
|||
|
|||
this.viewHalfX = this.domElement.offsetWidth / 2; |
|||
this.viewHalfY = this.domElement.offsetHeight / 2; |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
this.onMouseDown = function ( event ) { |
|||
|
|||
if ( this.domElement !== document ) { |
|||
|
|||
this.domElement.focus(); |
|||
|
|||
} |
|||
|
|||
event.preventDefault(); |
|||
event.stopPropagation(); |
|||
|
|||
if ( this.activeLook ) { |
|||
|
|||
switch ( event.button ) { |
|||
|
|||
case 0: this.moveForward = true; break; |
|||
case 2: this.moveBackward = true; break; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
this.mouseDragOn = true; |
|||
|
|||
}; |
|||
|
|||
this.onMouseUp = function ( event ) { |
|||
|
|||
event.preventDefault(); |
|||
event.stopPropagation(); |
|||
|
|||
if ( this.activeLook ) { |
|||
|
|||
switch ( event.button ) { |
|||
|
|||
case 0: this.moveForward = false; break; |
|||
case 2: this.moveBackward = false; break; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
this.mouseDragOn = false; |
|||
|
|||
}; |
|||
|
|||
this.onMouseMove = function ( event ) { |
|||
|
|||
if ( this.domElement === document ) { |
|||
|
|||
this.mouseX = event.pageX - this.viewHalfX; |
|||
this.mouseY = event.pageY - this.viewHalfY; |
|||
|
|||
} else { |
|||
|
|||
this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX; |
|||
this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY; |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
this.onKeyDown = function ( event ) { |
|||
|
|||
//event.preventDefault();
|
|||
|
|||
switch ( event.keyCode ) { |
|||
|
|||
case 38: /*up*/ |
|||
case 87: /*W*/ this.moveForward = true; break; |
|||
|
|||
case 37: /*left*/ |
|||
case 65: /*A*/ this.moveLeft = true; break; |
|||
|
|||
case 40: /*down*/ |
|||
case 83: /*S*/ this.moveBackward = true; break; |
|||
|
|||
case 39: /*right*/ |
|||
case 68: /*D*/ this.moveRight = true; break; |
|||
|
|||
case 82: /*R*/ this.moveUp = true; break; |
|||
case 70: /*F*/ this.moveDown = true; break; |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
this.onKeyUp = function ( event ) { |
|||
|
|||
switch ( event.keyCode ) { |
|||
|
|||
case 38: /*up*/ |
|||
case 87: /*W*/ this.moveForward = false; break; |
|||
|
|||
case 37: /*left*/ |
|||
case 65: /*A*/ this.moveLeft = false; break; |
|||
|
|||
case 40: /*down*/ |
|||
case 83: /*S*/ this.moveBackward = false; break; |
|||
|
|||
case 39: /*right*/ |
|||
case 68: /*D*/ this.moveRight = false; break; |
|||
|
|||
case 82: /*R*/ this.moveUp = false; break; |
|||
case 70: /*F*/ this.moveDown = false; break; |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
this.update = function ( delta ) { |
|||
|
|||
if ( this.enabled === false ) return; |
|||
|
|||
if ( this.heightSpeed ) { |
|||
|
|||
var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax ); |
|||
var heightDelta = y - this.heightMin; |
|||
|
|||
this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef ); |
|||
|
|||
} else { |
|||
|
|||
this.autoSpeedFactor = 0.0; |
|||
|
|||
} |
|||
|
|||
var actualMoveSpeed = delta * this.movementSpeed; |
|||
|
|||
if ( this.moveForward || ( this.autoForward && ! this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) ); |
|||
if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed ); |
|||
|
|||
if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed ); |
|||
if ( this.moveRight ) this.object.translateX( actualMoveSpeed ); |
|||
|
|||
if ( this.moveUp ) this.object.translateY( actualMoveSpeed ); |
|||
if ( this.moveDown ) this.object.translateY( - actualMoveSpeed ); |
|||
|
|||
var actualLookSpeed = delta * this.lookSpeed; |
|||
|
|||
if ( ! this.activeLook ) { |
|||
|
|||
actualLookSpeed = 0; |
|||
|
|||
} |
|||
|
|||
var verticalLookRatio = 1; |
|||
|
|||
if ( this.constrainVertical ) { |
|||
|
|||
verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin ); |
|||
|
|||
} |
|||
|
|||
this.lon += this.mouseX * actualLookSpeed; |
|||
if ( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio; |
|||
|
|||
this.lat = Math.max( - 85, Math.min( 85, this.lat ) ); |
|||
this.phi = THREE.Math.degToRad( 90 - this.lat ); |
|||
|
|||
this.theta = THREE.Math.degToRad( this.lon ); |
|||
|
|||
if ( this.constrainVertical ) { |
|||
|
|||
this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax ); |
|||
|
|||
} |
|||
|
|||
var targetPosition = this.target, |
|||
position = this.object.position; |
|||
|
|||
targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta ); |
|||
targetPosition.y = position.y + 100 * Math.cos( this.phi ); |
|||
targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta ); |
|||
|
|||
this.object.lookAt( targetPosition ); |
|||
|
|||
}; |
|||
|
|||
function contextmenu( event ) { |
|||
|
|||
event.preventDefault(); |
|||
|
|||
} |
|||
|
|||
this.dispose = function () { |
|||
|
|||
this.domElement.removeEventListener( 'contextmenu', contextmenu, false ); |
|||
this.domElement.removeEventListener( 'mousedown', _onMouseDown, false ); |
|||
this.domElement.removeEventListener( 'mousemove', _onMouseMove, false ); |
|||
this.domElement.removeEventListener( 'mouseup', _onMouseUp, false ); |
|||
|
|||
window.removeEventListener( 'keydown', _onKeyDown, false ); |
|||
window.removeEventListener( 'keyup', _onKeyUp, false ); |
|||
|
|||
}; |
|||
|
|||
var _onMouseMove = bind( this, this.onMouseMove ); |
|||
var _onMouseDown = bind( this, this.onMouseDown ); |
|||
var _onMouseUp = bind( this, this.onMouseUp ); |
|||
var _onKeyDown = bind( this, this.onKeyDown ); |
|||
var _onKeyUp = bind( this, this.onKeyUp ); |
|||
|
|||
this.domElement.addEventListener( 'contextmenu', contextmenu, false ); |
|||
this.domElement.addEventListener( 'mousemove', _onMouseMove, false ); |
|||
this.domElement.addEventListener( 'mousedown', _onMouseDown, false ); |
|||
this.domElement.addEventListener( 'mouseup', _onMouseUp, false ); |
|||
|
|||
window.addEventListener( 'keydown', _onKeyDown, false ); |
|||
window.addEventListener( 'keyup', _onKeyUp, false ); |
|||
|
|||
function bind( scope, fn ) { |
|||
|
|||
return function () { |
|||
|
|||
fn.apply( scope, arguments ); |
|||
|
|||
}; |
|||
|
|||
} |
|||
|
|||
this.handleResize(); |
|||
|
|||
}; |
File diff suppressed because it is too large
@ -0,0 +1,387 @@ |
|||
/** |
|||
* Modules.js是3D库区图显示模型存放的地方 |
|||
* |
|||
* @author 谢宁, Created on 2018-06-07 |
|||
*/ |
|||
/** ***************************************************************** */ |
|||
//模型材质信息
|
|||
var planeMat, RackMat, RackMat2, CargoMat, LineMat, RollTexture, RollMat; |
|||
//库区信息
|
|||
var storageZoneSize = 0, storageZoneList = []; |
|||
//货架信息
|
|||
var shelfSize = 0, shelfList = []; |
|||
//货位信息
|
|||
var storageUnitSize = 0, storageUnitList = []; |
|||
//货物信息
|
|||
var cargoSize = 0, cargoList = [], CargosExist; |
|||
|
|||
//创建库区对象
|
|||
function storageZone(StorageZoneId,StorageZoneName, |
|||
coordinateX,coordinateZ, |
|||
width,length, |
|||
textColor,fontSize,textposition) |
|||
{ |
|||
this.StorageZoneId=StorageZoneId; |
|||
this.StorageZoneName=StorageZoneName; |
|||
this.coordinateX=coordinateX; |
|||
this.coordinateZ=coordinateZ; |
|||
this.width=width; |
|||
this.length=length; |
|||
this.textColor=textColor; |
|||
this.fontSize=fontSize; |
|||
this.textposition=textposition; |
|||
} |
|||
|
|||
//根据库区编码获取库区对象
|
|||
function getStorageZoneById(StorageZoneId) { |
|||
for(var i = 0; i < storageZoneSize; i++){ |
|||
if(storageZoneList[i].StorageZoneId == StorageZoneId){ |
|||
return storageZoneList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//创建货架对象
|
|||
function shelf(storageZoneId, shelfId, shelfName, |
|||
planeLength , planeWidth , planeHeight , |
|||
holderLength , holderWidth , holderHeight , |
|||
positionX , positionY , positionZ , |
|||
layerNum , columnNum) |
|||
{ |
|||
this.storageZoneId=storageZoneId; |
|||
this.shelfId=shelfId; |
|||
this.shelfName=shelfName; |
|||
this.planeLength=planeLength; |
|||
this.planeWidth=planeWidth; |
|||
this.planeHeight=planeHeight; |
|||
this.holderLength=holderLength; |
|||
this.holderWidth=holderWidth; |
|||
this.holderHeight=holderHeight; |
|||
this.positionX=positionX; |
|||
this.positionY=positionY; |
|||
this.positionZ=positionZ; |
|||
this.layerNum=layerNum; |
|||
this.columnNum=columnNum; |
|||
} |
|||
|
|||
//根据货架编码获取货架对象
|
|||
function getShelfById(shelfId) { |
|||
for(var i = 0; i < shelfSize; i++){ |
|||
if(shelfList[i].shelfId == shelfId){ |
|||
return shelfList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//创建货位对象
|
|||
function storageUnit(storageZoneId, shelfId, shelfName, |
|||
inLayerNum , inColumnNum , |
|||
positionX , positionY , positionZ, storageUnitId) |
|||
{ |
|||
this.storageZoneId=storageZoneId; |
|||
this.shelfId=shelfId; |
|||
this.shelfName=shelfName; |
|||
this.inLayerNum=inLayerNum; |
|||
this.inColumnNum=inColumnNum; |
|||
this.positionX=positionX; |
|||
this.positionY=positionY; |
|||
this.positionZ=positionZ; |
|||
this.storageUnitId=storageUnitId; |
|||
} |
|||
|
|||
//根据货架ID、层数、列数获取货位对象
|
|||
function getStorageUnitById(shelfId,inLayerNum,inColumnNum) { |
|||
for(var i = 0; i < storageUnitSize; i++){ |
|||
if(storageUnitList[i].shelfId == shelfId && storageUnitList[i].inLayerNum == inLayerNum && storageUnitList[i].inColumnNum == inColumnNum){ |
|||
return storageUnitList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//根据库位编码获取货位对象
|
|||
function getStorageUnitByUnitId(storageUnitId) { |
|||
for(var i = 0; i < storageUnitSize; i++){ |
|||
if(storageUnitList[i].storageUnitId == storageUnitId){ |
|||
return storageUnitList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//创建货物对象
|
|||
function cargo(batchNo, prodBatchNo, inBatchNo, |
|||
matId, matClassId, matName, |
|||
qty, qtyUom, qty2, |
|||
warehouseId, storageZoneId, storageUnitId, |
|||
positionX , positionY , positionZ, |
|||
length , width , height) |
|||
{ |
|||
this.batchNo=batchNo; |
|||
this.prodBatchNo=prodBatchNo; |
|||
this.inBatchNo=inBatchNo; |
|||
this.matId=matId; |
|||
this.matClassId=matClassId; |
|||
this.matName=matName; |
|||
this.qtyUom=qtyUom; |
|||
this.qty2=qty2; |
|||
this.warehouseId=warehouseId; |
|||
this.storageZoneId=storageZoneId; |
|||
this.storageUnitId=storageUnitId; |
|||
this.positionX=positionX; |
|||
this.positionY=positionY; |
|||
this.positionZ=positionZ; |
|||
this.length=length; |
|||
this.width=width; |
|||
this.height=height; |
|||
} |
|||
|
|||
/** 初始化材质信息 */ |
|||
function initMat() { |
|||
planeMat = new THREE.MeshLambertMaterial(); |
|||
RackMat = new THREE.MeshLambertMaterial(); |
|||
RackMat2 = new THREE.MeshPhongMaterial({color:0x1C86EE}); |
|||
CargoMat = new THREE.MeshLambertMaterial(); |
|||
LineMat = new THREE.MeshLambertMaterial(); |
|||
RollMat = new THREE.MeshLambertMaterial(); |
|||
|
|||
new THREE.TextureLoader().load( './ThreeJs/images/plane.png', function( map ) { |
|||
planeMat.map = map; |
|||
planeMat.transparent = true; |
|||
planeMat.opacity = 0.8; |
|||
planeMat.needsUpdate = true; |
|||
} ); |
|||
new THREE.TextureLoader().load( "./ThreeJs/images/rack.png", function( map ) { |
|||
RackMat.map = map; |
|||
RackMat.needsUpdate = true; |
|||
} ); |
|||
new THREE.TextureLoader().load( "./ThreeJs/images/box.png", function( map ) { |
|||
CargoMat.map = map; |
|||
CargoMat.needsUpdate = true; |
|||
} ); |
|||
new THREE.TextureLoader().load( "./ThreeJs/images/line.png", function( map ) { |
|||
LineMat.map = map; |
|||
LineMat.needsUpdate = true; |
|||
} ); |
|||
RollTexture = new THREE.TextureLoader().load( "./ThreeJs/images/biaoyu.png", function( map ) { |
|||
RollMat.map = map; |
|||
RollMat.needsUpdate = true; |
|||
RollMat.transparent = true; |
|||
RollMat.side = THREE.DoubleSide; |
|||
} ); |
|||
RollTexture.wrapS = THREE.RepeatWrapping; |
|||
RollTexture.wrapT=THREE.RepeatWrapping; |
|||
} |
|||
|
|||
//region 放置天空盒
|
|||
function addSkybox( size,scene ) { |
|||
urls = [ |
|||
'./ThreeJs/images/skybox/远山_RT.jpg', // right
|
|||
'./ThreeJs/images/skybox/远山_LF.jpg', // left
|
|||
'./ThreeJs/images/skybox/远山_UP.jpg', // top
|
|||
'./ThreeJs/images/skybox/远山_DN.jpg', // bottom
|
|||
'./ThreeJs/images/skybox/远山_BK.jpg', // back
|
|||
'./ThreeJs/images/skybox/远山_FR.jpg' // front
|
|||
]; |
|||
var skyboxCubemap = new THREE.CubeTextureLoader().load( urls ); |
|||
skyboxCubemap.format = THREE.RGBFormat; |
|||
|
|||
var skyboxShader = THREE.ShaderLib['cube']; |
|||
skyboxShader.uniforms['tCube'].value = skyboxCubemap; |
|||
var obj = new THREE.Mesh( |
|||
new THREE.BoxGeometry( size, size, size ), |
|||
new THREE.ShaderMaterial({ |
|||
fragmentShader : skyboxShader.fragmentShader, |
|||
vertexShader : skyboxShader.vertexShader, |
|||
uniforms : skyboxShader.uniforms, |
|||
depthWrite : false, |
|||
side : THREE.BackSide |
|||
}) |
|||
); |
|||
scene.add( obj ); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 滚动的物体
|
|||
function addRollPlane(scene) { |
|||
var geometry = new THREE.PlaneGeometry( 400, 20 ); |
|||
var obj = new THREE.Mesh( geometry, RollMat ); |
|||
obj.position.set(0,150,-690); |
|||
scene.add( obj ); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 放置视频面板
|
|||
function addVideoPlane( x,y,z,width,length, videoId ) { |
|||
var planeGeometry = new THREE.PlaneGeometry(width, length); |
|||
var material = new THREE.MeshPhongMaterial(); |
|||
material.side = THREE.DoubleSide; |
|||
var video = document.getElementById(videoId); |
|||
var texture = new THREE.VideoTexture(video); |
|||
texture.minFilter = THREE.LinearFilter; |
|||
texture.magFilter = THREE.LinearFilter; |
|||
texture.format = THREE.RGBFormat; |
|||
material.map = texture; |
|||
var mesh = new THREE.Mesh(planeGeometry, material); |
|||
mesh.position.set(x,y,z); |
|||
return mesh; |
|||
} |
|||
//endregion
|
|||
|
|||
//region 矩形区域
|
|||
function addPlane(x,z,width,length,scene) { |
|||
var lineWidth = 8 |
|||
var geometry = new THREE.PlaneGeometry( lineWidth, length ); |
|||
var obj = new THREE.Mesh( geometry, LineMat ); |
|||
obj.position.set(x,1.5,z); |
|||
obj.rotation.x = -Math.PI / 2.0; |
|||
var obj2 = obj.clone(); |
|||
obj2.translateX(width); |
|||
|
|||
var geometry2 = new THREE.PlaneGeometry( lineWidth, width ); |
|||
var obj3 = new THREE.Mesh( geometry2, LineMat ); |
|||
obj3.position.set(x+width/2,1.5,z-length/2+lineWidth/2); |
|||
obj3.rotation.x = -Math.PI / 2.0; |
|||
obj3.rotation.z = -Math.PI / 2.0; |
|||
var obj4 = obj3.clone(); |
|||
obj4.translateX(length-lineWidth); |
|||
|
|||
var group = new THREE.Group(); |
|||
group.add(obj); |
|||
group.add(obj2); |
|||
group.add(obj3); |
|||
group.add(obj4); |
|||
group.translateX(-width/2); |
|||
scene.add( group ); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 库区
|
|||
/** 放置虚线框区域和库区名称 */ |
|||
function addArea(x,z,width,length,scene,name,textColor,font_size,textposition) { |
|||
addPlane(x,z,width,length,scene); |
|||
|
|||
new THREE.FontLoader().load('./ThreeJs/FZYaoTi_Regular.json',function(font){ |
|||
////加入立体文字
|
|||
var text= new THREE.TextGeometry(name.split("$")[1],{ |
|||
// 设定文字字体
|
|||
font:font, |
|||
//尺寸
|
|||
size:font_size, |
|||
//厚度
|
|||
height:0.01 |
|||
}); |
|||
text.computeBoundingBox(); |
|||
//3D文字材质
|
|||
var m = new THREE.MeshStandardMaterial({color:"#" + textColor}); |
|||
var mesh = new THREE.Mesh(text,m) |
|||
if(textposition == "左对齐"){ |
|||
mesh.position.x = x - width/2 + 10; |
|||
}else if(textposition == "居中"){ |
|||
mesh.position.x = x - 15; |
|||
}else if(textposition == "右对齐"){ |
|||
mesh.position.x = x + width/2 - 60; |
|||
} |
|||
mesh.position.y = 1.3; |
|||
mesh.position.z = z + length/2 - 20; |
|||
mesh.rotation.x = -Math.PI / 2.0; |
|||
scene.add(mesh); |
|||
}); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 货架货位
|
|||
|
|||
/** 放置单层货架 */ |
|||
/** x,y,z 整个模型在场景中的位置 */ |
|||
/** plane_x,plane_y,plane_z 货架板面的长高宽 */ |
|||
/** holder_x,holder_y,holder_z 货架支架的长高宽 */ |
|||
/** scene,name,num 要添加的场景,货架的名字,单层货架的库位数量 */ |
|||
function addRack(x,y,z,plane_x,plane_y,plane_z,holder_x,holder_y,holder_z,scene,name,num) { |
|||
var plane = new THREE.BoxGeometry( plane_x, plane_y, plane_z/num ); |
|||
var gz = []; |
|||
for(var i = 0; i < num; i++){ |
|||
gz.push( z + plane_z/num/2 + (plane_z/num)*i ); |
|||
var obj = new THREE.Mesh( plane, RackMat ); |
|||
obj.position.set(x , y, gz[i]) ; |
|||
var msg = name+"$"+(GET_COLUMN_NUM() - i); |
|||
|
|||
var storageUnitId = msg.split("$")[1] + "$" + msg.split("$")[3] + "$" + msg.split("$")[4]; |
|||
|
|||
//添加货位
|
|||
var storageUnit_obj = new storageUnit(msg.split("$")[0], |
|||
msg.split("$")[1], |
|||
msg.split("$")[2], |
|||
msg.split("$")[3], |
|||
msg.split("$")[4], |
|||
x, y, gz[i], storageUnitId); |
|||
storageUnitList.push(storageUnit_obj); |
|||
storageUnitSize++; |
|||
|
|||
var Unit = getStorageUnitById(msg.split("$")[1],msg.split("$")[3],msg.split("$")[4]); |
|||
obj.name = "货位"+"$"+Unit.storageUnitId; |
|||
scene.add(obj); |
|||
} |
|||
|
|||
var holder = new THREE.BoxGeometry( holder_x, holder_y, holder_z ); |
|||
var obj2 = new THREE.Mesh( holder, RackMat2, 0 ); |
|||
var obj3 = new THREE.Mesh( holder, RackMat2, 0 ); |
|||
var obj4 = new THREE.Mesh( holder, RackMat2, 0 ); |
|||
var obj5 = new THREE.Mesh( holder, RackMat2, 0 ); |
|||
|
|||
obj2.position.set(x-plane_x/2+holder_x/2,y-holder_y/2-plane_y/2,z+holder_z/2); |
|||
obj3.position.set(x+plane_x/2-holder_x/2,y-holder_y/2-plane_y/2,z+holder_z/2); |
|||
obj4.position.set(x-plane_x/2+holder_x/2,y-holder_y/2-plane_y/2,z+plane_z-holder_z/2); |
|||
obj5.position.set(x+plane_x/2-holder_x/2,y-holder_y/2-plane_y/2,z+plane_z-holder_z/2); |
|||
scene.add(obj2);scene.add(obj3);scene.add(obj4);scene.add(obj5); |
|||
} |
|||
|
|||
/** 放置一叠货架 */ |
|||
/** stack_num 货架的叠数 */ |
|||
function addStackOfRack(x,y,z,plane_x,plane_y,plane_z,holder_x,holder_y,holder_z,scene,name,num,stack_num) { |
|||
for(var i = 0; i < stack_num; i++){ |
|||
addRack(x,y*(i+1),z,plane_x,plane_y,plane_z,holder_x,holder_y,holder_z,scene,name+"$"+(i+1),num); |
|||
} |
|||
} |
|||
|
|||
/** 根据3D库图货架配置表添加货架 */ |
|||
function addShelf(scene) { |
|||
var shelf_list = GET_SHELF_LIST(); |
|||
shelfSize = shelf_list.length; |
|||
for(var i = 0; i < shelfSize; i++){ |
|||
var shelf_obj = new shelf(shelf_list[i].StorageZoneId, |
|||
shelf_list[i].shelfId, |
|||
shelf_list[i].shelfName, |
|||
GET_PLANE_LENGTH(),GET_PLANE_WIDTH(),GET_PLANE_HEIGHT(), |
|||
GET_HOLDER_LENGTH(),GET_HOLDER_WIDTH(),GET_HOLDER_HEIGHT(), |
|||
shelf_list[i].x, |
|||
shelf_list[i].y, |
|||
shelf_list[i].z, |
|||
GET_LAYER_NUM(),GET_COLUMN_NUM()); |
|||
shelfList.push(shelf_obj); |
|||
} |
|||
|
|||
for(var i = 0;i < shelfSize; i++){ |
|||
addStackOfRack(shelfList[i].positionX,shelfList[i].positionY,shelfList[i].positionZ,shelfList[i].planeLength,shelfList[i].planeHeight,shelfList[i].planeWidth,shelfList[i].holderLength,shelfList[i].holderHeight,shelfList[i].holderWidth,scene,shelfList[i].storageZoneId+"$"+shelfList[i].shelfId+"$"+shelfList[i].shelfName,shelfList[i].columnNum,shelfList[i].layerNum); |
|||
} |
|||
} |
|||
|
|||
//region 货物
|
|||
/** 放置单个货物 */ |
|||
function addCargo(x,y,z,box_x,box_y,box_z,scene,name) { |
|||
var geometry = new THREE.BoxGeometry( box_x, box_y, box_z ); |
|||
var obj = new THREE.Mesh( geometry, CargoMat ); |
|||
obj.position.set(x,y,z); |
|||
obj.name = name; |
|||
scene.add(obj); |
|||
} |
|||
|
|||
/** 添加单个货位上的货物 */ |
|||
function addOneUnitCargos(shelfId,inLayerNum,inColumnNum,scene) { |
|||
var storageUnit = getStorageUnitById(shelfId,inLayerNum,inColumnNum); |
|||
var shelf = getShelfById(storageUnit.shelfId); |
|||
var storageUnitid = storageUnit.storageUnitId; |
|||
var x = storageUnit.positionX; |
|||
var y = storageUnit.positionY + GET_BOX_SIZE()/2 + shelf.planeHeight/2; |
|||
var z = storageUnit.positionZ; |
|||
addCargo(x,y,z,GET_BOX_SIZE(),GET_BOX_SIZE(),GET_BOX_SIZE(),scene,"货物"+"$"+storageUnitid) |
|||
} |
|||
//endregion
|
File diff suppressed because it is too large
@ -0,0 +1,571 @@ |
|||
/** |
|||
* @author spidersharma / http://eduperiment.com/
|
|||
*/ |
|||
|
|||
THREE.OutlinePass = function ( resolution, scene, camera, selectedObjects ) { |
|||
|
|||
this.renderScene = scene; |
|||
this.renderCamera = camera; |
|||
this.selectedObjects = selectedObjects !== undefined ? selectedObjects : []; |
|||
this.visibleEdgeColor = new THREE.Color( 1, 1, 1 ); |
|||
this.hiddenEdgeColor = new THREE.Color( 0.1, 0.04, 0.02 ); |
|||
this.edgeGlow = 0.0; |
|||
this.usePatternTexture = false; |
|||
this.edgeThickness = 1.0; |
|||
this.edgeStrength = 3.0; |
|||
this.downSampleRatio = 2; |
|||
this.pulsePeriod = 0; |
|||
|
|||
THREE.Pass.call( this ); |
|||
|
|||
this.resolution = ( resolution !== undefined ) ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 ); |
|||
|
|||
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat }; |
|||
|
|||
var resx = Math.round( this.resolution.x / this.downSampleRatio ); |
|||
var resy = Math.round( this.resolution.y / this.downSampleRatio ); |
|||
|
|||
this.maskBufferMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff } ); |
|||
this.maskBufferMaterial.side = THREE.DoubleSide; |
|||
this.renderTargetMaskBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars ); |
|||
this.renderTargetMaskBuffer.texture.name = "OutlinePass.mask"; |
|||
this.renderTargetMaskBuffer.texture.generateMipmaps = false; |
|||
|
|||
this.depthMaterial = new THREE.MeshDepthMaterial(); |
|||
this.depthMaterial.side = THREE.DoubleSide; |
|||
this.depthMaterial.depthPacking = THREE.RGBADepthPacking; |
|||
this.depthMaterial.blending = THREE.NoBlending; |
|||
|
|||
this.prepareMaskMaterial = this.getPrepareMaskMaterial(); |
|||
this.prepareMaskMaterial.side = THREE.DoubleSide; |
|||
this.prepareMaskMaterial.fragmentShader = replaceDepthToViewZ( this.prepareMaskMaterial.fragmentShader, this.renderCamera ); |
|||
|
|||
this.renderTargetDepthBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars ); |
|||
this.renderTargetDepthBuffer.texture.name = "OutlinePass.depth"; |
|||
this.renderTargetDepthBuffer.texture.generateMipmaps = false; |
|||
|
|||
this.renderTargetMaskDownSampleBuffer = new THREE.WebGLRenderTarget( resx, resy, pars ); |
|||
this.renderTargetMaskDownSampleBuffer.texture.name = "OutlinePass.depthDownSample"; |
|||
this.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false; |
|||
|
|||
this.renderTargetBlurBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars ); |
|||
this.renderTargetBlurBuffer1.texture.name = "OutlinePass.blur1"; |
|||
this.renderTargetBlurBuffer1.texture.generateMipmaps = false; |
|||
this.renderTargetBlurBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars ); |
|||
this.renderTargetBlurBuffer2.texture.name = "OutlinePass.blur2"; |
|||
this.renderTargetBlurBuffer2.texture.generateMipmaps = false; |
|||
|
|||
this.edgeDetectionMaterial = this.getEdgeDetectionMaterial(); |
|||
this.renderTargetEdgeBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars ); |
|||
this.renderTargetEdgeBuffer1.texture.name = "OutlinePass.edge1"; |
|||
this.renderTargetEdgeBuffer1.texture.generateMipmaps = false; |
|||
this.renderTargetEdgeBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars ); |
|||
this.renderTargetEdgeBuffer2.texture.name = "OutlinePass.edge2"; |
|||
this.renderTargetEdgeBuffer2.texture.generateMipmaps = false; |
|||
|
|||
var MAX_EDGE_THICKNESS = 4; |
|||
var MAX_EDGE_GLOW = 4; |
|||
|
|||
this.separableBlurMaterial1 = this.getSeperableBlurMaterial( MAX_EDGE_THICKNESS ); |
|||
this.separableBlurMaterial1.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy ); |
|||
this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = 1; |
|||
this.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW ); |
|||
this.separableBlurMaterial2.uniforms[ "texSize" ].value = new THREE.Vector2( Math.round( resx / 2 ), Math.round( resy / 2 ) ); |
|||
this.separableBlurMaterial2.uniforms[ "kernelRadius" ].value = MAX_EDGE_GLOW; |
|||
|
|||
// Overlay material
|
|||
this.overlayMaterial = this.getOverlayMaterial(); |
|||
|
|||
// copy material
|
|||
if ( THREE.CopyShader === undefined ) |
|||
console.error( "THREE.OutlinePass relies on THREE.CopyShader" ); |
|||
|
|||
var copyShader = THREE.CopyShader; |
|||
|
|||
this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms ); |
|||
this.copyUniforms[ "opacity" ].value = 1.0; |
|||
|
|||
this.materialCopy = new THREE.ShaderMaterial( { |
|||
uniforms: this.copyUniforms, |
|||
vertexShader: copyShader.vertexShader, |
|||
fragmentShader: copyShader.fragmentShader, |
|||
blending: THREE.NoBlending, |
|||
depthTest: false, |
|||
depthWrite: false, |
|||
transparent: true |
|||
} ); |
|||
|
|||
this.enabled = true; |
|||
this.needsSwap = false; |
|||
|
|||
this.oldClearColor = new THREE.Color(); |
|||
this.oldClearAlpha = 1; |
|||
|
|||
this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); |
|||
this.scene = new THREE.Scene(); |
|||
|
|||
this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null ); |
|||
this.quad.frustumCulled = false; // Avoid getting clipped
|
|||
this.scene.add( this.quad ); |
|||
|
|||
this.tempPulseColor1 = new THREE.Color(); |
|||
this.tempPulseColor2 = new THREE.Color(); |
|||
this.textureMatrix = new THREE.Matrix4(); |
|||
|
|||
function replaceDepthToViewZ( string, camera ) { |
|||
|
|||
var type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic'; |
|||
|
|||
return string.replace( /DEPTH_TO_VIEW_Z/g, type + 'DepthToViewZ' ); |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { |
|||
|
|||
constructor: THREE.OutlinePass, |
|||
|
|||
dispose: function () { |
|||
|
|||
this.renderTargetMaskBuffer.dispose(); |
|||
this.renderTargetDepthBuffer.dispose(); |
|||
this.renderTargetMaskDownSampleBuffer.dispose(); |
|||
this.renderTargetBlurBuffer1.dispose(); |
|||
this.renderTargetBlurBuffer2.dispose(); |
|||
this.renderTargetEdgeBuffer1.dispose(); |
|||
this.renderTargetEdgeBuffer2.dispose(); |
|||
|
|||
}, |
|||
|
|||
setSize: function ( width, height ) { |
|||
|
|||
this.renderTargetMaskBuffer.setSize( width, height ); |
|||
|
|||
var resx = Math.round( width / this.downSampleRatio ); |
|||
var resy = Math.round( height / this.downSampleRatio ); |
|||
this.renderTargetMaskDownSampleBuffer.setSize( resx, resy ); |
|||
this.renderTargetBlurBuffer1.setSize( resx, resy ); |
|||
this.renderTargetEdgeBuffer1.setSize( resx, resy ); |
|||
this.separableBlurMaterial1.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy ); |
|||
|
|||
resx = Math.round( resx / 2 ); |
|||
resy = Math.round( resy / 2 ); |
|||
|
|||
this.renderTargetBlurBuffer2.setSize( resx, resy ); |
|||
this.renderTargetEdgeBuffer2.setSize( resx, resy ); |
|||
|
|||
this.separableBlurMaterial2.uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy ); |
|||
|
|||
}, |
|||
|
|||
changeVisibilityOfSelectedObjects: function ( bVisible ) { |
|||
|
|||
function gatherSelectedMeshesCallBack( object ) { |
|||
|
|||
if ( object.isMesh ) { |
|||
|
|||
if ( bVisible ) { |
|||
|
|||
object.visible = object.userData.oldVisible; |
|||
delete object.userData.oldVisible; |
|||
|
|||
} else { |
|||
|
|||
object.userData.oldVisible = object.visible; |
|||
object.visible = bVisible; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
for ( var i = 0; i < this.selectedObjects.length; i ++ ) { |
|||
|
|||
var selectedObject = this.selectedObjects[ i ]; |
|||
selectedObject.traverse( gatherSelectedMeshesCallBack ); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
changeVisibilityOfNonSelectedObjects: function ( bVisible ) { |
|||
|
|||
var selectedMeshes = []; |
|||
|
|||
function gatherSelectedMeshesCallBack( object ) { |
|||
|
|||
if ( object.isMesh ) selectedMeshes.push( object ); |
|||
|
|||
} |
|||
|
|||
for ( var i = 0; i < this.selectedObjects.length; i ++ ) { |
|||
|
|||
var selectedObject = this.selectedObjects[ i ]; |
|||
selectedObject.traverse( gatherSelectedMeshesCallBack ); |
|||
|
|||
} |
|||
|
|||
function VisibilityChangeCallBack( object ) { |
|||
|
|||
if ( object.isMesh || object.isLine || object.isSprite ) { |
|||
|
|||
var bFound = false; |
|||
|
|||
for ( var i = 0; i < selectedMeshes.length; i ++ ) { |
|||
|
|||
var selectedObjectId = selectedMeshes[ i ].id; |
|||
|
|||
if ( selectedObjectId === object.id ) { |
|||
|
|||
bFound = true; |
|||
break; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
if ( ! bFound ) { |
|||
|
|||
var visibility = object.visible; |
|||
|
|||
if ( ! bVisible || object.bVisible ) object.visible = bVisible; |
|||
|
|||
object.bVisible = visibility; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
this.renderScene.traverse( VisibilityChangeCallBack ); |
|||
|
|||
}, |
|||
|
|||
updateTextureMatrix: function () { |
|||
|
|||
this.textureMatrix.set( 0.5, 0.0, 0.0, 0.5, |
|||
0.0, 0.5, 0.0, 0.5, |
|||
0.0, 0.0, 0.5, 0.5, |
|||
0.0, 0.0, 0.0, 1.0 ); |
|||
this.textureMatrix.multiply( this.renderCamera.projectionMatrix ); |
|||
this.textureMatrix.multiply( this.renderCamera.matrixWorldInverse ); |
|||
|
|||
}, |
|||
|
|||
render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { |
|||
|
|||
if ( this.selectedObjects.length > 0 ) { |
|||
|
|||
this.oldClearColor.copy( renderer.getClearColor() ); |
|||
this.oldClearAlpha = renderer.getClearAlpha(); |
|||
var oldAutoClear = renderer.autoClear; |
|||
|
|||
renderer.autoClear = false; |
|||
|
|||
if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST ); |
|||
|
|||
renderer.setClearColor( 0xffffff, 1 ); |
|||
|
|||
// Make selected objects invisible
|
|||
this.changeVisibilityOfSelectedObjects( false ); |
|||
|
|||
var currentBackground = this.renderScene.background; |
|||
this.renderScene.background = null; |
|||
|
|||
// 1. Draw Non Selected objects in the depth buffer
|
|||
this.renderScene.overrideMaterial = this.depthMaterial; |
|||
renderer.render( this.renderScene, this.renderCamera, this.renderTargetDepthBuffer, true ); |
|||
|
|||
// Make selected objects visible
|
|||
this.changeVisibilityOfSelectedObjects( true ); |
|||
|
|||
// Update Texture Matrix for Depth compare
|
|||
this.updateTextureMatrix(); |
|||
|
|||
// Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects
|
|||
this.changeVisibilityOfNonSelectedObjects( false ); |
|||
this.renderScene.overrideMaterial = this.prepareMaskMaterial; |
|||
this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value = new THREE.Vector2( this.renderCamera.near, this.renderCamera.far ); |
|||
this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture; |
|||
this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix; |
|||
renderer.render( this.renderScene, this.renderCamera, this.renderTargetMaskBuffer, true ); |
|||
this.renderScene.overrideMaterial = null; |
|||
this.changeVisibilityOfNonSelectedObjects( true ); |
|||
|
|||
this.renderScene.background = currentBackground; |
|||
|
|||
// 2. Downsample to Half resolution
|
|||
this.quad.material = this.materialCopy; |
|||
this.copyUniforms[ "tDiffuse" ].value = this.renderTargetMaskBuffer.texture; |
|||
renderer.render( this.scene, this.camera, this.renderTargetMaskDownSampleBuffer, true ); |
|||
|
|||
this.tempPulseColor1.copy( this.visibleEdgeColor ); |
|||
this.tempPulseColor2.copy( this.hiddenEdgeColor ); |
|||
|
|||
if ( this.pulsePeriod > 0 ) { |
|||
|
|||
var scalar = ( 1 + 0.25 ) / 2 + Math.cos( performance.now() * 0.01 / this.pulsePeriod ) * ( 1.0 - 0.25 ) / 2; |
|||
this.tempPulseColor1.multiplyScalar( scalar ); |
|||
this.tempPulseColor2.multiplyScalar( scalar ); |
|||
|
|||
} |
|||
|
|||
// 3. Apply Edge Detection Pass
|
|||
this.quad.material = this.edgeDetectionMaterial; |
|||
this.edgeDetectionMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskDownSampleBuffer.texture; |
|||
this.edgeDetectionMaterial.uniforms[ "texSize" ].value = new THREE.Vector2( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height ); |
|||
this.edgeDetectionMaterial.uniforms[ "visibleEdgeColor" ].value = this.tempPulseColor1; |
|||
this.edgeDetectionMaterial.uniforms[ "hiddenEdgeColor" ].value = this.tempPulseColor2; |
|||
renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer1, true ); |
|||
|
|||
// 4. Apply Blur on Half res
|
|||
this.quad.material = this.separableBlurMaterial1; |
|||
this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture; |
|||
this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX; |
|||
this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = this.edgeThickness; |
|||
renderer.render( this.scene, this.camera, this.renderTargetBlurBuffer1, true ); |
|||
this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer1.texture; |
|||
this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY; |
|||
renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer1, true ); |
|||
|
|||
// Apply Blur on quarter res
|
|||
this.quad.material = this.separableBlurMaterial2; |
|||
this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture; |
|||
this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX; |
|||
renderer.render( this.scene, this.camera, this.renderTargetBlurBuffer2, true ); |
|||
this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer2.texture; |
|||
this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY; |
|||
renderer.render( this.scene, this.camera, this.renderTargetEdgeBuffer2, true ); |
|||
|
|||
// Blend it additively over the input texture
|
|||
this.quad.material = this.overlayMaterial; |
|||
this.overlayMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskBuffer.texture; |
|||
this.overlayMaterial.uniforms[ "edgeTexture1" ].value = this.renderTargetEdgeBuffer1.texture; |
|||
this.overlayMaterial.uniforms[ "edgeTexture2" ].value = this.renderTargetEdgeBuffer2.texture; |
|||
this.overlayMaterial.uniforms[ "patternTexture" ].value = this.patternTexture; |
|||
this.overlayMaterial.uniforms[ "edgeStrength" ].value = this.edgeStrength; |
|||
this.overlayMaterial.uniforms[ "edgeGlow" ].value = this.edgeGlow; |
|||
this.overlayMaterial.uniforms[ "usePatternTexture" ].value = this.usePatternTexture; |
|||
|
|||
|
|||
if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST ); |
|||
|
|||
renderer.render( this.scene, this.camera, readBuffer, false ); |
|||
|
|||
renderer.setClearColor( this.oldClearColor, this.oldClearAlpha ); |
|||
renderer.autoClear = oldAutoClear; |
|||
|
|||
} |
|||
|
|||
if ( this.renderToScreen ) { |
|||
|
|||
this.quad.material = this.materialCopy; |
|||
this.copyUniforms[ "tDiffuse" ].value = readBuffer.texture; |
|||
renderer.render( this.scene, this.camera ); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
getPrepareMaskMaterial: function () { |
|||
|
|||
return new THREE.ShaderMaterial( { |
|||
|
|||
uniforms: { |
|||
"depthTexture": { value: null }, |
|||
"cameraNearFar": { value: new THREE.Vector2( 0.5, 0.5 ) }, |
|||
"textureMatrix": { value: new THREE.Matrix4() } |
|||
}, |
|||
|
|||
vertexShader: [ |
|||
'varying vec4 projTexCoord;', |
|||
'varying vec4 vPosition;', |
|||
'uniform mat4 textureMatrix;', |
|||
|
|||
'void main() {', |
|||
|
|||
' vPosition = modelViewMatrix * vec4( position, 1.0 );', |
|||
' vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', |
|||
' projTexCoord = textureMatrix * worldPosition;', |
|||
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', |
|||
|
|||
'}' |
|||
].join( '\n' ), |
|||
|
|||
fragmentShader: [ |
|||
'#include <packing>', |
|||
'varying vec4 vPosition;', |
|||
'varying vec4 projTexCoord;', |
|||
'uniform sampler2D depthTexture;', |
|||
'uniform vec2 cameraNearFar;', |
|||
|
|||
'void main() {', |
|||
|
|||
' float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));', |
|||
' float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );', |
|||
' float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;', |
|||
' gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);', |
|||
|
|||
'}' |
|||
].join( '\n' ) |
|||
|
|||
} ); |
|||
|
|||
}, |
|||
|
|||
getEdgeDetectionMaterial: function () { |
|||
|
|||
return new THREE.ShaderMaterial( { |
|||
|
|||
uniforms: { |
|||
"maskTexture": { value: null }, |
|||
"texSize": { value: new THREE.Vector2( 0.5, 0.5 ) }, |
|||
"visibleEdgeColor": { value: new THREE.Vector3( 1.0, 1.0, 1.0 ) }, |
|||
"hiddenEdgeColor": { value: new THREE.Vector3( 1.0, 1.0, 1.0 ) }, |
|||
}, |
|||
|
|||
vertexShader: |
|||
"varying vec2 vUv;\n\ |
|||
void main() {\n\ |
|||
vUv = uv;\n\ |
|||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\ |
|||
}", |
|||
|
|||
fragmentShader: |
|||
"varying vec2 vUv;\ |
|||
uniform sampler2D maskTexture;\ |
|||
uniform vec2 texSize;\ |
|||
uniform vec3 visibleEdgeColor;\ |
|||
uniform vec3 hiddenEdgeColor;\ |
|||
\ |
|||
void main() {\n\ |
|||
vec2 invSize = 1.0 / texSize;\ |
|||
vec4 uvOffset = vec4(1.0, 0.0, 0.0, 1.0) * vec4(invSize, invSize);\ |
|||
vec4 c1 = texture2D( maskTexture, vUv + uvOffset.xy);\ |
|||
vec4 c2 = texture2D( maskTexture, vUv - uvOffset.xy);\ |
|||
vec4 c3 = texture2D( maskTexture, vUv + uvOffset.yw);\ |
|||
vec4 c4 = texture2D( maskTexture, vUv - uvOffset.yw);\ |
|||
float diff1 = (c1.r - c2.r)*0.5;\ |
|||
float diff2 = (c3.r - c4.r)*0.5;\ |
|||
float d = length( vec2(diff1, diff2) );\ |
|||
float a1 = min(c1.g, c2.g);\ |
|||
float a2 = min(c3.g, c4.g);\ |
|||
float visibilityFactor = min(a1, a2);\ |
|||
vec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;\ |
|||
gl_FragColor = vec4(edgeColor, 1.0) * vec4(d);\ |
|||
}" |
|||
} ); |
|||
|
|||
}, |
|||
|
|||
getSeperableBlurMaterial: function ( maxRadius ) { |
|||
|
|||
return new THREE.ShaderMaterial( { |
|||
|
|||
defines: { |
|||
"MAX_RADIUS": maxRadius, |
|||
}, |
|||
|
|||
uniforms: { |
|||
"colorTexture": { value: null }, |
|||
"texSize": { value: new THREE.Vector2( 0.5, 0.5 ) }, |
|||
"direction": { value: new THREE.Vector2( 0.5, 0.5 ) }, |
|||
"kernelRadius": { value: 1.0 } |
|||
}, |
|||
|
|||
vertexShader: |
|||
"varying vec2 vUv;\n\ |
|||
void main() {\n\ |
|||
vUv = uv;\n\ |
|||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\ |
|||
}", |
|||
|
|||
fragmentShader: |
|||
"#include <common>\ |
|||
varying vec2 vUv;\ |
|||
uniform sampler2D colorTexture;\ |
|||
uniform vec2 texSize;\ |
|||
uniform vec2 direction;\ |
|||
uniform float kernelRadius;\ |
|||
\ |
|||
float gaussianPdf(in float x, in float sigma) {\ |
|||
return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;\ |
|||
}\ |
|||
void main() {\ |
|||
vec2 invSize = 1.0 / texSize;\ |
|||
float weightSum = gaussianPdf(0.0, kernelRadius);\ |
|||
vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;\ |
|||
vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);\ |
|||
vec2 uvOffset = delta;\ |
|||
for( int i = 1; i <= MAX_RADIUS; i ++ ) {\ |
|||
float w = gaussianPdf(uvOffset.x, kernelRadius);\ |
|||
vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;\ |
|||
vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;\ |
|||
diffuseSum += ((sample1 + sample2) * w);\ |
|||
weightSum += (2.0 * w);\ |
|||
uvOffset += delta;\ |
|||
}\ |
|||
gl_FragColor = vec4(diffuseSum/weightSum, 1.0);\ |
|||
}" |
|||
} ); |
|||
|
|||
}, |
|||
|
|||
getOverlayMaterial: function () { |
|||
|
|||
return new THREE.ShaderMaterial( { |
|||
|
|||
uniforms: { |
|||
"maskTexture": { value: null }, |
|||
"edgeTexture1": { value: null }, |
|||
"edgeTexture2": { value: null }, |
|||
"patternTexture": { value: null }, |
|||
"edgeStrength": { value: 1.0 }, |
|||
"edgeGlow": { value: 1.0 }, |
|||
"usePatternTexture": { value: 0.0 } |
|||
}, |
|||
|
|||
vertexShader: |
|||
"varying vec2 vUv;\n\ |
|||
void main() {\n\ |
|||
vUv = uv;\n\ |
|||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\ |
|||
}", |
|||
|
|||
fragmentShader: |
|||
"varying vec2 vUv;\ |
|||
uniform sampler2D maskTexture;\ |
|||
uniform sampler2D edgeTexture1;\ |
|||
uniform sampler2D edgeTexture2;\ |
|||
uniform sampler2D patternTexture;\ |
|||
uniform float edgeStrength;\ |
|||
uniform float edgeGlow;\ |
|||
uniform bool usePatternTexture;\ |
|||
\ |
|||
void main() {\ |
|||
vec4 edgeValue1 = texture2D(edgeTexture1, vUv);\ |
|||
vec4 edgeValue2 = texture2D(edgeTexture2, vUv);\ |
|||
vec4 maskColor = texture2D(maskTexture, vUv);\ |
|||
vec4 patternColor = texture2D(patternTexture, 6.0 * vUv);\ |
|||
float visibilityFactor = 1.0 - maskColor.g > 0.0 ? 1.0 : 0.5;\ |
|||
vec4 edgeValue = edgeValue1 + edgeValue2 * edgeGlow;\ |
|||
vec4 finalColor = edgeStrength * maskColor.r * edgeValue;\ |
|||
if(usePatternTexture)\ |
|||
finalColor += + visibilityFactor * (1.0 - maskColor.r) * (1.0 - patternColor.r);\ |
|||
gl_FragColor = finalColor;\ |
|||
}", |
|||
blending: THREE.AdditiveBlending, |
|||
depthTest: false, |
|||
depthWrite: false, |
|||
transparent: true |
|||
} ); |
|||
|
|||
} |
|||
|
|||
} ); |
|||
|
|||
THREE.OutlinePass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 ); |
|||
THREE.OutlinePass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 ); |
@ -0,0 +1,63 @@ |
|||
/** |
|||
* @author alteredq / http://alteredqualia.com/
|
|||
*/ |
|||
|
|||
THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { |
|||
|
|||
THREE.Pass.call( this ); |
|||
|
|||
this.scene = scene; |
|||
this.camera = camera; |
|||
|
|||
this.overrideMaterial = overrideMaterial; |
|||
|
|||
this.clearColor = clearColor; |
|||
this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0; |
|||
|
|||
this.clear = true; |
|||
this.clearDepth = false; |
|||
this.needsSwap = false; |
|||
|
|||
}; |
|||
|
|||
THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { |
|||
|
|||
constructor: THREE.RenderPass, |
|||
|
|||
render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { |
|||
|
|||
var oldAutoClear = renderer.autoClear; |
|||
renderer.autoClear = false; |
|||
|
|||
this.scene.overrideMaterial = this.overrideMaterial; |
|||
|
|||
var oldClearColor, oldClearAlpha; |
|||
|
|||
if ( this.clearColor ) { |
|||
|
|||
oldClearColor = renderer.getClearColor().getHex(); |
|||
oldClearAlpha = renderer.getClearAlpha(); |
|||
|
|||
renderer.setClearColor( this.clearColor, this.clearAlpha ); |
|||
|
|||
} |
|||
|
|||
if ( this.clearDepth ) { |
|||
|
|||
renderer.clearDepth(); |
|||
|
|||
} |
|||
|
|||
renderer.render( this.scene, this.camera, this.renderToScreen ? null : readBuffer, this.clear ); |
|||
|
|||
if ( this.clearColor ) { |
|||
|
|||
renderer.setClearColor( oldClearColor, oldClearAlpha ); |
|||
|
|||
} |
|||
|
|||
this.scene.overrideMaterial = null; |
|||
renderer.autoClear = oldAutoClear; |
|||
} |
|||
|
|||
} ); |
@ -0,0 +1,67 @@ |
|||
/** |
|||
* @author alteredq / http://alteredqualia.com/
|
|||
*/ |
|||
|
|||
THREE.ShaderPass = function ( shader, textureID ) { |
|||
|
|||
THREE.Pass.call( this ); |
|||
|
|||
this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; |
|||
|
|||
if ( shader instanceof THREE.ShaderMaterial ) { |
|||
|
|||
this.uniforms = shader.uniforms; |
|||
|
|||
this.material = shader; |
|||
|
|||
} else if ( shader ) { |
|||
|
|||
this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); |
|||
|
|||
this.material = new THREE.ShaderMaterial( { |
|||
|
|||
defines: Object.assign( {}, shader.defines ), |
|||
uniforms: this.uniforms, |
|||
vertexShader: shader.vertexShader, |
|||
fragmentShader: shader.fragmentShader |
|||
|
|||
} ); |
|||
|
|||
} |
|||
|
|||
this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); |
|||
this.scene = new THREE.Scene(); |
|||
|
|||
this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null ); |
|||
this.quad.frustumCulled = false; // Avoid getting clipped
|
|||
this.scene.add( this.quad ); |
|||
|
|||
}; |
|||
|
|||
THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), { |
|||
|
|||
constructor: THREE.ShaderPass, |
|||
|
|||
render: function( renderer, writeBuffer, readBuffer, delta, maskActive ) { |
|||
|
|||
if ( this.uniforms[ this.textureID ] ) { |
|||
|
|||
this.uniforms[ this.textureID ].value = readBuffer.texture; |
|||
|
|||
} |
|||
|
|||
this.quad.material = this.material; |
|||
|
|||
if ( this.renderToScreen ) { |
|||
|
|||
renderer.render( this.scene, this.camera ); |
|||
|
|||
} else { |
|||
|
|||
renderer.render( this.scene, this.camera, writeBuffer, this.clear ); |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
} ); |
@ -0,0 +1,519 @@ |
|||
// Generated by CoffeeScript 1.6.3
|
|||
(function() { |
|||
var BACK, COPLANAR, EPSILON, FRONT, SPANNING, returning, |
|||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, |
|||
__slice = [].slice, |
|||
__hasProp = {}.hasOwnProperty, |
|||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; |
|||
|
|||
EPSILON = 1e-5; |
|||
|
|||
COPLANAR = 0; |
|||
|
|||
FRONT = 1; |
|||
|
|||
BACK = 2; |
|||
|
|||
SPANNING = 3; |
|||
|
|||
returning = function(value, fn) { |
|||
fn(); |
|||
return value; |
|||
}; |
|||
|
|||
window.ThreeBSP = (function() { |
|||
function ThreeBSP(treeIsh, matrix) { |
|||
this.matrix = matrix; |
|||
this.intersect = __bind(this.intersect, this); |
|||
this.union = __bind(this.union, this); |
|||
this.subtract = __bind(this.subtract, this); |
|||
this.toGeometry = __bind(this.toGeometry, this); |
|||
this.toMesh = __bind(this.toMesh, this); |
|||
this.toTree = __bind(this.toTree, this); |
|||
if (this.matrix == null) { |
|||
this.matrix = new THREE.Matrix4(); |
|||
} |
|||
this.tree = this.toTree(treeIsh); |
|||
} |
|||
|
|||
ThreeBSP.prototype.toTree = function(treeIsh) { |
|||
var face, geometry, i, polygons, _fn, _i, _len, _ref, |
|||
_this = this; |
|||
if (treeIsh instanceof ThreeBSP.Node) { |
|||
return treeIsh; |
|||
} |
|||
polygons = []; |
|||
geometry = treeIsh instanceof THREE.Geometry ? treeIsh : treeIsh instanceof THREE.Mesh ? (treeIsh.updateMatrix(), this.matrix = treeIsh.matrix.clone(), treeIsh.geometry) : void 0; |
|||
_ref = geometry.faces; |
|||
_fn = function(face, i) { |
|||
var faceVertexUvs, idx, polygon, vIndex, vName, vertex, _j, _len1, _ref1, _ref2; |
|||
faceVertexUvs = (_ref1 = geometry.faceVertexUvs) != null ? _ref1[0][i] : void 0; |
|||
if (faceVertexUvs == null) { |
|||
faceVertexUvs = [new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2()]; |
|||
} |
|||
polygon = new ThreeBSP.Polygon(); |
|||
_ref2 = ['a', 'b', 'c', 'd']; |
|||
for (vIndex = _j = 0, _len1 = _ref2.length; _j < _len1; vIndex = ++_j) { |
|||
vName = _ref2[vIndex]; |
|||
if ((idx = face[vName]) != null) { |
|||
vertex = geometry.vertices[idx]; |
|||
vertex = new ThreeBSP.Vertex(vertex.x, vertex.y, vertex.z, face.vertexNormals[0], new THREE.Vector2(faceVertexUvs[vIndex].x, faceVertexUvs[vIndex].y)); |
|||
vertex.applyMatrix4(_this.matrix); |
|||
polygon.vertices.push(vertex); |
|||
} |
|||
} |
|||
return polygons.push(polygon.calculateProperties()); |
|||
}; |
|||
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { |
|||
face = _ref[i]; |
|||
_fn(face, i); |
|||
} |
|||
return new ThreeBSP.Node(polygons); |
|||
}; |
|||
|
|||
ThreeBSP.prototype.toMesh = function(material) { |
|||
var geometry, mesh, |
|||
_this = this; |
|||
if (material == null) { |
|||
material = new THREE.MeshNormalMaterial(); |
|||
} |
|||
geometry = this.toGeometry(); |
|||
return returning((mesh = new THREE.Mesh(geometry, material)), function() { |
|||
mesh.position.setFromMatrixPosition(_this.matrix); |
|||
return mesh.rotation.setFromRotationMatrix(_this.matrix); |
|||
}); |
|||
}; |
|||
|
|||
ThreeBSP.prototype.toGeometry = function() { |
|||
var geometry, matrix, |
|||
_this = this; |
|||
matrix = new THREE.Matrix4().getInverse(this.matrix); |
|||
return returning((geometry = new THREE.Geometry()), function() { |
|||
var face, idx, polyVerts, polygon, v, vertUvs, verts, _i, _len, _ref, _results; |
|||
_ref = _this.tree.allPolygons(); |
|||
_results = []; |
|||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
|||
polygon = _ref[_i]; |
|||
polyVerts = (function() { |
|||
var _j, _len1, _ref1, _results1; |
|||
_ref1 = polygon.vertices; |
|||
_results1 = []; |
|||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { |
|||
v = _ref1[_j]; |
|||
_results1.push(v.clone().applyMatrix4(matrix)); |
|||
} |
|||
return _results1; |
|||
})(); |
|||
_results.push((function() { |
|||
var _j, _ref1, _results1; |
|||
_results1 = []; |
|||
for (idx = _j = 2, _ref1 = polyVerts.length; 2 <= _ref1 ? _j < _ref1 : _j > _ref1; idx = 2 <= _ref1 ? ++_j : --_j) { |
|||
verts = [polyVerts[0], polyVerts[idx - 1], polyVerts[idx]]; |
|||
vertUvs = (function() { |
|||
var _k, _len1, _ref2, _ref3, _results2; |
|||
_results2 = []; |
|||
for (_k = 0, _len1 = verts.length; _k < _len1; _k++) { |
|||
v = verts[_k]; |
|||
_results2.push(new THREE.Vector2((_ref2 = v.uv) != null ? _ref2.x : void 0, (_ref3 = v.uv) != null ? _ref3.y : void 0)); |
|||
} |
|||
return _results2; |
|||
})(); |
|||
face = (function(func, args, ctor) { |
|||
ctor.prototype = func.prototype; |
|||
var child = new ctor, result = func.apply(child, args); |
|||
return Object(result) === result ? result : child; |
|||
})(THREE.Face3, __slice.call((function() { |
|||
var _k, _len1, _results2; |
|||
_results2 = []; |
|||
for (_k = 0, _len1 = verts.length; _k < _len1; _k++) { |
|||
v = verts[_k]; |
|||
_results2.push(geometry.vertices.push(v) - 1); |
|||
} |
|||
return _results2; |
|||
})()).concat([polygon.normal.clone()]), function(){}); |
|||
geometry.faces.push(face); |
|||
_results1.push(geometry.faceVertexUvs[0].push(vertUvs)); |
|||
} |
|||
return _results1; |
|||
})()); |
|||
} |
|||
return _results; |
|||
}); |
|||
}; |
|||
|
|||
ThreeBSP.prototype.subtract = function(other) { |
|||
var them, us, _ref; |
|||
_ref = [this.tree.clone(), other.tree.clone()], us = _ref[0], them = _ref[1]; |
|||
us.invert().clipTo(them); |
|||
them.clipTo(us).invert().clipTo(us).invert(); |
|||
return new ThreeBSP(us.build(them.allPolygons()).invert(), this.matrix); |
|||
}; |
|||
|
|||
ThreeBSP.prototype.union = function(other) { |
|||
var them, us, _ref; |
|||
_ref = [this.tree.clone(), other.tree.clone()], us = _ref[0], them = _ref[1]; |
|||
us.clipTo(them); |
|||
them.clipTo(us).invert().clipTo(us).invert(); |
|||
return new ThreeBSP(us.build(them.allPolygons()), this.matrix); |
|||
}; |
|||
|
|||
ThreeBSP.prototype.intersect = function(other) { |
|||
var them, us, _ref; |
|||
_ref = [this.tree.clone(), other.tree.clone()], us = _ref[0], them = _ref[1]; |
|||
them.clipTo(us.invert()).invert().clipTo(us.clipTo(them)); |
|||
return new ThreeBSP(us.build(them.allPolygons()).invert(), this.matrix); |
|||
}; |
|||
|
|||
return ThreeBSP; |
|||
|
|||
})(); |
|||
|
|||
ThreeBSP.Vertex = (function(_super) { |
|||
__extends(Vertex, _super); |
|||
|
|||
function Vertex(x, y, z, normal, uv) { |
|||
this.normal = normal != null ? normal : new THREE.Vector3(); |
|||
this.uv = uv != null ? uv : new THREE.Vector2(); |
|||
this.interpolate = __bind(this.interpolate, this); |
|||
this.lerp = __bind(this.lerp, this); |
|||
Vertex.__super__.constructor.call(this, x, y, z); |
|||
} |
|||
|
|||
Vertex.prototype.clone = function() { |
|||
return new ThreeBSP.Vertex(this.x, this.y, this.z, this.normal.clone(), this.uv.clone()); |
|||
}; |
|||
|
|||
Vertex.prototype.lerp = function(v, alpha) { |
|||
var _this = this; |
|||
return returning(Vertex.__super__.lerp.apply(this, arguments), function() { |
|||
_this.uv.add(v.uv.clone().sub(_this.uv).multiplyScalar(alpha)); |
|||
return _this.normal.lerp(v, alpha); |
|||
}); |
|||
}; |
|||
|
|||
Vertex.prototype.interpolate = function() { |
|||
var args, _ref; |
|||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; |
|||
return (_ref = this.clone()).lerp.apply(_ref, args); |
|||
}; |
|||
|
|||
return Vertex; |
|||
|
|||
})(THREE.Vector3); |
|||
|
|||
ThreeBSP.Polygon = (function() { |
|||
function Polygon(vertices, normal, w) { |
|||
this.vertices = vertices != null ? vertices : []; |
|||
this.normal = normal; |
|||
this.w = w; |
|||
this.subdivide = __bind(this.subdivide, this); |
|||
this.tessellate = __bind(this.tessellate, this); |
|||
this.classifySide = __bind(this.classifySide, this); |
|||
this.classifyVertex = __bind(this.classifyVertex, this); |
|||
this.invert = __bind(this.invert, this); |
|||
this.clone = __bind(this.clone, this); |
|||
this.calculateProperties = __bind(this.calculateProperties, this); |
|||
if (this.vertices.length) { |
|||
this.calculateProperties(); |
|||
} |
|||
} |
|||
|
|||
Polygon.prototype.calculateProperties = function() { |
|||
var _this = this; |
|||
return returning(this, function() { |
|||
var a, b, c, _ref; |
|||
_ref = _this.vertices, a = _ref[0], b = _ref[1], c = _ref[2]; |
|||
_this.normal = b.clone().sub(a).cross(c.clone().sub(a)).normalize(); |
|||
return _this.w = _this.normal.clone().dot(a); |
|||
}); |
|||
}; |
|||
|
|||
Polygon.prototype.clone = function() { |
|||
var v; |
|||
return new ThreeBSP.Polygon((function() { |
|||
var _i, _len, _ref, _results; |
|||
_ref = this.vertices; |
|||
_results = []; |
|||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
|||
v = _ref[_i]; |
|||
_results.push(v.clone()); |
|||
} |
|||
return _results; |
|||
}).call(this), this.normal.clone(), this.w); |
|||
}; |
|||
|
|||
Polygon.prototype.invert = function() { |
|||
var _this = this; |
|||
return returning(this, function() { |
|||
_this.normal.multiplyScalar(-1); |
|||
_this.w *= -1; |
|||
return _this.vertices.reverse(); |
|||
}); |
|||
}; |
|||
|
|||
Polygon.prototype.classifyVertex = function(vertex) { |
|||
var side; |
|||
side = this.normal.dot(vertex) - this.w; |
|||
switch (false) { |
|||
case !(side < -EPSILON): |
|||
return BACK; |
|||
case !(side > EPSILON): |
|||
return FRONT; |
|||
default: |
|||
return COPLANAR; |
|||
} |
|||
}; |
|||
|
|||
Polygon.prototype.classifySide = function(polygon) { |
|||
var back, front, tally, v, _i, _len, _ref, _ref1, |
|||
_this = this; |
|||
_ref = [0, 0], front = _ref[0], back = _ref[1]; |
|||
tally = function(v) { |
|||
switch (_this.classifyVertex(v)) { |
|||
case FRONT: |
|||
return front += 1; |
|||
case BACK: |
|||
return back += 1; |
|||
} |
|||
}; |
|||
_ref1 = polygon.vertices; |
|||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { |
|||
v = _ref1[_i]; |
|||
tally(v); |
|||
} |
|||
if (front > 0 && back === 0) { |
|||
return FRONT; |
|||
} |
|||
if (front === 0 && back > 0) { |
|||
return BACK; |
|||
} |
|||
if ((front === back && back === 0)) { |
|||
return COPLANAR; |
|||
} |
|||
return SPANNING; |
|||
}; |
|||
|
|||
Polygon.prototype.tessellate = function(poly) { |
|||
var b, count, f, i, j, polys, t, ti, tj, v, vi, vj, _i, _len, _ref, _ref1, _ref2, |
|||
_this = this; |
|||
_ref = { |
|||
f: [], |
|||
b: [], |
|||
count: poly.vertices.length |
|||
}, f = _ref.f, b = _ref.b, count = _ref.count; |
|||
if (this.classifySide(poly) !== SPANNING) { |
|||
return [poly]; |
|||
} |
|||
_ref1 = poly.vertices; |
|||
for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) { |
|||
vi = _ref1[i]; |
|||
vj = poly.vertices[(j = (i + 1) % count)]; |
|||
_ref2 = (function() { |
|||
var _j, _len1, _ref2, _results; |
|||
_ref2 = [vi, vj]; |
|||
_results = []; |
|||
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { |
|||
v = _ref2[_j]; |
|||
_results.push(this.classifyVertex(v)); |
|||
} |
|||
return _results; |
|||
}).call(this), ti = _ref2[0], tj = _ref2[1]; |
|||
if (ti !== BACK) { |
|||
f.push(vi); |
|||
} |
|||
if (ti !== FRONT) { |
|||
b.push(vi); |
|||
} |
|||
if ((ti | tj) === SPANNING) { |
|||
t = (this.w - this.normal.dot(vi)) / this.normal.dot(vj.clone().sub(vi)); |
|||
v = vi.interpolate(vj, t); |
|||
f.push(v); |
|||
b.push(v); |
|||
} |
|||
} |
|||
return returning((polys = []), function() { |
|||
if (f.length >= 3) { |
|||
polys.push(new ThreeBSP.Polygon(f)); |
|||
} |
|||
if (b.length >= 3) { |
|||
return polys.push(new ThreeBSP.Polygon(b)); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
Polygon.prototype.subdivide = function(polygon, coplanar_front, coplanar_back, front, back) { |
|||
var poly, side, _i, _len, _ref, _results; |
|||
_ref = this.tessellate(polygon); |
|||
_results = []; |
|||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
|||
poly = _ref[_i]; |
|||
side = this.classifySide(poly); |
|||
switch (side) { |
|||
case FRONT: |
|||
_results.push(front.push(poly)); |
|||
break; |
|||
case BACK: |
|||
_results.push(back.push(poly)); |
|||
break; |
|||
case COPLANAR: |
|||
if (this.normal.dot(poly.normal) > 0) { |
|||
_results.push(coplanar_front.push(poly)); |
|||
} else { |
|||
_results.push(coplanar_back.push(poly)); |
|||
} |
|||
break; |
|||
default: |
|||
throw new Error("BUG: Polygon of classification " + side + " in subdivision"); |
|||
} |
|||
} |
|||
return _results; |
|||
}; |
|||
|
|||
return Polygon; |
|||
|
|||
})(); |
|||
|
|||
ThreeBSP.Node = (function() { |
|||
Node.prototype.clone = function() { |
|||
var node, |
|||
_this = this; |
|||
return returning((node = new ThreeBSP.Node()), function() { |
|||
var p, _ref, _ref1, _ref2; |
|||
node.divider = (_ref = _this.divider) != null ? _ref.clone() : void 0; |
|||
node.polygons = (function() { |
|||
var _i, _len, _ref1, _results; |
|||
_ref1 = this.polygons; |
|||
_results = []; |
|||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { |
|||
p = _ref1[_i]; |
|||
_results.push(p.clone()); |
|||
} |
|||
return _results; |
|||
}).call(_this); |
|||
node.front = (_ref1 = _this.front) != null ? _ref1.clone() : void 0; |
|||
return node.back = (_ref2 = _this.back) != null ? _ref2.clone() : void 0; |
|||
}); |
|||
}; |
|||
|
|||
function Node(polygons) { |
|||
this.clipTo = __bind(this.clipTo, this); |
|||
this.clipPolygons = __bind(this.clipPolygons, this); |
|||
this.invert = __bind(this.invert, this); |
|||
this.allPolygons = __bind(this.allPolygons, this); |
|||
this.isConvex = __bind(this.isConvex, this); |
|||
this.build = __bind(this.build, this); |
|||
this.clone = __bind(this.clone, this); |
|||
this.polygons = []; |
|||
if ((polygons != null) && polygons.length) { |
|||
this.build(polygons); |
|||
} |
|||
} |
|||
|
|||
Node.prototype.build = function(polygons) { |
|||
var _this = this; |
|||
return returning(this, function() { |
|||
var poly, polys, side, sides, _i, _len, _results; |
|||
sides = { |
|||
front: [], |
|||
back: [] |
|||
}; |
|||
if (_this.divider == null) { |
|||
_this.divider = polygons[0].clone(); |
|||
} |
|||
for (_i = 0, _len = polygons.length; _i < _len; _i++) { |
|||
poly = polygons[_i]; |
|||
_this.divider.subdivide(poly, _this.polygons, _this.polygons, sides.front, sides.back); |
|||
} |
|||
_results = []; |
|||
for (side in sides) { |
|||
if (!__hasProp.call(sides, side)) continue; |
|||
polys = sides[side]; |
|||
if (polys.length) { |
|||
if (_this[side] == null) { |
|||
_this[side] = new ThreeBSP.Node(); |
|||
} |
|||
_results.push(_this[side].build(polys)); |
|||
} else { |
|||
_results.push(void 0); |
|||
} |
|||
} |
|||
return _results; |
|||
}); |
|||
}; |
|||
|
|||
Node.prototype.isConvex = function(polys) { |
|||
var inner, outer, _i, _j, _len, _len1; |
|||
for (_i = 0, _len = polys.length; _i < _len; _i++) { |
|||
inner = polys[_i]; |
|||
for (_j = 0, _len1 = polys.length; _j < _len1; _j++) { |
|||
outer = polys[_j]; |
|||
if (inner !== outer && outer.classifySide(inner) !== BACK) { |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
return true; |
|||
}; |
|||
|
|||
Node.prototype.allPolygons = function() { |
|||
var _ref, _ref1; |
|||
return this.polygons.slice().concat(((_ref1 = this.front) != null ? _ref1.allPolygons() : void 0) || []).concat(((_ref = this.back) != null ? _ref.allPolygons() : void 0) || []); |
|||
}; |
|||
|
|||
Node.prototype.invert = function() { |
|||
var _this = this; |
|||
return returning(this, function() { |
|||
var flipper, poly, _i, _j, _len, _len1, _ref, _ref1, _ref2; |
|||
_ref = _this.polygons; |
|||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { |
|||
poly = _ref[_i]; |
|||
poly.invert(); |
|||
} |
|||
_ref1 = [_this.divider, _this.front, _this.back]; |
|||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { |
|||
flipper = _ref1[_j]; |
|||
if (flipper != null) { |
|||
flipper.invert(); |
|||
} |
|||
} |
|||
return _ref2 = [_this.back, _this.front], _this.front = _ref2[0], _this.back = _ref2[1], _ref2; |
|||
}); |
|||
}; |
|||
|
|||
Node.prototype.clipPolygons = function(polygons) { |
|||
var back, front, poly, _i, _len; |
|||
if (!this.divider) { |
|||
return polygons.slice(); |
|||
} |
|||
front = []; |
|||
back = []; |
|||
for (_i = 0, _len = polygons.length; _i < _len; _i++) { |
|||
poly = polygons[_i]; |
|||
this.divider.subdivide(poly, front, back, front, back); |
|||
} |
|||
if (this.front) { |
|||
front = this.front.clipPolygons(front); |
|||
} |
|||
if (this.back) { |
|||
back = this.back.clipPolygons(back); |
|||
} |
|||
return front.concat(this.back ? back : []); |
|||
}; |
|||
|
|||
Node.prototype.clipTo = function(node) { |
|||
var _this = this; |
|||
return returning(this, function() { |
|||
var _ref, _ref1; |
|||
_this.polygons = node.clipPolygons(_this.polygons); |
|||
if ((_ref = _this.front) != null) { |
|||
_ref.clipTo(node); |
|||
} |
|||
return (_ref1 = _this.back) != null ? _ref1.clipTo(node) : void 0; |
|||
}); |
|||
}; |
|||
|
|||
return Node; |
|||
|
|||
})(); |
|||
|
|||
}).call(this); |
@ -0,0 +1,147 @@ |
|||
/* |
|||
* @author xiening |
|||
* Running this will allow you to show white line around objects which you selected. |
|||
*/ |
|||
/* |
|||
* 需要在jsp中导入的包 |
|||
<script src="./ThreeJs/three.js"></script> |
|||
<script src="./ThreeJs/EffectComposer.js"></script> |
|||
<script src="./ThreeJs/RenderPass.js"></script> |
|||
<script src="./ThreeJs/OutlinePass.js"></script> |
|||
<script src="./ThreeJs/FXAAShader.js"></script> |
|||
<script src="./ThreeJs/ShaderPass.js"></script> |
|||
<script src="./ThreeJs/CopyShader.js"></script> |
|||
*/ |
|||
|
|||
THREE.ThreeJs_Composer = function ( _renderer, _scene, _camera, _options, _selectobject) { |
|||
var raycaster = new THREE.Raycaster(); |
|||
var mouse = new THREE.Vector2(); |
|||
var composer = new THREE.EffectComposer( _renderer ); |
|||
var renderPass = new THREE.RenderPass( _scene, _camera ); |
|||
var selectedObjects = []; |
|||
composer.addPass( renderPass ); |
|||
var outlinePass = new THREE.OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), _scene, _camera ); |
|||
outlinePass.edgeStrength = 5;//包围线浓度
|
|||
outlinePass.edgeGlow = 0.5;//边缘线范围
|
|||
outlinePass.edgeThickness = 2;//边缘线浓度
|
|||
outlinePass.pulsePeriod = 2;//包围线闪烁评率
|
|||
outlinePass.visibleEdgeColor.set( '#ffffff' );//包围线颜色
|
|||
outlinePass.hiddenEdgeColor.set( '#190a05' );//被遮挡的边界线颜色
|
|||
composer.addPass( outlinePass ); |
|||
var effectFXAA = new THREE.ShaderPass( THREE.FXAAShader ); |
|||
effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight ); |
|||
effectFXAA.renderToScreen = true; |
|||
// composer.addPass( effectFXAA );
|
|||
|
|||
window.addEventListener( 'click', onMouseClick); |
|||
window.addEventListener( 'dblclick', onMouseDblClick); |
|||
|
|||
var door_state_left1 = true; //默认是门是关闭的
|
|||
var door_state_right1 = true; //默认是门是关闭的
|
|||
function onMouseClick( event ) { |
|||
var x, y; |
|||
if ( event.changedTouches ) { |
|||
x = event.changedTouches[ 0 ].pageX; |
|||
y = event.changedTouches[ 0 ].pageY; |
|||
} else { |
|||
x = event.clientX; |
|||
y = event.clientY; |
|||
} |
|||
mouse.x = ( x / window.innerWidth ) * 2 - 1; |
|||
mouse.y = - ( y / window.innerHeight ) * 2 + 1; |
|||
raycaster.setFromCamera( mouse, _camera ); |
|||
var intersects = raycaster.intersectObjects( [ _scene ], true ); |
|||
|
|||
if(intersects.length == 0){ |
|||
$("#label").attr("style","display:none;");//隐藏说明性标签
|
|||
return; |
|||
} |
|||
if(intersects[0].object.name == "地面" || (intersects[0].object.name == "") || (intersects[0].object.name == "墙面")){ |
|||
$("#label").attr("style","display:none;");//隐藏说明性标签
|
|||
selectedObjects.pop(); |
|||
}else{ |
|||
$("#label").attr("style","display:block;");// 显示说明性标签
|
|||
$("#label").css({left: x, top: y-40});// 修改标签的位置
|
|||
$("#label").text(intersects[0].object.name);// 显示模型信息
|
|||
|
|||
selectedObjects.pop(); |
|||
selectedObjects.push( intersects[0].object ); |
|||
outlinePass.selectedObjects = selectedObjects;//给选中的线条和物体加发光特效
|
|||
} |
|||
|
|||
var Msg = intersects[0].object.name.split("$"); |
|||
if(Msg[0] == "货物") { |
|||
_options.batchNo = "一个货物"; |
|||
_options.qty = "100"; |
|||
_options.qtyUom = "kg"; |
|||
_options.qty2 = "10"; |
|||
_options.selectObj = intersects[0].object.name; |
|||
_selectobject.push( intersects[0].object ); |
|||
} |
|||
|
|||
if(intersects[0].object.name == "左门1"){ |
|||
if(door_state_left1){ |
|||
new TWEEN.Tween(intersects[0].object.rotation).to({ |
|||
y: -0.5*Math.PI |
|||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){ |
|||
}).start(); |
|||
door_state_left1 = false; |
|||
}else{ |
|||
new TWEEN.Tween(intersects[0].object.rotation).to({ |
|||
y: 0 |
|||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){ |
|||
}).start(); |
|||
door_state_left1 = true; |
|||
} |
|||
}else if(intersects[0].object.name == "右门1"){ |
|||
if(door_state_right1){ |
|||
new TWEEN.Tween(intersects[0].object.rotation).to({ |
|||
y: 0.5*Math.PI |
|||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){ |
|||
}).start(); |
|||
door_state_right1 = false; |
|||
}else{ |
|||
new TWEEN.Tween(intersects[0].object.rotation).to({ |
|||
y: 0 |
|||
}, 5000).easing(TWEEN.Easing.Elastic.Out).onComplete(function(){ |
|||
}).start(); |
|||
door_state_right1 = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function onMouseDblClick( event ) { |
|||
var x, y; |
|||
if ( event.changedTouches ) { |
|||
x = event.changedTouches[ 0 ].pageX; |
|||
y = event.changedTouches[ 0 ].pageY; |
|||
} else { |
|||
x = event.clientX; |
|||
y = event.clientY; |
|||
} |
|||
mouse.x = ( x / window.innerWidth ) * 2 - 1; |
|||
mouse.y = - ( y / window.innerHeight ) * 2 + 1; |
|||
raycaster.setFromCamera( mouse, _camera ); |
|||
var intersects = raycaster.intersectObjects( [ _scene ], true ); |
|||
|
|||
if(intersects.length == 0){ |
|||
return; |
|||
} |
|||
|
|||
var Msg = intersects[0].object.name.split("$"); |
|||
if(Msg[0] == "货物") { |
|||
var href = "DispatchAction.do?efFormEname=YMIQ083DP&inqu_status-0-storageUnitId=" + Msg[1]; |
|||
EFColorbox({ |
|||
href : href, |
|||
title:"货物详情", |
|||
innerWidth:'1200px', |
|||
innerHeight:'800px', |
|||
iframe : true, |
|||
scrolling : false, |
|||
overlayClose: false |
|||
}); |
|||
} |
|||
} |
|||
|
|||
return composer; |
|||
} |
@ -0,0 +1,102 @@ |
|||
/* |
|||
* @author xiening |
|||
* Running this will allow you to drag three.js objects around the screen. |
|||
*/ |
|||
/* |
|||
* 需要在jsp中导入的包 |
|||
<script src="./ThreeJs/DragControls.js"></script> |
|||
<script src="./ThreeJs/TransformControls.js"></script> |
|||
*/ |
|||
|
|||
THREE.ThreeJs_Drag = function ( _camera, _domElement, _scene, _controls, _isPaused) { |
|||
// 过滤不是 Mesh 的物体,例如辅助网格
|
|||
var objects = []; |
|||
for (var i = 0; i < _scene.children.length; i++) { |
|||
var Msg = _scene.children[i].name.split("$"); |
|||
if (_scene.children[i].isMesh && Msg[0] == "货物") { |
|||
objects.push(_scene.children[i]); |
|||
} |
|||
} |
|||
|
|||
var dragControls = new THREE.DragControls( objects, _camera, _domElement ); |
|||
dragControls.addEventListener( 'dragstart', function ( event ) { |
|||
_controls.enabled = false; |
|||
_isPaused = true; |
|||
} ); |
|||
dragControls.addEventListener( 'dragend', function ( event ) { |
|||
_controls.enabled = true; |
|||
_isPaused = false; |
|||
} ); |
|||
// // 添加平移控件
|
|||
// var transformControls = new THREE.TransformControls(_camera, _domElement);
|
|||
// transformControls.addEventListener( 'change', function () {
|
|||
// cancelHideTransform();
|
|||
// } );
|
|||
// transformControls.addEventListener( 'mouseDown', function () {
|
|||
// cancelHideTransform();
|
|||
// } );
|
|||
// transformControls.addEventListener( 'mouseUp', function () {
|
|||
// delayHideTransform();
|
|||
// } );
|
|||
// _scene.add(transformControls);
|
|||
//
|
|||
// // 过滤不是 Mesh 的物体,例如辅助网格
|
|||
// var objects = [];
|
|||
// for (var i = 0; i < _scene.children.length; i++) {
|
|||
// var Msg = _scene.children[i].name.split("$");
|
|||
// if (_scene.children[i].isMesh && Msg[0] == "货物") {
|
|||
// objects.push(_scene.children[i]);
|
|||
// }
|
|||
// }
|
|||
//
|
|||
// // 初始化拖拽控件
|
|||
// var dragControls = new THREE.DragControls(objects, _camera, _domElement);
|
|||
//
|
|||
// // 鼠标划入过事件
|
|||
// dragControls.addEventListener('hoveron', function (event) {
|
|||
// // 让变换控件对象和选中的对象绑定
|
|||
// transformControls.attach(event.object);
|
|||
// cancelHideTransform();
|
|||
// });
|
|||
//
|
|||
// // 鼠标划出事件
|
|||
// dragControls.addEventListener('hoveroff', function (event) {
|
|||
// delayHideTransform();
|
|||
// });
|
|||
//
|
|||
// // 开始拖拽
|
|||
// dragControls.addEventListener('dragstart', function (event) {
|
|||
// controls.enabled = false;
|
|||
// });
|
|||
//
|
|||
// // 拖拽结束
|
|||
// dragControls.addEventListener('dragend', function (event) {
|
|||
// controls.enabled = true;
|
|||
// });
|
|||
//
|
|||
// controls.addEventListener( 'start', function () {
|
|||
// cancelHideTransform();
|
|||
// } );
|
|||
//
|
|||
// controls.addEventListener( 'end', function () {
|
|||
// delayHideTransform();
|
|||
// } );
|
|||
//
|
|||
// var hiding;
|
|||
// function delayHideTransform() {
|
|||
// cancelHideTransform();
|
|||
// hideTransform();
|
|||
// }
|
|||
//
|
|||
// function hideTransform() {
|
|||
// hiding = setTimeout( function () {
|
|||
// transformControls.detach( transformControls.object );
|
|||
// }, 1000 );
|
|||
// }
|
|||
//
|
|||
// function cancelHideTransform() {
|
|||
// if ( hiding ) clearTimeout( hiding );
|
|||
// }
|
|||
//
|
|||
// return transformControls;
|
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,895 @@ |
|||
/** |
|||
* Tween.js - Licensed under the MIT license |
|||
* https://github.com/tweenjs/tween.js
|
|||
* ---------------------------------------------- |
|||
* |
|||
* See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
|
|||
* Thank you all, you're awesome! |
|||
*/ |
|||
|
|||
var TWEEN = TWEEN || (function () { |
|||
|
|||
var _tweens = []; |
|||
|
|||
return { |
|||
|
|||
getAll: function () { |
|||
|
|||
return _tweens; |
|||
|
|||
}, |
|||
|
|||
removeAll: function () { |
|||
|
|||
_tweens = []; |
|||
|
|||
}, |
|||
|
|||
add: function (tween) { |
|||
|
|||
_tweens.push(tween); |
|||
|
|||
}, |
|||
|
|||
remove: function (tween) { |
|||
|
|||
var i = _tweens.indexOf(tween); |
|||
|
|||
if (i !== -1) { |
|||
_tweens.splice(i, 1); |
|||
} |
|||
|
|||
}, |
|||
|
|||
update: function (time, preserve) { |
|||
|
|||
if (_tweens.length === 0) { |
|||
return false; |
|||
} |
|||
|
|||
var i = 0; |
|||
|
|||
time = time !== undefined ? time : TWEEN.now(); |
|||
|
|||
while (i < _tweens.length) { |
|||
|
|||
if (_tweens[i].update(time) || preserve) { |
|||
i++; |
|||
} else { |
|||
_tweens.splice(i, 1); |
|||
} |
|||
|
|||
} |
|||
|
|||
return true; |
|||
|
|||
} |
|||
}; |
|||
|
|||
})(); |
|||
|
|||
|
|||
// Include a performance.now polyfill.
|
|||
// In node.js, use process.hrtime.
|
|||
if (typeof (window) === 'undefined' && typeof (process) !== 'undefined') { |
|||
TWEEN.now = function () { |
|||
var time = process.hrtime(); |
|||
|
|||
// Convert [seconds, nanoseconds] to milliseconds.
|
|||
return time[0] * 1000 + time[1] / 1000000; |
|||
}; |
|||
} |
|||
// In a browser, use window.performance.now if it is available.
|
|||
else if (typeof (window) !== 'undefined' && |
|||
window.performance !== undefined && |
|||
window.performance.now !== undefined) { |
|||
// This must be bound, because directly assigning this function
|
|||
// leads to an invocation exception in Chrome.
|
|||
TWEEN.now = window.performance.now.bind(window.performance); |
|||
} |
|||
// Use Date.now if it is available.
|
|||
else if (Date.now !== undefined) { |
|||
TWEEN.now = Date.now; |
|||
} |
|||
// Otherwise, use 'new Date().getTime()'.
|
|||
else { |
|||
TWEEN.now = function () { |
|||
return new Date().getTime(); |
|||
}; |
|||
} |
|||
|
|||
|
|||
function assign(target, source) { |
|||
var keys = Object.keys(source); |
|||
var length = keys.length; |
|||
|
|||
for (var i = 0; i < length; i += 1) { |
|||
target[keys[i]] = source[keys[i]]; |
|||
} |
|||
|
|||
return target; |
|||
} |
|||
|
|||
|
|||
TWEEN.Tween = function (object) { |
|||
|
|||
this._object = object; |
|||
this._valuesStart = {}; |
|||
this._valuesEnd = {}; |
|||
this._valuesStartRepeat = {}; |
|||
this._duration = 1000; |
|||
this._repeat = 0; |
|||
this._repeatDelayTime = undefined; |
|||
this._yoyo = false; |
|||
this._isPlaying = false; |
|||
this._reversed = false; |
|||
this._delayTime = 0; |
|||
this._startTime = null; |
|||
this._easingFunction = TWEEN.Easing.Linear.None; |
|||
this._interpolationFunction = TWEEN.Interpolation.Linear; |
|||
this._chainedTweens = []; |
|||
this._onStartCallback = null; |
|||
this._onStartCallbackFired = false; |
|||
this._onUpdateCallback = null; |
|||
this._onCompleteCallback = null; |
|||
this._onStopCallback = null; |
|||
|
|||
}; |
|||
|
|||
TWEEN.Tween.prototype = assign(Object.create(Object.prototype), { |
|||
to: function to(properties, duration) { |
|||
|
|||
this._valuesEnd = properties; |
|||
|
|||
if (duration !== undefined) { |
|||
this._duration = duration; |
|||
} |
|||
|
|||
return this; |
|||
|
|||
}, |
|||
|
|||
start: function start(time) { |
|||
|
|||
TWEEN.add(this); |
|||
|
|||
this._isPlaying = true; |
|||
|
|||
this._onStartCallbackFired = false; |
|||
|
|||
this._startTime = time !== undefined ? time : TWEEN.now(); |
|||
this._startTime += this._delayTime; |
|||
|
|||
for (var property in this._valuesEnd) { |
|||
|
|||
// Check if an Array was provided as property value
|
|||
if (this._valuesEnd[property] instanceof Array) { |
|||
|
|||
if (this._valuesEnd[property].length === 0) { |
|||
continue; |
|||
} |
|||
|
|||
// Create a local copy of the Array with the start value at the front
|
|||
this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]); |
|||
|
|||
} |
|||
|
|||
// If `to()` specifies a property that doesn't exist in the source object,
|
|||
// we should not set that property in the object
|
|||
if (this._object[property] === undefined) { |
|||
continue; |
|||
} |
|||
|
|||
// Save the starting value.
|
|||
this._valuesStart[property] = this._object[property]; |
|||
|
|||
if ((this._valuesStart[property] instanceof Array) === false) { |
|||
this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
|
|||
} |
|||
|
|||
this._valuesStartRepeat[property] = this._valuesStart[property] || 0; |
|||
|
|||
} |
|||
|
|||
return this; |
|||
|
|||
}, |
|||
|
|||
stop: function stop() { |
|||
|
|||
if (!this._isPlaying) { |
|||
return this; |
|||
} |
|||
|
|||
TWEEN.remove(this); |
|||
this._isPlaying = false; |
|||
|
|||
if (this._onStopCallback !== null) { |
|||
this._onStopCallback.call(this._object, this._object); |
|||
} |
|||
|
|||
this.stopChainedTweens(); |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
end: function end() { |
|||
|
|||
this.update(this._startTime + this._duration); |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
stopChainedTweens: function stopChainedTweens() { |
|||
|
|||
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { |
|||
this._chainedTweens[i].stop(); |
|||
} |
|||
|
|||
}, |
|||
|
|||
delay: function delay(amount) { |
|||
|
|||
this._delayTime = amount; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
repeat: function repeat(times) { |
|||
|
|||
this._repeat = times; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
repeatDelay: function repeatDelay(amount) { |
|||
|
|||
this._repeatDelayTime = amount; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
yoyo: function yoyo(yoyo) { |
|||
|
|||
this._yoyo = yoyo; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
easing: function easing(easing) { |
|||
|
|||
this._easingFunction = easing; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
interpolation: function interpolation(interpolation) { |
|||
|
|||
this._interpolationFunction = interpolation; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
chain: function chain() { |
|||
|
|||
this._chainedTweens = arguments; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
onStart: function onStart(callback) { |
|||
|
|||
this._onStartCallback = callback; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
onUpdate: function onUpdate(callback) { |
|||
|
|||
this._onUpdateCallback = callback; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
onComplete: function onComplete(callback) { |
|||
|
|||
this._onCompleteCallback = callback; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
onStop: function onStop(callback) { |
|||
|
|||
this._onStopCallback = callback; |
|||
return this; |
|||
|
|||
}, |
|||
|
|||
update: function update(time) { |
|||
|
|||
var property; |
|||
var elapsed; |
|||
var value; |
|||
|
|||
if (time < this._startTime) { |
|||
return true; |
|||
} |
|||
|
|||
if (this._onStartCallbackFired === false) { |
|||
|
|||
if (this._onStartCallback !== null) { |
|||
this._onStartCallback.call(this._object, this._object); |
|||
} |
|||
|
|||
this._onStartCallbackFired = true; |
|||
} |
|||
|
|||
elapsed = (time - this._startTime) / this._duration; |
|||
elapsed = elapsed > 1 ? 1 : elapsed; |
|||
|
|||
value = this._easingFunction(elapsed); |
|||
|
|||
for (property in this._valuesEnd) { |
|||
|
|||
// Don't update properties that do not exist in the source object
|
|||
if (this._valuesStart[property] === undefined) { |
|||
continue; |
|||
} |
|||
|
|||
var start = this._valuesStart[property] || 0; |
|||
var end = this._valuesEnd[property]; |
|||
|
|||
if (end instanceof Array) { |
|||
|
|||
this._object[property] = this._interpolationFunction(end, value); |
|||
|
|||
} else { |
|||
|
|||
// Parses relative end values with start as base (e.g.: +10, -3)
|
|||
if (typeof (end) === 'string') { |
|||
|
|||
if (end.charAt(0) === '+' || end.charAt(0) === '-') { |
|||
end = start + parseFloat(end); |
|||
} else { |
|||
end = parseFloat(end); |
|||
} |
|||
} |
|||
|
|||
// Protect against non numeric properties.
|
|||
if (typeof (end) === 'number') { |
|||
this._object[property] = start + (end - start) * value; |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
if (this._onUpdateCallback !== null) { |
|||
this._onUpdateCallback.call(this._object, value); |
|||
} |
|||
|
|||
if (elapsed === 1) { |
|||
|
|||
if (this._repeat > 0) { |
|||
|
|||
if (isFinite(this._repeat)) { |
|||
this._repeat--; |
|||
} |
|||
|
|||
// Reassign starting values, restart by making startTime = now
|
|||
for (property in this._valuesStartRepeat) { |
|||
|
|||
if (typeof (this._valuesEnd[property]) === 'string') { |
|||
this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]); |
|||
} |
|||
|
|||
if (this._yoyo) { |
|||
var tmp = this._valuesStartRepeat[property]; |
|||
|
|||
this._valuesStartRepeat[property] = this._valuesEnd[property]; |
|||
this._valuesEnd[property] = tmp; |
|||
} |
|||
|
|||
this._valuesStart[property] = this._valuesStartRepeat[property]; |
|||
|
|||
} |
|||
|
|||
if (this._yoyo) { |
|||
this._reversed = !this._reversed; |
|||
} |
|||
|
|||
if (this._repeatDelayTime !== undefined) { |
|||
this._startTime = time + this._repeatDelayTime; |
|||
} else { |
|||
this._startTime = time + this._delayTime; |
|||
} |
|||
|
|||
return true; |
|||
|
|||
} else { |
|||
|
|||
if (this._onCompleteCallback !== null) { |
|||
|
|||
this._onCompleteCallback.call(this._object, this._object); |
|||
} |
|||
|
|||
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { |
|||
// Make the chained tweens start exactly at the time they should,
|
|||
// even if the `update()` method was called way past the duration of the tween
|
|||
this._chainedTweens[i].start(this._startTime + this._duration); |
|||
} |
|||
|
|||
return false; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
return true; |
|||
|
|||
} |
|||
}); |
|||
|
|||
|
|||
TWEEN.Easing = { |
|||
|
|||
Linear: { |
|||
|
|||
None: function (k) { |
|||
|
|||
return k; |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Quadratic: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return k * k; |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
return k * (2 - k); |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if ((k *= 2) < 1) { |
|||
return 0.5 * k * k; |
|||
} |
|||
|
|||
return - 0.5 * (--k * (k - 2) - 1); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Cubic: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return k * k * k; |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
return --k * k * k + 1; |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if ((k *= 2) < 1) { |
|||
return 0.5 * k * k * k; |
|||
} |
|||
|
|||
return 0.5 * ((k -= 2) * k * k + 2); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Quartic: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return k * k * k * k; |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
return 1 - (--k * k * k * k); |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if ((k *= 2) < 1) { |
|||
return 0.5 * k * k * k * k; |
|||
} |
|||
|
|||
return - 0.5 * ((k -= 2) * k * k * k - 2); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Quintic: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return k * k * k * k * k; |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
return --k * k * k * k * k + 1; |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if ((k *= 2) < 1) { |
|||
return 0.5 * k * k * k * k * k; |
|||
} |
|||
|
|||
return 0.5 * ((k -= 2) * k * k * k * k + 2); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Sinusoidal: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return 1 - Math.cos(k * Math.PI / 2); |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
return Math.sin(k * Math.PI / 2); |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
return 0.5 * (1 - Math.cos(Math.PI * k)); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Exponential: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return k === 0 ? 0 : Math.pow(1024, k - 1); |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k); |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if (k === 0) { |
|||
return 0; |
|||
} |
|||
|
|||
if (k === 1) { |
|||
return 1; |
|||
} |
|||
|
|||
if ((k *= 2) < 1) { |
|||
return 0.5 * Math.pow(1024, k - 1); |
|||
} |
|||
|
|||
return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Circular: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return 1 - Math.sqrt(1 - k * k); |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
return Math.sqrt(1 - (--k * k)); |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if ((k *= 2) < 1) { |
|||
return - 0.5 * (Math.sqrt(1 - k * k) - 1); |
|||
} |
|||
|
|||
return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Elastic: { |
|||
|
|||
In: function (k) { |
|||
|
|||
if (k === 0) { |
|||
return 0; |
|||
} |
|||
|
|||
if (k === 1) { |
|||
return 1; |
|||
} |
|||
|
|||
return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
if (k === 0) { |
|||
return 0; |
|||
} |
|||
|
|||
if (k === 1) { |
|||
return 1; |
|||
} |
|||
|
|||
return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1; |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if (k === 0) { |
|||
return 0; |
|||
} |
|||
|
|||
if (k === 1) { |
|||
return 1; |
|||
} |
|||
|
|||
k *= 2; |
|||
|
|||
if (k < 1) { |
|||
return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); |
|||
} |
|||
|
|||
return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1; |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Back: { |
|||
|
|||
In: function (k) { |
|||
|
|||
var s = 1.70158; |
|||
|
|||
return k * k * ((s + 1) * k - s); |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
var s = 1.70158; |
|||
|
|||
return --k * k * ((s + 1) * k + s) + 1; |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
var s = 1.70158 * 1.525; |
|||
|
|||
if ((k *= 2) < 1) { |
|||
return 0.5 * (k * k * ((s + 1) * k - s)); |
|||
} |
|||
|
|||
return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Bounce: { |
|||
|
|||
In: function (k) { |
|||
|
|||
return 1 - TWEEN.Easing.Bounce.Out(1 - k); |
|||
|
|||
}, |
|||
|
|||
Out: function (k) { |
|||
|
|||
if (k < (1 / 2.75)) { |
|||
return 7.5625 * k * k; |
|||
} else if (k < (2 / 2.75)) { |
|||
return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75; |
|||
} else if (k < (2.5 / 2.75)) { |
|||
return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375; |
|||
} else { |
|||
return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375; |
|||
} |
|||
|
|||
}, |
|||
|
|||
InOut: function (k) { |
|||
|
|||
if (k < 0.5) { |
|||
return TWEEN.Easing.Bounce.In(k * 2) * 0.5; |
|||
} |
|||
|
|||
return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
TWEEN.Interpolation = { |
|||
|
|||
Linear: function (v, k) { |
|||
|
|||
var m = v.length - 1; |
|||
var f = m * k; |
|||
var i = Math.floor(f); |
|||
var fn = TWEEN.Interpolation.Utils.Linear; |
|||
|
|||
if (k < 0) { |
|||
return fn(v[0], v[1], f); |
|||
} |
|||
|
|||
if (k > 1) { |
|||
return fn(v[m], v[m - 1], m - f); |
|||
} |
|||
|
|||
return fn(v[i], v[i + 1 > m ? m : i + 1], f - i); |
|||
|
|||
}, |
|||
|
|||
Bezier: function (v, k) { |
|||
|
|||
var b = 0; |
|||
var n = v.length - 1; |
|||
var pw = Math.pow; |
|||
var bn = TWEEN.Interpolation.Utils.Bernstein; |
|||
|
|||
for (var i = 0; i <= n; i++) { |
|||
b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); |
|||
} |
|||
|
|||
return b; |
|||
|
|||
}, |
|||
|
|||
CatmullRom: function (v, k) { |
|||
|
|||
var m = v.length - 1; |
|||
var f = m * k; |
|||
var i = Math.floor(f); |
|||
var fn = TWEEN.Interpolation.Utils.CatmullRom; |
|||
|
|||
if (v[0] === v[m]) { |
|||
|
|||
if (k < 0) { |
|||
i = Math.floor(f = m * (1 + k)); |
|||
} |
|||
|
|||
return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i); |
|||
|
|||
} else { |
|||
|
|||
if (k < 0) { |
|||
return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]); |
|||
} |
|||
|
|||
if (k > 1) { |
|||
return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]); |
|||
} |
|||
|
|||
return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i); |
|||
|
|||
} |
|||
|
|||
}, |
|||
|
|||
Utils: { |
|||
|
|||
Linear: function (p0, p1, t) { |
|||
|
|||
return (p1 - p0) * t + p0; |
|||
|
|||
}, |
|||
|
|||
Bernstein: function (n, i) { |
|||
|
|||
var fc = TWEEN.Interpolation.Utils.Factorial; |
|||
|
|||
return fc(n) / fc(i) / fc(n - i); |
|||
|
|||
}, |
|||
|
|||
Factorial: (function () { |
|||
|
|||
var a = [1]; |
|||
|
|||
return function (n) { |
|||
|
|||
var s = 1; |
|||
|
|||
if (a[n]) { |
|||
return a[n]; |
|||
} |
|||
|
|||
for (var i = n; i > 1; i--) { |
|||
s *= i; |
|||
} |
|||
|
|||
a[n] = s; |
|||
return s; |
|||
|
|||
}; |
|||
|
|||
})(), |
|||
|
|||
CatmullRom: function (p0, p1, p2, p3, t) { |
|||
|
|||
var v0 = (p2 - p0) * 0.5; |
|||
var v1 = (p3 - p1) * 0.5; |
|||
var t2 = t * t; |
|||
var t3 = t * t2; |
|||
|
|||
return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (- 3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
}; |
|||
|
|||
// UMD (Universal Module Definition)
|
|||
(function (root) { |
|||
|
|||
if (typeof define === 'function' && define.amd) { |
|||
|
|||
// AMD
|
|||
define([], function () { |
|||
return TWEEN; |
|||
}); |
|||
|
|||
} else if (typeof module !== 'undefined' && typeof exports === 'object') { |
|||
|
|||
// Node.js
|
|||
module.exports = TWEEN; |
|||
|
|||
} else if (root !== undefined) { |
|||
|
|||
// Global variable
|
|||
root.TWEEN = TWEEN; |
|||
|
|||
} |
|||
|
|||
})(this); |
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,899 @@ |
|||
<!DOCTYPE html> |
|||
<!-- saved from url=(0037)http://three.zuoben.top/case-031.html --> |
|||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
|||
<title>Threejs实现数字化工厂安全生产监控</title> |
|||
|
|||
<script src="./hm.js"></script><script type="text/javascript" src="./statistics(1).js"></script> |
|||
<!-- <script type="text/javascript" src="./steak(1).js"></script> --> |
|||
<script type="text/javascript" src="./three.js"></script> |
|||
<script type="text/javascript" src="./OrbitControls.js"></script> |
|||
<script type="text/javascript" src="./GLTFLoader.js"></script> |
|||
<script type="text/javascript" src="./ThreeBSP.js"></script> |
|||
<script type="text/javascript" src="./dat.gui.js"></script><style type="text/css">.dg { |
|||
/** Clear list styles */ |
|||
/* Auto-place container */ |
|||
/* Auto-placed GUI's */ |
|||
/* Line items that don't contain folders. */ |
|||
/** Folder names */ |
|||
/** Hides closed items */ |
|||
/** Controller row */ |
|||
/** Name-half (left) */ |
|||
/** Controller-half (right) */ |
|||
/** Controller placement */ |
|||
/** Shorter number boxes when slider is present. */ |
|||
/** Ensure the entire boolean and function row shows a hand */ } |
|||
.dg ul { |
|||
list-style: none; |
|||
margin: 0; |
|||
padding: 0; |
|||
width: 100%; |
|||
clear: both; } |
|||
.dg.ac { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
height: 0; |
|||
z-index: 0; } |
|||
.dg:not(.ac) .main { |
|||
/** Exclude mains in ac so that we don't hide close button */ |
|||
overflow: hidden; } |
|||
.dg.main { |
|||
-webkit-transition: opacity 0.1s linear; |
|||
-o-transition: opacity 0.1s linear; |
|||
-moz-transition: opacity 0.1s linear; |
|||
transition: opacity 0.1s linear; } |
|||
.dg.main.taller-than-window { |
|||
overflow-y: auto; } |
|||
.dg.main.taller-than-window .close-button { |
|||
opacity: 1; |
|||
/* TODO, these are style notes */ |
|||
margin-top: -1px; |
|||
border-top: 1px solid #2c2c2c; } |
|||
.dg.main ul.closed .close-button { |
|||
opacity: 1 !important; } |
|||
.dg.main:hover .close-button, |
|||
.dg.main .close-button.drag { |
|||
opacity: 1; } |
|||
.dg.main .close-button { |
|||
/*opacity: 0;*/ |
|||
-webkit-transition: opacity 0.1s linear; |
|||
-o-transition: opacity 0.1s linear; |
|||
-moz-transition: opacity 0.1s linear; |
|||
transition: opacity 0.1s linear; |
|||
border: 0; |
|||
position: absolute; |
|||
line-height: 19px; |
|||
height: 20px; |
|||
/* TODO, these are style notes */ |
|||
cursor: pointer; |
|||
text-align: center; |
|||
background-color: #000; } |
|||
.dg.main .close-button:hover { |
|||
background-color: #111; } |
|||
.dg.a { |
|||
float: right; |
|||
margin-right: 15px; |
|||
overflow-x: hidden; } |
|||
.dg.a.has-save > ul { |
|||
margin-top: 27px; } |
|||
.dg.a.has-save > ul.closed { |
|||
margin-top: 0; } |
|||
.dg.a .save-row { |
|||
position: fixed; |
|||
top: 0; |
|||
z-index: 1002; } |
|||
.dg li { |
|||
-webkit-transition: height 0.1s ease-out; |
|||
-o-transition: height 0.1s ease-out; |
|||
-moz-transition: height 0.1s ease-out; |
|||
transition: height 0.1s ease-out; } |
|||
.dg li:not(.folder) { |
|||
cursor: auto; |
|||
height: 27px; |
|||
line-height: 27px; |
|||
overflow: hidden; |
|||
padding: 0 4px 0 5px; } |
|||
.dg li.folder { |
|||
padding: 0; |
|||
border-left: 4px solid rgba(0, 0, 0, 0); } |
|||
.dg li.title { |
|||
cursor: pointer; |
|||
margin-left: -4px; } |
|||
.dg .closed li:not(.title), |
|||
.dg .closed ul li, |
|||
.dg .closed ul li > * { |
|||
height: 0; |
|||
overflow: hidden; |
|||
border: 0; } |
|||
.dg .cr { |
|||
clear: both; |
|||
padding-left: 3px; |
|||
height: 27px; } |
|||
.dg .property-name { |
|||
cursor: default; |
|||
float: left; |
|||
clear: left; |
|||
width: 40%; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; } |
|||
.dg .c { |
|||
float: left; |
|||
width: 60%; } |
|||
.dg .c input[type=text] { |
|||
border: 0; |
|||
margin-top: 4px; |
|||
padding: 3px; |
|||
width: 100%; |
|||
float: right; } |
|||
.dg .has-slider input[type=text] { |
|||
width: 30%; |
|||
/*display: none;*/ |
|||
margin-left: 0; } |
|||
.dg .slider { |
|||
float: left; |
|||
width: 66%; |
|||
margin-left: -5px; |
|||
margin-right: 0; |
|||
height: 19px; |
|||
margin-top: 4px; } |
|||
.dg .slider-fg { |
|||
height: 100%; } |
|||
.dg .c input[type=checkbox] { |
|||
margin-top: 9px; } |
|||
.dg .c select { |
|||
margin-top: 5px; } |
|||
.dg .cr.function, |
|||
.dg .cr.function .property-name, |
|||
.dg .cr.function *, |
|||
.dg .cr.boolean, |
|||
.dg .cr.boolean * { |
|||
cursor: pointer; } |
|||
.dg .selector { |
|||
display: none; |
|||
position: absolute; |
|||
margin-left: -9px; |
|||
margin-top: 23px; |
|||
z-index: 10; } |
|||
.dg .c:hover .selector, |
|||
.dg .selector.drag { |
|||
display: block; } |
|||
.dg li.save-row { |
|||
padding: 0; } |
|||
.dg li.save-row .button { |
|||
display: inline-block; |
|||
padding: 0px 6px; } |
|||
.dg.dialogue { |
|||
background-color: #222; |
|||
width: 460px; |
|||
padding: 15px; |
|||
font-size: 13px; |
|||
line-height: 15px; } |
|||
|
|||
/* TODO Separate style and structure */ |
|||
#dg-new-constructor { |
|||
padding: 10px; |
|||
color: #222; |
|||
font-family: Monaco, monospace; |
|||
font-size: 10px; |
|||
border: 0; |
|||
resize: none; |
|||
box-shadow: inset 1px 1px 1px #888; |
|||
word-wrap: break-word; |
|||
margin: 12px 0; |
|||
display: block; |
|||
width: 440px; |
|||
overflow-y: scroll; |
|||
height: 100px; |
|||
position: relative; } |
|||
|
|||
#dg-local-explain { |
|||
display: none; |
|||
font-size: 11px; |
|||
line-height: 17px; |
|||
border-radius: 3px; |
|||
background-color: #333; |
|||
padding: 8px; |
|||
margin-top: 10px; } |
|||
#dg-local-explain code { |
|||
font-size: 10px; } |
|||
|
|||
#dat-gui-save-locally { |
|||
display: none; } |
|||
|
|||
/** Main type */ |
|||
.dg { |
|||
color: #eee; |
|||
font: 11px 'Lucida Grande', sans-serif; |
|||
text-shadow: 0 -1px 0 #111; |
|||
/** Auto place */ |
|||
/* Controller row, <li> */ |
|||
/** Controllers */ } |
|||
.dg.main { |
|||
/** Scrollbar */ } |
|||
.dg.main::-webkit-scrollbar { |
|||
width: 5px; |
|||
background: #1a1a1a; } |
|||
.dg.main::-webkit-scrollbar-corner { |
|||
height: 0; |
|||
display: none; } |
|||
.dg.main::-webkit-scrollbar-thumb { |
|||
border-radius: 5px; |
|||
background: #676767; } |
|||
.dg li:not(.folder) { |
|||
background: #1a1a1a; |
|||
border-bottom: 1px solid #2c2c2c; } |
|||
.dg li.save-row { |
|||
line-height: 25px; |
|||
background: #dad5cb; |
|||
border: 0; } |
|||
.dg li.save-row select { |
|||
margin-left: 5px; |
|||
width: 108px; } |
|||
.dg li.save-row .button { |
|||
margin-left: 5px; |
|||
margin-top: 1px; |
|||
border-radius: 2px; |
|||
font-size: 9px; |
|||
line-height: 7px; |
|||
padding: 4px 4px 5px 4px; |
|||
background: #c5bdad; |
|||
color: #fff; |
|||
text-shadow: 0 1px 0 #b0a58f; |
|||
box-shadow: 0 -1px 0 #b0a58f; |
|||
cursor: pointer; } |
|||
.dg li.save-row .button.gears { |
|||
background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat; |
|||
height: 7px; |
|||
width: 8px; } |
|||
.dg li.save-row .button:hover { |
|||
background-color: #bab19e; |
|||
box-shadow: 0 -1px 0 #b0a58f; } |
|||
.dg li.folder { |
|||
border-bottom: 0; } |
|||
.dg li.title { |
|||
padding-left: 16px; |
|||
background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat; |
|||
cursor: pointer; |
|||
border-bottom: 1px solid rgba(255, 255, 255, 0.2); } |
|||
.dg .closed li.title { |
|||
background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); } |
|||
.dg .cr.boolean { |
|||
border-left: 3px solid #806787; } |
|||
.dg .cr.function { |
|||
border-left: 3px solid #e61d5f; } |
|||
.dg .cr.number { |
|||
border-left: 3px solid #2fa1d6; } |
|||
.dg .cr.number input[type=text] { |
|||
color: #2fa1d6; } |
|||
.dg .cr.string { |
|||
border-left: 3px solid #1ed36f; } |
|||
.dg .cr.string input[type=text] { |
|||
color: #1ed36f; } |
|||
.dg .cr.function:hover, .dg .cr.boolean:hover { |
|||
background: #111; } |
|||
.dg .c input[type=text] { |
|||
background: #303030; |
|||
outline: none; } |
|||
.dg .c input[type=text]:hover { |
|||
background: #3c3c3c; } |
|||
.dg .c input[type=text]:focus { |
|||
background: #494949; |
|||
color: #fff; } |
|||
.dg .c .slider { |
|||
background: #303030; |
|||
cursor: ew-resize; } |
|||
.dg .c .slider-fg { |
|||
background: #2fa1d6; } |
|||
.dg .c .slider:hover { |
|||
background: #3c3c3c; } |
|||
.dg .c .slider:hover .slider-fg { |
|||
background: #44abda; } |
|||
</style> |
|||
<script type="text/javascript" charset="UTF-8" src="./Tween.min.js"></script> |
|||
<style> |
|||
body { |
|||
margin: 0; |
|||
overflow: hidden; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div id="dom"><canvas width="1427" height="794" style="width: 1427px; height: 794px;"></canvas></div> |
|||
<script type="text/javascript"> |
|||
var camera; |
|||
var renderer; |
|||
var peopleMesh; |
|||
var peopleMixer; |
|||
var mixer; |
|||
var matArrayA = []; //内墙 |
|||
var matArr = []; //外墙 |
|||
var texture; |
|||
var textureSecure; |
|||
var curve; |
|||
|
|||
function init() { |
|||
var urls = [ |
|||
'assets/bgImage/skyBox6/posx.jpg', |
|||
'assets/bgImage/skyBox6/negx.jpg', |
|||
'assets/bgImage/skyBox6/posy.jpg', |
|||
'assets/bgImage/skyBox6/negy.jpg', |
|||
'assets/bgImage/skyBox6/posz.jpg', |
|||
'assets/bgImage/skyBox6/negz.jpg' |
|||
]; |
|||
// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。 |
|||
var scene = new THREE.Scene(); |
|||
var cubeLoader = new THREE.CubeTextureLoader(); |
|||
// scene.background = cubeLoader.load(urls); |
|||
scene.opacity = 0; |
|||
|
|||
// 创建一个摄像机,它定义了我们正在看的地方 |
|||
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100000); |
|||
// 将摄像机对准场景的中心 |
|||
camera.position.z = 2000; |
|||
camera.position.y = 800; |
|||
camera.lookAt(scene.position); |
|||
var orbit = new THREE.OrbitControls(camera); |
|||
|
|||
// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景 |
|||
renderer = new THREE.WebGLRenderer({ |
|||
antialias: true, |
|||
logarithmicDepthBuffer: true, |
|||
}); |
|||
renderer.setClearColor(new THREE.Color("#0e0934")); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
|
|||
var ambientLight = new THREE.AmbientLight("#ffffff", 1); |
|||
scene.add(ambientLight); |
|||
|
|||
// 将呈现器的输出添加到HTML元素 |
|||
document.getElementById("dom").appendChild(renderer.domElement); |
|||
|
|||
// 启动动画 |
|||
renderScene(); |
|||
initContent(); |
|||
initSloganModel(); |
|||
|
|||
for (var i = 0; i < 8; i++) { |
|||
let px = 1060 - i * 300; |
|||
addArea(px, -400, 200, 500, scene, "库区1-" + (i + 1) + "号", "FF0000", 20, "居中"); |
|||
} |
|||
for (var i = 0; i < 8; i++) { |
|||
let px = 1060 - i * 300; |
|||
if (i != 1 && i != 2 && i != 5 && i != 6) { |
|||
addArea(px, 400, 200, 500, scene, "库区2-" + (i + 1) + "号", "FF0000", 20, "居中"); |
|||
} |
|||
} |
|||
initSecureModel(); |
|||
|
|||
// 初始化模型 |
|||
function initContent() { |
|||
createFloor(); |
|||
createWallMaterail(); |
|||
var mat = new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
}); |
|||
createCubeWall(10, 200, 1400, 0, matArr, -1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 1400, 1, matArr, 1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 2600, 1.5, matArr, 0, 100, -700, "墙面"); |
|||
//创建挖了门的墙 |
|||
var wall = returnWallObject(2600, 200, 10, 0, mat, 0, 100, 700, "墙面"); |
|||
var door_cube1 = returnWallObject(200, 180, 10, 0, mat, -600, 90, 700, "前门1"); |
|||
var door_cube2 = returnWallObject(200, 180, 10, 0, mat, 600, 90, 700, "前门2"); |
|||
var window_cube1 = returnWallObject(100, 100, 10, 0, mat, -900, 90, 700, "窗户1"); |
|||
var window_cube2 = returnWallObject(100, 100, 10, 0, mat, 900, 90, 700, "窗户2"); |
|||
var window_cube3 = returnWallObject(100, 100, 10, 0, mat, -200, 90, 700, "窗户3"); |
|||
var window_cube4 = returnWallObject(100, 100, 10, 0, mat, 200, 90, 700, "窗户4"); |
|||
var objects_cube = []; |
|||
objects_cube.push(door_cube1); |
|||
objects_cube.push(door_cube2); |
|||
objects_cube.push(window_cube1); |
|||
objects_cube.push(window_cube2); |
|||
objects_cube.push(window_cube3); |
|||
objects_cube.push(window_cube4); |
|||
createResultBsp(wall, objects_cube); |
|||
// 为墙面安装门 |
|||
createDoor(100, 180, 2, 0, -700, 90, 700, "左门1"); |
|||
createDoor(100, 180, 2, 0, -500, 90, 700, "右门1"); |
|||
createDoor(100, 180, 2, 0, 500, 90, 700, "左门2"); |
|||
createDoor(100, 180, 2, 0, 700, 90, 700, "右门2"); |
|||
// 为墙面安装窗户 |
|||
createWindow(100, 100, 2, 0, -900, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, 900, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, -200, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, 200, 90, 700, "窗户"); |
|||
} |
|||
|
|||
setTimeout(function() { |
|||
doorOpenColse(true); |
|||
}, 2000); |
|||
setTimeout(function() { |
|||
initPeople(); |
|||
}, 2500); |
|||
|
|||
// 添加人物模型 |
|||
function initPeople() { |
|||
var loader = new THREE.GLTFLoader(); |
|||
loader.load('assets/models/man/man.gltf', function(result) { |
|||
console.log(result) |
|||
result.scene.scale.set(50, 50, 50); |
|||
// result.scene.rotation.y = Math.PI / 2; |
|||
peopleMesh = result.scene; |
|||
scene.add(peopleMesh); |
|||
|
|||
peopleMixer = new THREE.AnimationMixer(peopleMesh); |
|||
let AnimationAction = peopleMixer.clipAction(result.animations[0]); |
|||
AnimationAction.play(); |
|||
|
|||
motion() |
|||
}); |
|||
} |
|||
|
|||
function motion() { |
|||
// 通过类CatmullRomCurve3创建一个3D样条曲线 |
|||
curve = new THREE.CatmullRomCurve3([ |
|||
new THREE.Vector3(602, 3, 790), |
|||
new THREE.Vector3(597, 3, -3), |
|||
new THREE.Vector3(-605, 3, -3), |
|||
new THREE.Vector3(-602, 3, 790) |
|||
], false, "catmullrom", 0.01); |
|||
// 样条曲线均匀分割100分,返回51个顶点坐标 |
|||
var points = curve.getPoints(100); |
|||
var geometry = new THREE.Geometry(); |
|||
// 把从曲线轨迹上获得的顶点坐标赋值给几何体 |
|||
geometry.vertices = points |
|||
var material = new THREE.LineBasicMaterial({ |
|||
color: 0x4488ff |
|||
}); |
|||
var line = new THREE.Line(geometry, material); |
|||
// scene.add(line) |
|||
|
|||
// 通过Threejs的帧动画相关API播放网格模型沿着曲线做动画运动 |
|||
// 声明一个数组用于存储时间序列 |
|||
let arr = [] |
|||
for (let i = 0; i < 101; i++) { |
|||
arr.push(i) |
|||
} |
|||
// 生成一个时间序列 |
|||
var times = new Float32Array(arr); |
|||
|
|||
var posArr = [] |
|||
points.forEach(elem => { |
|||
posArr.push(elem.x, elem.y, elem.z) |
|||
}); |
|||
// 创建一个和时间序列相对应的位置坐标系列 |
|||
var values = new Float32Array(posArr); |
|||
// 创建一个帧动画的关键帧数据,曲线上的位置序列对应一个时间序列 |
|||
var posTrack = new THREE.KeyframeTrack('.position', times, values); |
|||
let duration = 101; |
|||
let clip = new THREE.AnimationClip("default", duration, [posTrack]); |
|||
mixer = new THREE.AnimationMixer(peopleMesh); |
|||
let AnimationAction = mixer.clipAction(clip); |
|||
AnimationAction.play(); |
|||
} |
|||
|
|||
function changeLookAt(t) { |
|||
// 当前点在线条上的位置 |
|||
var position = curve.getPointAt(t); |
|||
peopleMesh.position.copy(position); |
|||
if(position.z < 0) { |
|||
peopleMesh.rotation.y = Math.PI; |
|||
// camera.position.set(position.x + 200, 70, position.z); |
|||
} |
|||
if(position.z > 0 && position.x > 0) { |
|||
peopleMesh.rotation.y = Math.PI / 2; |
|||
// camera.position.set(position.x , 70, position.z+ 200); |
|||
} |
|||
if(position.z > 0 && position.x < 0) { |
|||
peopleMesh.rotation.y = -Math.PI / 2; |
|||
// camera.position.set(position.x , 70, position.z - 200); |
|||
} |
|||
// console.log(position) |
|||
// camera.position.set(position.x / 2, 69, position.z / 2); |
|||
camera.lookAt(position); |
|||
// camera.lookAt(position);659.0248303057256, y: 69.31162905236907, z: 921 |
|||
|
|||
|
|||
// 返回一个点t在曲线上位置向量的法线向量 |
|||
const tangent = curve.getTangentAt(t); |
|||
// 位置向量和切线向量相加即为所需朝向的点向量 |
|||
const lookAtVec = tangent.add(position); |
|||
// peopleMesh.lookAt(lookAtVec); |
|||
} |
|||
|
|||
//Secure 安全通道 |
|||
function initSecureModel() { |
|||
var planGeometry = new THREE.PlaneGeometry(680, 40); |
|||
textureSecure = new THREE.TextureLoader().load('assets/textures/roll.png'); |
|||
textureSecure.wrapS = THREE.RepeatWrapping |
|||
|
|||
var tubeMaterial = new THREE.MeshBasicMaterial({ |
|||
map: textureSecure, |
|||
transparent: true, |
|||
side: THREE.DoubleSide, |
|||
}); |
|||
|
|||
// 设置数组材质对象作为网格模型材质参数 |
|||
var obj = new THREE.Mesh(planGeometry, tubeMaterial); //网格模型对象Mesh |
|||
obj.position.z = 350; |
|||
obj.position.y = 1.5; |
|||
obj.position.x = 599; |
|||
obj.rotateX(Math.PI / 2.0); |
|||
obj.rotateZ(Math.PI / 2.0); |
|||
var obj2 = obj.clone(); |
|||
obj2.translateY(1200); |
|||
obj2.rotateZ(Math.PI); |
|||
|
|||
var geometry2 = new THREE.PlaneGeometry(1230, 40); |
|||
var obj3 = new THREE.Mesh(geometry2, tubeMaterial); |
|||
obj3.position.set(0, 1.5, -10); |
|||
obj3.rotation.x = -Math.PI / 2.0; |
|||
|
|||
var group = new THREE.Group(); |
|||
group.add(obj); |
|||
group.add(obj2); |
|||
group.add(obj3); |
|||
scene.add(group); |
|||
} |
|||
|
|||
//region 矩形区域 |
|||
function addPlane(x, z, width, length, scene) { |
|||
var LineMat = new THREE.MeshLambertMaterial(); |
|||
new THREE.TextureLoader().load("assets/textures/line.png", function(map) { |
|||
LineMat.map = map; |
|||
LineMat.needsUpdate = true; |
|||
}); |
|||
var lineWidth = 8 |
|||
var geometry = new THREE.PlaneGeometry(lineWidth, length); |
|||
var obj = new THREE.Mesh(geometry, LineMat); |
|||
obj.position.set(x, 1.5, z); |
|||
obj.rotation.x = -Math.PI / 2.0; |
|||
var obj2 = obj.clone(); |
|||
obj2.translateX(width); |
|||
|
|||
var geometry2 = new THREE.PlaneGeometry(lineWidth, width); |
|||
var obj3 = new THREE.Mesh(geometry2, LineMat); |
|||
obj3.position.set(x + width / 2, 1.5, z - length / 2 + lineWidth / 2); |
|||
obj3.rotation.x = -Math.PI / 2.0; |
|||
obj3.rotation.z = -Math.PI / 2.0; |
|||
var obj4 = obj3.clone(); |
|||
obj4.translateX(length - lineWidth); |
|||
|
|||
var group = new THREE.Group(); |
|||
group.add(obj); |
|||
group.add(obj2); |
|||
group.add(obj3); |
|||
group.add(obj4); |
|||
group.translateX(-width / 2); |
|||
scene.add(group); |
|||
} |
|||
|
|||
// 口号标语 |
|||
function initSloganModel() { |
|||
var planGeometry = new THREE.PlaneGeometry(500, 35); |
|||
texture = new THREE.TextureLoader().load('assets/textures/biaoyu.png'); |
|||
texture.wrapS = THREE.RepeatWrapping |
|||
|
|||
var tubeMaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
transparent: true, |
|||
side: THREE.DoubleSide, |
|||
}); |
|||
|
|||
// 设置数组材质对象作为网格模型材质参数 |
|||
var mesh = new THREE.Mesh(planGeometry, tubeMaterial); //网格模型对象Mesh |
|||
mesh.position.y = 175; |
|||
mesh.position.z = 710; |
|||
// mesh.rotateZ(3.14); |
|||
scene.add(mesh); //网格模型添加到场景中 |
|||
} |
|||
|
|||
//region 库区 |
|||
/** 放置虚线框区域和库区名称 */ |
|||
function addArea(x, z, width, length, scene, name, textColor, font_size, textposition) { |
|||
addPlane(x, z, width, length, scene); |
|||
|
|||
new THREE.FontLoader().load('font/FZYaoTi_Regular.json', function(font) { |
|||
//加入立体文字 |
|||
var text = new THREE.TextGeometry(name, { |
|||
// 设定文字字体 |
|||
font: font, |
|||
//尺寸 |
|||
size: font_size, |
|||
//厚度 |
|||
height: 0.01 |
|||
}); |
|||
text.computeBoundingBox(); |
|||
//3D文字材质 |
|||
var m = new THREE.MeshStandardMaterial({ |
|||
color: "#" + textColor |
|||
}); |
|||
var mesh = new THREE.Mesh(text, m) |
|||
if (textposition == "左对齐") { |
|||
mesh.position.x = x - width / 2 + 10; |
|||
} else if (textposition == "居中") { |
|||
mesh.position.x = x - 65; |
|||
} else if (textposition == "右对齐") { |
|||
mesh.position.x = x + width / 2 - 60; |
|||
} |
|||
mesh.position.y = 1.3; |
|||
mesh.position.z = z + length / 2 - 20; |
|||
mesh.rotation.x = -Math.PI / 2.0; |
|||
scene.add(mesh); |
|||
}); |
|||
} |
|||
|
|||
//创建墙纹理 |
|||
function createWallMaterail() { |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
})); //前 0xafc0ca :灰色 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0x9cb2d1 |
|||
})); //后 0x9cb2d1:淡紫 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xd6e4ec |
|||
})); //上 0xd6e4ec: 偏白色 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xd6e4ec |
|||
})); //下 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
})); //左 0xafc0ca :灰色 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
})); //右 |
|||
} |
|||
|
|||
//返回墙对象 |
|||
function returnWallObject(width, height, depth, angle, material, x, y, z, name) { |
|||
var cubeGeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.x = x; |
|||
cube.position.y = y; |
|||
cube.position.z = z; |
|||
cube.rotation.y += angle * Math.PI; |
|||
cube.name = name; |
|||
return cube; |
|||
} |
|||
|
|||
//墙上挖门,通过两个几何体生成BSP对象 |
|||
function createResultBsp(bsp, objects_cube) { |
|||
var material = new THREE.MeshPhongMaterial({ |
|||
color: 0x9cb2d1, |
|||
specular: 0x9cb2d1, |
|||
shininess: 30, |
|||
transparent: true, |
|||
opacity: 1 |
|||
}); |
|||
var BSP = new ThreeBSP(bsp); |
|||
for (var i = 0; i < objects_cube.length; i++) { |
|||
var less_bsp = new ThreeBSP(objects_cube[i]); |
|||
BSP = BSP.subtract(less_bsp); |
|||
} |
|||
var result = BSP.toMesh(material); |
|||
result.material.flatshading = THREE.FlatShading; |
|||
result.geometry.computeFaceNormals(); //重新计算几何体侧面法向量 |
|||
result.geometry.computeVertexNormals(); |
|||
result.material.needsUpdate = true; //更新纹理 |
|||
result.geometry.buffersNeedUpdate = true; |
|||
result.geometry.uvsNeedUpdate = true; |
|||
scene.add(result); |
|||
} |
|||
|
|||
//创建地板 |
|||
function createFloor() { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("assets/textures/floor.jpg", function(texture) { |
|||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; |
|||
texture.repeat.set(10, 10); |
|||
var floorGeometry = new THREE.BoxGeometry(2600, 1400, 1); |
|||
var floorMaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
}); |
|||
var floor = new THREE.Mesh(floorGeometry, floorMaterial); |
|||
floor.rotation.x = -Math.PI / 2; |
|||
floor.name = "地面"; |
|||
scene.add(floor); |
|||
}); |
|||
} |
|||
|
|||
//创建墙 |
|||
function createCubeWall(width, height, depth, angle, material, x, y, z, name) { |
|||
var cubeGeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.x = x; |
|||
cube.position.y = y; |
|||
cube.position.z = z; |
|||
cube.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
cube.name = name; |
|||
scene.add(cube); |
|||
} |
|||
|
|||
//创建门 |
|||
function createDoor(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
|
|||
var doorgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var doormaterial_left = new THREE.MeshPhongMaterial({ |
|||
map: loader.load("assets/textures/door_left.png") |
|||
}); |
|||
doormaterial_left.opacity = 1.0; |
|||
doormaterial_left.transparent = true; |
|||
var doormaterial_right = new THREE.MeshPhongMaterial({ |
|||
map: loader.load("assets/textures/door_right.png") |
|||
}); |
|||
doormaterial_right.opacity = 1.0; |
|||
doormaterial_right.transparent = true; |
|||
|
|||
var doormaterialArr = []; |
|||
if (name.indexOf("左门") > -1) { |
|||
doorgeometry.translate(50, 0, 0); |
|||
doormaterialArr = [doormaterial_left, doormaterial_left, doormaterial_left, |
|||
doormaterial_left, doormaterial_left, doormaterial_right |
|||
]; |
|||
} else { |
|||
doorgeometry.translate(-50, 0, 0); |
|||
doormaterialArr = [doormaterial_right, doormaterial_right, doormaterial_right, |
|||
doormaterial_right, doormaterial_right, doormaterial_left |
|||
]; |
|||
} |
|||
|
|||
var door = new THREE.Mesh(doorgeometry, doormaterialArr); |
|||
door.position.set(x, y, z); |
|||
door.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
door.name = name; |
|||
scene.add(door); |
|||
} |
|||
|
|||
//创建窗户 |
|||
function createWindow(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("assets/textures/window.png", function(texture) { |
|||
var windowgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var windowmaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
color: 0xffffff |
|||
}); |
|||
windowmaterial.opacity = 1.0; |
|||
windowmaterial.transparent = true; |
|||
var window = new THREE.Mesh(windowgeometry, windowmaterial); |
|||
window.position.set(x, y, z); |
|||
window.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
window.name = name; |
|||
scene.add(window); |
|||
}); |
|||
} |
|||
|
|||
// 键盘事件 |
|||
document.onkeydown = function(event) { |
|||
// 打开 |
|||
if (event.keyCode == 79) { |
|||
doorOpenColse(true); |
|||
} |
|||
// 关闭 |
|||
if (event.keyCode == 67) { |
|||
doorOpenColse(false); |
|||
} |
|||
} |
|||
|
|||
// 门打开关闭 |
|||
function doorOpenColse(bool) { |
|||
|
|||
var l1 = scene.getObjectByName("左门1"); |
|||
var l2 = scene.getObjectByName("左门2"); |
|||
var r1 = scene.getObjectByName("右门1"); |
|||
var r2 = scene.getObjectByName("右门2"); |
|||
// 打开 |
|||
if (bool) { |
|||
new TWEEN.Tween({ |
|||
lv: 0, |
|||
rv: 0, |
|||
}) |
|||
.to({ |
|||
lv: -0.5 * Math.PI, |
|||
rv: 0.5 * Math.PI, |
|||
}, 1000) |
|||
.easing(TWEEN.Easing.Bounce.Out) |
|||
.onUpdate(function() { |
|||
l1.rotation.y = this.lv; |
|||
l2.rotation.y = this.lv; |
|||
r1.rotation.y = this.rv; |
|||
r2.rotation.y = this.rv; |
|||
}) |
|||
.start(); |
|||
} |
|||
// 关闭 |
|||
if (!bool) { |
|||
new TWEEN.Tween({ |
|||
lv: -0.5 * Math.PI, |
|||
rv: 0.5 * Math.PI, |
|||
}) |
|||
.to({ |
|||
lv: 0, |
|||
rv: 0, |
|||
}, 1000) |
|||
.easing(TWEEN.Easing.Bounce.Out) |
|||
.onUpdate(function() { |
|||
l1.rotation.y = this.lv; |
|||
l2.rotation.y = this.lv; |
|||
r1.rotation.y = this.rv; |
|||
r2.rotation.y = this.rv; |
|||
}) |
|||
.start(); |
|||
} |
|||
} |
|||
|
|||
// 拾取对象 |
|||
function pickupObjects(event) { |
|||
// 点击屏幕创建一个向量 |
|||
var raycaster = new THREE.Raycaster(); |
|||
var vector = new THREE.Vector2((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window |
|||
.innerHeight) * 2 + 1); |
|||
var fxl = new THREE.Vector3(0, 1, 0); |
|||
var groundplane = new THREE.Plane(fxl, 0); |
|||
raycaster.setFromCamera(vector, camera); |
|||
var ray = raycaster.ray; |
|||
let intersects = ray.intersectPlane(groundplane); |
|||
console.log(intersects) |
|||
|
|||
|
|||
// 点击屏幕创建一个向量 |
|||
var vector1 = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window |
|||
.innerHeight) * 2 + 1, 0.5); |
|||
vector1 = vector1.unproject(camera); // 将屏幕的坐标转换成三维场景中的坐标 |
|||
var raycaster = new THREE.Raycaster(camera.position, vector1.sub(camera.position).normalize()); |
|||
var intersects1 = raycaster.intersectObjects(scene.children, true); |
|||
if (intersects1.length > 0) { |
|||
console.log(intersects1) |
|||
// intersects1[0].object.material.color.set("#ff0000"); |
|||
} |
|||
} |
|||
document.addEventListener('click', pickupObjects, false); //监听单击拾取对象初始化球体 |
|||
|
|||
var clock = new THREE.Clock(); //声明一个时钟对象 |
|||
const loopTime = 50 * 1000; // loopTime: 循环一圈的时间 |
|||
function renderScene() { |
|||
orbit.update(); |
|||
TWEEN.update(); |
|||
// 使用requestAnimationFrame函数进行渲染 |
|||
requestAnimationFrame(renderScene); |
|||
renderer.render(scene, camera); |
|||
// 更新帧动画的时间 |
|||
if (mixer) { |
|||
// mixer.update(clock.getDelta()); |
|||
} |
|||
if (peopleMixer) { |
|||
peopleMixer.update(clock.getDelta()); |
|||
} |
|||
|
|||
if (curve) { |
|||
let time = Date.now(); |
|||
let t = (time % loopTime) / loopTime; // 计算当前时间进度百分比 |
|||
changeLookAt(t); |
|||
} |
|||
|
|||
if (textureSecure) { |
|||
texture.offset.x += 0.004; |
|||
textureSecure.offset.x += 0.0005; |
|||
} |
|||
// console.log(camera.position) |
|||
} |
|||
|
|||
// 渲染的场景 |
|||
renderer.render(scene, camera); |
|||
} |
|||
window.onload = init; |
|||
|
|||
// 随着窗体的变化修改场景 |
|||
function onResize() { |
|||
camera.aspect = window.innerWidth / window.innerHeight; |
|||
camera.updateProjectionMatrix(); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
} |
|||
// 监听窗体调整大小事件 |
|||
window.addEventListener('resize', onResize, false); |
|||
</script> |
|||
|
|||
|
|||
</body></html> |
@ -0,0 +1,65 @@ |
|||
/** |
|||
* 这是模型的静态常量配置 |
|||
* 和货架的配置(一般要从数据库读取,这里仅做演示) |
|||
* @author 谢宁, Created on 2020-01-07 |
|||
*/ |
|||
/** ***************************************************************** */ |
|||
|
|||
var PLANE_LENGTH = 24; //货架板面长度
|
|||
var PLANE_WIDTH = 55; //货架板面宽度
|
|||
var PLANE_HEIGHT = 2; //货架板面高度
|
|||
var HOLDER_LENGTH = 2; //支架长度
|
|||
var HOLDER_WIDTH = 2; //支架宽度
|
|||
var HOLDER_HEIGHT = 25; //支架高度
|
|||
var LAYER_NUM = 3; //货架层数
|
|||
var COLUMN_NUM = 2; //货架每层列数
|
|||
var BOX_SIZE = 16; //货物的大小(立方体)
|
|||
|
|||
//货架数组
|
|||
var shelf_list = new Array(); |
|||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A1',shelfName:'货架A1',x:-100,y:27,z:0}); |
|||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A2',shelfName:'货架A2',x:0,y:27,z:0}); |
|||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A3',shelfName:'货架A3',x:100,y:27,z:0}); |
|||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A4',shelfName:'货架A4',x:200,y:27,z:0}); |
|||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A5',shelfName:'货架A5',x:300,y:27,z:0}); |
|||
shelf_list.push({StorageZoneId:'Z1',shelfId:'A6',shelfName:'货架A6',x:400,y:27,z:0}); |
|||
|
|||
function GET_PLANE_LENGTH(){ |
|||
return PLANE_LENGTH; |
|||
} |
|||
|
|||
function GET_PLANE_WIDTH(){ |
|||
return PLANE_WIDTH; |
|||
} |
|||
|
|||
function GET_PLANE_HEIGHT(){ |
|||
return PLANE_HEIGHT; |
|||
} |
|||
|
|||
function GET_HOLDER_LENGTH(){ |
|||
return HOLDER_LENGTH; |
|||
} |
|||
|
|||
function GET_HOLDER_WIDTH(){ |
|||
return HOLDER_WIDTH; |
|||
} |
|||
|
|||
function GET_HOLDER_HEIGHT(){ |
|||
return HOLDER_HEIGHT; |
|||
} |
|||
|
|||
function GET_LAYER_NUM(){ |
|||
return LAYER_NUM; |
|||
} |
|||
|
|||
function GET_COLUMN_NUM(){ |
|||
return COLUMN_NUM; |
|||
} |
|||
|
|||
function GET_BOX_SIZE(){ |
|||
return BOX_SIZE; |
|||
} |
|||
|
|||
function GET_SHELF_LIST(){ |
|||
return shelf_list; |
|||
} |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,67 @@ |
|||
(function(){var h={},mt={},c={id:"b892a7413f8edd0cd98c6bdffda3481c",dm:["zuoben.top"],js:"tongji.baidu.com/hm-web/js/",etrk:[],cetrk:[],cptrk:[],icon:'',ctrk:["%5b%22http%3a%5c%2f%5c%2fzuoben.top%5c%2fmain.html%22%5d"],vdur:1800000,age:31536000000,qiao:0,pt:0,spa:0,aet:'',hca:'5410B84C334F9C01',ab:'0',v:1,brd:'Wj0OJeC62A7DeA7jwdzrhhlxOHi5lRnTH6aooR4PLNkdCoSMOQm4EG0Pax8g0KuMfYMcogKK3gOTH4DF_2uxOjjg8UtVJeC6EG0Ptf8g0f5'};var s=void 0,t=!0,u=null,x=!1;mt.cookie={};mt.cookie.set=function(e,a,b){var k;b.C&&(k=new Date,k.setTime(k.getTime()+b.C));document.cookie=e+"="+a+(b.domain?"; domain="+b.domain:"")+(b.path?"; path="+b.path:"")+(k?"; expires="+k.toGMTString():"")+(b.dc?"; secure":"")};mt.cookie.get=function(e){return(e=RegExp("(^| )"+e+"=([^;]*)(;|$)").exec(document.cookie))?e[2]:u}; |
|||
mt.cookie.rb=function(e,a){try{var b="Hm_ck_"+ +new Date;mt.cookie.set(b,"42",{domain:e,path:a,C:s});var k="42"===mt.cookie.get(b)?"1":"0";mt.cookie.set(b,"",{domain:e,path:a,C:-1});return k}catch(d){return"0"}};mt.event={};mt.event.c=function(e,a,b,k){e.addEventListener?e.addEventListener(a,b,k||x):e.attachEvent&&e.attachEvent("on"+a,function(d){b.call(e,d)})}; |
|||
(function(){var e=mt.event;mt.lang={};mt.lang.i=function(a,b){return"[object "+b+"]"==={}.toString.call(a)};mt.lang.j=function(a){return mt.lang.i(a,"Function")};mt.lang.J=function(a){return mt.lang.i(a,"Object")};mt.lang.Wb=function(a){return mt.lang.i(a,"Number")&&isFinite(a)};mt.lang.Z=function(a){return mt.lang.i(a,"String")};mt.lang.isArray=function(a){return mt.lang.i(a,"Array")};mt.lang.n=function(a){return a.replace?a.replace(/'/g,"'0").replace(/\*/g,"'1").replace(/!/g,"'2"):a};mt.lang.trim= |
|||
function(a){return a.replace(/^\s+|\s+$/g,"")};mt.lang.find=function(a,b,k){if(mt.lang.isArray(a)&&mt.lang.j(b))for(var d=a.length,f=0;f<d;f++)if(f in a&&b.call(k||a,a[f],f))return a[f];return u};mt.lang.X=function(a,b){return mt.lang.find(a,function(k){return k===b})!=u};mt.lang.filter=function(a,b){var k=-1,d=0,f=a==u?0:a.length,g=[];if(mt.lang.j(b))for(;++k<f;){var l=a[k];b(l,k,a)&&(g[d++]=l)}return g};mt.lang.unique=function(a,b){var k=a.length,d=a.slice(0),f,g;for(mt.lang.j(b)||(b=function(b, |
|||
d){return b===d});0<--k;){g=d[k];for(f=k;f--;)if(b(g,d[f])){d.splice(k,1);break}}return d};mt.lang.Zb=function(a,b){function k(b){b=(d+d+Number(b).toString(2)).slice(-64);return[parseInt(b.slice(0,32),2),parseInt(b.slice(-32),2)]}var d="00000000000000000000000000000000",f=k(a),g=k(b);return parseInt((d+((f[0]|g[0])>>>0).toString(2)).slice(-32)+(d+((f[1]|g[1])>>>0).toString(2)).slice(-32),2)};mt.lang.extend=function(a){for(var b=Array.prototype.slice.call(arguments,1),k=0;k<b.length;k++){var d=b[k], |
|||
f;for(f in d)Object.prototype.hasOwnProperty.call(d,f)&&d[f]&&(a[f]=d[f])}return a};mt.lang.Ob=function(a){function b(b,d){var a=window.history,g=a[b];a[b]=function(){g.apply(a,arguments);mt.lang.j(d)&&d()}}b("pushState",function(){a()});b("replaceState",function(){a()});e.c(window,window.history.pushState?"popstate":"hashchange",function(){a()})};return mt.lang})();mt.url={};mt.url.f=function(e,a){var b=e.match(RegExp("(^|&|\\?|#)("+a+")=([^&#]*)(&|$|#)",""));return b?b[3]:u}; |
|||
mt.url.Sa=function(e){return(e=e.match(/^(https?:\/\/)?([^\/\?#]*)/))?e[2].replace(/.*@/,""):u};mt.url.V=function(e){return(e=mt.url.Sa(e))?e.replace(/:\d+$/,""):e};mt.url.pb=function(e){var a=document.location.href,a=a.replace(/^https?:\/\//,"");return 0===a.indexOf(e)};mt.url.qb=function(e,a){e="."+e.replace(/:\d+/,"");a="."+a.replace(/:\d+/,"");var b=e.indexOf(a);return-1<b&&b+a.length===e.length}; |
|||
(function(){var e=mt.lang,a=mt.url;mt.d={};mt.d.La=function(b){return document.getElementById(b)};mt.d.Vb=function(b){if(!b)return u;try{b=String(b);if(0===b.indexOf("!HMCQ!"))return b;if(0===b.indexOf("!HMCC!"))return document.querySelector(b.substring(6,b.length));for(var k=b.split(">"),d=document.body,a=k.length-1;0<=a;a--)if(-1<k[a].indexOf("#")){var g=k[a].split("#")[1];(d=document.getElementById(g))||(d=document.getElementById(decodeURIComponent(g)));k=k.splice(a+1,k.length-(a+1));break}for(b= |
|||
0;d&&b<k.length;){var l=String(k[b]).toLowerCase();if(!("html"===l||"body"===l)){var a=0,e=k[b].match(/\[(\d+)\]/i),g=[];if(e)a=e[1]-1,l=l.split("[")[0];else if(1!==d.childNodes.length){for(var p=0,n=0,m=d.childNodes.length;n<m;n++){var q=d.childNodes[n];1===q.nodeType&&q.nodeName.toLowerCase()===l&&p++;if(1<p)return u}if(1!==p)return u}for(p=0;p<d.childNodes.length;p++)1===d.childNodes[p].nodeType&&d.childNodes[p].nodeName.toLowerCase()===l&&g.push(d.childNodes[p]);if(!g[a])return u;d=g[a]}b++}return d}catch(v){return u}}; |
|||
mt.d.fa=function(b,a){var d=[],f=[];if(!b)return f;for(;b.parentNode!=u;){for(var g=0,l=0,e=b.parentNode.childNodes.length,p=0;p<e;p++){var n=b.parentNode.childNodes[p];if(n.nodeName===b.nodeName&&(g++,n===b&&(l=g),0<l&&1<g))break}if((e=""!==b.id)&&a){d.unshift("#"+encodeURIComponent(b.id));break}else e&&(e="#"+encodeURIComponent(b.id),e=0<d.length?e+">"+d.join(">"):e,f.push(e)),d.unshift(encodeURIComponent(String(b.nodeName).toLowerCase())+(1<g?"["+l+"]":""));b=b.parentNode}f.push(d.join(">"));return f}; |
|||
mt.d.Xa=function(b){return(b=mt.d.fa(b,t))&&b.length?String(b[0]):""};mt.d.Wa=function(b){return mt.d.fa(b,x)};mt.d.Ma=function(b){var a;for(a="A";(b=b.parentNode)&&1==b.nodeType;)if(b.tagName==a)return b;return u};mt.d.Pa=function(b){return 9===b.nodeType?b:b.ownerDocument||b.document};mt.d.Ua=function(b){var a={top:0,left:0};if(!b)return a;var d=mt.d.Pa(b).documentElement;"undefined"!==typeof b.getBoundingClientRect&&(a=b.getBoundingClientRect());return{top:a.top+(window.pageYOffset||d.scrollTop)- |
|||
(d.clientTop||0),left:a.left+(window.pageXOffset||d.scrollLeft)-(d.clientLeft||0)}};mt.d.gc=function(b,a){if(b)for(var d=b.childNodes,f=0,g=d.length;f<g;f++){var e=d[f];if(e&&3===e.nodeType)return d=e.textContent||e.innerText||e.nodeValue||"",e.textContent?e.textContent=a:e.innerText?e.innerText=a:e.nodeValue=a,d}};mt.d.ec=function(b,a){if(!b)return{};var d={};a=a||{};for(var f in a)a.hasOwnProperty(f)&&a[f]!==s&&(d[f]=b.getAttribute(f)||"",b.setAttribute(f,a[f]));return d};mt.d.getAttribute=function(b, |
|||
a){var d=b.getAttribute&&b.getAttribute(a)||u;if(!d&&b.attributes&&b.attributes.length)for(var f=b.attributes,e=f.length,l=0;l<e;l++)f[l].nodeName===a&&(d=f[l].nodeValue);return d};mt.d.Qa=function(b){var a="document";b.tagName!==s&&(a=b.tagName);return a.toLowerCase()};mt.d.Za=function(b){var a="";b.textContent?a=e.trim(b.textContent):b.innerText&&(a=e.trim(b.innerText));a&&(a=a.replace(/\s+/g," ").substring(0,255));return a};mt.d.Ub=function(b,k){var d;e.Z(b)&&0===String(b).indexOf("!HMCQ!")?(d= |
|||
String(b),d=a.f(document.location.href,d.substring(6,d.length))):e.Z(b)||(d=mt.d.Qa(b),"input"===d&&k&&("button"===b.type||"submit"===b.type)?d=e.trim(b.value)||"":"input"===d&&!k&&"password"!==b.type?d=e.trim(b.value)||"":"img"===d?(d=mt.d.getAttribute,d=d(b,"alt")||d(b,"title")||d(b,"src")):d="body"===d||"html"===d?["(hm-default-content-for-",d,")"].join(""):mt.d.Za(b));return String(d||"").substring(0,255)};(function(){(mt.d.ac=function(){function b(){if(!b.K){b.K=t;for(var a=0,d=f.length;a<d;a++)f[a]()}} |
|||
function a(){try{document.documentElement.doScroll("left")}catch(d){setTimeout(a,1);return}b()}var d=x,f=[],e;document.addEventListener?e=function(){document.removeEventListener("DOMContentLoaded",e,x);b()}:document.attachEvent&&(e=function(){"complete"===document.readyState&&(document.detachEvent("onreadystatechange",e),b())});(function(){if(!d)if(d=t,"complete"===document.readyState)b.K=t;else if(document.addEventListener)document.addEventListener("DOMContentLoaded",e,x),window.addEventListener("load", |
|||
b,x);else if(document.attachEvent){document.attachEvent("onreadystatechange",e);window.attachEvent("onload",b);var f=x;try{f=window.frameElement==u}catch(r){}document.documentElement.doScroll&&f&&a()}})();return function(a){b.K?a():f.push(a)}}()).K=x})();return mt.d})(); |
|||
(function(){var e=mt.event;mt.e={};mt.e.mb=/msie (\d+\.\d+)/i.test(navigator.userAgent);mt.e.cookieEnabled=navigator.cookieEnabled;mt.e.javaEnabled=navigator.javaEnabled();mt.e.language=navigator.language||navigator.browserLanguage||navigator.systemLanguage||navigator.userLanguage||"";mt.e.Ab=(window.screen.width||0)+"x"+(window.screen.height||0);mt.e.colorDepth=window.screen.colorDepth||0;mt.e.Ya=function(){var a;a=a||document;return parseInt(window.pageYOffset||a.documentElement.scrollTop||a.body&& |
|||
a.body.scrollTop||0,10)};mt.e.$a=function(){var a=document;return parseInt(window.innerHeight||a.documentElement.clientHeight||a.body&&a.body.clientHeight||0,10)};mt.e.W=function(){return mt.e.Ya()+mt.e.$a()};mt.e.sa=0;mt.e.bb=function(){var a=document;return parseInt(window.innerWidth||a.documentElement.clientWidth||a.body.offsetWidth||0,10)};mt.e.orientation=0;(function(){function a(){var a=0;window.orientation!==s&&(a=window.orientation);screen&&(screen.orientation&&screen.orientation.angle!== |
|||
s)&&(a=screen.orientation.angle);mt.e.orientation=a;mt.e.sa=mt.e.bb()}a();e.c(window,"orientationchange",a)})();return mt.e})();mt.w={};mt.w.parse=function(e){return(new Function("return ("+e+")"))()}; |
|||
mt.w.stringify=function(){function e(a){/["\\\x00-\x1f]/.test(a)&&(a=a.replace(/["\\\x00-\x1f]/g,function(a){var f=b[a];if(f)return f;f=a.charCodeAt();return"\\u00"+Math.floor(f/16).toString(16)+(f%16).toString(16)}));return'"'+a+'"'}function a(a){return 10>a?"0"+a:a}var b={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};return function(b){switch(typeof b){case "undefined":return"undefined";case "number":return isFinite(b)?String(b):"null";case "string":return e(b);case "boolean":return String(b); |
|||
default:if(b===u)return"null";if(b instanceof Array){var d=["["],f=b.length,g,l,r;for(l=0;l<f;l++)switch(r=b[l],typeof r){case "undefined":case "function":case "unknown":break;default:g&&d.push(","),d.push(mt.w.stringify(r)),g=1}d.push("]");return d.join("")}if(b instanceof Date)return'"'+b.getFullYear()+"-"+a(b.getMonth()+1)+"-"+a(b.getDate())+"T"+a(b.getHours())+":"+a(b.getMinutes())+":"+a(b.getSeconds())+'"';g=["{"];l=mt.w.stringify;for(f in b)if(Object.prototype.hasOwnProperty.call(b,f))switch(r= |
|||
b[f],typeof r){case "undefined":case "unknown":case "function":break;default:d&&g.push(","),d=1,g.push(l(f)+":"+l(r))}g.push("}");return g.join("")}}}();mt.localStorage={};mt.localStorage.Q=function(){if(!mt.localStorage.g)try{mt.localStorage.g=document.createElement("input"),mt.localStorage.g.type="hidden",mt.localStorage.g.style.display="none",mt.localStorage.g.addBehavior("#default#userData"),document.getElementsByTagName("head")[0].appendChild(mt.localStorage.g)}catch(e){return x}return t}; |
|||
mt.localStorage.set=function(e,a,b){var k=new Date;k.setTime(k.getTime()+(b||31536E6));try{window.localStorage?(a=k.getTime()+"|"+a,window.localStorage.setItem(e,a)):mt.localStorage.Q()&&(mt.localStorage.g.expires=k.toUTCString(),mt.localStorage.g.load(document.location.hostname),mt.localStorage.g.setAttribute(e,a),mt.localStorage.g.save(document.location.hostname))}catch(d){}}; |
|||
mt.localStorage.get=function(e){if(window.localStorage){if(e=window.localStorage.getItem(e)){var a=e.indexOf("|"),b=e.substring(0,a)-0;if(b&&b>(new Date).getTime())return e.substring(a+1)}}else if(mt.localStorage.Q())try{return mt.localStorage.g.load(document.location.hostname),mt.localStorage.g.getAttribute(e)}catch(k){}return u}; |
|||
mt.localStorage.remove=function(e){if(window.localStorage)window.localStorage.removeItem(e);else if(mt.localStorage.Q())try{mt.localStorage.g.load(document.location.hostname),mt.localStorage.g.removeAttribute(e),mt.localStorage.g.save(document.location.hostname)}catch(a){}};mt.sessionStorage={};mt.sessionStorage.set=function(e,a){try{window.sessionStorage&&window.sessionStorage.setItem(e,a)}catch(b){}}; |
|||
mt.sessionStorage.get=function(e){try{return window.sessionStorage?window.sessionStorage.getItem(e):u}catch(a){return u}};mt.sessionStorage.remove=function(e){try{window.sessionStorage&&window.sessionStorage.removeItem(e)}catch(a){}}; |
|||
(function(){var e=mt.w;mt.A={};mt.A.log=function(a,b){var e=new Image,d="mini_tangram_log_"+Math.floor(2147483648*Math.random()).toString(36);window[d]=e;e.onload=function(){e.onload=u;e=window[d]=u;b&&b(a)};e.src=a};mt.A.get=function(a,b){return mt.A.wa({url:a,method:"GET",data:b.data,timeout:b.timeout,noCache:t,success:b.success,fail:b.fail})};mt.A.wa=function(a){function b(a){var b=[],d;for(d in a)a.hasOwnProperty(d)&&b.push(encodeURIComponent(d)+"="+encodeURIComponent(a[d]));return b.join("&")} |
|||
function k(b){var d=a[b];if(d)if(q&&clearTimeout(q),"success"!==b)d&&d(m);else{var f;try{f=e.parse(m.responseText)}catch(g){d&&d(m);return}d&&d(m,f)}}a=a||{};var d=a.data;"object"===typeof d&&(d=b(a.data||{}));var f=a.url,g=(a.method||"GET").toUpperCase(),l=a.headers||{},r=a.timeout||0,p=a.noCache||x,n=a.withCredentials||x,m,q;try{a:if(window.XMLHttpRequest)m=new XMLHttpRequest;else{try{m=new ActiveXObject("Microsoft.XMLHTTP");break a}catch(v){}m=s}"GET"===g&&(d&&(f+=(0<=f.indexOf("?")?"&":"?")+d, |
|||
d=u),p&&(f+=(0<=f.indexOf("?")?"&":"?")+"b"+ +new Date+"=1"));m.open(g,f,t);m.onreadystatechange=function(){if(4===m.readyState){var a=0;try{a=m.status}catch(b){k("fail");return}200<=a&&300>a||304===a||1223===a?k("success"):k("fail")}};for(var w in l)l.hasOwnProperty(w)&&m.setRequestHeader(w,l[w]);n&&(m.withCredentials=t);r&&(q=setTimeout(function(){m.onreadystatechange=function(){};m.abort();k("fail")},r));m.send(d)}catch(A){k("fail")}return m};return mt.A})(); |
|||
h.o={kb:"http://tongji.baidu.com/hm-web/welcome/ico",aa:"hm.baidu.com/hm.gif",xa:/^(tongji|hmcdn).baidu.com$/,Gb:"tongji.baidu.com",hb:"hmmd",ib:"hmpl",Jb:"utm_medium",gb:"hmkw",Lb:"utm_term",eb:"hmci",Ib:"utm_content",jb:"hmsr",Kb:"utm_source",fb:"hmcu",Hb:"utm_campaign",ka:0,B:Math.round(+new Date/1E3),protocol:"https:"===document.location.protocol?"https:":"http:",L:"https:",Da:6E5,bc:5E3,Ea:5,ca:1024,G:2147483647,ra:"hca cc cf ci ck cl cm cp cu cw ds vl ep et ja ln lo lt rnd si su v cv lv api sn r ww p u tt".split(" "), |
|||
ga:t,Pb:{id:"data-hm-id",Tb:"data-hm-class",jc:"data-hm-xpath",content:"data-hm-content",hc:"data-hm-tag",link:"data-hm-link"},Rb:"data-hm-enabled",Qb:"data-hm-disabled",xb:"https://hmcdn.baidu.com/static/tongji/plugins/",na:["UrlChangeTracker"],Nb:{$b:0,ic:1,Xb:2},Yb:"https://fclog.baidu.com/log/ocpcagl?type=behavior&emd=euc"}; |
|||
(function(){var e={t:{},c:function(a,b){this.t[a]=this.t[a]||[];this.t[a].push(b)},k:function(a,b){this.t[a]=this.t[a]||[];for(var e=this.t[a].length,d=0;d<e;d++)this.t[a][d](b)}};return h.s=e})(); |
|||
(function(){var e=mt.lang,a=/^https?:\/\//,b={Oa:function(a){var b;try{b=JSON.parse(decodeURIComponent(a[0]))}catch(f){}return b},la:function(a,d){return b.ma(h.b&&h.b.a&&h.b.a.u,a,d)||b.ma(document.location.href,a,d)},ma:function(b,d,f){if(b===s)return x;a.test(d)||(b=b.replace(a,""));d=d.replace(/\/$/,"");b=b.replace(/\/$/,"");f&&(b=b.replace(/^(https?:\/\/)?www\./,"$1"));return RegExp("^"+d.replace(/[?.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*")+"$").test(b)},H:function(a,d){var f=b.Oa(a);if(!e.i(f, |
|||
"Undefined")){if(e.isArray(f)){for(var g=0;g<f.length;g++)if(b.la(f[g],d))return t;return x}if(e.J(f)){var g=[],l;for(l in f)f.hasOwnProperty(l)&&b.la(l,d)&&(g=g.concat(f[l]));return g}}}};return h.S=b})(); |
|||
(function(){function e(b,e){var d=document.createElement("script");d.charset="utf-8";a.j(e)&&(d.readyState?d.onreadystatechange=function(){if("loaded"===d.readyState||"complete"===d.readyState)d.onreadystatechange=u,e()}:d.onload=function(){e()});d.src=b;var f=document.getElementsByTagName("script")[0];f.parentNode.insertBefore(d,f)}var a=mt.lang;return h.load=e})(); |
|||
(function(){var e=h.o,a={D:function(){if(""!==c.icon){var a=c.icon.split("|"),k=e.kb+"?s="+c.id,d="https://hmcdn.baidu.com/static"+a[0]+".gif";document.write("swf"===a[1]||"gif"===a[1]?'<a href="'+k+'" target="_blank"><img border="0" src="'+d+'" width="'+a[2]+'" height="'+a[3]+'"></a>':'<a href="'+k+'" target="_blank">'+a[0]+"</a>")}}};h.s.c("pv-b",a.D);return a})(); |
|||
(function(){var e=mt.url,a=mt.cookie,b=mt.localStorage,k=mt.sessionStorage,d={getData:function(d){try{return a.get(d)||k.get(d)||b.get(d)}catch(e){}},setData:function(f,e,l){try{a.set(f,e,{domain:d.I(),path:d.U(),C:l}),l?b.set(f,e,l):k.set(f,e)}catch(r){}},removeData:function(e){try{a.set(e,"",{domain:d.I(),path:d.U(),C:-1}),k.remove(e),b.remove(e)}catch(g){}},I:function(){for(var a=document.location.hostname,b=0,d=c.dm.length;b<d;b++)if(e.qb(a,c.dm[b]))return c.dm[b].replace(/(:\d+)?[/?#].*/,""); |
|||
return a},U:function(){for(var a=0,b=c.dm.length;a<b;a++){var d=c.dm[a];if(-1<d.indexOf("/")&&e.pb(d))return d.replace(/^[^/]+(\/.*)/,"$1")+"/"}return"/"}};return h.R=d})(); |
|||
(function(){var e=mt.lang,a=mt.d,b=h.S,k={Ha:function(d,e){return function(g){var l=g.target||g.srcElement;if(l){var r=b.H(e)||[],p=l.getAttribute(d.P);g=g.clientX+":"+g.clientY;if(p&&p===g)l.removeAttribute(d.P);else if(0<r.length&&(l=a.Wa(l))&&l.length)if(r=l.length,p=l[l.length-1],1E4>r*p.split(">").length)for(p=0;p<r;p++)k.qa(d,l[p]);else k.qa(d,p)}}},qa:function(a,b){for(var g={},l=String(b).split(">").length,k=0;k<l;k++)g[b]="",/\[1\]$/.test(b)&&(g[b.substring(0,b.lastIndexOf("["))]=""),/\]$/.test(b)|| |
|||
(g[b+"[1]"]=""),b=b.substring(0,b.lastIndexOf(">"));a&&(e.J(a)&&a.ba)&&a.ba(g)},zb:function(a,b){return function(e){(e.target||e.srcElement).setAttribute(a.P,e.clientX+":"+e.clientY);a&&a.N&&(b?a.N(b):a.N("#"+encodeURIComponent(this.id),e.type))}}};return h.Ia=k})(); |
|||
(function(){var e=mt.d,a=mt.event,b=h.S,k=h.Ia,d={P:"HM_fix",ua:function(){a.c(document,"click",k.Ha(d,c.etrk),t);if(!document.addEventListener)for(var f=b.H(c.etrk)||[],g=0;g<f.length;g++){var l=f[g];-1===l.indexOf(">")&&(0===l.indexOf("#")&&(l=l.substring(1)),(l=e.La(l))&&a.c(l,"click",k.zb(d),t))}},ba:function(a){for(var e=b.H(c.etrk)||[],k=0;k<e.length;k++){var r=e[k];a.hasOwnProperty(r)&&d.N(r)}},N:function(a,b){h.b.a.et=1;h.b.a.ep="{id:"+a+",eventType:"+(b||"click")+"}";h.b.m()}};h.s.c("pv-b", |
|||
d.ua);return d})(); |
|||
(function(){var e=mt.d,a=mt.lang,b=mt.event,k=mt.e,d=h.o,f=h.S,g=[],l={ta:function(){c.ctrk&&0<c.ctrk.length&&(b.c(document,"mouseup",l.Ca()),b.c(window,"unload",function(){l.M()}),setInterval(function(){l.M()},d.Da))},Ca:function(){return function(a){if(f.H(c.ctrk,t)&&(a=l.Na(a),""!==a)){var b=(d.L+"//"+d.aa+"?"+h.b.pa().replace(/ep=[^&]*/,"ep="+encodeURIComponent(a))).length;b+(d.G+"").length>d.ca||(b+encodeURIComponent(g.join("!")+(g.length?"!":"")).length+(d.G+"").length>d.ca&&l.M(),g.push(a), |
|||
(g.length>=d.Ea||/\*a\*/.test(a))&&l.M())}}},Na:function(b){var d=b.target||b.srcElement,f,m;k.mb?(m=Math.max(document.documentElement.scrollTop,document.body.scrollTop),f=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft),f=b.clientX+f,m=b.clientY+m):(f=b.pageX,m=b.pageY);b=l.Ta(b,d,f,m);var q=window.innerWidth||document.documentElement.clientWidth||document.body.offsetWidth;switch(c.align){case 1:f-=q/2;break;case 2:f-=q}q=[];q.push(f);q.push(m);q.push(b.ub);q.push(b.vb);q.push(b.yb); |
|||
q.push(a.n(b.wb));q.push(b.Mb);q.push(b.cb);(d="a"===(d.tagName||"").toLowerCase()?d:e.Ma(d))?(q.push("a"),q.push(a.n(encodeURIComponent(d.href)))):q.push("b");return q.join("*")},Ta:function(b,d,f,m){b=e.Xa(d);var q=0,g=0,w=0,l=0;if(d&&(q=d.offsetWidth||d.clientWidth,g=d.offsetHeight||d.clientHeight,l=e.Ua(d),w=l.left,l=l.top,a.j(d.getBBox)&&(g=d.getBBox(),q=g.width,g=g.height),"html"===(d.tagName||"").toLowerCase()))q=Math.max(q,d.clientWidth),g=Math.max(g,d.clientHeight);return{ub:Math.round(100* |
|||
((f-w)/q)),vb:Math.round(100*((m-l)/g)),yb:k.orientation,wb:b,Mb:q,cb:g}},M:function(){0!==g.length&&(h.b.a.et=2,h.b.a.ep=g.join("!"),h.b.m(),g=[])}};h.s.c("pv-b",l.ta);return l})(); |
|||
(function(){function e(){return function(){h.b.a.et=3;h.b.a.ep=h.T.Va()+","+h.T.Ra();h.b.a.hca=c.hca;h.b.m()}}function a(){clearTimeout(C);var b;w&&(b="visible"==document[w]);A&&(b=!document[A]);l="undefined"==typeof b?t:b;if((!g||!r)&&l&&p)v=t,m=+new Date;else if(g&&r&&(!l||!p))v=x,q+=+new Date-m;g=l;r=p;C=setTimeout(a,100)}function b(b){var a=document,d="";if(b in a)d=b;else for(var m=["webkit","ms","moz","o"],e=0;e<m.length;e++){var f=m[e]+b.charAt(0).toUpperCase()+b.slice(1);if(f in a){d=f;break}}return d} |
|||
function k(b){if(!("focus"==b.type||"blur"==b.type)||!(b.target&&b.target!=window))p="focus"==b.type||"focusin"==b.type?t:x,a()}var d=mt.event,f=h.s,g=t,l=t,r=t,p=t,n=+new Date,m=n,q=0,v=t,w=b("visibilityState"),A=b("hidden"),C;a();(function(){var b=w.replace(/[vV]isibilityState/,"visibilitychange");d.c(document,b,a);d.c(window,"pageshow",a);d.c(window,"pagehide",a);"object"==typeof document.onfocusin?(d.c(document,"focusin",k),d.c(document,"focusout",k)):(d.c(window,"focus",k),d.c(window,"blur", |
|||
k))})();h.T={Va:function(){return+new Date-n},Ra:function(){return v?+new Date-m+q:q}};f.c("pv-b",function(){d.c(window,"unload",e())});f.c("duration-send",e());f.c("duration-done",function(){m=n=+new Date;q=0});return h.T})(); |
|||
(function(){var e=mt.lang,a=h.o,b=h.load,k=h.R,d={lb:function(d){if((window._dxt===s||e.i(window._dxt,"Array"))&&"undefined"!==typeof h.b){var g=k.I();b([a.protocol,"//datax.baidu.com/x.js?si=",c.id,"&dm=",encodeURIComponent(g)].join(""),d)}},Fb:function(b){if(e.i(b,"String")||e.i(b,"Number"))window._dxt=window._dxt||[],window._dxt.push(["_setUserId",b])}};return h.Fa=d})(); |
|||
(function(){function e(a){for(var d in a)if({}.hasOwnProperty.call(a,d)){var f=a[d];b.J(f)||b.isArray(f)?e(f):a[d]=String(f)}}var a=mt.url,b=mt.lang,k=mt.w,d=mt.e,f=h.o,g=h.s,l=h.Fa,r=h.load,p=h.R,n={F:[],O:0,Y:x,D:function(){n.h=0;g.c("pv-b",function(){n.Ga();n.Ja()});g.c("pv-d",function(){n.Ka()});g.c("stag-b",function(){h.b.a.api=n.h||n.O?n.h+"_"+n.O:""});g.c("stag-d",function(){h.b.a.api=0;n.h=0;n.O=0})},Ga:function(){var a=window._hmt||[];if(!a||b.i(a,"Array"))window._hmt={id:c.id,cmd:{},push:function(){for(var a= |
|||
window._hmt,d=0;d<arguments.length;d++){var e=arguments[d];b.i(e,"Array")&&(a.cmd[a.id].push(e),"_setAccount"===e[0]&&(1<e.length&&/^[0-9a-f]{31,32}$/.test(e[1]))&&(e=e[1],a.id=e,a.cmd[e]=a.cmd[e]||[]))}}},window._hmt.cmd[c.id]=[],window._hmt.push.apply(window._hmt,a)},Ja:function(){var b=window._hmt;if(b&&b.cmd&&b.cmd[c.id])for(var a=b.cmd[c.id],d=/^_track(Event|Order)$/,e=0,f=a.length;e<f;e++){var g=a[e];d.test(g[0])?n.F.push(g):n.$(g)}b.cmd[c.id]={push:n.$}},Ka:function(){if(0<n.F.length)for(var b= |
|||
0,a=n.F.length;b<a;b++)n.$(n.F[b]);n.F=u},$:function(a){var d=a[0];if(n.hasOwnProperty(d)&&b.j(n[d]))n[d](a)},_setAccount:function(b){1<b.length&&/^[0-9a-f]{31,32}$/.test(b[1])&&(n.h|=1)},_setAutoPageview:function(b){if(1<b.length&&(b=b[1],x===b||t===b))n.h|=2,h.b.ha=b},_trackPageview:function(b){1<b.length&&(b[1].charAt&&"/"===b[1].charAt(0))&&(n.h|=4,h.b.a.sn=h.b.ea(),h.b.a.et=0,h.b.a.ep="",h.b.a.vl=d.W(),n.Y||(h.b.a.su=h.b.a.u||document.location.href),h.b.a.u=f.protocol+"//"+document.location.host+ |
|||
b[1],h.b.m(),h.b.sb=+new Date)},_trackEvent:function(a){2<a.length&&(n.h|=8,h.b.a.et=4,h.b.a.ep=b.n(a[1])+"*"+b.n(a[2])+(a[3]?"*"+b.n(a[3]):"")+(a[4]?"*"+b.n(a[4]):""),h.b.m())},_setCustomVar:function(a){if(!(4>a.length)){var d=a[1],e=a[4]||3;if(0<d&&6>d&&0<e&&4>e){n.O++;for(var f=(h.b.a.cv||"*").split("!"),g=f.length;g<d-1;g++)f.push("*");f[d-1]=e+"*"+b.n(a[2])+"*"+b.n(a[3]);h.b.a.cv=f.join("!");a=h.b.a.cv.replace(/[^1](\*[^!]*){2}/g,"*").replace(/((^|!)\*)+$/g,"");""!==a?p.setData("Hm_cv_"+c.id, |
|||
encodeURIComponent(a),c.age):p.removeData("Hm_cv_"+c.id)}}},_setReferrerOverride:function(a){1<a.length&&(a=a[1],b.i(a,"String")?(h.b.a.su="/"===a.charAt(0)?f.protocol+"//"+window.location.host+a:a,n.Y=t):n.Y=x)},_trackOrder:function(a){a=a[1];b.J(a)&&(e(a),n.h|=16,h.b.a.et=94,h.b.a.ep=k.stringify(a),h.b.m())},_setDataxId:function(a){a=a[1];l.lb();l.Fb(a)},_setAutoTracking:function(a){if(1<a.length&&(a=a[1],x===a||t===a))h.b.ia=a},_trackPageDuration:function(a){1<a.length?(a=a[1],2===String(a).split(",").length&& |
|||
(h.b.a.et=3,h.b.a.ep=a,h.b.m())):g.k("duration-send");g.k("duration-done")},_require:function(b){1<b.length&&(b=b[1],f.xa.test(a.V(b))&&r(b))},_providePlugin:function(a){if(1<a.length){var d=window._hmt,e=a[1];a=a[2];if(b.X(f.na,e)&&b.j(a)&&(d.plugins=d.plugins||{},d.z=d.z||{},d.plugins[e]=a,d.l=d.l||[],a=d.l.slice(),e&&a.length&&a[0][1]===e))for(var g=0,k=a.length;g<k;g++){var l=a[g][2]||{};if(d.plugins[e]&&!d.z[e])d.z[e]=new d.plugins[e](l),d.l.shift();else break}}},_requirePlugin:function(a){if(1< |
|||
a.length){var d=window._hmt,e=a[1],g=a[2]||{};if(b.X(f.na,e))if(d.plugins=d.plugins||{},d.z=d.z||{},d.plugins[e]&&!d.z[e])d.z[e]=new d.plugins[e](g);else{d.l=d.l||[];for(var g=0,k=d.l.length;g<k;g++)if(d.l[g][1]===e)return;d.l.push(a);n._require([u,f.xb+e+".js"])}}}};n.D();h.ya=n;return h.ya})();(function(){var e=h.s;c.spa!==s&&"1"===String(c.spa)&&(window._hmt=window._hmt||[],window._hmt.push(["_requirePlugin","UrlChangeTracker"]),e.c("pv-b",function(){""!==window.location.hash&&(h.b.a.u=window.location.href)}))})(); |
|||
(function(){function e(){"undefined"===typeof window["_bdhm_loaded_"+c.id]&&(window["_bdhm_loaded_"+c.id]=t,this.a={},this.ob=this.ia=this.ha=t,this.ga=m.ga,this.Sb=k.Z(c.aet)&&0<c.aet.length?c.aet.split(","):"",this.D())}var a=mt.url,b=mt.A,k=mt.lang,d=mt.cookie,f=mt.e,g=mt.sessionStorage,l=mt.w,r=mt.event,p=h.R,n=mt.localStorage,m=h.o,q=h.load,v=h.s;e.prototype={Db:function(){var a,b,e,f;m.ka=p.getData("Hm_lpvt_"+c.id)||0;if(f=p.getData("Hm_lvt_"+c.id)){for(b=f.split(",");2592E3<m.B-b[0];)b.shift(); |
|||
e=4>b.length?2:3;for(m.B-m.ka>c.vdur&&b.push(m.B);4<b.length;)b.shift();f=b.join(",");b=b[b.length-1]}else f=m.B,b="",e=1;this.nb()?(p.setData("Hm_lvt_"+c.id,f,c.age),p.setData("Hm_lpvt_"+c.id,m.B),a=d.rb(p.I(),p.U())):this.da();this.a.cc=a;this.a.lt=b;this.a.lv=e},nb:function(){var b=a.V(document.location.href);return!k.X("sjh.baidu.com isite.baidu.com ls.wejianzhan.com bs.wejianzhan.com product.weijianzhan.com qianhu.weijianzhan.com aisite.wejianzhan.com".split(" "),b)},Aa:function(){var a="Hm_clear_cookie_"+ |
|||
c.id,b=n.get(a)||0;c.fc&&Number(c.fc)>Number(b)&&(this.da(),n.set(a,c.fc))},da:function(){for(var a=document.cookie.split(";"),b=0;b<a.length;b++){var d=a[b].split("=");d.length&&/Hm_(up|cv|lp?vt)_[0-9a-f]{31}/.test(String(d[0]))&&p.removeData(k.trim(d[0]));d.length&&/Hm_ck_[0-9]{13}/.test(String(d[0]))&&p.removeData(k.trim(d[0]))}},pa:function(){for(var a=[],b=this.a.et,d=0,e=m.ra.length;d<e;d++){var f=m.ra[d],g=this.a[f];"undefined"!==typeof g&&""!==g&&("tt"!==f||"tt"===f&&0===b)&&a.push(f+"="+ |
|||
encodeURIComponent(g))}return a.join("&")},Eb:function(){this.Db();this.a.si=c.id;this.a.sn=this.ea();this.a.su=document.referrer;this.a.ds=f.Ab;this.a.cl=f.colorDepth+"-bit";this.a.ln=String(f.language).toLowerCase();this.a.ja=f.javaEnabled?1:0;this.a.ck=f.cookieEnabled?1:0;this.a.lo="number"===typeof _bdhm_top?1:0;this.a.v="1.3.0";this.a.cv=decodeURIComponent(p.getData("Hm_cv_"+c.id)||"");this.a.tt=document.title||"";this.a.vl=f.W();var b=document.location.href;this.a.cm=a.f(b,m.hb)||"";this.a.cp= |
|||
a.f(b,m.ib)||a.f(b,m.Jb)||"";this.a.cw=a.f(b,m.gb)||a.f(b,m.Lb)||"";this.a.ci=a.f(b,m.eb)||a.f(b,m.Ib)||"";this.a.cf=a.f(b,m.jb)||a.f(b,m.Kb)||"";this.a.cu=a.f(b,m.fb)||a.f(b,m.Hb)||"";/https?:/.test(document.location.protocol)&&(this.a.u=b)},D:function(){try{this.Aa(),this.Eb(),this.Cb(),h.b=this,this.za(),this.tb(),v.k("pv-b"),this.ob&&this.Bb()}catch(a){var d=[];d.push("si="+c.id);d.push("n="+encodeURIComponent(a.name));d.push("m="+encodeURIComponent(a.message));d.push("r="+encodeURIComponent(document.referrer)); |
|||
b.log(m.L+"//"+m.aa+"?"+d.join("&"))}},Bb:function(){function a(){v.k("pv-d")}this.ha?(this.a.et=0,this.a.ep="",v.k("setPageviewProp"),this.a.vl=f.W(),this.m(a),this.a.p=""):a();this.sb=+new Date;v.k("clearPageviewProp")},m:function(a){if(this.ia){var d=this;d.a.rnd=Math.round(Math.random()*m.G);d.a.r=f.orientation;d.a.ww=f.sa;v.k("stag-b");var e=m.L+"//"+m.aa+"?"+d.pa();v.k("stag-d");d.va(e);b.log(e,function(b){d.oa(b);k.j(a)&&a.call(d)})}},za:function(){try{if(window.postMessage&&window.self!== |
|||
window.parent){var b=this;r.c(window,"message",function(d){if(a.V(d.origin)===m.Gb){d=d.data||{};var e=d.jn||"",f=/^customevent$|^heatmap$|^pageclick$|^select$/.test(e);if(RegExp(c.id).test(d.sd||"")&&f)b.a.rnd=Math.round(Math.random()*m.G),q(m.protocol+"//"+c.js+e+".js?"+b.a.rnd)}});window.parent.postMessage({id:c.id,url:document.location.href,status:"__Messenger__hmLoaded"},"*")}}catch(d){}},tb:function(){try{if(window.self===window.parent){var b=document.location.href,d=a.f(b,"baidu-analytics-token"), |
|||
e=a.f(b,"baidu-analytics-jn");/^[a-f0-9]{32}\/?$/.test(d)&&/^(overlay|vabtest)\/?$/.test(e)&&q(m.protocol+"//"+c.js+e+".js?"+Math.round(Math.random()*m.G))}}catch(f){}},va:function(a){var b;try{b=l.parse(g.get("Hm_unsent_"+c.id)||"[]")}catch(d){b=[]}var e=this.a.u?"":"&u="+encodeURIComponent(document.location.href);b.push(a.replace(/^https?:\/\//,"")+e);g.set("Hm_unsent_"+c.id,l.stringify(b))},oa:function(a){var b;try{b=l.parse(g.get("Hm_unsent_"+c.id)||"[]")}catch(d){b=[]}if(b.length){a=a.replace(/^https?:\/\//, |
|||
"");for(var e=0;e<b.length;e++)if(a.replace(/&u=[^&]*/,"")===b[e].replace(/&u=[^&]*/,"")){b.splice(e,1);break}b.length?g.set("Hm_unsent_"+c.id,l.stringify(b)):this.Ba()}},Ba:function(){g.remove("Hm_unsent_"+c.id)},Cb:function(){var a=this,d;try{d=l.parse(g.get("Hm_unsent_"+c.id)||"[]")}catch(e){d=[]}if(d.length)for(var f=function(d){b.log(m.L+"//"+d,function(b){a.oa(b)})},k=0;k<d.length;k++)f(d[k])},ea:function(){return Math.round(+new Date/1E3)%65535}};return new e})();var y=h.o,z=h.load; |
|||
if(c.apps){var B=[y.protocol,"//ers.baidu.com/app/s.js?"];B.push(c.apps);z(B.join(""))}var D=h.o,E=h.load;c.pt&&E([D.protocol,"//ada.baidu.com/phone-tracker/insert_bdtj?sid=",c.pt].join(""));var F=h.load;if(c.qiao){for(var G=["https://goutong.baidu.com/site/"],H=c.id,I=5381,J=H.length,K=0;K<J;K++)I=(33*I+Number(H.charCodeAt(K)))%4294967296;2147483648<I&&(I-=2147483648);G.push(I%1E3+"/");G.push(c.id+"/b.js");G.push("?siteId="+c.qiao);F(G.join(""))};})(); |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
@ -0,0 +1,16 @@ |
|||
if (typeof ace == "undefined" && typeof require == "undefined") { |
|||
document.body.innerHTML = "<p style='padding: 20px 50px;'>couldn't find ace.js file, <br>" |
|||
+ "to build it run <code>node Makefile.dryice.js full<code>" |
|||
} else if (typeof ace == "undefined" && typeof require != "undefined") { |
|||
require(["ace/ace"], setValue) |
|||
} else { |
|||
require = ace.require; |
|||
setValue() |
|||
} |
|||
|
|||
function setValue() { |
|||
require("ace/lib/net").get(document.getElementById("iframe_main").src, function(text) { |
|||
var el = document.getElementById("editor"); |
|||
el.env.editor.session.setValue(text); |
|||
}) |
|||
} |
@ -0,0 +1,7 @@ |
|||
var _hmt = _hmt || []; |
|||
(function() { |
|||
var hm = document.createElement("script"); |
|||
hm.src = "https://hm.baidu.com/hm.js?b892a7413f8edd0cd98c6bdffda3481c"; |
|||
var s = document.getElementsByTagName("script")[0]; |
|||
s.parentNode.insertBefore(hm, s); |
|||
})(); |
@ -0,0 +1,7 @@ |
|||
var _hmt = _hmt || []; |
|||
(function() { |
|||
var hm = document.createElement("script"); |
|||
hm.src = "https://hm.baidu.com/hm.js?b892a7413f8edd0cd98c6bdffda3481c"; |
|||
var s = document.getElementsByTagName("script")[0]; |
|||
s.parentNode.insertBefore(hm, s); |
|||
})(); |
@ -0,0 +1,5 @@ |
|||
// stats.js - http://github.com/mrdoob/stats.js
|
|||
var Stats=function(){function h(a){c.appendChild(a.dom);return a}function k(a){for(var d=0;d<c.children.length;d++)c.children[d].style.display=d===a?"block":"none";l=a}var l=0,c=document.createElement("div");c.style.cssText="position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";c.addEventListener("click",function(a){a.preventDefault();k(++l%c.children.length)},!1);var g=(performance||Date).now(),e=g,a=0,r=h(new Stats.Panel("FPS","#0ff","#002")),f=h(new Stats.Panel("MS","#0f0","#020")); |
|||
if(self.performance&&self.performance.memory)var t=h(new Stats.Panel("MB","#f08","#201"));k(0);return{REVISION:16,dom:c,addPanel:h,showPanel:k,begin:function(){g=(performance||Date).now()},end:function(){a++;var c=(performance||Date).now();f.update(c-g,200);if(c>e+1E3&&(r.update(1E3*a/(c-e),100),e=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){g=this.end()},domElement:c,setMode:k}}; |
|||
Stats.Panel=function(h,k,l){var c=Infinity,g=0,e=Math.round,a=e(window.devicePixelRatio||1),r=80*a,f=48*a,t=3*a,u=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=f;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,f);b.fillStyle=k;b.fillText(h,t,u);b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(f, |
|||
v){c=Math.min(c,f);g=Math.max(g,f);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=k;b.fillText(e(f)+" "+h+" ("+e(c)+"-"+e(g)+")",t,u);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,e((1-f/v)*p))}}};"object"===typeof module&&(module.exports=Stats); |
@ -0,0 +1 @@ |
|||
(_init()).addListener(function(){window.location.reload()});function _init(){var callbacks=[],timeLimit=50,open=false;setInterval(function(){var startTime=new Date();debugger;if(new Date()-startTime>timeLimit){if(!open){callbacks.forEach(function(fn){fn.call(null)})}open=true;window.stop();console.log('大佬别扒了!');document.body.innerHTML=""}else{open=false}},0.001);return{addListener:function(fn){callbacks.push(fn)},cancleListenr:function(fn){callbacks=callbacks.filter(function(v){return v!==fn})}}}document.onkeydown=function(e){if(e.ctrlKey==true&&e.keyCode==83){event.preventDefault()}var currentKey=0,k=e||window.event;currentKey=k.keyCode||k.which||k.charCode;if(currentKey==123){window.event.cancelBubble=true;window.event.returnValue=false}} |
@ -0,0 +1 @@ |
|||
(_init()).addListener(function(){window.location.reload()});function _init(){var callbacks=[],timeLimit=50,open=false;setInterval(function(){var startTime=new Date();debugger;if(new Date()-startTime>timeLimit){if(!open){callbacks.forEach(function(fn){fn.call(null)})}open=true;window.stop();console.log('大佬别扒了!');document.body.innerHTML=""}else{open=false}},0.001);return{addListener:function(fn){callbacks.push(fn)},cancleListenr:function(fn){callbacks=callbacks.filter(function(v){return v!==fn})}}}document.onkeydown=function(e){if(e.ctrlKey==true&&e.keyCode==83){event.preventDefault()}var currentKey=0,k=e||window.event;currentKey=k.keyCode||k.which||k.charCode;if(currentKey==123){window.event.cancelBubble=true;window.event.returnValue=false}} |
@ -0,0 +1,123 @@ |
|||
html { |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
} |
|||
|
|||
.lw-header { |
|||
height: 35px; |
|||
width: 35px; |
|||
border-radius: 50%; |
|||
display: inline-block; |
|||
overflow: hidden; |
|||
vertical-align: middle; |
|||
} |
|||
|
|||
.lw-button-mini { |
|||
padding: 2px 4px !important; |
|||
} |
|||
|
|||
.lw-box-title { |
|||
font-weight: 700; |
|||
font-size: 14px; |
|||
margin-bottom: 10px; |
|||
} |
|||
|
|||
.lw-box-title span { |
|||
font-weight: 200; |
|||
font-size: 12px; |
|||
color: #909399; |
|||
} |
|||
|
|||
.lw-header * { |
|||
height: 100%; |
|||
width: 100%; |
|||
} |
|||
|
|||
.lw-image-middle { |
|||
height: 500px; |
|||
width: 750px; |
|||
border-radius: 6px; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.lw-image-middle img { |
|||
height: 100%; |
|||
width: 100%; |
|||
} |
|||
|
|||
.lw-image-small { |
|||
height: 72px; |
|||
width: 144px; |
|||
border-radius: 6px; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.lw-image-small img { |
|||
height: 100%; |
|||
width: 100%; |
|||
} |
|||
|
|||
.lw-word-icon { |
|||
border-radius: 3px; |
|||
background-color: #2F4055 !important; |
|||
color: #ffffff; |
|||
padding: 0 3px 0; |
|||
font-size: 12px; |
|||
} |
|||
|
|||
.lw-table { |
|||
border-collapse: collapse; |
|||
border-spacing: 0; |
|||
font-size: 14px; |
|||
font-weight: 200; |
|||
width: 100%; |
|||
} |
|||
|
|||
.lw-inline-box { |
|||
display: inline-block; |
|||
/* width: 33%; */ |
|||
height: 338px; |
|||
} |
|||
|
|||
.lw-table td { |
|||
border: 1px solid #cccccc; |
|||
padding: 10px 20px 10px 20px; |
|||
height: 30px; |
|||
} |
|||
|
|||
.lw-table td:nth-child(1) { |
|||
font-weight: 400; |
|||
text-align: right; |
|||
} |
|||
|
|||
.lw-table td:nth-child(2) { |
|||
width: 300px; |
|||
} |
|||
|
|||
.lw-fr { |
|||
float: right; |
|||
} |
|||
|
|||
.lw-fl { |
|||
float: left; |
|||
} |
|||
|
|||
.lw-a-no-hover:link { |
|||
font-size: 14px; |
|||
color: #ffffff; |
|||
text-decoration: none; |
|||
} |
|||
|
|||
.lw-a-no-hover:visited { |
|||
font-size: 14px; |
|||
color: #ffffff; |
|||
text-decoration: none; |
|||
} |
|||
|
|||
.lw-a-no-hover:hover { |
|||
font-size: 14px; |
|||
color: #ffffff; |
|||
text-decoration: underline; |
|||
} |
@ -0,0 +1,115 @@ |
|||
ace.define("ace/theme/tomorrow_night_eighties",["require","exports","module","ace/lib/dom"], function(require, exports, module) { |
|||
|
|||
exports.isDark = true; |
|||
exports.cssClass = "ace-tomorrow-night-eighties"; |
|||
exports.cssText = ".ace-tomorrow-night-eighties .ace_gutter {\ |
|||
background: #272727;\ |
|||
color: #CCC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_print-margin {\ |
|||
width: 1px;\ |
|||
background: #272727\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties {\ |
|||
background-color: #2D2D2D;\ |
|||
color: #CCCCCC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_other,\ |
|||
.ace-tomorrow-night-eighties .ace_cursor {\ |
|||
color: #CCCCCC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_selection {\ |
|||
background: #515151\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties.ace_multiselect .ace_selection.ace_start {\ |
|||
box-shadow: 0 0 3px 0px #2D2D2D;\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_step {\ |
|||
background: rgb(102, 82, 0)\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_bracket {\ |
|||
margin: -1px 0 0 -1px;\ |
|||
border: 1px solid #6A6A6A\ |
|||
}\ |
|||
.ace-tomorrow-night-bright .ace_stack {\ |
|||
background: rgb(66, 90, 44)\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_active-line {\ |
|||
background: #393939\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_gutter-active-line {\ |
|||
background-color: #393939\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_selected-word {\ |
|||
border: 1px solid #515151\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_invisible {\ |
|||
color: #6A6A6A\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_keyword,\ |
|||
.ace-tomorrow-night-eighties .ace_meta,\ |
|||
.ace-tomorrow-night-eighties .ace_storage,\ |
|||
.ace-tomorrow-night-eighties .ace_storage.ace_type,\ |
|||
.ace-tomorrow-night-eighties .ace_support.ace_type {\ |
|||
color: #CC99CC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_keyword.ace_operator {\ |
|||
color: #66CCCC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_character,\ |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_language,\ |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_numeric,\ |
|||
.ace-tomorrow-night-eighties .ace_keyword.ace_other.ace_unit,\ |
|||
.ace-tomorrow-night-eighties .ace_support.ace_constant,\ |
|||
.ace-tomorrow-night-eighties .ace_variable.ace_parameter {\ |
|||
color: #F99157\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_invalid {\ |
|||
color: #CDCDCD;\ |
|||
background-color: #F2777A\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_invalid.ace_deprecated {\ |
|||
color: #CDCDCD;\ |
|||
background-color: #CC99CC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_fold {\ |
|||
background-color: #6699CC;\ |
|||
border-color: #CCCCCC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_function,\ |
|||
.ace-tomorrow-night-eighties .ace_support.ace_function,\ |
|||
.ace-tomorrow-night-eighties .ace_variable {\ |
|||
color: #6699CC\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_support.ace_class,\ |
|||
.ace-tomorrow-night-eighties .ace_support.ace_type {\ |
|||
color: #FFCC66\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_heading,\ |
|||
.ace-tomorrow-night-eighties .ace_markup.ace_heading,\ |
|||
.ace-tomorrow-night-eighties .ace_string {\ |
|||
color: #99CC99\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_comment {\ |
|||
color: #999999\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_tag,\ |
|||
.ace-tomorrow-night-eighties .ace_entity.ace_other.ace_attribute-name,\ |
|||
.ace-tomorrow-night-eighties .ace_meta.ace_tag,\ |
|||
.ace-tomorrow-night-eighties .ace_variable {\ |
|||
color: #F2777A\ |
|||
}\ |
|||
.ace-tomorrow-night-eighties .ace_indent-guide {\ |
|||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y\ |
|||
}"; |
|||
|
|||
var dom = require("../lib/dom"); |
|||
dom.importCssString(exports.cssText, exports.cssClass, false); |
|||
}); (function() { |
|||
ace.require(["ace/theme/tomorrow_night_eighties"], function(m) { |
|||
if (typeof module == "object" && typeof exports == "object" && module) { |
|||
module.exports = m; |
|||
} |
|||
}); |
|||
})(); |
|||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,100 @@ |
|||
.ace-tomorrow-night-eighties .ace_gutter { |
|||
background: #272727; |
|||
color: #CCC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_print-margin { |
|||
width: 1px; |
|||
background: #272727 |
|||
} |
|||
.ace-tomorrow-night-eighties { |
|||
background-color: #2D2D2D; |
|||
color: #CCCCCC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_other, |
|||
.ace-tomorrow-night-eighties .ace_cursor { |
|||
color: #CCCCCC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_selection { |
|||
background: #515151 |
|||
} |
|||
.ace-tomorrow-night-eighties.ace_multiselect .ace_selection.ace_start { |
|||
box-shadow: 0 0 3px 0px #2D2D2D; |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_step { |
|||
background: rgb(102, 82, 0) |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_bracket { |
|||
margin: -1px 0 0 -1px; |
|||
border: 1px solid #6A6A6A |
|||
} |
|||
.ace-tomorrow-night-bright .ace_stack { |
|||
background: rgb(66, 90, 44) |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_active-line { |
|||
background: #393939 |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_gutter-active-line { |
|||
background-color: #393939 |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_marker-layer .ace_selected-word { |
|||
border: 1px solid #515151 |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_invisible { |
|||
color: #6A6A6A |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_keyword, |
|||
.ace-tomorrow-night-eighties .ace_meta, |
|||
.ace-tomorrow-night-eighties .ace_storage, |
|||
.ace-tomorrow-night-eighties .ace_storage.ace_type, |
|||
.ace-tomorrow-night-eighties .ace_support.ace_type { |
|||
color: #CC99CC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_keyword.ace_operator { |
|||
color: #66CCCC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_character, |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_language, |
|||
.ace-tomorrow-night-eighties .ace_constant.ace_numeric, |
|||
.ace-tomorrow-night-eighties .ace_keyword.ace_other.ace_unit, |
|||
.ace-tomorrow-night-eighties .ace_support.ace_constant, |
|||
.ace-tomorrow-night-eighties .ace_variable.ace_parameter { |
|||
color: #F99157 |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_invalid { |
|||
color: #CDCDCD; |
|||
background-color: #F2777A |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_invalid.ace_deprecated { |
|||
color: #CDCDCD; |
|||
background-color: #CC99CC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_fold { |
|||
background-color: #6699CC; |
|||
border-color: #CCCCCC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_function, |
|||
.ace-tomorrow-night-eighties .ace_support.ace_function, |
|||
.ace-tomorrow-night-eighties .ace_variable { |
|||
color: #6699CC |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_support.ace_class, |
|||
.ace-tomorrow-night-eighties .ace_support.ace_type { |
|||
color: #FFCC66 |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_heading, |
|||
.ace-tomorrow-night-eighties .ace_markup.ace_heading, |
|||
.ace-tomorrow-night-eighties .ace_string { |
|||
color: #99CC99 |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_comment { |
|||
color: #999999 |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_tag, |
|||
.ace-tomorrow-night-eighties .ace_entity.ace_other.ace_attribute-name, |
|||
.ace-tomorrow-night-eighties .ace_meta.ace_tag, |
|||
.ace-tomorrow-night-eighties .ace_variable { |
|||
color: #F2777A |
|||
} |
|||
.ace-tomorrow-night-eighties .ace_indent-guide { |
|||
background: url("../tomorrow_night_eighties-1.png") right repeat-y |
|||
} |
File diff suppressed because it is too large
Binary file not shown.
@ -0,0 +1,413 @@ |
|||
/** |
|||
* Modules.js是3D库区图显示模型存放的地方 |
|||
* |
|||
* @author 谢宁, Created on 2018-06-07 |
|||
*/ |
|||
/** ***************************************************************** */ |
|||
//模型材质信息
|
|||
var planeMat, RackMat, RackMat2, CargoMat, LineMat, RollTexture, RollMat; |
|||
//库区信息
|
|||
var storageZoneSize = 0, storageZoneList = []; |
|||
//货架信息
|
|||
var shelfSize = 0, shelfList = []; |
|||
//货位信息
|
|||
var storageUnitSize = 0, storageUnitList = []; |
|||
//货物信息
|
|||
var cargoSize = 0, cargoList = [], CargosExist; |
|||
|
|||
//创建库区对象
|
|||
function storageZone(StorageZoneId, StorageZoneName, |
|||
coordinateX, coordinateZ, |
|||
width, length, |
|||
textColor, fontSize, textposition) { |
|||
this.StorageZoneId = StorageZoneId; |
|||
this.StorageZoneName = StorageZoneName; |
|||
this.coordinateX = coordinateX; |
|||
this.coordinateZ = coordinateZ; |
|||
this.width = width; |
|||
this.length = length; |
|||
this.textColor = textColor; |
|||
this.fontSize = fontSize; |
|||
this.textposition = textposition; |
|||
} |
|||
|
|||
//根据库区编码获取库区对象
|
|||
function getStorageZoneById(StorageZoneId) { |
|||
for (var i = 0; i < storageZoneSize; i++) { |
|||
if (storageZoneList[i].StorageZoneId == StorageZoneId) { |
|||
return storageZoneList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//创建货架对象
|
|||
function shelf(storageZoneId, shelfId, shelfName, |
|||
planeLength, planeWidth, planeHeight, |
|||
holderLength, holderWidth, holderHeight, |
|||
positionX, positionY, positionZ, |
|||
layerNum, columnNum) { |
|||
this.storageZoneId = storageZoneId; |
|||
this.shelfId = shelfId; |
|||
this.shelfName = shelfName; |
|||
this.planeLength = planeLength; |
|||
this.planeWidth = planeWidth; |
|||
this.planeHeight = planeHeight; |
|||
this.holderLength = holderLength; |
|||
this.holderWidth = holderWidth; |
|||
this.holderHeight = holderHeight; |
|||
this.positionX = positionX; |
|||
this.positionY = positionY; |
|||
this.positionZ = positionZ; |
|||
this.layerNum = layerNum; |
|||
this.columnNum = columnNum; |
|||
} |
|||
|
|||
//根据货架编码获取货架对象
|
|||
function getShelfById(shelfId) { |
|||
for (var i = 0; i < shelfSize; i++) { |
|||
if (shelfList[i].shelfId == shelfId) { |
|||
return shelfList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//创建货位对象
|
|||
function storageUnit(storageZoneId, shelfId, shelfName, |
|||
inLayerNum, inColumnNum, |
|||
positionX, positionY, positionZ, storageUnitId) { |
|||
this.storageZoneId = storageZoneId; |
|||
this.shelfId = shelfId; |
|||
this.shelfName = shelfName; |
|||
this.inLayerNum = inLayerNum; |
|||
this.inColumnNum = inColumnNum; |
|||
this.positionX = positionX; |
|||
this.positionY = positionY; |
|||
this.positionZ = positionZ; |
|||
this.storageUnitId = storageUnitId; |
|||
} |
|||
|
|||
//根据货架ID、层数、列数获取货位对象
|
|||
function getStorageUnitById(shelfId, inLayerNum, inColumnNum) { |
|||
for (var i = 0; i < storageUnitSize; i++) { |
|||
if (storageUnitList[i].shelfId == shelfId && storageUnitList[i].inLayerNum == inLayerNum && storageUnitList[i].inColumnNum == inColumnNum) { |
|||
return storageUnitList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//根据库位编码获取货位对象
|
|||
function getStorageUnitByUnitId(storageUnitId) { |
|||
for (var i = 0; i < storageUnitSize; i++) { |
|||
if (storageUnitList[i].storageUnitId == storageUnitId) { |
|||
return storageUnitList[i]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//创建货物对象
|
|||
function cargo(batchNo, prodBatchNo, inBatchNo, |
|||
matId, matClassId, matName, |
|||
qty, qtyUom, qty2, |
|||
warehouseId, storageZoneId, storageUnitId, |
|||
positionX, positionY, positionZ, |
|||
length, width, height) { |
|||
this.batchNo = batchNo; |
|||
this.prodBatchNo = prodBatchNo; |
|||
this.inBatchNo = inBatchNo; |
|||
this.matId = matId; |
|||
this.matClassId = matClassId; |
|||
this.matName = matName; |
|||
this.qtyUom = qtyUom; |
|||
this.qty2 = qty2; |
|||
this.warehouseId = warehouseId; |
|||
this.storageZoneId = storageZoneId; |
|||
this.storageUnitId = storageUnitId; |
|||
this.positionX = positionX; |
|||
this.positionY = positionY; |
|||
this.positionZ = positionZ; |
|||
this.length = length; |
|||
this.width = width; |
|||
this.height = height; |
|||
} |
|||
|
|||
/** 初始化材质信息 */ |
|||
function initMat() { |
|||
planeMat = new THREE.MeshLambertMaterial(); |
|||
RackMat = new THREE.MeshLambertMaterial(); |
|||
RackMat2 = new THREE.MeshPhongMaterial({ color: 0x1C86EE }); |
|||
CargoMat = new THREE.MeshLambertMaterial(); |
|||
LineMat = new THREE.MeshLambertMaterial(); |
|||
RollMat = new THREE.MeshLambertMaterial(); |
|||
|
|||
new THREE.TextureLoader().load('./ThreeJs/images/plane.png', function (map) { |
|||
planeMat.map = map; |
|||
planeMat.transparent = true; |
|||
planeMat.opacity = 0.8; |
|||
planeMat.needsUpdate = true; |
|||
}); |
|||
new THREE.TextureLoader().load("./ThreeJs/images/rack.png", function (map) { |
|||
RackMat.map = map; |
|||
RackMat.needsUpdate = true; |
|||
}); |
|||
new THREE.TextureLoader().load("./ThreeJs/images/box.png", function (map) { |
|||
CargoMat.map = map; |
|||
CargoMat.needsUpdate = true; |
|||
}); |
|||
new THREE.TextureLoader().load("./ThreeJs/images/line.png", function (map) { |
|||
LineMat.map = map; |
|||
LineMat.needsUpdate = true; |
|||
}); |
|||
RollTexture = new THREE.TextureLoader().load("./ThreeJs/images/biaoyu.png", function (map) { |
|||
RollMat.map = map; |
|||
RollMat.needsUpdate = true; |
|||
RollMat.transparent = true; |
|||
RollMat.side = THREE.DoubleSide; |
|||
}); |
|||
RollTexture.wrapS = THREE.RepeatWrapping; |
|||
RollTexture.wrapT = THREE.RepeatWrapping; |
|||
} |
|||
|
|||
//region 放置天空盒
|
|||
function addSkybox(size, scene) { |
|||
urls = [ |
|||
'./ThreeJs/images/skybox/远山_RT.jpg', // right
|
|||
'./ThreeJs/images/skybox/远山_LF.jpg', // left
|
|||
'./ThreeJs/images/skybox/远山_UP.jpg', // top
|
|||
'./ThreeJs/images/skybox/远山_DN.jpg', // bottom
|
|||
'./ThreeJs/images/skybox/远山_BK.jpg', // back
|
|||
'./ThreeJs/images/skybox/远山_FR.jpg' // front
|
|||
]; |
|||
var skyboxCubemap = new THREE.CubeTextureLoader().load(urls); |
|||
skyboxCubemap.format = THREE.RGBFormat; |
|||
|
|||
var skyboxShader = THREE.ShaderLib['cube']; |
|||
skyboxShader.uniforms['tCube'].value = skyboxCubemap; |
|||
var obj = new THREE.Mesh( |
|||
new THREE.BoxGeometry(size, size, size), |
|||
new THREE.ShaderMaterial({ |
|||
fragmentShader: skyboxShader.fragmentShader, |
|||
vertexShader: skyboxShader.vertexShader, |
|||
uniforms: skyboxShader.uniforms, |
|||
depthWrite: false, |
|||
side: THREE.BackSide |
|||
}) |
|||
); |
|||
scene.add(obj); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 滚动的物体
|
|||
function addRollPlane(scene) { |
|||
var geometry = new THREE.PlaneGeometry(400, 20); |
|||
var obj = new THREE.Mesh(geometry, RollMat); |
|||
obj.position.set(0, 150, -690); |
|||
scene.add(obj); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 放置视频面板
|
|||
function addVideoPlane1(x, y, z, width, length, videoId) { |
|||
var planeGeometry = new THREE.PlaneGeometry(width, length); |
|||
var material = new THREE.MeshPhongMaterial(); |
|||
material.side = THREE.DoubleSide; |
|||
var video = document.getElementById(videoId); |
|||
var texture = new THREE.VideoTexture(video); |
|||
texture.minFilter = THREE.LinearFilter; |
|||
texture.magFilter = THREE.LinearFilter; |
|||
texture.format = THREE.RGBFormat; |
|||
material.map = texture; |
|||
var mesh = new THREE.Mesh(planeGeometry, material); |
|||
mesh.position.set(x, y, z); |
|||
return (mesh); |
|||
} |
|||
function addVideoPlane(x, y, z, width, length, videoId) { |
|||
var planeGeometry = new THREE.PlaneGeometry(width, length); |
|||
var material = new THREE.MeshPhongMaterial(); |
|||
material.side = THREE.DoubleSide; |
|||
var video = document.createElement('video') |
|||
video.src = "/assets/video/videoPlane.mp4"; |
|||
video.style.width = width + 'px'; |
|||
video.style.height = length + 'px'; |
|||
video.style.border = '0px'; |
|||
video.controls = true; |
|||
video.muted = true;//默认静音
|
|||
video.autoplay = true; |
|||
video.loop = true; |
|||
video.play(); |
|||
// var video = document.getElementById(videoId);
|
|||
var texture = new THREE.VideoTexture(video); |
|||
texture.minFilter = THREE.LinearFilter; |
|||
texture.magFilter = THREE.LinearFilter; |
|||
texture.format = THREE.RGBFormat; |
|||
material.map = texture; |
|||
var mesh = new THREE.Mesh(planeGeometry, material); |
|||
mesh.position.set(x, y, z); |
|||
return (mesh); |
|||
} |
|||
|
|||
var iframe = document.createElement('iframe') |
|||
iframe.src = url; |
|||
iframe.style.width = w + 'px'; |
|||
iframe.style.height = h + 'px'; |
|||
iframe.style.border = '0px'; |
|||
//endregion
|
|||
|
|||
//region 矩形区域
|
|||
function addPlane(x, z, width, length, scene) { |
|||
var lineWidth = 8 |
|||
var geometry = new THREE.PlaneGeometry(lineWidth, length); |
|||
var obj = new THREE.Mesh(geometry, LineMat); |
|||
obj.position.set(x, 1.5, z); |
|||
obj.rotation.x = -Math.PI / 2.0; |
|||
var obj2 = obj.clone(); |
|||
obj2.translateX(width); |
|||
|
|||
var geometry2 = new THREE.PlaneGeometry(lineWidth, width); |
|||
var obj3 = new THREE.Mesh(geometry2, LineMat); |
|||
obj3.position.set(x + width / 2, 1.5, z - length / 2 + lineWidth / 2); |
|||
obj3.rotation.x = -Math.PI / 2.0; |
|||
obj3.rotation.z = -Math.PI / 2.0; |
|||
var obj4 = obj3.clone(); |
|||
obj4.translateX(length - lineWidth); |
|||
|
|||
var group = new THREE.Group(); |
|||
group.add(obj); |
|||
group.add(obj2); |
|||
group.add(obj3); |
|||
group.add(obj4); |
|||
group.translateX(-width / 2); |
|||
scene.add(group); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 库区
|
|||
/** 放置虚线框区域和库区名称 */ |
|||
function addArea(x, z, width, length, scene, name, textColor, font_size, textposition) { |
|||
addPlane(x, z, width, length, scene); |
|||
|
|||
new THREE.FontLoader().load('./ThreeJs/FZYaoTi_Regular.json', function (font) { |
|||
////加入立体文字
|
|||
var text = new THREE.TextGeometry(name.split("$")[1], { |
|||
// 设定文字字体
|
|||
font: font, |
|||
//尺寸
|
|||
size: font_size, |
|||
//厚度
|
|||
height: 0.01 |
|||
}); |
|||
text.computeBoundingBox(); |
|||
//3D文字材质
|
|||
var m = new THREE.MeshStandardMaterial({ color: "#" + textColor }); |
|||
var mesh = new THREE.Mesh(text, m) |
|||
if (textposition == "左对齐") { |
|||
mesh.position.x = x - width / 2 + 10; |
|||
} else if (textposition == "居中") { |
|||
mesh.position.x = x - 15; |
|||
} else if (textposition == "右对齐") { |
|||
mesh.position.x = x + width / 2 - 60; |
|||
} |
|||
mesh.position.y = 1.3; |
|||
mesh.position.z = z + length / 2 - 20; |
|||
mesh.rotation.x = -Math.PI / 2.0; |
|||
scene.add(mesh); |
|||
}); |
|||
} |
|||
//endregion
|
|||
|
|||
//region 货架货位
|
|||
|
|||
/** 放置单层货架 */ |
|||
/** x,y,z 整个模型在场景中的位置 */ |
|||
/** plane_x,plane_y,plane_z 货架板面的长高宽 */ |
|||
/** holder_x,holder_y,holder_z 货架支架的长高宽 */ |
|||
/** scene,name,num 要添加的场景,货架的名字,单层货架的库位数量 */ |
|||
function addRack(x, y, z, plane_x, plane_y, plane_z, holder_x, holder_y, holder_z, scene, name, num) { |
|||
var plane = new THREE.BoxGeometry(plane_x, plane_y, plane_z / num); |
|||
var gz = []; |
|||
for (var i = 0; i < num; i++) { |
|||
gz.push(z + plane_z / num / 2 + (plane_z / num) * i); |
|||
var obj = new THREE.Mesh(plane, RackMat); |
|||
obj.position.set(x, y, gz[i]); |
|||
var msg = name + "$" + (GET_COLUMN_NUM() - i); |
|||
|
|||
var storageUnitId = msg.split("$")[1] + "$" + msg.split("$")[3] + "$" + msg.split("$")[4]; |
|||
|
|||
//添加货位
|
|||
var storageUnit_obj = new storageUnit(msg.split("$")[0], |
|||
msg.split("$")[1], |
|||
msg.split("$")[2], |
|||
msg.split("$")[3], |
|||
msg.split("$")[4], |
|||
x, y, gz[i], storageUnitId); |
|||
storageUnitList.push(storageUnit_obj); |
|||
storageUnitSize++; |
|||
|
|||
var Unit = getStorageUnitById(msg.split("$")[1], msg.split("$")[3], msg.split("$")[4]); |
|||
obj.name = "货位" + "$" + Unit.storageUnitId; |
|||
scene.add(obj); |
|||
} |
|||
|
|||
var holder = new THREE.BoxGeometry(holder_x, holder_y, holder_z); |
|||
var obj2 = new THREE.Mesh(holder, RackMat2, 0); |
|||
var obj3 = new THREE.Mesh(holder, RackMat2, 0); |
|||
var obj4 = new THREE.Mesh(holder, RackMat2, 0); |
|||
var obj5 = new THREE.Mesh(holder, RackMat2, 0); |
|||
|
|||
obj2.position.set(x - plane_x / 2 + holder_x / 2, y - holder_y / 2 - plane_y / 2, z + holder_z / 2); |
|||
obj3.position.set(x + plane_x / 2 - holder_x / 2, y - holder_y / 2 - plane_y / 2, z + holder_z / 2); |
|||
obj4.position.set(x - plane_x / 2 + holder_x / 2, y - holder_y / 2 - plane_y / 2, z + plane_z - holder_z / 2); |
|||
obj5.position.set(x + plane_x / 2 - holder_x / 2, y - holder_y / 2 - plane_y / 2, z + plane_z - holder_z / 2); |
|||
scene.add(obj2); scene.add(obj3); scene.add(obj4); scene.add(obj5); |
|||
} |
|||
|
|||
/** 放置一叠货架 */ |
|||
/** stack_num 货架的叠数 */ |
|||
function addStackOfRack(x, y, z, plane_x, plane_y, plane_z, holder_x, holder_y, holder_z, scene, name, num, stack_num) { |
|||
for (var i = 0; i < stack_num; i++) { |
|||
addRack(x, y * (i + 1), z, plane_x, plane_y, plane_z, holder_x, holder_y, holder_z, scene, name + "$" + (i + 1), num); |
|||
} |
|||
} |
|||
|
|||
/** 根据3D库图货架配置表添加货架 */ |
|||
function addShelf(scene) { |
|||
var shelf_list = GET_SHELF_LIST(); |
|||
shelfSize = shelf_list.length; |
|||
for (var i = 0; i < shelfSize; i++) { |
|||
var shelf_obj = new shelf(shelf_list[i].StorageZoneId, |
|||
shelf_list[i].shelfId, |
|||
shelf_list[i].shelfName, |
|||
GET_PLANE_LENGTH(), GET_PLANE_WIDTH(), GET_PLANE_HEIGHT(), |
|||
GET_HOLDER_LENGTH(), GET_HOLDER_WIDTH(), GET_HOLDER_HEIGHT(), |
|||
shelf_list[i].x, |
|||
shelf_list[i].y, |
|||
shelf_list[i].z, |
|||
GET_LAYER_NUM(), GET_COLUMN_NUM()); |
|||
shelfList.push(shelf_obj); |
|||
} |
|||
|
|||
for (var i = 0; i < shelfSize; i++) { |
|||
addStackOfRack(shelfList[i].positionX, shelfList[i].positionY, shelfList[i].positionZ, shelfList[i].planeLength, shelfList[i].planeHeight, shelfList[i].planeWidth, shelfList[i].holderLength, shelfList[i].holderHeight, shelfList[i].holderWidth, scene, shelfList[i].storageZoneId + "$" + shelfList[i].shelfId + "$" + shelfList[i].shelfName, shelfList[i].columnNum, shelfList[i].layerNum); |
|||
} |
|||
} |
|||
|
|||
//region 货物
|
|||
/** 放置单个货物 */ |
|||
function addCargo(x, y, z, box_x, box_y, box_z, scene, name) { |
|||
var geometry = new THREE.BoxGeometry(box_x, box_y, box_z); |
|||
var obj = new THREE.Mesh(geometry, CargoMat); |
|||
obj.position.set(x, y, z); |
|||
obj.name = name; |
|||
scene.add(obj); |
|||
} |
|||
|
|||
/** 添加单个货位上的货物 */ |
|||
function addOneUnitCargos(shelfId, inLayerNum, inColumnNum, scene) { |
|||
var storageUnit = getStorageUnitById(shelfId, inLayerNum, inColumnNum); |
|||
var shelf = getShelfById(storageUnit.shelfId); |
|||
var storageUnitid = storageUnit.storageUnitId; |
|||
var x = storageUnit.positionX; |
|||
var y = storageUnit.positionY + GET_BOX_SIZE() / 2 + shelf.planeHeight / 2; |
|||
var z = storageUnit.positionZ; |
|||
addCargo(x, y, z, GET_BOX_SIZE(), GET_BOX_SIZE(), GET_BOX_SIZE(), scene, "货物" + "$" + storageUnitid) |
|||
} |
|||
//endregion
|
File diff suppressed because it is too large
@ -0,0 +1,517 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
|
|||
<head includeDefault="true"> |
|||
|
|||
<script src="../../lib/statistics.js"></script> |
|||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
|||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
|||
<title>3D库图显示</title> |
|||
<style> |
|||
body { |
|||
margin: 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
#label { |
|||
position: absolute; |
|||
padding: 10px; |
|||
background: rgba(255, 255, 255, 0.6); |
|||
line-height: 1; |
|||
border-radius: 5px; |
|||
} |
|||
|
|||
#video { |
|||
position: absolute; |
|||
width: 0; |
|||
height: 0; |
|||
} |
|||
|
|||
</style> |
|||
<script src="./lib/three.js"></script> |
|||
<script src="./lib/stats.min.js"></script> |
|||
<script src="./lib/DragControls.js"></script> |
|||
<script src="./lib/OrbitControls.js"></script> |
|||
<script src="./lib/FirstPersonControls.js"></script> |
|||
<script src="./lib/TransformControls.js"></script> |
|||
<script src="./lib/dat.gui.min.js"></script> |
|||
<script src="./lib/EffectComposer.js"></script> |
|||
<script src="./lib/RenderPass.js"></script> |
|||
<script src="./lib/OutlinePass.js"></script> |
|||
<script src="./lib/FXAAShader.js"></script> |
|||
<script src="./lib/CopyShader.js"></script> |
|||
<script src="./lib/ShaderPass.js"></script> |
|||
<script src="./lib/ThreeBSP.js"></script> |
|||
<script src="./lib/ThreeJs_Drag.js" charset="UTF-8"></script> |
|||
<script src="./lib/ThreeJs_Composer.js" charset="UTF-8"></script> |
|||
<script src="./lib/Modules.js" charset="UTF-8"></script> |
|||
<script src="./lib/Tween.js"></script> |
|||
<script src="./lib/jquery-1.11.0.min.js"></script> |
|||
<script src="./echarts/echarts.min.js"></script> |
|||
<script src="./lib/config.js"></script> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="label"></div> |
|||
<div id="container"></div> |
|||
<video id="video" autoplay loop muted> |
|||
<source src="./video/videoPlane.mp4"> |
|||
</video> |
|||
|
|||
<script> |
|||
|
|||
var stats = initStats(); |
|||
var scene, camera, renderer, controls, light, composer, transformControls, options; |
|||
var matArrayA = []; //内墙 |
|||
var matArrayB = []; //外墙 |
|||
var group = new THREE.Group(); |
|||
|
|||
// 初始化场景 |
|||
function initScene() { |
|||
scene = new THREE.Scene(); |
|||
} |
|||
|
|||
// 初始化相机 |
|||
function initCamera() { |
|||
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000); |
|||
camera.position.set(0, 50, 200); |
|||
} |
|||
|
|||
// 初始化灯光 |
|||
function initLight() { |
|||
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.3); //模拟远处类似太阳的光源 |
|||
directionalLight.color.setHSL(0.1, 1, 0.95); |
|||
directionalLight.position.set(0, 200, 0).normalize(); |
|||
scene.add(directionalLight); |
|||
|
|||
var ambient = new THREE.AmbientLight(0xffffff, 1); //AmbientLight,影响整个场景的光源 |
|||
ambient.position.set(0, 0, 0); |
|||
scene.add(ambient); |
|||
} |
|||
|
|||
// 初始化性能插件 |
|||
function initStats() { |
|||
var stats = new Stats(); |
|||
|
|||
stats.domElement.style.position = 'absolute'; |
|||
stats.domElement.style.left = '0px'; |
|||
stats.domElement.style.top = '0px'; |
|||
|
|||
document.body.appendChild(stats.domElement); |
|||
return stats; |
|||
} |
|||
|
|||
// 初始化GUI |
|||
function initGui() { |
|||
options = new function () { |
|||
this.batchNo = ''; this.qty = 0; this.qtyUom = ''; this.qty2 = 0; |
|||
this.实时全景监控 = function () { |
|||
window.open("3DVideo.html"); |
|||
}; |
|||
}; |
|||
var gui = new dat.GUI(); |
|||
gui.domElement.style = 'position:absolute;top:10px;right:0px;height:600px'; |
|||
gui.add(options, 'batchNo').name("物料批号:").listen(); |
|||
gui.add(options, 'qty').name("数量:").listen(); |
|||
gui.add(options, 'qtyUom').name("单位:").listen(); |
|||
gui.add(options, 'qty2').name("件数:").listen(); |
|||
gui.add(options, '实时全景监控'); |
|||
} |
|||
|
|||
// 初始化渲染器 |
|||
function initRenderer() { |
|||
renderer = new THREE.WebGLRenderer({ |
|||
antialias: true |
|||
}); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
renderer.setClearColor(0x4682B4, 1.0); |
|||
document.body.appendChild(renderer.domElement); |
|||
} |
|||
|
|||
//创建地板 |
|||
function createFloor() { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/floor.jpg", function (texture) { |
|||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; |
|||
texture.repeat.set(10, 10); |
|||
var floorGeometry = new THREE.BoxGeometry(2600, 1400, 1); |
|||
var floorMaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
}); |
|||
var floor = new THREE.Mesh(floorGeometry, floorMaterial); |
|||
floor.rotation.x = -Math.PI / 2; |
|||
floor.name = "地面"; |
|||
scene.add(floor); |
|||
}); |
|||
} |
|||
|
|||
//创建墙 |
|||
function createCubeWall(width, height, depth, angle, material, x, y, z, name) { |
|||
var cubeGeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.x = x; |
|||
cube.position.y = y; |
|||
cube.position.z = z; |
|||
cube.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
cube.name = name; |
|||
scene.add(cube); |
|||
} |
|||
|
|||
//创建门_左侧 |
|||
function createDoor_left(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/door_left.png", function (texture) { |
|||
var doorgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
doorgeometry.translate(50, 0, 0); |
|||
var doormaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
color: 0xffffff |
|||
}); |
|||
doormaterial.opacity = 1.0; |
|||
doormaterial.transparent = true; |
|||
var door = new THREE.Mesh(doorgeometry, doormaterial); |
|||
door.position.set(x, y, z); |
|||
door.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
door.name = name; |
|||
scene.add(door); |
|||
}); |
|||
} |
|||
|
|||
//创建门_右侧 |
|||
function createDoor_right(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/door_right.png", function (texture) { |
|||
var doorgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
doorgeometry.translate(-50, 0, 0); |
|||
var doormaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
color: 0xffffff |
|||
}); |
|||
doormaterial.opacity = 1.0; |
|||
doormaterial.transparent = true; |
|||
var door = new THREE.Mesh(doorgeometry, doormaterial); |
|||
door.position.set(x, y, z); |
|||
door.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针8 |
|||
door.name = name; |
|||
scene.add(door); |
|||
}); |
|||
} |
|||
|
|||
//创建窗户 |
|||
function createWindow(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("./ThreeJs/images/window.png", function (texture) { |
|||
var windowgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var windowmaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
color: 0xffffff |
|||
}); |
|||
windowmaterial.opacity = 1.0; |
|||
windowmaterial.transparent = true; |
|||
var window = new THREE.Mesh(windowgeometry, windowmaterial); |
|||
window.position.set(x, y, z); |
|||
window.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
window.name = name; |
|||
scene.add(window); |
|||
}); |
|||
} |
|||
|
|||
//返回墙对象 |
|||
function returnWallObject(width, height, depth, angle, material, x, y, z, name) { |
|||
var cubeGeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.x = x; |
|||
cube.position.y = y; |
|||
cube.position.z = z; |
|||
cube.rotation.y += angle * Math.PI; |
|||
cube.name = name; |
|||
return cube; |
|||
} |
|||
|
|||
//墙上挖门,通过两个几何体生成BSP对象 |
|||
function createResultBsp(bsp, objects_cube) { |
|||
var material = new THREE.MeshPhongMaterial({ |
|||
color: 0x9cb2d1, |
|||
specular: 0x9cb2d1, |
|||
shininess: 30, |
|||
transparent: true, |
|||
opacity: 1 |
|||
}); |
|||
var BSP = new ThreeBSP(bsp); |
|||
for (var i = 0; i < objects_cube.length; i++) { |
|||
var less_bsp = new ThreeBSP(objects_cube[i]); |
|||
BSP = BSP.subtract(less_bsp); |
|||
} |
|||
var result = BSP.toMesh(material); |
|||
result.material.flatshading = THREE.FlatShading; |
|||
result.geometry.computeFaceNormals(); //重新计算几何体侧面法向量 |
|||
result.geometry.computeVertexNormals(); |
|||
result.material.needsUpdate = true; //更新纹理 |
|||
result.geometry.buffersNeedUpdate = true; |
|||
result.geometry.uvsNeedUpdate = true; |
|||
scene.add(result); |
|||
} |
|||
|
|||
//创建墙纹理 |
|||
function createWallMaterail() { |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //前 0xafc0ca :灰色 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //后 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //上 0xd6e4ec: 偏白色 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //下 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //左 0xafc0ca :灰色 |
|||
matArrayA.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //右 |
|||
|
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //前 0xafc0ca :灰色 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0x9cb2d1 })); //后 0x9cb2d1:淡紫 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //上 0xd6e4ec: 偏白色 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xd6e4ec })); //下 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //左 0xafc0ca :灰色 |
|||
matArrayB.push(new THREE.MeshPhongMaterial({ color: 0xafc0ca })); //右 |
|||
} |
|||
|
|||
|
|||
// 初始化模型 |
|||
function initContent() { |
|||
createFloor(); |
|||
createWallMaterail(); |
|||
createCubeWall(10, 200, 1400, 0, matArrayB, -1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 1400, 1, matArrayB, 1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 2600, 1.5, matArrayB, 0, 100, -700, "墙面"); |
|||
//创建挖了门的墙 |
|||
var wall = returnWallObject(2600, 200, 10, 0, matArrayB, 0, 100, 700, "墙面"); |
|||
var door_cube1 = returnWallObject(200, 180, 10, 0, matArrayB, -600, 90, 700, "前门1"); |
|||
var door_cube2 = returnWallObject(200, 180, 10, 0, matArrayB, 600, 90, 700, "前门2"); |
|||
var window_cube1 = returnWallObject(100, 100, 10, 0, matArrayB, -900, 90, 700, "窗户1"); |
|||
var window_cube2 = returnWallObject(100, 100, 10, 0, matArrayB, 900, 90, 700, "窗户2"); |
|||
var window_cube3 = returnWallObject(100, 100, 10, 0, matArrayB, -200, 90, 700, "窗户3"); |
|||
var window_cube4 = returnWallObject(100, 100, 10, 0, matArrayB, 200, 90, 700, "窗户4"); |
|||
var objects_cube = []; |
|||
objects_cube.push(door_cube1); |
|||
objects_cube.push(door_cube2); |
|||
objects_cube.push(window_cube1); |
|||
objects_cube.push(window_cube2); |
|||
objects_cube.push(window_cube3); |
|||
objects_cube.push(window_cube4); |
|||
createResultBsp(wall, objects_cube); |
|||
//为墙面安装门 |
|||
createDoor_left(100, 180, 2, 0, -700, 90, 700, "左门1"); |
|||
createDoor_right(100, 180, 2, 0, -500, 90, 700, "右门1"); |
|||
createDoor_left(100, 180, 2, 0, 500, 90, 700, "左门2"); |
|||
createDoor_right(100, 180, 2, 0, 700, 90, 700, "右门2"); |
|||
//为墙面安装窗户 |
|||
createWindow(100, 100, 2, 0, -900, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, 900, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, -200, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, 200, 90, 700, "窗户"); |
|||
} |
|||
|
|||
// 初始化轨迹球控件 |
|||
function initControls() { |
|||
controls = new THREE.OrbitControls(camera, renderer.domElement); |
|||
controls.enableDamping = true; |
|||
controls.dampingFactor = 0.5; |
|||
// 视角最小距离 |
|||
controls.minDistance = 100; |
|||
// 视角最远距离 |
|||
controls.maxDistance = 1000; |
|||
// 最大角度 |
|||
controls.maxPolarAngle = Math.PI / 2.2; |
|||
controls.target = new THREE.Vector3(50, 50, 0); |
|||
} |
|||
|
|||
function initEcharts() { |
|||
pieChart = echarts.init($("<canvas width='512' height='512'></canvas>")[0]); |
|||
option = { |
|||
color: ['#3398DB'], |
|||
tooltip: { |
|||
trigger: 'axis', |
|||
axisPointer: { |
|||
type: 'shadow' |
|||
} |
|||
}, |
|||
grid: { |
|||
left: '3%', |
|||
right: '4%', |
|||
bottom: '3%', |
|||
containLabel: true |
|||
}, |
|||
xAxis: [ |
|||
{ |
|||
type: 'category', |
|||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], |
|||
axisTick: { |
|||
alignWithLabel: true |
|||
} |
|||
} |
|||
], |
|||
yAxis: [ |
|||
{ |
|||
type: 'value' |
|||
} |
|||
], |
|||
series: [ |
|||
{ |
|||
name: '直接访问', |
|||
type: 'bar', |
|||
barWidth: '60%', |
|||
data: [10, 52, 200, 334, 390, 330, 220] |
|||
} |
|||
] |
|||
}; |
|||
pieChart.setOption(option); |
|||
|
|||
pieChart.on('finished', function () { |
|||
var infoEchart = new THREE.TextureLoader().load(pieChart.getDataURL()); |
|||
|
|||
var infoEchartMaterial = new THREE.MeshBasicMaterial({ |
|||
transparent: true, |
|||
map: infoEchart, |
|||
side: THREE.DoubleSide |
|||
}); |
|||
|
|||
var echartPlane = new THREE.Mesh(new THREE.PlaneGeometry(100, 100), infoEchartMaterial); |
|||
echartPlane.position.set(100, 150, 0); |
|||
scene.add(echartPlane); |
|||
|
|||
}); |
|||
|
|||
pieChart2 = echarts.init($("<canvas width='512' height='512'></canvas>")[0]); |
|||
option2 = { |
|||
title: { |
|||
text: '某站点用户访问来源', |
|||
subtext: '纯属虚构', |
|||
x: 'center' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'item', |
|||
formatter: "{a} <br/>{b} : {c} ({d}%)" |
|||
}, |
|||
legend: { |
|||
orient: 'vertical', |
|||
left: 'left', |
|||
data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'] |
|||
}, |
|||
series: [ |
|||
{ |
|||
name: '访问来源', |
|||
type: 'pie', |
|||
radius: '55%', |
|||
center: ['50%', '60%'], |
|||
data: [ |
|||
{ value: 335, name: '直接访问' }, |
|||
{ value: 310, name: '邮件营销' }, |
|||
{ value: 234, name: '联盟广告' }, |
|||
{ value: 135, name: '视频广告' }, |
|||
{ value: 1548, name: '搜索引擎' } |
|||
], |
|||
itemStyle: { |
|||
emphasis: { |
|||
shadowBlur: 10, |
|||
shadowOffsetX: 0, |
|||
shadowColor: 'rgba(0, 0, 0, 0.5)' |
|||
} |
|||
} |
|||
} |
|||
] |
|||
}; |
|||
pieChart2.setOption(option2); |
|||
|
|||
pieChart2.on('finished', function () { |
|||
var spriteMap = new THREE.TextureLoader().load(pieChart2.getDataURL()); |
|||
|
|||
var spriteMaterial = new THREE.SpriteMaterial({ |
|||
transparent: true, |
|||
map: spriteMap, |
|||
side: THREE.DoubleSide |
|||
}); |
|||
|
|||
var sprite = new THREE.Sprite(spriteMaterial); |
|||
sprite.scale.set(150, 150, 1) |
|||
sprite.position.set(-100, 180, 0); |
|||
scene.add(sprite); |
|||
|
|||
}); |
|||
} |
|||
|
|||
// 初始化 |
|||
function init() { |
|||
initMat(); |
|||
initScene(); |
|||
addSkybox(10000, scene); |
|||
addVideoPlane(0, 60, -690, 200, 100, scene, 'video'); |
|||
initCamera(); |
|||
initRenderer(); |
|||
initContent(); |
|||
initLight(); |
|||
initControls(); |
|||
initGui(); |
|||
initEcharts(); |
|||
|
|||
addArea(0, 0, 1000, 500, scene, "ID1$库区1号", "FF0000", 20, "左对齐"); |
|||
|
|||
addShelf(scene); |
|||
|
|||
//添加货物 |
|||
var shelf_list = GET_SHELF_LIST(); |
|||
for (var i = 1; i <= GET_LAYER_NUM(); i++) { |
|||
for (var j = 1; j <= GET_COLUMN_NUM(); j++) { |
|||
for (var k = 1; k <= shelf_list.length; k++) { |
|||
addOneUnitCargos(shelf_list[k - 1].shelfId, i, j, scene); |
|||
} |
|||
} |
|||
} |
|||
|
|||
//添加选中时的蒙版 |
|||
composer = new THREE.ThreeJs_Composer(renderer, scene, camera, options); |
|||
|
|||
//添加拖动效果 |
|||
// 过滤不是 Mesh 的物体,例如辅助网格 |
|||
var objects = []; |
|||
for (var i = 0; i < scene.children.length; i++) { |
|||
var Msg = scene.children[i].name.split("$"); |
|||
if (scene.children[i].isMesh && Msg[0] == "货物") { |
|||
objects.push(scene.children[i]); |
|||
} |
|||
} |
|||
|
|||
var dragControls = new THREE.DragControls(objects, camera, renderer.domElement); |
|||
dragControls.addEventListener('dragstart', function (event) { |
|||
controls.enabled = false; |
|||
isPaused = true; |
|||
}); |
|||
dragControls.addEventListener('dragend', function (event) { |
|||
controls.enabled = true; |
|||
isPaused = false; |
|||
}); |
|||
|
|||
document.addEventListener('resize', onWindowResize, false); |
|||
} |
|||
|
|||
// 窗口变动触发的方法 |
|||
function onWindowResize() { |
|||
camera.aspect = window.innerWidth / window.innerHeight; |
|||
camera.updateProjectionMatrix(); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
} |
|||
|
|||
function animate() { |
|||
requestAnimationFrame(animate); |
|||
renderer.render(scene, camera); |
|||
composer.render(); |
|||
update(); |
|||
} |
|||
|
|||
// 更新控件 |
|||
function update() { |
|||
stats.update(); |
|||
controls.update(); |
|||
TWEEN.update(); |
|||
RollTexture.offset.x += 0.001; |
|||
} |
|||
|
|||
init(); |
|||
animate(); |
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,622 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
|
|||
<head> |
|||
<title>Threejs实现数字化工厂安全生产监控</title> |
|||
<meta charset="UTF-8"> |
|||
<script type="text/javascript" src="lib/statistics.js"></script> |
|||
<!-- <script type="text/javascript" src="lib/steak.js"></script> --> |
|||
<script type="text/javascript" src="lib/three.js"></script> |
|||
<script type="text/javascript" src="lib/OrbitControls.js"></script> |
|||
<script type="text/javascript" src="lib/GLTFLoader.js"></script> |
|||
<script type="text/javascript" src="lib/ThreeBSP.js"></script> |
|||
<script type="text/javascript" src="lib/dat.gui.js"></script> |
|||
<script type="text/javascript" charset="UTF-8" src="lib/Tween.min.js"></script> |
|||
<style> |
|||
body { |
|||
margin: 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
</style> |
|||
</head> |
|||
|
|||
<body> |
|||
<div id="dom"></div> |
|||
<script type="text/javascript"> |
|||
var camera; |
|||
var renderer; |
|||
var peopleMesh; |
|||
var peopleMixer; |
|||
var mixer; |
|||
var matArrayA = []; //内墙 |
|||
var matArr = []; //外墙 |
|||
var texture; |
|||
var textureSecure; |
|||
var curve; |
|||
|
|||
function init() { |
|||
var urls = [ |
|||
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/posx.jpg', |
|||
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/negx.jpg', |
|||
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/posy.jpg', |
|||
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/negy.jpg', |
|||
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/posz.jpg', |
|||
'http://zuoben.top/#3-8/assets/bgImage/skyBox6/negz.jpg' |
|||
]; |
|||
// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。 |
|||
var scene = new THREE.Scene(); |
|||
var cubeLoader = new THREE.CubeTextureLoader(); |
|||
// scene.background = cubeLoader.load(urls); |
|||
scene.opacity = 0; |
|||
|
|||
// 创建一个摄像机,它定义了我们正在看的地方 |
|||
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100000); |
|||
// 将摄像机对准场景的中心 |
|||
camera.position.z = 2000; |
|||
camera.position.y = 800; |
|||
camera.lookAt(scene.position); |
|||
var orbit = new THREE.OrbitControls(camera); |
|||
|
|||
// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景 |
|||
renderer = new THREE.WebGLRenderer({ |
|||
antialias: true, |
|||
logarithmicDepthBuffer: true, |
|||
}); |
|||
renderer.setClearColor(new THREE.Color("#0e0934")); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
|
|||
var ambientLight = new THREE.AmbientLight("#ffffff", 1); |
|||
scene.add(ambientLight); |
|||
|
|||
// 将呈现器的输出添加到HTML元素 |
|||
document.getElementById("dom").appendChild(renderer.domElement); |
|||
|
|||
// 启动动画 |
|||
renderScene(); |
|||
initContent(); |
|||
initSloganModel(); |
|||
|
|||
for (var i = 0; i < 8; i++) { |
|||
let px = 1060 - i * 300; |
|||
addArea(px, -400, 200, 500, scene, "库区1-" + (i + 1) + "号", "FF0000", 20, "居中"); |
|||
} |
|||
for (var i = 0; i < 8; i++) { |
|||
let px = 1060 - i * 300; |
|||
if (i != 1 && i != 2 && i != 5 && i != 6) { |
|||
addArea(px, 400, 200, 500, scene, "库区2-" + (i + 1) + "号", "FF0000", 20, "居中"); |
|||
} |
|||
} |
|||
initSecureModel(); |
|||
|
|||
// 初始化模型 |
|||
function initContent() { |
|||
createFloor(); |
|||
createWallMaterail(); |
|||
var mat = new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
}); |
|||
createCubeWall(10, 200, 1400, 0, matArr, -1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 1400, 1, matArr, 1295, 100, 0, "墙面"); |
|||
createCubeWall(10, 200, 2600, 1.5, matArr, 0, 100, -700, "墙面"); |
|||
//创建挖了门的墙 |
|||
var wall = returnWallObject(2600, 200, 10, 0, mat, 0, 100, 700, "墙面"); |
|||
var door_cube1 = returnWallObject(200, 180, 10, 0, mat, -600, 90, 700, "前门1"); |
|||
var door_cube2 = returnWallObject(200, 180, 10, 0, mat, 600, 90, 700, "前门2"); |
|||
var window_cube1 = returnWallObject(100, 100, 10, 0, mat, -900, 90, 700, "窗户1"); |
|||
var window_cube2 = returnWallObject(100, 100, 10, 0, mat, 900, 90, 700, "窗户2"); |
|||
var window_cube3 = returnWallObject(100, 100, 10, 0, mat, -200, 90, 700, "窗户3"); |
|||
var window_cube4 = returnWallObject(100, 100, 10, 0, mat, 200, 90, 700, "窗户4"); |
|||
var objects_cube = []; |
|||
objects_cube.push(door_cube1); |
|||
objects_cube.push(door_cube2); |
|||
objects_cube.push(window_cube1); |
|||
objects_cube.push(window_cube2); |
|||
objects_cube.push(window_cube3); |
|||
objects_cube.push(window_cube4); |
|||
createResultBsp(wall, objects_cube); |
|||
// 为墙面安装门 |
|||
createDoor(100, 180, 2, 0, -700, 90, 700, "左门1"); |
|||
createDoor(100, 180, 2, 0, -500, 90, 700, "右门1"); |
|||
createDoor(100, 180, 2, 0, 500, 90, 700, "左门2"); |
|||
createDoor(100, 180, 2, 0, 700, 90, 700, "右门2"); |
|||
// 为墙面安装窗户 |
|||
createWindow(100, 100, 2, 0, -900, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, 900, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, -200, 90, 700, "窗户"); |
|||
createWindow(100, 100, 2, 0, 200, 90, 700, "窗户"); |
|||
} |
|||
|
|||
setTimeout(function () { |
|||
doorOpenColse(true); |
|||
}, 2000); |
|||
setTimeout(function () { |
|||
initPeople(); |
|||
}, 2500); |
|||
|
|||
// 添加人物模型 |
|||
function initPeople() { |
|||
var loader = new THREE.GLTFLoader(); |
|||
loader.load('http://zuoben.top/#3-8/assets/models/man/man.gltf', function (result) { |
|||
console.log(result) |
|||
result.scene.scale.set(50, 50, 50); |
|||
// result.scene.rotation.y = Math.PI / 2; |
|||
peopleMesh = result.scene; |
|||
scene.add(peopleMesh); |
|||
|
|||
peopleMixer = new THREE.AnimationMixer(peopleMesh); |
|||
let AnimationAction = peopleMixer.clipAction(result.animations[0]); |
|||
AnimationAction.play(); |
|||
|
|||
motion() |
|||
}); |
|||
} |
|||
|
|||
function motion() { |
|||
// 通过类CatmullRomCurve3创建一个3D样条曲线 |
|||
curve = new THREE.CatmullRomCurve3([ |
|||
new THREE.Vector3(602, 3, 790), |
|||
new THREE.Vector3(597, 3, -3), |
|||
new THREE.Vector3(-605, 3, -3), |
|||
new THREE.Vector3(-602, 3, 790) |
|||
], false, "catmullrom", 0.01); |
|||
// 样条曲线均匀分割100分,返回51个顶点坐标 |
|||
var points = curve.getPoints(100); |
|||
var geometry = new THREE.Geometry(); |
|||
// 把从曲线轨迹上获得的顶点坐标赋值给几何体 |
|||
geometry.vertices = points |
|||
var material = new THREE.LineBasicMaterial({ |
|||
color: 0x4488ff |
|||
}); |
|||
var line = new THREE.Line(geometry, material); |
|||
// scene.add(line) |
|||
|
|||
// 通过Threejs的帧动画相关API播放网格模型沿着曲线做动画运动 |
|||
// 声明一个数组用于存储时间序列 |
|||
let arr = [] |
|||
for (let i = 0; i < 101; i++) { |
|||
arr.push(i) |
|||
} |
|||
// 生成一个时间序列 |
|||
var times = new Float32Array(arr); |
|||
|
|||
var posArr = [] |
|||
points.forEach(elem => { |
|||
posArr.push(elem.x, elem.y, elem.z) |
|||
}); |
|||
// 创建一个和时间序列相对应的位置坐标系列 |
|||
var values = new Float32Array(posArr); |
|||
// 创建一个帧动画的关键帧数据,曲线上的位置序列对应一个时间序列 |
|||
var posTrack = new THREE.KeyframeTrack('.position', times, values); |
|||
let duration = 101; |
|||
let clip = new THREE.AnimationClip("default", duration, [posTrack]); |
|||
mixer = new THREE.AnimationMixer(peopleMesh); |
|||
let AnimationAction = mixer.clipAction(clip); |
|||
AnimationAction.play(); |
|||
} |
|||
|
|||
function changeLookAt(t) { |
|||
// 当前点在线条上的位置 |
|||
var position = curve.getPointAt(t); |
|||
peopleMesh.position.copy(position); |
|||
if (position.z < 0) { |
|||
peopleMesh.rotation.y = Math.PI; |
|||
// camera.position.set(position.x + 200, 70, position.z); |
|||
} |
|||
if (position.z > 0 && position.x > 0) { |
|||
peopleMesh.rotation.y = Math.PI / 2; |
|||
// camera.position.set(position.x , 70, position.z+ 200); |
|||
} |
|||
if (position.z > 0 && position.x < 0) { |
|||
peopleMesh.rotation.y = -Math.PI / 2; |
|||
// camera.position.set(position.x , 70, position.z - 200); |
|||
} |
|||
// console.log(position) |
|||
// camera.position.set(position.x / 2, 69, position.z / 2); |
|||
camera.lookAt(position); |
|||
// camera.lookAt(position);659.0248303057256, y: 69.31162905236907, z: 921 |
|||
|
|||
|
|||
// 返回一个点t在曲线上位置向量的法线向量 |
|||
const tangent = curve.getTangentAt(t); |
|||
// 位置向量和切线向量相加即为所需朝向的点向量 |
|||
const lookAtVec = tangent.add(position); |
|||
// peopleMesh.lookAt(lookAtVec); |
|||
} |
|||
|
|||
//Secure 安全通道 |
|||
function initSecureModel() { |
|||
var planGeometry = new THREE.PlaneGeometry(680, 40); |
|||
textureSecure = new THREE.TextureLoader().load('assets/textures/roll.png'); |
|||
textureSecure.wrapS = THREE.RepeatWrapping |
|||
|
|||
var tubeMaterial = new THREE.MeshBasicMaterial({ |
|||
map: textureSecure, |
|||
transparent: true, |
|||
side: THREE.DoubleSide, |
|||
}); |
|||
|
|||
// 设置数组材质对象作为网格模型材质参数 |
|||
var obj = new THREE.Mesh(planGeometry, tubeMaterial); //网格模型对象Mesh |
|||
obj.position.z = 350; |
|||
obj.position.y = 1.5; |
|||
obj.position.x = 599; |
|||
obj.rotateX(Math.PI / 2.0); |
|||
obj.rotateZ(Math.PI / 2.0); |
|||
var obj2 = obj.clone(); |
|||
obj2.translateY(1200); |
|||
obj2.rotateZ(Math.PI); |
|||
|
|||
var geometry2 = new THREE.PlaneGeometry(1230, 40); |
|||
var obj3 = new THREE.Mesh(geometry2, tubeMaterial); |
|||
obj3.position.set(0, 1.5, -10); |
|||
obj3.rotation.x = -Math.PI / 2.0; |
|||
|
|||
var group = new THREE.Group(); |
|||
group.add(obj); |
|||
group.add(obj2); |
|||
group.add(obj3); |
|||
scene.add(group); |
|||
} |
|||
|
|||
//region 矩形区域 |
|||
function addPlane(x, z, width, length, scene) { |
|||
var LineMat = new THREE.MeshLambertMaterial(); |
|||
new THREE.TextureLoader().load("http://zuoben.top/#3-8/assets/textures/line.png", function (map) { |
|||
LineMat.map = map; |
|||
LineMat.needsUpdate = true; |
|||
}); |
|||
var lineWidth = 8 |
|||
var geometry = new THREE.PlaneGeometry(lineWidth, length); |
|||
var obj = new THREE.Mesh(geometry, LineMat); |
|||
obj.position.set(x, 1.5, z); |
|||
obj.rotation.x = -Math.PI / 2.0; |
|||
var obj2 = obj.clone(); |
|||
obj2.translateX(width); |
|||
|
|||
var geometry2 = new THREE.PlaneGeometry(lineWidth, width); |
|||
var obj3 = new THREE.Mesh(geometry2, LineMat); |
|||
obj3.position.set(x + width / 2, 1.5, z - length / 2 + lineWidth / 2); |
|||
obj3.rotation.x = -Math.PI / 2.0; |
|||
obj3.rotation.z = -Math.PI / 2.0; |
|||
var obj4 = obj3.clone(); |
|||
obj4.translateX(length - lineWidth); |
|||
|
|||
var group = new THREE.Group(); |
|||
group.add(obj); |
|||
group.add(obj2); |
|||
group.add(obj3); |
|||
group.add(obj4); |
|||
group.translateX(-width / 2); |
|||
scene.add(group); |
|||
} |
|||
|
|||
// 口号标语 |
|||
function initSloganModel() { |
|||
var planGeometry = new THREE.PlaneGeometry(500, 35); |
|||
texture = new THREE.TextureLoader().load('assets/textures/biaoyu.png'); |
|||
texture.wrapS = THREE.RepeatWrapping |
|||
|
|||
var tubeMaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
transparent: true, |
|||
side: THREE.DoubleSide, |
|||
}); |
|||
|
|||
// 设置数组材质对象作为网格模型材质参数 |
|||
var mesh = new THREE.Mesh(planGeometry, tubeMaterial); //网格模型对象Mesh |
|||
mesh.position.y = 175; |
|||
mesh.position.z = 710; |
|||
// mesh.rotateZ(3.14); |
|||
scene.add(mesh); //网格模型添加到场景中 |
|||
} |
|||
|
|||
//region 库区 |
|||
/** 放置虚线框区域和库区名称 */ |
|||
function addArea(x, z, width, length, scene, name, textColor, font_size, textposition) { |
|||
addPlane(x, z, width, length, scene); |
|||
|
|||
new THREE.FontLoader().load('http://zuoben.top/#3-8/font/FZYaoTi_Regular.json', function (font) { |
|||
//加入立体文字 |
|||
var text = new THREE.TextGeometry(name, { |
|||
// 设定文字字体 |
|||
font: font, |
|||
//尺寸 |
|||
size: font_size, |
|||
//厚度 |
|||
height: 0.01 |
|||
}); |
|||
text.computeBoundingBox(); |
|||
//3D文字材质 |
|||
var m = new THREE.MeshStandardMaterial({ |
|||
color: "#" + textColor |
|||
}); |
|||
var mesh = new THREE.Mesh(text, m) |
|||
if (textposition == "左对齐") { |
|||
mesh.position.x = x - width / 2 + 10; |
|||
} else if (textposition == "居中") { |
|||
mesh.position.x = x - 65; |
|||
} else if (textposition == "右对齐") { |
|||
mesh.position.x = x + width / 2 - 60; |
|||
} |
|||
mesh.position.y = 1.3; |
|||
mesh.position.z = z + length / 2 - 20; |
|||
mesh.rotation.x = -Math.PI / 2.0; |
|||
scene.add(mesh); |
|||
}); |
|||
} |
|||
|
|||
//创建墙纹理 |
|||
function createWallMaterail() { |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
})); //前 0xafc0ca :灰色 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0x9cb2d1 |
|||
})); //后 0x9cb2d1:淡紫 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xd6e4ec |
|||
})); //上 0xd6e4ec: 偏白色 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xd6e4ec |
|||
})); //下 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
})); //左 0xafc0ca :灰色 |
|||
matArr.push(new THREE.MeshPhongMaterial({ |
|||
color: 0xafc0ca |
|||
})); //右 |
|||
} |
|||
|
|||
//返回墙对象 |
|||
function returnWallObject(width, height, depth, angle, material, x, y, z, name) { |
|||
var cubeGeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.x = x; |
|||
cube.position.y = y; |
|||
cube.position.z = z; |
|||
cube.rotation.y += angle * Math.PI; |
|||
cube.name = name; |
|||
return cube; |
|||
} |
|||
|
|||
//墙上挖门,通过两个几何体生成BSP对象 |
|||
function createResultBsp(bsp, objects_cube) { |
|||
var material = new THREE.MeshPhongMaterial({ |
|||
color: 0x9cb2d1, |
|||
specular: 0x9cb2d1, |
|||
shininess: 30, |
|||
transparent: true, |
|||
opacity: 1 |
|||
}); |
|||
var BSP = new ThreeBSP(bsp); |
|||
for (var i = 0; i < objects_cube.length; i++) { |
|||
var less_bsp = new ThreeBSP(objects_cube[i]); |
|||
BSP = BSP.subtract(less_bsp); |
|||
} |
|||
var result = BSP.toMesh(material); |
|||
result.material.flatshading = THREE.FlatShading; |
|||
result.geometry.computeFaceNormals(); //重新计算几何体侧面法向量 |
|||
result.geometry.computeVertexNormals(); |
|||
result.material.needsUpdate = true; //更新纹理 |
|||
result.geometry.buffersNeedUpdate = true; |
|||
result.geometry.uvsNeedUpdate = true; |
|||
scene.add(result); |
|||
} |
|||
|
|||
//创建地板 |
|||
function createFloor() { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("assets/textures/floor.jpg", function (texture) { |
|||
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; |
|||
texture.repeat.set(10, 10); |
|||
var floorGeometry = new THREE.BoxGeometry(2600, 1400, 1); |
|||
var floorMaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
}); |
|||
var floor = new THREE.Mesh(floorGeometry, floorMaterial); |
|||
floor.rotation.x = -Math.PI / 2; |
|||
floor.name = "地面"; |
|||
scene.add(floor); |
|||
}); |
|||
} |
|||
|
|||
//创建墙 |
|||
function createCubeWall(width, height, depth, angle, material, x, y, z, name) { |
|||
var cubeGeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var cube = new THREE.Mesh(cubeGeometry, material); |
|||
cube.position.x = x; |
|||
cube.position.y = y; |
|||
cube.position.z = z; |
|||
cube.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
cube.name = name; |
|||
scene.add(cube); |
|||
} |
|||
|
|||
//创建门 |
|||
function createDoor(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
|
|||
var doorgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var doormaterial_left = new THREE.MeshPhongMaterial({ |
|||
map: loader.load("http://zuoben.top/#3-8/assets/textures/door_left.png") |
|||
}); |
|||
doormaterial_left.opacity = 1.0; |
|||
doormaterial_left.transparent = true; |
|||
var doormaterial_right = new THREE.MeshPhongMaterial({ |
|||
map: loader.load("http://zuoben.top/#3-8/assets/textures/door_right.png") |
|||
}); |
|||
doormaterial_right.opacity = 1.0; |
|||
doormaterial_right.transparent = true; |
|||
|
|||
var doormaterialArr = []; |
|||
if (name.indexOf("左门") > -1) { |
|||
doorgeometry.translate(50, 0, 0); |
|||
doormaterialArr = [doormaterial_left, doormaterial_left, doormaterial_left, |
|||
doormaterial_left, doormaterial_left, doormaterial_right |
|||
]; |
|||
} else { |
|||
doorgeometry.translate(-50, 0, 0); |
|||
doormaterialArr = [doormaterial_right, doormaterial_right, doormaterial_right, |
|||
doormaterial_right, doormaterial_right, doormaterial_left |
|||
]; |
|||
} |
|||
|
|||
var door = new THREE.Mesh(doorgeometry, doormaterialArr); |
|||
door.position.set(x, y, z); |
|||
door.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
door.name = name; |
|||
scene.add(door); |
|||
} |
|||
|
|||
//创建窗户 |
|||
function createWindow(width, height, depth, angle, x, y, z, name) { |
|||
var loader = new THREE.TextureLoader(); |
|||
loader.load("assets/textures/window.png", function (texture) { |
|||
var windowgeometry = new THREE.BoxGeometry(width, height, depth); |
|||
var windowmaterial = new THREE.MeshBasicMaterial({ |
|||
map: texture, |
|||
color: 0xffffff |
|||
}); |
|||
windowmaterial.opacity = 1.0; |
|||
windowmaterial.transparent = true; |
|||
var window = new THREE.Mesh(windowgeometry, windowmaterial); |
|||
window.position.set(x, y, z); |
|||
window.rotation.y += angle * Math.PI; //-逆时针旋转,+顺时针 |
|||
window.name = name; |
|||
scene.add(window); |
|||
}); |
|||
} |
|||
|
|||
// 键盘事件 |
|||
document.onkeydown = function (event) { |
|||
// 打开 |
|||
if (event.keyCode == 79) { |
|||
doorOpenColse(true); |
|||
} |
|||
// 关闭 |
|||
if (event.keyCode == 67) { |
|||
doorOpenColse(false); |
|||
} |
|||
} |
|||
|
|||
// 门打开关闭 |
|||
function doorOpenColse(bool) { |
|||
|
|||
var l1 = scene.getObjectByName("左门1"); |
|||
var l2 = scene.getObjectByName("左门2"); |
|||
var r1 = scene.getObjectByName("右门1"); |
|||
var r2 = scene.getObjectByName("右门2"); |
|||
// 打开 |
|||
if (bool) { |
|||
new TWEEN.Tween({ |
|||
lv: 0, |
|||
rv: 0, |
|||
}) |
|||
.to({ |
|||
lv: -0.5 * Math.PI, |
|||
rv: 0.5 * Math.PI, |
|||
}, 1000) |
|||
.easing(TWEEN.Easing.Bounce.Out) |
|||
.onUpdate(function () { |
|||
l1.rotation.y = this.lv; |
|||
l2.rotation.y = this.lv; |
|||
r1.rotation.y = this.rv; |
|||
r2.rotation.y = this.rv; |
|||
}) |
|||
.start(); |
|||
} |
|||
// 关闭 |
|||
if (!bool) { |
|||
new TWEEN.Tween({ |
|||
lv: -0.5 * Math.PI, |
|||
rv: 0.5 * Math.PI, |
|||
}) |
|||
.to({ |
|||
lv: 0, |
|||
rv: 0, |
|||
}, 1000) |
|||
.easing(TWEEN.Easing.Bounce.Out) |
|||
.onUpdate(function () { |
|||
l1.rotation.y = this.lv; |
|||
l2.rotation.y = this.lv; |
|||
r1.rotation.y = this.rv; |
|||
r2.rotation.y = this.rv; |
|||
}) |
|||
.start(); |
|||
} |
|||
} |
|||
|
|||
// 拾取对象 |
|||
function pickupObjects(event) { |
|||
// 点击屏幕创建一个向量 |
|||
var raycaster = new THREE.Raycaster(); |
|||
var vector = new THREE.Vector2((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window |
|||
.innerHeight) * 2 + 1); |
|||
var fxl = new THREE.Vector3(0, 1, 0); |
|||
var groundplane = new THREE.Plane(fxl, 0); |
|||
raycaster.setFromCamera(vector, camera); |
|||
var ray = raycaster.ray; |
|||
let intersects = ray.intersectPlane(groundplane); |
|||
console.log(intersects) |
|||
|
|||
|
|||
// 点击屏幕创建一个向量 |
|||
var vector1 = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window |
|||
.innerHeight) * 2 + 1, 0.5); |
|||
vector1 = vector1.unproject(camera); // 将屏幕的坐标转换成三维场景中的坐标 |
|||
var raycaster = new THREE.Raycaster(camera.position, vector1.sub(camera.position).normalize()); |
|||
var intersects1 = raycaster.intersectObjects(scene.children, true); |
|||
if (intersects1.length > 0) { |
|||
console.log(intersects1) |
|||
// intersects1[0].object.material.color.set("#ff0000"); |
|||
} |
|||
} |
|||
document.addEventListener('click', pickupObjects, false); //监听单击拾取对象初始化球体 |
|||
|
|||
var clock = new THREE.Clock(); //声明一个时钟对象 |
|||
const loopTime = 50 * 1000; // loopTime: 循环一圈的时间 |
|||
function renderScene() { |
|||
orbit.update(); |
|||
TWEEN.update(); |
|||
// 使用requestAnimationFrame函数进行渲染 |
|||
requestAnimationFrame(renderScene); |
|||
renderer.render(scene, camera); |
|||
// 更新帧动画的时间 |
|||
if (mixer) { |
|||
// mixer.update(clock.getDelta()); |
|||
} |
|||
if (peopleMixer) { |
|||
peopleMixer.update(clock.getDelta()); |
|||
} |
|||
|
|||
if (curve) { |
|||
let time = Date.now(); |
|||
let t = (time % loopTime) / loopTime; // 计算当前时间进度百分比 |
|||
changeLookAt(t); |
|||
} |
|||
|
|||
if (textureSecure) { |
|||
texture.offset.x += 0.004; |
|||
textureSecure.offset.x += 0.0005; |
|||
} |
|||
// console.log(camera.position) |
|||
} |
|||
|
|||
// 渲染的场景 |
|||
renderer.render(scene, camera); |
|||
} |
|||
window.onload = init; |
|||
|
|||
// 随着窗体的变化修改场景 |
|||
function onResize() { |
|||
camera.aspect = window.innerWidth / window.innerHeight; |
|||
camera.updateProjectionMatrix(); |
|||
renderer.setSize(window.innerWidth, window.innerHeight); |
|||
} |
|||
// 监听窗体调整大小事件 |
|||
window.addEventListener('resize', onResize, false); |
|||
</script> |
|||
</body> |
|||
|
|||
</html> |
Loading…
Reference in new issue