添加关照、全局等高线、修改图层问题
This commit is contained in:
130
dist/electron/static/sdk/three/jsm/helpers/LightProbeHelper.js
vendored
Normal file
130
dist/electron/static/sdk/three/jsm/helpers/LightProbeHelper.js
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
import {
|
||||
Mesh,
|
||||
ShaderMaterial,
|
||||
SphereGeometry
|
||||
} from 'three';
|
||||
|
||||
class LightProbeHelper extends Mesh {
|
||||
|
||||
constructor( lightProbe, size ) {
|
||||
|
||||
const material = new ShaderMaterial( {
|
||||
|
||||
type: 'LightProbeHelperMaterial',
|
||||
|
||||
uniforms: {
|
||||
|
||||
sh: { value: lightProbe.sh.coefficients }, // by reference
|
||||
|
||||
intensity: { value: lightProbe.intensity }
|
||||
|
||||
},
|
||||
|
||||
vertexShader: [
|
||||
|
||||
'varying vec3 vNormal;',
|
||||
|
||||
'void main() {',
|
||||
|
||||
' vNormal = normalize( normalMatrix * normal );',
|
||||
|
||||
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
|
||||
|
||||
'}',
|
||||
|
||||
].join( '\n' ),
|
||||
|
||||
fragmentShader: [
|
||||
|
||||
'#define RECIPROCAL_PI 0.318309886',
|
||||
|
||||
'vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {',
|
||||
|
||||
' // matrix is assumed to be orthogonal',
|
||||
|
||||
' return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );',
|
||||
|
||||
'}',
|
||||
|
||||
'// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf',
|
||||
'vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {',
|
||||
|
||||
' // normal is assumed to have unit length',
|
||||
|
||||
' float x = normal.x, y = normal.y, z = normal.z;',
|
||||
|
||||
' // band 0',
|
||||
' vec3 result = shCoefficients[ 0 ] * 0.886227;',
|
||||
|
||||
' // band 1',
|
||||
' result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;',
|
||||
' result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;',
|
||||
' result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;',
|
||||
|
||||
' // band 2',
|
||||
' result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;',
|
||||
' result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;',
|
||||
' result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );',
|
||||
' result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;',
|
||||
' result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );',
|
||||
|
||||
' return result;',
|
||||
|
||||
'}',
|
||||
|
||||
'uniform vec3 sh[ 9 ]; // sh coefficients',
|
||||
|
||||
'uniform float intensity; // light probe intensity',
|
||||
|
||||
'varying vec3 vNormal;',
|
||||
|
||||
'void main() {',
|
||||
|
||||
' vec3 normal = normalize( vNormal );',
|
||||
|
||||
' vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );',
|
||||
|
||||
' vec3 irradiance = shGetIrradianceAt( worldNormal, sh );',
|
||||
|
||||
' vec3 outgoingLight = RECIPROCAL_PI * irradiance * intensity;',
|
||||
|
||||
' gl_FragColor = linearToOutputTexel( vec4( outgoingLight, 1.0 ) );',
|
||||
|
||||
'}'
|
||||
|
||||
].join( '\n' )
|
||||
|
||||
} );
|
||||
|
||||
const geometry = new SphereGeometry( 1, 32, 16 );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.lightProbe = lightProbe;
|
||||
this.size = size;
|
||||
this.type = 'LightProbeHelper';
|
||||
|
||||
this.onBeforeRender();
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
onBeforeRender() {
|
||||
|
||||
this.position.copy( this.lightProbe.position );
|
||||
|
||||
this.scale.set( 1, 1, 1 ).multiplyScalar( this.size );
|
||||
|
||||
this.material.uniforms.intensity.value = this.lightProbe.intensity;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { LightProbeHelper };
|
73
dist/electron/static/sdk/three/jsm/helpers/OctreeHelper.js
vendored
Normal file
73
dist/electron/static/sdk/three/jsm/helpers/OctreeHelper.js
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
import {
|
||||
LineSegments,
|
||||
BufferGeometry,
|
||||
Float32BufferAttribute,
|
||||
LineBasicMaterial
|
||||
} from 'three';
|
||||
|
||||
class OctreeHelper extends LineSegments {
|
||||
|
||||
constructor( octree, color = 0xffff00 ) {
|
||||
|
||||
super( new BufferGeometry(), new LineBasicMaterial( { color: color, toneMapped: false } ) );
|
||||
|
||||
this.octree = octree;
|
||||
this.color = color;
|
||||
|
||||
this.type = 'OctreeHelper';
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const vertices = [];
|
||||
|
||||
function traverse( tree ) {
|
||||
|
||||
for ( let i = 0; i < tree.length; i ++ ) {
|
||||
|
||||
const min = tree[ i ].box.min;
|
||||
const max = tree[ i ].box.max;
|
||||
|
||||
vertices.push( max.x, max.y, max.z ); vertices.push( min.x, max.y, max.z ); // 0, 1
|
||||
vertices.push( min.x, max.y, max.z ); vertices.push( min.x, min.y, max.z ); // 1, 2
|
||||
vertices.push( min.x, min.y, max.z ); vertices.push( max.x, min.y, max.z ); // 2, 3
|
||||
vertices.push( max.x, min.y, max.z ); vertices.push( max.x, max.y, max.z ); // 3, 0
|
||||
|
||||
vertices.push( max.x, max.y, min.z ); vertices.push( min.x, max.y, min.z ); // 4, 5
|
||||
vertices.push( min.x, max.y, min.z ); vertices.push( min.x, min.y, min.z ); // 5, 6
|
||||
vertices.push( min.x, min.y, min.z ); vertices.push( max.x, min.y, min.z ); // 6, 7
|
||||
vertices.push( max.x, min.y, min.z ); vertices.push( max.x, max.y, min.z ); // 7, 4
|
||||
|
||||
vertices.push( max.x, max.y, max.z ); vertices.push( max.x, max.y, min.z ); // 0, 4
|
||||
vertices.push( min.x, max.y, max.z ); vertices.push( min.x, max.y, min.z ); // 1, 5
|
||||
vertices.push( min.x, min.y, max.z ); vertices.push( min.x, min.y, min.z ); // 2, 6
|
||||
vertices.push( max.x, min.y, max.z ); vertices.push( max.x, min.y, min.z ); // 3, 7
|
||||
|
||||
traverse( tree[ i ].subTrees );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
traverse( this.octree.subTrees );
|
||||
|
||||
this.geometry.dispose();
|
||||
|
||||
this.geometry = new BufferGeometry();
|
||||
this.geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { OctreeHelper };
|
109
dist/electron/static/sdk/three/jsm/helpers/PositionalAudioHelper.js
vendored
Normal file
109
dist/electron/static/sdk/three/jsm/helpers/PositionalAudioHelper.js
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
import {
|
||||
BufferGeometry,
|
||||
BufferAttribute,
|
||||
LineBasicMaterial,
|
||||
Line,
|
||||
MathUtils
|
||||
} from 'three';
|
||||
|
||||
class PositionalAudioHelper extends Line {
|
||||
|
||||
constructor( audio, range = 1, divisionsInnerAngle = 16, divisionsOuterAngle = 2 ) {
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
const divisions = divisionsInnerAngle + divisionsOuterAngle * 2;
|
||||
const positions = new Float32Array( ( divisions * 3 + 3 ) * 3 );
|
||||
geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
|
||||
|
||||
const materialInnerAngle = new LineBasicMaterial( { color: 0x00ff00 } );
|
||||
const materialOuterAngle = new LineBasicMaterial( { color: 0xffff00 } );
|
||||
|
||||
super( geometry, [ materialOuterAngle, materialInnerAngle ] );
|
||||
|
||||
this.audio = audio;
|
||||
this.range = range;
|
||||
this.divisionsInnerAngle = divisionsInnerAngle;
|
||||
this.divisionsOuterAngle = divisionsOuterAngle;
|
||||
this.type = 'PositionalAudioHelper';
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const audio = this.audio;
|
||||
const range = this.range;
|
||||
const divisionsInnerAngle = this.divisionsInnerAngle;
|
||||
const divisionsOuterAngle = this.divisionsOuterAngle;
|
||||
|
||||
const coneInnerAngle = MathUtils.degToRad( audio.panner.coneInnerAngle );
|
||||
const coneOuterAngle = MathUtils.degToRad( audio.panner.coneOuterAngle );
|
||||
|
||||
const halfConeInnerAngle = coneInnerAngle / 2;
|
||||
const halfConeOuterAngle = coneOuterAngle / 2;
|
||||
|
||||
let start = 0;
|
||||
let count = 0;
|
||||
let i;
|
||||
let stride;
|
||||
|
||||
const geometry = this.geometry;
|
||||
const positionAttribute = geometry.attributes.position;
|
||||
|
||||
geometry.clearGroups();
|
||||
|
||||
//
|
||||
|
||||
function generateSegment( from, to, divisions, materialIndex ) {
|
||||
|
||||
const step = ( to - from ) / divisions;
|
||||
|
||||
positionAttribute.setXYZ( start, 0, 0, 0 );
|
||||
count ++;
|
||||
|
||||
for ( i = from; i < to; i += step ) {
|
||||
|
||||
stride = start + count;
|
||||
|
||||
positionAttribute.setXYZ( stride, Math.sin( i ) * range, 0, Math.cos( i ) * range );
|
||||
positionAttribute.setXYZ( stride + 1, Math.sin( Math.min( i + step, to ) ) * range, 0, Math.cos( Math.min( i + step, to ) ) * range );
|
||||
positionAttribute.setXYZ( stride + 2, 0, 0, 0 );
|
||||
|
||||
count += 3;
|
||||
|
||||
}
|
||||
|
||||
geometry.addGroup( start, count, materialIndex );
|
||||
|
||||
start += count;
|
||||
count = 0;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
generateSegment( - halfConeOuterAngle, - halfConeInnerAngle, divisionsOuterAngle, 0 );
|
||||
generateSegment( - halfConeInnerAngle, halfConeInnerAngle, divisionsInnerAngle, 1 );
|
||||
generateSegment( halfConeInnerAngle, halfConeOuterAngle, divisionsOuterAngle, 0 );
|
||||
|
||||
//
|
||||
|
||||
positionAttribute.needsUpdate = true;
|
||||
|
||||
if ( coneInnerAngle === coneOuterAngle ) this.material[ 0 ].visible = false;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material[ 0 ].dispose();
|
||||
this.material[ 1 ].dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { PositionalAudioHelper };
|
85
dist/electron/static/sdk/three/jsm/helpers/RectAreaLightHelper.js
vendored
Normal file
85
dist/electron/static/sdk/three/jsm/helpers/RectAreaLightHelper.js
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
import {
|
||||
BackSide,
|
||||
BufferGeometry,
|
||||
Float32BufferAttribute,
|
||||
Line,
|
||||
LineBasicMaterial,
|
||||
Mesh,
|
||||
MeshBasicMaterial
|
||||
} from 'three';
|
||||
|
||||
/**
|
||||
* This helper must be added as a child of the light
|
||||
*/
|
||||
|
||||
class RectAreaLightHelper extends Line {
|
||||
|
||||
constructor( light, color ) {
|
||||
|
||||
const positions = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, - 1, 0, 1, 1, 0 ];
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
|
||||
geometry.computeBoundingSphere();
|
||||
|
||||
const material = new LineBasicMaterial( { fog: false } );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.light = light;
|
||||
this.color = color; // optional hardwired color for the helper
|
||||
this.type = 'RectAreaLightHelper';
|
||||
|
||||
//
|
||||
|
||||
const positions2 = [ 1, 1, 0, - 1, 1, 0, - 1, - 1, 0, 1, 1, 0, - 1, - 1, 0, 1, - 1, 0 ];
|
||||
|
||||
const geometry2 = new BufferGeometry();
|
||||
geometry2.setAttribute( 'position', new Float32BufferAttribute( positions2, 3 ) );
|
||||
geometry2.computeBoundingSphere();
|
||||
|
||||
this.add( new Mesh( geometry2, new MeshBasicMaterial( { side: BackSide, fog: false } ) ) );
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld() {
|
||||
|
||||
this.scale.set( 0.5 * this.light.width, 0.5 * this.light.height, 1 );
|
||||
|
||||
if ( this.color !== undefined ) {
|
||||
|
||||
this.material.color.set( this.color );
|
||||
this.children[ 0 ].material.color.set( this.color );
|
||||
|
||||
} else {
|
||||
|
||||
this.material.color.copy( this.light.color ).multiplyScalar( this.light.intensity );
|
||||
|
||||
// prevent hue shift
|
||||
const c = this.material.color;
|
||||
const max = Math.max( c.r, c.g, c.b );
|
||||
if ( max > 1 ) c.multiplyScalar( 1 / max );
|
||||
|
||||
this.children[ 0 ].material.color.copy( this.material.color );
|
||||
|
||||
}
|
||||
|
||||
// ignore world scale on light
|
||||
this.matrixWorld.extractRotation( this.light.matrixWorld ).scale( this.scale ).copyPosition( this.light.matrixWorld );
|
||||
|
||||
this.children[ 0 ].matrixWorld.copy( this.matrixWorld );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
this.children[ 0 ].geometry.dispose();
|
||||
this.children[ 0 ].material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { RectAreaLightHelper };
|
237
dist/electron/static/sdk/three/jsm/helpers/TextureHelper.js
vendored
Normal file
237
dist/electron/static/sdk/three/jsm/helpers/TextureHelper.js
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
import {
|
||||
BoxGeometry,
|
||||
BufferAttribute,
|
||||
DoubleSide,
|
||||
Mesh,
|
||||
PlaneGeometry,
|
||||
ShaderMaterial,
|
||||
Vector3,
|
||||
} from 'three';
|
||||
import { mergeGeometries } from '../utils/BufferGeometryUtils.js';
|
||||
|
||||
class TextureHelper extends Mesh {
|
||||
|
||||
constructor( texture, width = 1, height = 1, depth = 1 ) {
|
||||
|
||||
const material = new ShaderMaterial( {
|
||||
|
||||
type: 'TextureHelperMaterial',
|
||||
|
||||
side: DoubleSide,
|
||||
transparent: true,
|
||||
|
||||
uniforms: {
|
||||
|
||||
map: { value: texture },
|
||||
alpha: { value: getAlpha( texture ) },
|
||||
|
||||
},
|
||||
|
||||
vertexShader: [
|
||||
|
||||
'attribute vec3 uvw;',
|
||||
|
||||
'varying vec3 vUvw;',
|
||||
|
||||
'void main() {',
|
||||
|
||||
' vUvw = uvw;',
|
||||
|
||||
' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
|
||||
|
||||
'}',
|
||||
|
||||
].join( '\n' ),
|
||||
|
||||
fragmentShader: [
|
||||
|
||||
'precision highp float;',
|
||||
|
||||
'precision highp sampler2DArray;',
|
||||
|
||||
'precision highp sampler3D;',
|
||||
|
||||
'uniform {samplerType} map;',
|
||||
|
||||
'uniform float alpha;',
|
||||
|
||||
'varying vec3 vUvw;',
|
||||
|
||||
'vec4 textureHelper( in sampler2D map ) { return texture( map, vUvw.xy ); }',
|
||||
|
||||
'vec4 textureHelper( in sampler2DArray map ) { return texture( map, vUvw ); }',
|
||||
|
||||
'vec4 textureHelper( in sampler3D map ) { return texture( map, vUvw ); }',
|
||||
|
||||
'vec4 textureHelper( in samplerCube map ) { return texture( map, vUvw ); }',
|
||||
|
||||
'void main() {',
|
||||
|
||||
' gl_FragColor = linearToOutputTexel( vec4( textureHelper( map ).xyz, alpha ) );',
|
||||
|
||||
'}'
|
||||
|
||||
].join( '\n' ).replace( '{samplerType}', getSamplerType( texture ) )
|
||||
|
||||
} );
|
||||
|
||||
const geometry = texture.isCubeTexture
|
||||
? createCubeGeometry( width, height, depth )
|
||||
: createSliceGeometry( texture, width, height, depth );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.texture = texture;
|
||||
this.type = 'TextureHelper';
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getSamplerType( texture ) {
|
||||
|
||||
if ( texture.isCubeTexture ) {
|
||||
|
||||
return 'samplerCube';
|
||||
|
||||
} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
|
||||
|
||||
return 'sampler2DArray';
|
||||
|
||||
} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
|
||||
|
||||
return 'sampler3D';
|
||||
|
||||
} else {
|
||||
|
||||
return 'sampler2D';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getImageCount( texture ) {
|
||||
|
||||
if ( texture.isCubeTexture ) {
|
||||
|
||||
return 6;
|
||||
|
||||
} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
|
||||
|
||||
return texture.image.depth;
|
||||
|
||||
} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
|
||||
|
||||
return texture.image.depth;
|
||||
|
||||
} else {
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getAlpha( texture ) {
|
||||
|
||||
if ( texture.isCubeTexture ) {
|
||||
|
||||
return 1;
|
||||
|
||||
} else if ( texture.isDataArrayTexture || texture.isCompressedArrayTexture ) {
|
||||
|
||||
return Math.max( 1 / texture.image.depth, 0.25 );
|
||||
|
||||
} else if ( texture.isData3DTexture || texture.isCompressed3DTexture ) {
|
||||
|
||||
return Math.max( 1 / texture.image.depth, 0.25 );
|
||||
|
||||
} else {
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createCubeGeometry( width, height, depth ) {
|
||||
|
||||
const geometry = new BoxGeometry( width, height, depth );
|
||||
|
||||
const position = geometry.attributes.position;
|
||||
const uv = geometry.attributes.uv;
|
||||
const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
|
||||
|
||||
const _direction = new Vector3();
|
||||
|
||||
for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
|
||||
|
||||
_direction.fromBufferAttribute( position, j ).normalize();
|
||||
|
||||
const u = _direction.x;
|
||||
const v = _direction.y;
|
||||
const w = _direction.z;
|
||||
|
||||
uvw.setXYZ( j, u, v, w );
|
||||
|
||||
}
|
||||
|
||||
geometry.deleteAttribute( 'uv' );
|
||||
geometry.setAttribute( 'uvw', uvw );
|
||||
|
||||
return geometry;
|
||||
|
||||
}
|
||||
|
||||
function createSliceGeometry( texture, width, height, depth ) {
|
||||
|
||||
const sliceCount = getImageCount( texture );
|
||||
|
||||
const geometries = [];
|
||||
|
||||
for ( let i = 0; i < sliceCount; ++ i ) {
|
||||
|
||||
const geometry = new PlaneGeometry( width, height );
|
||||
|
||||
if ( sliceCount > 1 ) {
|
||||
|
||||
geometry.translate( 0, 0, depth * ( i / ( sliceCount - 1 ) - 0.5 ) );
|
||||
|
||||
}
|
||||
|
||||
const uv = geometry.attributes.uv;
|
||||
const uvw = new BufferAttribute( new Float32Array( uv.count * 3 ), 3 );
|
||||
|
||||
for ( let j = 0, jl = uv.count; j < jl; ++ j ) {
|
||||
|
||||
const u = uv.getX( j );
|
||||
const v = texture.flipY ? uv.getY( j ) : 1 - uv.getY( j );
|
||||
const w = sliceCount === 1
|
||||
? 1
|
||||
: texture.isDataArrayTexture || texture.isCompressedArrayTexture
|
||||
? i
|
||||
: i / ( sliceCount - 1 );
|
||||
|
||||
uvw.setXYZ( j, u, v, w );
|
||||
|
||||
}
|
||||
|
||||
geometry.deleteAttribute( 'uv' );
|
||||
geometry.setAttribute( 'uvw', uvw );
|
||||
|
||||
geometries.push( geometry );
|
||||
|
||||
}
|
||||
|
||||
return mergeGeometries( geometries );
|
||||
|
||||
}
|
||||
|
||||
export { TextureHelper };
|
96
dist/electron/static/sdk/three/jsm/helpers/VertexNormalsHelper.js
vendored
Normal file
96
dist/electron/static/sdk/three/jsm/helpers/VertexNormalsHelper.js
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
import {
|
||||
BufferGeometry,
|
||||
Float32BufferAttribute,
|
||||
LineSegments,
|
||||
LineBasicMaterial,
|
||||
Matrix3,
|
||||
Vector3
|
||||
} from 'three';
|
||||
|
||||
const _v1 = new Vector3();
|
||||
const _v2 = new Vector3();
|
||||
const _normalMatrix = new Matrix3();
|
||||
|
||||
class VertexNormalsHelper extends LineSegments {
|
||||
|
||||
constructor( object, size = 1, color = 0xff0000 ) {
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
|
||||
const nNormals = object.geometry.attributes.normal.count;
|
||||
const positions = new Float32BufferAttribute( nNormals * 2 * 3, 3 );
|
||||
|
||||
geometry.setAttribute( 'position', positions );
|
||||
|
||||
super( geometry, new LineBasicMaterial( { color, toneMapped: false } ) );
|
||||
|
||||
this.object = object;
|
||||
this.size = size;
|
||||
this.type = 'VertexNormalsHelper';
|
||||
|
||||
//
|
||||
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
this.object.updateMatrixWorld( true );
|
||||
|
||||
_normalMatrix.getNormalMatrix( this.object.matrixWorld );
|
||||
|
||||
const matrixWorld = this.object.matrixWorld;
|
||||
|
||||
const position = this.geometry.attributes.position;
|
||||
|
||||
//
|
||||
|
||||
const objGeometry = this.object.geometry;
|
||||
|
||||
if ( objGeometry ) {
|
||||
|
||||
const objPos = objGeometry.attributes.position;
|
||||
|
||||
const objNorm = objGeometry.attributes.normal;
|
||||
|
||||
let idx = 0;
|
||||
|
||||
// for simplicity, ignore index and drawcalls, and render every normal
|
||||
|
||||
for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
|
||||
|
||||
_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
|
||||
|
||||
_v2.fromBufferAttribute( objNorm, j );
|
||||
|
||||
_v2.applyMatrix3( _normalMatrix ).normalize().multiplyScalar( this.size ).add( _v1 );
|
||||
|
||||
position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
|
||||
|
||||
idx = idx + 1;
|
||||
|
||||
position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
|
||||
|
||||
idx = idx + 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
position.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { VertexNormalsHelper };
|
88
dist/electron/static/sdk/three/jsm/helpers/VertexTangentsHelper.js
vendored
Normal file
88
dist/electron/static/sdk/three/jsm/helpers/VertexTangentsHelper.js
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
import {
|
||||
BufferGeometry,
|
||||
Float32BufferAttribute,
|
||||
LineSegments,
|
||||
LineBasicMaterial,
|
||||
Vector3
|
||||
} from 'three';
|
||||
|
||||
const _v1 = new Vector3();
|
||||
const _v2 = new Vector3();
|
||||
|
||||
class VertexTangentsHelper extends LineSegments {
|
||||
|
||||
constructor( object, size = 1, color = 0x00ffff ) {
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
|
||||
const nTangents = object.geometry.attributes.tangent.count;
|
||||
const positions = new Float32BufferAttribute( nTangents * 2 * 3, 3 );
|
||||
|
||||
geometry.setAttribute( 'position', positions );
|
||||
|
||||
super( geometry, new LineBasicMaterial( { color, toneMapped: false } ) );
|
||||
|
||||
this.object = object;
|
||||
this.size = size;
|
||||
this.type = 'VertexTangentsHelper';
|
||||
|
||||
//
|
||||
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
this.object.updateMatrixWorld( true );
|
||||
|
||||
const matrixWorld = this.object.matrixWorld;
|
||||
|
||||
const position = this.geometry.attributes.position;
|
||||
|
||||
//
|
||||
|
||||
const objGeometry = this.object.geometry;
|
||||
|
||||
const objPos = objGeometry.attributes.position;
|
||||
|
||||
const objTan = objGeometry.attributes.tangent;
|
||||
|
||||
let idx = 0;
|
||||
|
||||
// for simplicity, ignore index and drawcalls, and render every tangent
|
||||
|
||||
for ( let j = 0, jl = objPos.count; j < jl; j ++ ) {
|
||||
|
||||
_v1.fromBufferAttribute( objPos, j ).applyMatrix4( matrixWorld );
|
||||
|
||||
_v2.fromBufferAttribute( objTan, j );
|
||||
|
||||
_v2.transformDirection( matrixWorld ).multiplyScalar( this.size ).add( _v1 );
|
||||
|
||||
position.setXYZ( idx, _v1.x, _v1.y, _v1.z );
|
||||
|
||||
idx = idx + 1;
|
||||
|
||||
position.setXYZ( idx, _v2.x, _v2.y, _v2.z );
|
||||
|
||||
idx = idx + 1;
|
||||
|
||||
}
|
||||
|
||||
position.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { VertexTangentsHelper };
|
333
dist/electron/static/sdk/three/jsm/helpers/ViewHelper.js
vendored
Normal file
333
dist/electron/static/sdk/three/jsm/helpers/ViewHelper.js
vendored
Normal file
@ -0,0 +1,333 @@
|
||||
import {
|
||||
BoxGeometry,
|
||||
CanvasTexture,
|
||||
Color,
|
||||
Euler,
|
||||
Mesh,
|
||||
MeshBasicMaterial,
|
||||
Object3D,
|
||||
OrthographicCamera,
|
||||
Quaternion,
|
||||
Raycaster,
|
||||
Sprite,
|
||||
SpriteMaterial,
|
||||
Vector2,
|
||||
Vector3,
|
||||
Vector4
|
||||
} from 'three';
|
||||
|
||||
class ViewHelper extends Object3D {
|
||||
|
||||
constructor( camera, domElement ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isViewHelper = true;
|
||||
|
||||
this.animating = false;
|
||||
this.center = new Vector3();
|
||||
|
||||
const color1 = new Color( '#ff3653' );
|
||||
const color2 = new Color( '#8adb00' );
|
||||
const color3 = new Color( '#2c8fff' );
|
||||
|
||||
const interactiveObjects = [];
|
||||
const raycaster = new Raycaster();
|
||||
const mouse = new Vector2();
|
||||
const dummy = new Object3D();
|
||||
|
||||
const orthoCamera = new OrthographicCamera( - 2, 2, 2, - 2, 0, 4 );
|
||||
orthoCamera.position.set( 0, 0, 2 );
|
||||
|
||||
const geometry = new BoxGeometry( 0.8, 0.05, 0.05 ).translate( 0.4, 0, 0 );
|
||||
|
||||
const xAxis = new Mesh( geometry, getAxisMaterial( color1 ) );
|
||||
const yAxis = new Mesh( geometry, getAxisMaterial( color2 ) );
|
||||
const zAxis = new Mesh( geometry, getAxisMaterial( color3 ) );
|
||||
|
||||
yAxis.rotation.z = Math.PI / 2;
|
||||
zAxis.rotation.y = - Math.PI / 2;
|
||||
|
||||
this.add( xAxis );
|
||||
this.add( zAxis );
|
||||
this.add( yAxis );
|
||||
|
||||
const posXAxisHelper = new Sprite( getSpriteMaterial( color1, 'X' ) );
|
||||
posXAxisHelper.userData.type = 'posX';
|
||||
const posYAxisHelper = new Sprite( getSpriteMaterial( color2, 'Y' ) );
|
||||
posYAxisHelper.userData.type = 'posY';
|
||||
const posZAxisHelper = new Sprite( getSpriteMaterial( color3, 'Z' ) );
|
||||
posZAxisHelper.userData.type = 'posZ';
|
||||
const negXAxisHelper = new Sprite( getSpriteMaterial( color1 ) );
|
||||
negXAxisHelper.userData.type = 'negX';
|
||||
const negYAxisHelper = new Sprite( getSpriteMaterial( color2 ) );
|
||||
negYAxisHelper.userData.type = 'negY';
|
||||
const negZAxisHelper = new Sprite( getSpriteMaterial( color3 ) );
|
||||
negZAxisHelper.userData.type = 'negZ';
|
||||
|
||||
posXAxisHelper.position.x = 1;
|
||||
posYAxisHelper.position.y = 1;
|
||||
posZAxisHelper.position.z = 1;
|
||||
negXAxisHelper.position.x = - 1;
|
||||
negXAxisHelper.scale.setScalar( 0.8 );
|
||||
negYAxisHelper.position.y = - 1;
|
||||
negYAxisHelper.scale.setScalar( 0.8 );
|
||||
negZAxisHelper.position.z = - 1;
|
||||
negZAxisHelper.scale.setScalar( 0.8 );
|
||||
|
||||
this.add( posXAxisHelper );
|
||||
this.add( posYAxisHelper );
|
||||
this.add( posZAxisHelper );
|
||||
this.add( negXAxisHelper );
|
||||
this.add( negYAxisHelper );
|
||||
this.add( negZAxisHelper );
|
||||
|
||||
interactiveObjects.push( posXAxisHelper );
|
||||
interactiveObjects.push( posYAxisHelper );
|
||||
interactiveObjects.push( posZAxisHelper );
|
||||
interactiveObjects.push( negXAxisHelper );
|
||||
interactiveObjects.push( negYAxisHelper );
|
||||
interactiveObjects.push( negZAxisHelper );
|
||||
|
||||
const point = new Vector3();
|
||||
const dim = 128;
|
||||
const turnRate = 2 * Math.PI; // turn rate in angles per second
|
||||
|
||||
this.render = function ( renderer ) {
|
||||
|
||||
this.quaternion.copy( camera.quaternion ).invert();
|
||||
this.updateMatrixWorld();
|
||||
|
||||
point.set( 0, 0, 1 );
|
||||
point.applyQuaternion( camera.quaternion );
|
||||
|
||||
if ( point.x >= 0 ) {
|
||||
|
||||
posXAxisHelper.material.opacity = 1;
|
||||
negXAxisHelper.material.opacity = 0.5;
|
||||
|
||||
} else {
|
||||
|
||||
posXAxisHelper.material.opacity = 0.5;
|
||||
negXAxisHelper.material.opacity = 1;
|
||||
|
||||
}
|
||||
|
||||
if ( point.y >= 0 ) {
|
||||
|
||||
posYAxisHelper.material.opacity = 1;
|
||||
negYAxisHelper.material.opacity = 0.5;
|
||||
|
||||
} else {
|
||||
|
||||
posYAxisHelper.material.opacity = 0.5;
|
||||
negYAxisHelper.material.opacity = 1;
|
||||
|
||||
}
|
||||
|
||||
if ( point.z >= 0 ) {
|
||||
|
||||
posZAxisHelper.material.opacity = 1;
|
||||
negZAxisHelper.material.opacity = 0.5;
|
||||
|
||||
} else {
|
||||
|
||||
posZAxisHelper.material.opacity = 0.5;
|
||||
negZAxisHelper.material.opacity = 1;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const x = domElement.offsetWidth - dim;
|
||||
|
||||
renderer.clearDepth();
|
||||
|
||||
renderer.getViewport( viewport );
|
||||
renderer.setViewport( x, 0, dim, dim );
|
||||
|
||||
renderer.render( this, orthoCamera );
|
||||
|
||||
renderer.setViewport( viewport.x, viewport.y, viewport.z, viewport.w );
|
||||
|
||||
};
|
||||
|
||||
const targetPosition = new Vector3();
|
||||
const targetQuaternion = new Quaternion();
|
||||
|
||||
const q1 = new Quaternion();
|
||||
const q2 = new Quaternion();
|
||||
const viewport = new Vector4();
|
||||
let radius = 0;
|
||||
|
||||
this.handleClick = function ( event ) {
|
||||
|
||||
if ( this.animating === true ) return false;
|
||||
|
||||
const rect = domElement.getBoundingClientRect();
|
||||
const offsetX = rect.left + ( domElement.offsetWidth - dim );
|
||||
const offsetY = rect.top + ( domElement.offsetHeight - dim );
|
||||
mouse.x = ( ( event.clientX - offsetX ) / ( rect.right - offsetX ) ) * 2 - 1;
|
||||
mouse.y = - ( ( event.clientY - offsetY ) / ( rect.bottom - offsetY ) ) * 2 + 1;
|
||||
|
||||
raycaster.setFromCamera( mouse, orthoCamera );
|
||||
|
||||
const intersects = raycaster.intersectObjects( interactiveObjects );
|
||||
|
||||
if ( intersects.length > 0 ) {
|
||||
|
||||
const intersection = intersects[ 0 ];
|
||||
const object = intersection.object;
|
||||
|
||||
prepareAnimationData( object, this.center );
|
||||
|
||||
this.animating = true;
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.update = function ( delta ) {
|
||||
|
||||
const step = delta * turnRate;
|
||||
|
||||
// animate position by doing a slerp and then scaling the position on the unit sphere
|
||||
|
||||
q1.rotateTowards( q2, step );
|
||||
camera.position.set( 0, 0, 1 ).applyQuaternion( q1 ).multiplyScalar( radius ).add( this.center );
|
||||
|
||||
// animate orientation
|
||||
|
||||
camera.quaternion.rotateTowards( targetQuaternion, step );
|
||||
|
||||
if ( q1.angleTo( q2 ) === 0 ) {
|
||||
|
||||
this.animating = false;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.dispose = function () {
|
||||
|
||||
geometry.dispose();
|
||||
|
||||
xAxis.material.dispose();
|
||||
yAxis.material.dispose();
|
||||
zAxis.material.dispose();
|
||||
|
||||
posXAxisHelper.material.map.dispose();
|
||||
posYAxisHelper.material.map.dispose();
|
||||
posZAxisHelper.material.map.dispose();
|
||||
negXAxisHelper.material.map.dispose();
|
||||
negYAxisHelper.material.map.dispose();
|
||||
negZAxisHelper.material.map.dispose();
|
||||
|
||||
posXAxisHelper.material.dispose();
|
||||
posYAxisHelper.material.dispose();
|
||||
posZAxisHelper.material.dispose();
|
||||
negXAxisHelper.material.dispose();
|
||||
negYAxisHelper.material.dispose();
|
||||
negZAxisHelper.material.dispose();
|
||||
|
||||
};
|
||||
|
||||
function prepareAnimationData( object, focusPoint ) {
|
||||
|
||||
switch ( object.userData.type ) {
|
||||
|
||||
case 'posX':
|
||||
targetPosition.set( 1, 0, 0 );
|
||||
targetQuaternion.setFromEuler( new Euler( 0, Math.PI * 0.5, 0 ) );
|
||||
break;
|
||||
|
||||
case 'posY':
|
||||
targetPosition.set( 0, 1, 0 );
|
||||
targetQuaternion.setFromEuler( new Euler( - Math.PI * 0.5, 0, 0 ) );
|
||||
break;
|
||||
|
||||
case 'posZ':
|
||||
targetPosition.set( 0, 0, 1 );
|
||||
targetQuaternion.setFromEuler( new Euler() );
|
||||
break;
|
||||
|
||||
case 'negX':
|
||||
targetPosition.set( - 1, 0, 0 );
|
||||
targetQuaternion.setFromEuler( new Euler( 0, - Math.PI * 0.5, 0 ) );
|
||||
break;
|
||||
|
||||
case 'negY':
|
||||
targetPosition.set( 0, - 1, 0 );
|
||||
targetQuaternion.setFromEuler( new Euler( Math.PI * 0.5, 0, 0 ) );
|
||||
break;
|
||||
|
||||
case 'negZ':
|
||||
targetPosition.set( 0, 0, - 1 );
|
||||
targetQuaternion.setFromEuler( new Euler( 0, Math.PI, 0 ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
console.error( 'ViewHelper: Invalid axis.' );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
radius = camera.position.distanceTo( focusPoint );
|
||||
targetPosition.multiplyScalar( radius ).add( focusPoint );
|
||||
|
||||
dummy.position.copy( focusPoint );
|
||||
|
||||
dummy.lookAt( camera.position );
|
||||
q1.copy( dummy.quaternion );
|
||||
|
||||
dummy.lookAt( targetPosition );
|
||||
q2.copy( dummy.quaternion );
|
||||
|
||||
}
|
||||
|
||||
function getAxisMaterial( color ) {
|
||||
|
||||
return new MeshBasicMaterial( { color: color, toneMapped: false } );
|
||||
|
||||
}
|
||||
|
||||
function getSpriteMaterial( color, text = null ) {
|
||||
|
||||
const canvas = document.createElement( 'canvas' );
|
||||
canvas.width = 64;
|
||||
canvas.height = 64;
|
||||
|
||||
const context = canvas.getContext( '2d' );
|
||||
context.beginPath();
|
||||
context.arc( 32, 32, 16, 0, 2 * Math.PI );
|
||||
context.closePath();
|
||||
context.fillStyle = color.getStyle();
|
||||
context.fill();
|
||||
|
||||
if ( text !== null ) {
|
||||
|
||||
context.font = '24px Arial';
|
||||
context.textAlign = 'center';
|
||||
context.fillStyle = '#000000';
|
||||
context.fillText( text, 32, 41 );
|
||||
|
||||
}
|
||||
|
||||
const texture = new CanvasTexture( canvas );
|
||||
|
||||
return new SpriteMaterial( { map: texture, toneMapped: false } );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { ViewHelper };
|
Reference in New Issue
Block a user