🐛 Update: Added support for the 'find' command in settings.local.json. Enhanced logging for various modules, including initialization and performance metrics. Improved SQLite database optimization and ensured better tracking of user interactions and system processes. 📚
This commit is contained in:
1
network-visualization/node_modules/three/src/Three.Legacy.js
generated
vendored
Normal file
1
network-visualization/node_modules/three/src/Three.Legacy.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
183
network-visualization/node_modules/three/src/Three.js
generated
vendored
Normal file
183
network-visualization/node_modules/three/src/Three.js
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
import { REVISION } from './constants.js';
|
||||
|
||||
export { WebGLArrayRenderTarget } from './renderers/WebGLArrayRenderTarget.js';
|
||||
export { WebGL3DRenderTarget } from './renderers/WebGL3DRenderTarget.js';
|
||||
export { WebGLMultipleRenderTargets } from './renderers/WebGLMultipleRenderTargets.js';
|
||||
export { WebGLCubeRenderTarget } from './renderers/WebGLCubeRenderTarget.js';
|
||||
export { WebGLRenderTarget } from './renderers/WebGLRenderTarget.js';
|
||||
export { WebGLRenderer } from './renderers/WebGLRenderer.js';
|
||||
export { WebGL1Renderer } from './renderers/WebGL1Renderer.js';
|
||||
export { ShaderLib } from './renderers/shaders/ShaderLib.js';
|
||||
export { UniformsLib } from './renderers/shaders/UniformsLib.js';
|
||||
export { UniformsUtils } from './renderers/shaders/UniformsUtils.js';
|
||||
export { ShaderChunk } from './renderers/shaders/ShaderChunk.js';
|
||||
export { FogExp2 } from './scenes/FogExp2.js';
|
||||
export { Fog } from './scenes/Fog.js';
|
||||
export { Scene } from './scenes/Scene.js';
|
||||
export { Sprite } from './objects/Sprite.js';
|
||||
export { LOD } from './objects/LOD.js';
|
||||
export { SkinnedMesh } from './objects/SkinnedMesh.js';
|
||||
export { Skeleton } from './objects/Skeleton.js';
|
||||
export { Bone } from './objects/Bone.js';
|
||||
export { Mesh } from './objects/Mesh.js';
|
||||
export { InstancedMesh } from './objects/InstancedMesh.js';
|
||||
export { LineSegments } from './objects/LineSegments.js';
|
||||
export { LineLoop } from './objects/LineLoop.js';
|
||||
export { Line } from './objects/Line.js';
|
||||
export { Points } from './objects/Points.js';
|
||||
export { Group } from './objects/Group.js';
|
||||
export { VideoTexture } from './textures/VideoTexture.js';
|
||||
export { FramebufferTexture } from './textures/FramebufferTexture.js';
|
||||
export { Source } from './textures/Source.js';
|
||||
export { DataTexture } from './textures/DataTexture.js';
|
||||
export { DataArrayTexture } from './textures/DataArrayTexture.js';
|
||||
export { Data3DTexture } from './textures/Data3DTexture.js';
|
||||
export { CompressedTexture } from './textures/CompressedTexture.js';
|
||||
export { CompressedArrayTexture } from './textures/CompressedArrayTexture.js';
|
||||
export { CompressedCubeTexture } from './textures/CompressedCubeTexture.js';
|
||||
export { CubeTexture } from './textures/CubeTexture.js';
|
||||
export { CanvasTexture } from './textures/CanvasTexture.js';
|
||||
export { DepthTexture } from './textures/DepthTexture.js';
|
||||
export { Texture } from './textures/Texture.js';
|
||||
export * from './geometries/Geometries.js';
|
||||
export * from './materials/Materials.js';
|
||||
export { AnimationLoader } from './loaders/AnimationLoader.js';
|
||||
export { CompressedTextureLoader } from './loaders/CompressedTextureLoader.js';
|
||||
export { CubeTextureLoader } from './loaders/CubeTextureLoader.js';
|
||||
export { DataTextureLoader } from './loaders/DataTextureLoader.js';
|
||||
export { TextureLoader } from './loaders/TextureLoader.js';
|
||||
export { ObjectLoader } from './loaders/ObjectLoader.js';
|
||||
export { MaterialLoader } from './loaders/MaterialLoader.js';
|
||||
export { BufferGeometryLoader } from './loaders/BufferGeometryLoader.js';
|
||||
export { DefaultLoadingManager, LoadingManager } from './loaders/LoadingManager.js';
|
||||
export { ImageLoader } from './loaders/ImageLoader.js';
|
||||
export { ImageBitmapLoader } from './loaders/ImageBitmapLoader.js';
|
||||
export { FileLoader } from './loaders/FileLoader.js';
|
||||
export { Loader } from './loaders/Loader.js';
|
||||
export { LoaderUtils } from './loaders/LoaderUtils.js';
|
||||
export { Cache } from './loaders/Cache.js';
|
||||
export { AudioLoader } from './loaders/AudioLoader.js';
|
||||
export { SpotLight } from './lights/SpotLight.js';
|
||||
export { PointLight } from './lights/PointLight.js';
|
||||
export { RectAreaLight } from './lights/RectAreaLight.js';
|
||||
export { HemisphereLight } from './lights/HemisphereLight.js';
|
||||
export { DirectionalLight } from './lights/DirectionalLight.js';
|
||||
export { AmbientLight } from './lights/AmbientLight.js';
|
||||
export { Light } from './lights/Light.js';
|
||||
export { LightProbe } from './lights/LightProbe.js';
|
||||
export { StereoCamera } from './cameras/StereoCamera.js';
|
||||
export { PerspectiveCamera } from './cameras/PerspectiveCamera.js';
|
||||
export { OrthographicCamera } from './cameras/OrthographicCamera.js';
|
||||
export { CubeCamera } from './cameras/CubeCamera.js';
|
||||
export { ArrayCamera } from './cameras/ArrayCamera.js';
|
||||
export { Camera } from './cameras/Camera.js';
|
||||
export { AudioListener } from './audio/AudioListener.js';
|
||||
export { PositionalAudio } from './audio/PositionalAudio.js';
|
||||
export { AudioContext } from './audio/AudioContext.js';
|
||||
export { AudioAnalyser } from './audio/AudioAnalyser.js';
|
||||
export { Audio } from './audio/Audio.js';
|
||||
export { VectorKeyframeTrack } from './animation/tracks/VectorKeyframeTrack.js';
|
||||
export { StringKeyframeTrack } from './animation/tracks/StringKeyframeTrack.js';
|
||||
export { QuaternionKeyframeTrack } from './animation/tracks/QuaternionKeyframeTrack.js';
|
||||
export { NumberKeyframeTrack } from './animation/tracks/NumberKeyframeTrack.js';
|
||||
export { ColorKeyframeTrack } from './animation/tracks/ColorKeyframeTrack.js';
|
||||
export { BooleanKeyframeTrack } from './animation/tracks/BooleanKeyframeTrack.js';
|
||||
export { PropertyMixer } from './animation/PropertyMixer.js';
|
||||
export { PropertyBinding } from './animation/PropertyBinding.js';
|
||||
export { KeyframeTrack } from './animation/KeyframeTrack.js';
|
||||
export { AnimationUtils } from './animation/AnimationUtils.js';
|
||||
export { AnimationObjectGroup } from './animation/AnimationObjectGroup.js';
|
||||
export { AnimationMixer } from './animation/AnimationMixer.js';
|
||||
export { AnimationClip } from './animation/AnimationClip.js';
|
||||
export { AnimationAction } from './animation/AnimationAction.js';
|
||||
export { RenderTarget } from './core/RenderTarget.js';
|
||||
export { Uniform } from './core/Uniform.js';
|
||||
export { UniformsGroup } from './core/UniformsGroup.js';
|
||||
export { InstancedBufferGeometry } from './core/InstancedBufferGeometry.js';
|
||||
export { BufferGeometry } from './core/BufferGeometry.js';
|
||||
export { InterleavedBufferAttribute } from './core/InterleavedBufferAttribute.js';
|
||||
export { InstancedInterleavedBuffer } from './core/InstancedInterleavedBuffer.js';
|
||||
export { InterleavedBuffer } from './core/InterleavedBuffer.js';
|
||||
export { InstancedBufferAttribute } from './core/InstancedBufferAttribute.js';
|
||||
export { GLBufferAttribute } from './core/GLBufferAttribute.js';
|
||||
export * from './core/BufferAttribute.js';
|
||||
export { Object3D } from './core/Object3D.js';
|
||||
export { Raycaster } from './core/Raycaster.js';
|
||||
export { Layers } from './core/Layers.js';
|
||||
export { EventDispatcher } from './core/EventDispatcher.js';
|
||||
export { Clock } from './core/Clock.js';
|
||||
export { QuaternionLinearInterpolant } from './math/interpolants/QuaternionLinearInterpolant.js';
|
||||
export { LinearInterpolant } from './math/interpolants/LinearInterpolant.js';
|
||||
export { DiscreteInterpolant } from './math/interpolants/DiscreteInterpolant.js';
|
||||
export { CubicInterpolant } from './math/interpolants/CubicInterpolant.js';
|
||||
export { Interpolant } from './math/Interpolant.js';
|
||||
export { Triangle } from './math/Triangle.js';
|
||||
export { MathUtils } from './math/MathUtils.js';
|
||||
export { Spherical } from './math/Spherical.js';
|
||||
export { Cylindrical } from './math/Cylindrical.js';
|
||||
export { Plane } from './math/Plane.js';
|
||||
export { Frustum } from './math/Frustum.js';
|
||||
export { Sphere } from './math/Sphere.js';
|
||||
export { Ray } from './math/Ray.js';
|
||||
export { Matrix4 } from './math/Matrix4.js';
|
||||
export { Matrix3 } from './math/Matrix3.js';
|
||||
export { Box3 } from './math/Box3.js';
|
||||
export { Box2 } from './math/Box2.js';
|
||||
export { Line3 } from './math/Line3.js';
|
||||
export { Euler } from './math/Euler.js';
|
||||
export { Vector4 } from './math/Vector4.js';
|
||||
export { Vector3 } from './math/Vector3.js';
|
||||
export { Vector2 } from './math/Vector2.js';
|
||||
export { Quaternion } from './math/Quaternion.js';
|
||||
export { Color } from './math/Color.js';
|
||||
export { ColorManagement } from './math/ColorManagement.js';
|
||||
export { SphericalHarmonics3 } from './math/SphericalHarmonics3.js';
|
||||
export { SpotLightHelper } from './helpers/SpotLightHelper.js';
|
||||
export { SkeletonHelper } from './helpers/SkeletonHelper.js';
|
||||
export { PointLightHelper } from './helpers/PointLightHelper.js';
|
||||
export { HemisphereLightHelper } from './helpers/HemisphereLightHelper.js';
|
||||
export { GridHelper } from './helpers/GridHelper.js';
|
||||
export { PolarGridHelper } from './helpers/PolarGridHelper.js';
|
||||
export { DirectionalLightHelper } from './helpers/DirectionalLightHelper.js';
|
||||
export { CameraHelper } from './helpers/CameraHelper.js';
|
||||
export { BoxHelper } from './helpers/BoxHelper.js';
|
||||
export { Box3Helper } from './helpers/Box3Helper.js';
|
||||
export { PlaneHelper } from './helpers/PlaneHelper.js';
|
||||
export { ArrowHelper } from './helpers/ArrowHelper.js';
|
||||
export { AxesHelper } from './helpers/AxesHelper.js';
|
||||
export * from './extras/curves/Curves.js';
|
||||
export { Shape } from './extras/core/Shape.js';
|
||||
export { Path } from './extras/core/Path.js';
|
||||
export { ShapePath } from './extras/core/ShapePath.js';
|
||||
export { CurvePath } from './extras/core/CurvePath.js';
|
||||
export { Curve } from './extras/core/Curve.js';
|
||||
export { DataUtils } from './extras/DataUtils.js';
|
||||
export { ImageUtils } from './extras/ImageUtils.js';
|
||||
export { ShapeUtils } from './extras/ShapeUtils.js';
|
||||
export { PMREMGenerator } from './extras/PMREMGenerator.js';
|
||||
export { WebGLUtils } from './renderers/webgl/WebGLUtils.js';
|
||||
export { createCanvasElement } from './utils.js';
|
||||
export * from './constants.js';
|
||||
export * from './Three.Legacy.js';
|
||||
|
||||
if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) {
|
||||
|
||||
__THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'register', { detail: {
|
||||
revision: REVISION,
|
||||
} } ) );
|
||||
|
||||
}
|
||||
|
||||
if ( typeof window !== 'undefined' ) {
|
||||
|
||||
if ( window.__THREE__ ) {
|
||||
|
||||
console.warn( 'WARNING: Multiple instances of Three.js being imported.' );
|
||||
|
||||
} else {
|
||||
|
||||
window.__THREE__ = REVISION;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
700
network-visualization/node_modules/three/src/animation/AnimationAction.js
generated
vendored
Normal file
700
network-visualization/node_modules/three/src/animation/AnimationAction.js
generated
vendored
Normal file
@@ -0,0 +1,700 @@
|
||||
import { WrapAroundEnding, ZeroCurvatureEnding, ZeroSlopeEnding, LoopPingPong, LoopOnce, LoopRepeat, NormalAnimationBlendMode, AdditiveAnimationBlendMode } from '../constants.js';
|
||||
|
||||
|
||||
class AnimationAction {
|
||||
|
||||
constructor( mixer, clip, localRoot = null, blendMode = clip.blendMode ) {
|
||||
|
||||
this._mixer = mixer;
|
||||
this._clip = clip;
|
||||
this._localRoot = localRoot;
|
||||
this.blendMode = blendMode;
|
||||
|
||||
const tracks = clip.tracks,
|
||||
nTracks = tracks.length,
|
||||
interpolants = new Array( nTracks );
|
||||
|
||||
const interpolantSettings = {
|
||||
endingStart: ZeroCurvatureEnding,
|
||||
endingEnd: ZeroCurvatureEnding
|
||||
};
|
||||
|
||||
for ( let i = 0; i !== nTracks; ++ i ) {
|
||||
|
||||
const interpolant = tracks[ i ].createInterpolant( null );
|
||||
interpolants[ i ] = interpolant;
|
||||
interpolant.settings = interpolantSettings;
|
||||
|
||||
}
|
||||
|
||||
this._interpolantSettings = interpolantSettings;
|
||||
|
||||
this._interpolants = interpolants; // bound by the mixer
|
||||
|
||||
// inside: PropertyMixer (managed by the mixer)
|
||||
this._propertyBindings = new Array( nTracks );
|
||||
|
||||
this._cacheIndex = null; // for the memory manager
|
||||
this._byClipCacheIndex = null; // for the memory manager
|
||||
|
||||
this._timeScaleInterpolant = null;
|
||||
this._weightInterpolant = null;
|
||||
|
||||
this.loop = LoopRepeat;
|
||||
this._loopCount = - 1;
|
||||
|
||||
// global mixer time when the action is to be started
|
||||
// it's set back to 'null' upon start of the action
|
||||
this._startTime = null;
|
||||
|
||||
// scaled local time of the action
|
||||
// gets clamped or wrapped to 0..clip.duration according to loop
|
||||
this.time = 0;
|
||||
|
||||
this.timeScale = 1;
|
||||
this._effectiveTimeScale = 1;
|
||||
|
||||
this.weight = 1;
|
||||
this._effectiveWeight = 1;
|
||||
|
||||
this.repetitions = Infinity; // no. of repetitions when looping
|
||||
|
||||
this.paused = false; // true -> zero effective time scale
|
||||
this.enabled = true; // false -> zero effective weight
|
||||
|
||||
this.clampWhenFinished = false;// keep feeding the last frame?
|
||||
|
||||
this.zeroSlopeAtStart = true;// for smooth interpolation w/o separate
|
||||
this.zeroSlopeAtEnd = true;// clips for start, loop and end
|
||||
|
||||
}
|
||||
|
||||
// State & Scheduling
|
||||
|
||||
play() {
|
||||
|
||||
this._mixer._activateAction( this );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
||||
this._mixer._deactivateAction( this );
|
||||
|
||||
return this.reset();
|
||||
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
||||
this.paused = false;
|
||||
this.enabled = true;
|
||||
|
||||
this.time = 0; // restart clip
|
||||
this._loopCount = - 1;// forget previous loops
|
||||
this._startTime = null;// forget scheduling
|
||||
|
||||
return this.stopFading().stopWarping();
|
||||
|
||||
}
|
||||
|
||||
isRunning() {
|
||||
|
||||
return this.enabled && ! this.paused && this.timeScale !== 0 &&
|
||||
this._startTime === null && this._mixer._isActiveAction( this );
|
||||
|
||||
}
|
||||
|
||||
// return true when play has been called
|
||||
isScheduled() {
|
||||
|
||||
return this._mixer._isActiveAction( this );
|
||||
|
||||
}
|
||||
|
||||
startAt( time ) {
|
||||
|
||||
this._startTime = time;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setLoop( mode, repetitions ) {
|
||||
|
||||
this.loop = mode;
|
||||
this.repetitions = repetitions;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// Weight
|
||||
|
||||
// set the weight stopping any scheduled fading
|
||||
// although .enabled = false yields an effective weight of zero, this
|
||||
// method does *not* change .enabled, because it would be confusing
|
||||
setEffectiveWeight( weight ) {
|
||||
|
||||
this.weight = weight;
|
||||
|
||||
// note: same logic as when updated at runtime
|
||||
this._effectiveWeight = this.enabled ? weight : 0;
|
||||
|
||||
return this.stopFading();
|
||||
|
||||
}
|
||||
|
||||
// return the weight considering fading and .enabled
|
||||
getEffectiveWeight() {
|
||||
|
||||
return this._effectiveWeight;
|
||||
|
||||
}
|
||||
|
||||
fadeIn( duration ) {
|
||||
|
||||
return this._scheduleFading( duration, 0, 1 );
|
||||
|
||||
}
|
||||
|
||||
fadeOut( duration ) {
|
||||
|
||||
return this._scheduleFading( duration, 1, 0 );
|
||||
|
||||
}
|
||||
|
||||
crossFadeFrom( fadeOutAction, duration, warp ) {
|
||||
|
||||
fadeOutAction.fadeOut( duration );
|
||||
this.fadeIn( duration );
|
||||
|
||||
if ( warp ) {
|
||||
|
||||
const fadeInDuration = this._clip.duration,
|
||||
fadeOutDuration = fadeOutAction._clip.duration,
|
||||
|
||||
startEndRatio = fadeOutDuration / fadeInDuration,
|
||||
endStartRatio = fadeInDuration / fadeOutDuration;
|
||||
|
||||
fadeOutAction.warp( 1.0, startEndRatio, duration );
|
||||
this.warp( endStartRatio, 1.0, duration );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
crossFadeTo( fadeInAction, duration, warp ) {
|
||||
|
||||
return fadeInAction.crossFadeFrom( this, duration, warp );
|
||||
|
||||
}
|
||||
|
||||
stopFading() {
|
||||
|
||||
const weightInterpolant = this._weightInterpolant;
|
||||
|
||||
if ( weightInterpolant !== null ) {
|
||||
|
||||
this._weightInterpolant = null;
|
||||
this._mixer._takeBackControlInterpolant( weightInterpolant );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// Time Scale Control
|
||||
|
||||
// set the time scale stopping any scheduled warping
|
||||
// although .paused = true yields an effective time scale of zero, this
|
||||
// method does *not* change .paused, because it would be confusing
|
||||
setEffectiveTimeScale( timeScale ) {
|
||||
|
||||
this.timeScale = timeScale;
|
||||
this._effectiveTimeScale = this.paused ? 0 : timeScale;
|
||||
|
||||
return this.stopWarping();
|
||||
|
||||
}
|
||||
|
||||
// return the time scale considering warping and .paused
|
||||
getEffectiveTimeScale() {
|
||||
|
||||
return this._effectiveTimeScale;
|
||||
|
||||
}
|
||||
|
||||
setDuration( duration ) {
|
||||
|
||||
this.timeScale = this._clip.duration / duration;
|
||||
|
||||
return this.stopWarping();
|
||||
|
||||
}
|
||||
|
||||
syncWith( action ) {
|
||||
|
||||
this.time = action.time;
|
||||
this.timeScale = action.timeScale;
|
||||
|
||||
return this.stopWarping();
|
||||
|
||||
}
|
||||
|
||||
halt( duration ) {
|
||||
|
||||
return this.warp( this._effectiveTimeScale, 0, duration );
|
||||
|
||||
}
|
||||
|
||||
warp( startTimeScale, endTimeScale, duration ) {
|
||||
|
||||
const mixer = this._mixer,
|
||||
now = mixer.time,
|
||||
timeScale = this.timeScale;
|
||||
|
||||
let interpolant = this._timeScaleInterpolant;
|
||||
|
||||
if ( interpolant === null ) {
|
||||
|
||||
interpolant = mixer._lendControlInterpolant();
|
||||
this._timeScaleInterpolant = interpolant;
|
||||
|
||||
}
|
||||
|
||||
const times = interpolant.parameterPositions,
|
||||
values = interpolant.sampleValues;
|
||||
|
||||
times[ 0 ] = now;
|
||||
times[ 1 ] = now + duration;
|
||||
|
||||
values[ 0 ] = startTimeScale / timeScale;
|
||||
values[ 1 ] = endTimeScale / timeScale;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
stopWarping() {
|
||||
|
||||
const timeScaleInterpolant = this._timeScaleInterpolant;
|
||||
|
||||
if ( timeScaleInterpolant !== null ) {
|
||||
|
||||
this._timeScaleInterpolant = null;
|
||||
this._mixer._takeBackControlInterpolant( timeScaleInterpolant );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// Object Accessors
|
||||
|
||||
getMixer() {
|
||||
|
||||
return this._mixer;
|
||||
|
||||
}
|
||||
|
||||
getClip() {
|
||||
|
||||
return this._clip;
|
||||
|
||||
}
|
||||
|
||||
getRoot() {
|
||||
|
||||
return this._localRoot || this._mixer._root;
|
||||
|
||||
}
|
||||
|
||||
// Interna
|
||||
|
||||
_update( time, deltaTime, timeDirection, accuIndex ) {
|
||||
|
||||
// called by the mixer
|
||||
|
||||
if ( ! this.enabled ) {
|
||||
|
||||
// call ._updateWeight() to update ._effectiveWeight
|
||||
|
||||
this._updateWeight( time );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
const startTime = this._startTime;
|
||||
|
||||
if ( startTime !== null ) {
|
||||
|
||||
// check for scheduled start of action
|
||||
|
||||
const timeRunning = ( time - startTime ) * timeDirection;
|
||||
if ( timeRunning < 0 || timeDirection === 0 ) {
|
||||
|
||||
deltaTime = 0;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
this._startTime = null; // unschedule
|
||||
deltaTime = timeDirection * timeRunning;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// apply time scale and advance time
|
||||
|
||||
deltaTime *= this._updateTimeScale( time );
|
||||
const clipTime = this._updateTime( deltaTime );
|
||||
|
||||
// note: _updateTime may disable the action resulting in
|
||||
// an effective weight of 0
|
||||
|
||||
const weight = this._updateWeight( time );
|
||||
|
||||
if ( weight > 0 ) {
|
||||
|
||||
const interpolants = this._interpolants;
|
||||
const propertyMixers = this._propertyBindings;
|
||||
|
||||
switch ( this.blendMode ) {
|
||||
|
||||
case AdditiveAnimationBlendMode:
|
||||
|
||||
for ( let j = 0, m = interpolants.length; j !== m; ++ j ) {
|
||||
|
||||
interpolants[ j ].evaluate( clipTime );
|
||||
propertyMixers[ j ].accumulateAdditive( weight );
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NormalAnimationBlendMode:
|
||||
default:
|
||||
|
||||
for ( let j = 0, m = interpolants.length; j !== m; ++ j ) {
|
||||
|
||||
interpolants[ j ].evaluate( clipTime );
|
||||
propertyMixers[ j ].accumulate( accuIndex, weight );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_updateWeight( time ) {
|
||||
|
||||
let weight = 0;
|
||||
|
||||
if ( this.enabled ) {
|
||||
|
||||
weight = this.weight;
|
||||
const interpolant = this._weightInterpolant;
|
||||
|
||||
if ( interpolant !== null ) {
|
||||
|
||||
const interpolantValue = interpolant.evaluate( time )[ 0 ];
|
||||
|
||||
weight *= interpolantValue;
|
||||
|
||||
if ( time > interpolant.parameterPositions[ 1 ] ) {
|
||||
|
||||
this.stopFading();
|
||||
|
||||
if ( interpolantValue === 0 ) {
|
||||
|
||||
// faded out, disable
|
||||
this.enabled = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._effectiveWeight = weight;
|
||||
return weight;
|
||||
|
||||
}
|
||||
|
||||
_updateTimeScale( time ) {
|
||||
|
||||
let timeScale = 0;
|
||||
|
||||
if ( ! this.paused ) {
|
||||
|
||||
timeScale = this.timeScale;
|
||||
|
||||
const interpolant = this._timeScaleInterpolant;
|
||||
|
||||
if ( interpolant !== null ) {
|
||||
|
||||
const interpolantValue = interpolant.evaluate( time )[ 0 ];
|
||||
|
||||
timeScale *= interpolantValue;
|
||||
|
||||
if ( time > interpolant.parameterPositions[ 1 ] ) {
|
||||
|
||||
this.stopWarping();
|
||||
|
||||
if ( timeScale === 0 ) {
|
||||
|
||||
// motion has halted, pause
|
||||
this.paused = true;
|
||||
|
||||
} else {
|
||||
|
||||
// warp done - apply final time scale
|
||||
this.timeScale = timeScale;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._effectiveTimeScale = timeScale;
|
||||
return timeScale;
|
||||
|
||||
}
|
||||
|
||||
_updateTime( deltaTime ) {
|
||||
|
||||
const duration = this._clip.duration;
|
||||
const loop = this.loop;
|
||||
|
||||
let time = this.time + deltaTime;
|
||||
let loopCount = this._loopCount;
|
||||
|
||||
const pingPong = ( loop === LoopPingPong );
|
||||
|
||||
if ( deltaTime === 0 ) {
|
||||
|
||||
if ( loopCount === - 1 ) return time;
|
||||
|
||||
return ( pingPong && ( loopCount & 1 ) === 1 ) ? duration - time : time;
|
||||
|
||||
}
|
||||
|
||||
if ( loop === LoopOnce ) {
|
||||
|
||||
if ( loopCount === - 1 ) {
|
||||
|
||||
// just started
|
||||
|
||||
this._loopCount = 0;
|
||||
this._setEndings( true, true, false );
|
||||
|
||||
}
|
||||
|
||||
handle_stop: {
|
||||
|
||||
if ( time >= duration ) {
|
||||
|
||||
time = duration;
|
||||
|
||||
} else if ( time < 0 ) {
|
||||
|
||||
time = 0;
|
||||
|
||||
} else {
|
||||
|
||||
this.time = time;
|
||||
|
||||
break handle_stop;
|
||||
|
||||
}
|
||||
|
||||
if ( this.clampWhenFinished ) this.paused = true;
|
||||
else this.enabled = false;
|
||||
|
||||
this.time = time;
|
||||
|
||||
this._mixer.dispatchEvent( {
|
||||
type: 'finished', action: this,
|
||||
direction: deltaTime < 0 ? - 1 : 1
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
} else { // repetitive Repeat or PingPong
|
||||
|
||||
if ( loopCount === - 1 ) {
|
||||
|
||||
// just started
|
||||
|
||||
if ( deltaTime >= 0 ) {
|
||||
|
||||
loopCount = 0;
|
||||
|
||||
this._setEndings( true, this.repetitions === 0, pingPong );
|
||||
|
||||
} else {
|
||||
|
||||
// when looping in reverse direction, the initial
|
||||
// transition through zero counts as a repetition,
|
||||
// so leave loopCount at -1
|
||||
|
||||
this._setEndings( this.repetitions === 0, true, pingPong );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( time >= duration || time < 0 ) {
|
||||
|
||||
// wrap around
|
||||
|
||||
const loopDelta = Math.floor( time / duration ); // signed
|
||||
time -= duration * loopDelta;
|
||||
|
||||
loopCount += Math.abs( loopDelta );
|
||||
|
||||
const pending = this.repetitions - loopCount;
|
||||
|
||||
if ( pending <= 0 ) {
|
||||
|
||||
// have to stop (switch state, clamp time, fire event)
|
||||
|
||||
if ( this.clampWhenFinished ) this.paused = true;
|
||||
else this.enabled = false;
|
||||
|
||||
time = deltaTime > 0 ? duration : 0;
|
||||
|
||||
this.time = time;
|
||||
|
||||
this._mixer.dispatchEvent( {
|
||||
type: 'finished', action: this,
|
||||
direction: deltaTime > 0 ? 1 : - 1
|
||||
} );
|
||||
|
||||
} else {
|
||||
|
||||
// keep running
|
||||
|
||||
if ( pending === 1 ) {
|
||||
|
||||
// entering the last round
|
||||
|
||||
const atStart = deltaTime < 0;
|
||||
this._setEndings( atStart, ! atStart, pingPong );
|
||||
|
||||
} else {
|
||||
|
||||
this._setEndings( false, false, pingPong );
|
||||
|
||||
}
|
||||
|
||||
this._loopCount = loopCount;
|
||||
|
||||
this.time = time;
|
||||
|
||||
this._mixer.dispatchEvent( {
|
||||
type: 'loop', action: this, loopDelta: loopDelta
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this.time = time;
|
||||
|
||||
}
|
||||
|
||||
if ( pingPong && ( loopCount & 1 ) === 1 ) {
|
||||
|
||||
// invert time for the "pong round"
|
||||
|
||||
return duration - time;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return time;
|
||||
|
||||
}
|
||||
|
||||
_setEndings( atStart, atEnd, pingPong ) {
|
||||
|
||||
const settings = this._interpolantSettings;
|
||||
|
||||
if ( pingPong ) {
|
||||
|
||||
settings.endingStart = ZeroSlopeEnding;
|
||||
settings.endingEnd = ZeroSlopeEnding;
|
||||
|
||||
} else {
|
||||
|
||||
// assuming for LoopOnce atStart == atEnd == true
|
||||
|
||||
if ( atStart ) {
|
||||
|
||||
settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
|
||||
|
||||
} else {
|
||||
|
||||
settings.endingStart = WrapAroundEnding;
|
||||
|
||||
}
|
||||
|
||||
if ( atEnd ) {
|
||||
|
||||
settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
|
||||
|
||||
} else {
|
||||
|
||||
settings.endingEnd = WrapAroundEnding;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_scheduleFading( duration, weightNow, weightThen ) {
|
||||
|
||||
const mixer = this._mixer, now = mixer.time;
|
||||
let interpolant = this._weightInterpolant;
|
||||
|
||||
if ( interpolant === null ) {
|
||||
|
||||
interpolant = mixer._lendControlInterpolant();
|
||||
this._weightInterpolant = interpolant;
|
||||
|
||||
}
|
||||
|
||||
const times = interpolant.parameterPositions,
|
||||
values = interpolant.sampleValues;
|
||||
|
||||
times[ 0 ] = now;
|
||||
values[ 0 ] = weightNow;
|
||||
times[ 1 ] = now + duration;
|
||||
values[ 1 ] = weightThen;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { AnimationAction };
|
||||
473
network-visualization/node_modules/three/src/animation/AnimationClip.js
generated
vendored
Normal file
473
network-visualization/node_modules/three/src/animation/AnimationClip.js
generated
vendored
Normal file
@@ -0,0 +1,473 @@
|
||||
import * as AnimationUtils from './AnimationUtils.js';
|
||||
import { KeyframeTrack } from './KeyframeTrack.js';
|
||||
import { BooleanKeyframeTrack } from './tracks/BooleanKeyframeTrack.js';
|
||||
import { ColorKeyframeTrack } from './tracks/ColorKeyframeTrack.js';
|
||||
import { NumberKeyframeTrack } from './tracks/NumberKeyframeTrack.js';
|
||||
import { QuaternionKeyframeTrack } from './tracks/QuaternionKeyframeTrack.js';
|
||||
import { StringKeyframeTrack } from './tracks/StringKeyframeTrack.js';
|
||||
import { VectorKeyframeTrack } from './tracks/VectorKeyframeTrack.js';
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
import { NormalAnimationBlendMode } from '../constants.js';
|
||||
|
||||
class AnimationClip {
|
||||
|
||||
constructor( name, duration = - 1, tracks, blendMode = NormalAnimationBlendMode ) {
|
||||
|
||||
this.name = name;
|
||||
this.tracks = tracks;
|
||||
this.duration = duration;
|
||||
this.blendMode = blendMode;
|
||||
|
||||
this.uuid = MathUtils.generateUUID();
|
||||
|
||||
// this means it should figure out its duration by scanning the tracks
|
||||
if ( this.duration < 0 ) {
|
||||
|
||||
this.resetDuration();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static parse( json ) {
|
||||
|
||||
const tracks = [],
|
||||
jsonTracks = json.tracks,
|
||||
frameTime = 1.0 / ( json.fps || 1.0 );
|
||||
|
||||
for ( let i = 0, n = jsonTracks.length; i !== n; ++ i ) {
|
||||
|
||||
tracks.push( parseKeyframeTrack( jsonTracks[ i ] ).scale( frameTime ) );
|
||||
|
||||
}
|
||||
|
||||
const clip = new this( json.name, json.duration, tracks, json.blendMode );
|
||||
clip.uuid = json.uuid;
|
||||
|
||||
return clip;
|
||||
|
||||
}
|
||||
|
||||
static toJSON( clip ) {
|
||||
|
||||
const tracks = [],
|
||||
clipTracks = clip.tracks;
|
||||
|
||||
const json = {
|
||||
|
||||
'name': clip.name,
|
||||
'duration': clip.duration,
|
||||
'tracks': tracks,
|
||||
'uuid': clip.uuid,
|
||||
'blendMode': clip.blendMode
|
||||
|
||||
};
|
||||
|
||||
for ( let i = 0, n = clipTracks.length; i !== n; ++ i ) {
|
||||
|
||||
tracks.push( KeyframeTrack.toJSON( clipTracks[ i ] ) );
|
||||
|
||||
}
|
||||
|
||||
return json;
|
||||
|
||||
}
|
||||
|
||||
static CreateFromMorphTargetSequence( name, morphTargetSequence, fps, noLoop ) {
|
||||
|
||||
const numMorphTargets = morphTargetSequence.length;
|
||||
const tracks = [];
|
||||
|
||||
for ( let i = 0; i < numMorphTargets; i ++ ) {
|
||||
|
||||
let times = [];
|
||||
let values = [];
|
||||
|
||||
times.push(
|
||||
( i + numMorphTargets - 1 ) % numMorphTargets,
|
||||
i,
|
||||
( i + 1 ) % numMorphTargets );
|
||||
|
||||
values.push( 0, 1, 0 );
|
||||
|
||||
const order = AnimationUtils.getKeyframeOrder( times );
|
||||
times = AnimationUtils.sortedArray( times, 1, order );
|
||||
values = AnimationUtils.sortedArray( values, 1, order );
|
||||
|
||||
// if there is a key at the first frame, duplicate it as the
|
||||
// last frame as well for perfect loop.
|
||||
if ( ! noLoop && times[ 0 ] === 0 ) {
|
||||
|
||||
times.push( numMorphTargets );
|
||||
values.push( values[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
tracks.push(
|
||||
new NumberKeyframeTrack(
|
||||
'.morphTargetInfluences[' + morphTargetSequence[ i ].name + ']',
|
||||
times, values
|
||||
).scale( 1.0 / fps ) );
|
||||
|
||||
}
|
||||
|
||||
return new this( name, - 1, tracks );
|
||||
|
||||
}
|
||||
|
||||
static findByName( objectOrClipArray, name ) {
|
||||
|
||||
let clipArray = objectOrClipArray;
|
||||
|
||||
if ( ! Array.isArray( objectOrClipArray ) ) {
|
||||
|
||||
const o = objectOrClipArray;
|
||||
clipArray = o.geometry && o.geometry.animations || o.animations;
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i < clipArray.length; i ++ ) {
|
||||
|
||||
if ( clipArray[ i ].name === name ) {
|
||||
|
||||
return clipArray[ i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
static CreateClipsFromMorphTargetSequences( morphTargets, fps, noLoop ) {
|
||||
|
||||
const animationToMorphTargets = {};
|
||||
|
||||
// tested with https://regex101.com/ on trick sequences
|
||||
// such flamingo_flyA_003, flamingo_run1_003, crdeath0059
|
||||
const pattern = /^([\w-]*?)([\d]+)$/;
|
||||
|
||||
// sort morph target names into animation groups based
|
||||
// patterns like Walk_001, Walk_002, Run_001, Run_002
|
||||
for ( let i = 0, il = morphTargets.length; i < il; i ++ ) {
|
||||
|
||||
const morphTarget = morphTargets[ i ];
|
||||
const parts = morphTarget.name.match( pattern );
|
||||
|
||||
if ( parts && parts.length > 1 ) {
|
||||
|
||||
const name = parts[ 1 ];
|
||||
|
||||
let animationMorphTargets = animationToMorphTargets[ name ];
|
||||
|
||||
if ( ! animationMorphTargets ) {
|
||||
|
||||
animationToMorphTargets[ name ] = animationMorphTargets = [];
|
||||
|
||||
}
|
||||
|
||||
animationMorphTargets.push( morphTarget );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const clips = [];
|
||||
|
||||
for ( const name in animationToMorphTargets ) {
|
||||
|
||||
clips.push( this.CreateFromMorphTargetSequence( name, animationToMorphTargets[ name ], fps, noLoop ) );
|
||||
|
||||
}
|
||||
|
||||
return clips;
|
||||
|
||||
}
|
||||
|
||||
// parse the animation.hierarchy format
|
||||
static parseAnimation( animation, bones ) {
|
||||
|
||||
if ( ! animation ) {
|
||||
|
||||
console.error( 'THREE.AnimationClip: No animation in JSONLoader data.' );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
const addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) {
|
||||
|
||||
// only return track if there are actually keys.
|
||||
if ( animationKeys.length !== 0 ) {
|
||||
|
||||
const times = [];
|
||||
const values = [];
|
||||
|
||||
AnimationUtils.flattenJSON( animationKeys, times, values, propertyName );
|
||||
|
||||
// empty keys are filtered out, so check again
|
||||
if ( times.length !== 0 ) {
|
||||
|
||||
destTracks.push( new trackType( trackName, times, values ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const tracks = [];
|
||||
|
||||
const clipName = animation.name || 'default';
|
||||
const fps = animation.fps || 30;
|
||||
const blendMode = animation.blendMode;
|
||||
|
||||
// automatic length determination in AnimationClip.
|
||||
let duration = animation.length || - 1;
|
||||
|
||||
const hierarchyTracks = animation.hierarchy || [];
|
||||
|
||||
for ( let h = 0; h < hierarchyTracks.length; h ++ ) {
|
||||
|
||||
const animationKeys = hierarchyTracks[ h ].keys;
|
||||
|
||||
// skip empty tracks
|
||||
if ( ! animationKeys || animationKeys.length === 0 ) continue;
|
||||
|
||||
// process morph targets
|
||||
if ( animationKeys[ 0 ].morphTargets ) {
|
||||
|
||||
// figure out all morph targets used in this track
|
||||
const morphTargetNames = {};
|
||||
|
||||
let k;
|
||||
|
||||
for ( k = 0; k < animationKeys.length; k ++ ) {
|
||||
|
||||
if ( animationKeys[ k ].morphTargets ) {
|
||||
|
||||
for ( let m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) {
|
||||
|
||||
morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = - 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// create a track for each morph target with all zero
|
||||
// morphTargetInfluences except for the keys in which
|
||||
// the morphTarget is named.
|
||||
for ( const morphTargetName in morphTargetNames ) {
|
||||
|
||||
const times = [];
|
||||
const values = [];
|
||||
|
||||
for ( let m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) {
|
||||
|
||||
const animationKey = animationKeys[ k ];
|
||||
|
||||
times.push( animationKey.time );
|
||||
values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 );
|
||||
|
||||
}
|
||||
|
||||
tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) );
|
||||
|
||||
}
|
||||
|
||||
duration = morphTargetNames.length * fps;
|
||||
|
||||
} else {
|
||||
|
||||
// ...assume skeletal animation
|
||||
|
||||
const boneName = '.bones[' + bones[ h ].name + ']';
|
||||
|
||||
addNonemptyTrack(
|
||||
VectorKeyframeTrack, boneName + '.position',
|
||||
animationKeys, 'pos', tracks );
|
||||
|
||||
addNonemptyTrack(
|
||||
QuaternionKeyframeTrack, boneName + '.quaternion',
|
||||
animationKeys, 'rot', tracks );
|
||||
|
||||
addNonemptyTrack(
|
||||
VectorKeyframeTrack, boneName + '.scale',
|
||||
animationKeys, 'scl', tracks );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( tracks.length === 0 ) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
const clip = new this( clipName, duration, tracks, blendMode );
|
||||
|
||||
return clip;
|
||||
|
||||
}
|
||||
|
||||
resetDuration() {
|
||||
|
||||
const tracks = this.tracks;
|
||||
let duration = 0;
|
||||
|
||||
for ( let i = 0, n = tracks.length; i !== n; ++ i ) {
|
||||
|
||||
const track = this.tracks[ i ];
|
||||
|
||||
duration = Math.max( duration, track.times[ track.times.length - 1 ] );
|
||||
|
||||
}
|
||||
|
||||
this.duration = duration;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
trim() {
|
||||
|
||||
for ( let i = 0; i < this.tracks.length; i ++ ) {
|
||||
|
||||
this.tracks[ i ].trim( 0, this.duration );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
validate() {
|
||||
|
||||
let valid = true;
|
||||
|
||||
for ( let i = 0; i < this.tracks.length; i ++ ) {
|
||||
|
||||
valid = valid && this.tracks[ i ].validate();
|
||||
|
||||
}
|
||||
|
||||
return valid;
|
||||
|
||||
}
|
||||
|
||||
optimize() {
|
||||
|
||||
for ( let i = 0; i < this.tracks.length; i ++ ) {
|
||||
|
||||
this.tracks[ i ].optimize();
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
const tracks = [];
|
||||
|
||||
for ( let i = 0; i < this.tracks.length; i ++ ) {
|
||||
|
||||
tracks.push( this.tracks[ i ].clone() );
|
||||
|
||||
}
|
||||
|
||||
return new this.constructor( this.name, this.duration, tracks, this.blendMode );
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
return this.constructor.toJSON( this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getTrackTypeForValueTypeName( typeName ) {
|
||||
|
||||
switch ( typeName.toLowerCase() ) {
|
||||
|
||||
case 'scalar':
|
||||
case 'double':
|
||||
case 'float':
|
||||
case 'number':
|
||||
case 'integer':
|
||||
|
||||
return NumberKeyframeTrack;
|
||||
|
||||
case 'vector':
|
||||
case 'vector2':
|
||||
case 'vector3':
|
||||
case 'vector4':
|
||||
|
||||
return VectorKeyframeTrack;
|
||||
|
||||
case 'color':
|
||||
|
||||
return ColorKeyframeTrack;
|
||||
|
||||
case 'quaternion':
|
||||
|
||||
return QuaternionKeyframeTrack;
|
||||
|
||||
case 'bool':
|
||||
case 'boolean':
|
||||
|
||||
return BooleanKeyframeTrack;
|
||||
|
||||
case 'string':
|
||||
|
||||
return StringKeyframeTrack;
|
||||
|
||||
}
|
||||
|
||||
throw new Error( 'THREE.KeyframeTrack: Unsupported typeName: ' + typeName );
|
||||
|
||||
}
|
||||
|
||||
function parseKeyframeTrack( json ) {
|
||||
|
||||
if ( json.type === undefined ) {
|
||||
|
||||
throw new Error( 'THREE.KeyframeTrack: track type undefined, can not parse' );
|
||||
|
||||
}
|
||||
|
||||
const trackType = getTrackTypeForValueTypeName( json.type );
|
||||
|
||||
if ( json.times === undefined ) {
|
||||
|
||||
const times = [], values = [];
|
||||
|
||||
AnimationUtils.flattenJSON( json.keys, times, values, 'value' );
|
||||
|
||||
json.times = times;
|
||||
json.values = values;
|
||||
|
||||
}
|
||||
|
||||
// derived classes can define a static parse method
|
||||
if ( trackType.parse !== undefined ) {
|
||||
|
||||
return trackType.parse( json );
|
||||
|
||||
} else {
|
||||
|
||||
// by default, we assume a constructor compatible with the base
|
||||
return new trackType( json.name, json.times, json.values, json.interpolation );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { AnimationClip };
|
||||
770
network-visualization/node_modules/three/src/animation/AnimationMixer.js
generated
vendored
Normal file
770
network-visualization/node_modules/three/src/animation/AnimationMixer.js
generated
vendored
Normal file
@@ -0,0 +1,770 @@
|
||||
import { AnimationAction } from './AnimationAction.js';
|
||||
import { EventDispatcher } from '../core/EventDispatcher.js';
|
||||
import { LinearInterpolant } from '../math/interpolants/LinearInterpolant.js';
|
||||
import { PropertyBinding } from './PropertyBinding.js';
|
||||
import { PropertyMixer } from './PropertyMixer.js';
|
||||
import { AnimationClip } from './AnimationClip.js';
|
||||
import { NormalAnimationBlendMode } from '../constants.js';
|
||||
|
||||
|
||||
const _controlInterpolantsResultBuffer = new Float32Array( 1 );
|
||||
|
||||
|
||||
class AnimationMixer extends EventDispatcher {
|
||||
|
||||
constructor( root ) {
|
||||
|
||||
super();
|
||||
|
||||
this._root = root;
|
||||
this._initMemoryManager();
|
||||
this._accuIndex = 0;
|
||||
this.time = 0;
|
||||
this.timeScale = 1.0;
|
||||
|
||||
}
|
||||
|
||||
_bindAction( action, prototypeAction ) {
|
||||
|
||||
const root = action._localRoot || this._root,
|
||||
tracks = action._clip.tracks,
|
||||
nTracks = tracks.length,
|
||||
bindings = action._propertyBindings,
|
||||
interpolants = action._interpolants,
|
||||
rootUuid = root.uuid,
|
||||
bindingsByRoot = this._bindingsByRootAndName;
|
||||
|
||||
let bindingsByName = bindingsByRoot[ rootUuid ];
|
||||
|
||||
if ( bindingsByName === undefined ) {
|
||||
|
||||
bindingsByName = {};
|
||||
bindingsByRoot[ rootUuid ] = bindingsByName;
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i !== nTracks; ++ i ) {
|
||||
|
||||
const track = tracks[ i ],
|
||||
trackName = track.name;
|
||||
|
||||
let binding = bindingsByName[ trackName ];
|
||||
|
||||
if ( binding !== undefined ) {
|
||||
|
||||
++ binding.referenceCount;
|
||||
bindings[ i ] = binding;
|
||||
|
||||
} else {
|
||||
|
||||
binding = bindings[ i ];
|
||||
|
||||
if ( binding !== undefined ) {
|
||||
|
||||
// existing binding, make sure the cache knows
|
||||
|
||||
if ( binding._cacheIndex === null ) {
|
||||
|
||||
++ binding.referenceCount;
|
||||
this._addInactiveBinding( binding, rootUuid, trackName );
|
||||
|
||||
}
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
const path = prototypeAction && prototypeAction.
|
||||
_propertyBindings[ i ].binding.parsedPath;
|
||||
|
||||
binding = new PropertyMixer(
|
||||
PropertyBinding.create( root, trackName, path ),
|
||||
track.ValueTypeName, track.getValueSize() );
|
||||
|
||||
++ binding.referenceCount;
|
||||
this._addInactiveBinding( binding, rootUuid, trackName );
|
||||
|
||||
bindings[ i ] = binding;
|
||||
|
||||
}
|
||||
|
||||
interpolants[ i ].resultBuffer = binding.buffer;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_activateAction( action ) {
|
||||
|
||||
if ( ! this._isActiveAction( action ) ) {
|
||||
|
||||
if ( action._cacheIndex === null ) {
|
||||
|
||||
// this action has been forgotten by the cache, but the user
|
||||
// appears to be still using it -> rebind
|
||||
|
||||
const rootUuid = ( action._localRoot || this._root ).uuid,
|
||||
clipUuid = action._clip.uuid,
|
||||
actionsForClip = this._actionsByClip[ clipUuid ];
|
||||
|
||||
this._bindAction( action,
|
||||
actionsForClip && actionsForClip.knownActions[ 0 ] );
|
||||
|
||||
this._addInactiveAction( action, clipUuid, rootUuid );
|
||||
|
||||
}
|
||||
|
||||
const bindings = action._propertyBindings;
|
||||
|
||||
// increment reference counts / sort out state
|
||||
for ( let i = 0, n = bindings.length; i !== n; ++ i ) {
|
||||
|
||||
const binding = bindings[ i ];
|
||||
|
||||
if ( binding.useCount ++ === 0 ) {
|
||||
|
||||
this._lendBinding( binding );
|
||||
binding.saveOriginalState();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._lendAction( action );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_deactivateAction( action ) {
|
||||
|
||||
if ( this._isActiveAction( action ) ) {
|
||||
|
||||
const bindings = action._propertyBindings;
|
||||
|
||||
// decrement reference counts / sort out state
|
||||
for ( let i = 0, n = bindings.length; i !== n; ++ i ) {
|
||||
|
||||
const binding = bindings[ i ];
|
||||
|
||||
if ( -- binding.useCount === 0 ) {
|
||||
|
||||
binding.restoreOriginalState();
|
||||
this._takeBackBinding( binding );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this._takeBackAction( action );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Memory manager
|
||||
|
||||
_initMemoryManager() {
|
||||
|
||||
this._actions = []; // 'nActiveActions' followed by inactive ones
|
||||
this._nActiveActions = 0;
|
||||
|
||||
this._actionsByClip = {};
|
||||
// inside:
|
||||
// {
|
||||
// knownActions: Array< AnimationAction > - used as prototypes
|
||||
// actionByRoot: AnimationAction - lookup
|
||||
// }
|
||||
|
||||
|
||||
this._bindings = []; // 'nActiveBindings' followed by inactive ones
|
||||
this._nActiveBindings = 0;
|
||||
|
||||
this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
|
||||
|
||||
|
||||
this._controlInterpolants = []; // same game as above
|
||||
this._nActiveControlInterpolants = 0;
|
||||
|
||||
const scope = this;
|
||||
|
||||
this.stats = {
|
||||
|
||||
actions: {
|
||||
get total() {
|
||||
|
||||
return scope._actions.length;
|
||||
|
||||
},
|
||||
get inUse() {
|
||||
|
||||
return scope._nActiveActions;
|
||||
|
||||
}
|
||||
},
|
||||
bindings: {
|
||||
get total() {
|
||||
|
||||
return scope._bindings.length;
|
||||
|
||||
},
|
||||
get inUse() {
|
||||
|
||||
return scope._nActiveBindings;
|
||||
|
||||
}
|
||||
},
|
||||
controlInterpolants: {
|
||||
get total() {
|
||||
|
||||
return scope._controlInterpolants.length;
|
||||
|
||||
},
|
||||
get inUse() {
|
||||
|
||||
return scope._nActiveControlInterpolants;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Memory management for AnimationAction objects
|
||||
|
||||
_isActiveAction( action ) {
|
||||
|
||||
const index = action._cacheIndex;
|
||||
return index !== null && index < this._nActiveActions;
|
||||
|
||||
}
|
||||
|
||||
_addInactiveAction( action, clipUuid, rootUuid ) {
|
||||
|
||||
const actions = this._actions,
|
||||
actionsByClip = this._actionsByClip;
|
||||
|
||||
let actionsForClip = actionsByClip[ clipUuid ];
|
||||
|
||||
if ( actionsForClip === undefined ) {
|
||||
|
||||
actionsForClip = {
|
||||
|
||||
knownActions: [ action ],
|
||||
actionByRoot: {}
|
||||
|
||||
};
|
||||
|
||||
action._byClipCacheIndex = 0;
|
||||
|
||||
actionsByClip[ clipUuid ] = actionsForClip;
|
||||
|
||||
} else {
|
||||
|
||||
const knownActions = actionsForClip.knownActions;
|
||||
|
||||
action._byClipCacheIndex = knownActions.length;
|
||||
knownActions.push( action );
|
||||
|
||||
}
|
||||
|
||||
action._cacheIndex = actions.length;
|
||||
actions.push( action );
|
||||
|
||||
actionsForClip.actionByRoot[ rootUuid ] = action;
|
||||
|
||||
}
|
||||
|
||||
_removeInactiveAction( action ) {
|
||||
|
||||
const actions = this._actions,
|
||||
lastInactiveAction = actions[ actions.length - 1 ],
|
||||
cacheIndex = action._cacheIndex;
|
||||
|
||||
lastInactiveAction._cacheIndex = cacheIndex;
|
||||
actions[ cacheIndex ] = lastInactiveAction;
|
||||
actions.pop();
|
||||
|
||||
action._cacheIndex = null;
|
||||
|
||||
|
||||
const clipUuid = action._clip.uuid,
|
||||
actionsByClip = this._actionsByClip,
|
||||
actionsForClip = actionsByClip[ clipUuid ],
|
||||
knownActionsForClip = actionsForClip.knownActions,
|
||||
|
||||
lastKnownAction =
|
||||
knownActionsForClip[ knownActionsForClip.length - 1 ],
|
||||
|
||||
byClipCacheIndex = action._byClipCacheIndex;
|
||||
|
||||
lastKnownAction._byClipCacheIndex = byClipCacheIndex;
|
||||
knownActionsForClip[ byClipCacheIndex ] = lastKnownAction;
|
||||
knownActionsForClip.pop();
|
||||
|
||||
action._byClipCacheIndex = null;
|
||||
|
||||
|
||||
const actionByRoot = actionsForClip.actionByRoot,
|
||||
rootUuid = ( action._localRoot || this._root ).uuid;
|
||||
|
||||
delete actionByRoot[ rootUuid ];
|
||||
|
||||
if ( knownActionsForClip.length === 0 ) {
|
||||
|
||||
delete actionsByClip[ clipUuid ];
|
||||
|
||||
}
|
||||
|
||||
this._removeInactiveBindingsForAction( action );
|
||||
|
||||
}
|
||||
|
||||
_removeInactiveBindingsForAction( action ) {
|
||||
|
||||
const bindings = action._propertyBindings;
|
||||
|
||||
for ( let i = 0, n = bindings.length; i !== n; ++ i ) {
|
||||
|
||||
const binding = bindings[ i ];
|
||||
|
||||
if ( -- binding.referenceCount === 0 ) {
|
||||
|
||||
this._removeInactiveBinding( binding );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_lendAction( action ) {
|
||||
|
||||
// [ active actions | inactive actions ]
|
||||
// [ active actions >| inactive actions ]
|
||||
// s a
|
||||
// <-swap->
|
||||
// a s
|
||||
|
||||
const actions = this._actions,
|
||||
prevIndex = action._cacheIndex,
|
||||
|
||||
lastActiveIndex = this._nActiveActions ++,
|
||||
|
||||
firstInactiveAction = actions[ lastActiveIndex ];
|
||||
|
||||
action._cacheIndex = lastActiveIndex;
|
||||
actions[ lastActiveIndex ] = action;
|
||||
|
||||
firstInactiveAction._cacheIndex = prevIndex;
|
||||
actions[ prevIndex ] = firstInactiveAction;
|
||||
|
||||
}
|
||||
|
||||
_takeBackAction( action ) {
|
||||
|
||||
// [ active actions | inactive actions ]
|
||||
// [ active actions |< inactive actions ]
|
||||
// a s
|
||||
// <-swap->
|
||||
// s a
|
||||
|
||||
const actions = this._actions,
|
||||
prevIndex = action._cacheIndex,
|
||||
|
||||
firstInactiveIndex = -- this._nActiveActions,
|
||||
|
||||
lastActiveAction = actions[ firstInactiveIndex ];
|
||||
|
||||
action._cacheIndex = firstInactiveIndex;
|
||||
actions[ firstInactiveIndex ] = action;
|
||||
|
||||
lastActiveAction._cacheIndex = prevIndex;
|
||||
actions[ prevIndex ] = lastActiveAction;
|
||||
|
||||
}
|
||||
|
||||
// Memory management for PropertyMixer objects
|
||||
|
||||
_addInactiveBinding( binding, rootUuid, trackName ) {
|
||||
|
||||
const bindingsByRoot = this._bindingsByRootAndName,
|
||||
bindings = this._bindings;
|
||||
|
||||
let bindingByName = bindingsByRoot[ rootUuid ];
|
||||
|
||||
if ( bindingByName === undefined ) {
|
||||
|
||||
bindingByName = {};
|
||||
bindingsByRoot[ rootUuid ] = bindingByName;
|
||||
|
||||
}
|
||||
|
||||
bindingByName[ trackName ] = binding;
|
||||
|
||||
binding._cacheIndex = bindings.length;
|
||||
bindings.push( binding );
|
||||
|
||||
}
|
||||
|
||||
_removeInactiveBinding( binding ) {
|
||||
|
||||
const bindings = this._bindings,
|
||||
propBinding = binding.binding,
|
||||
rootUuid = propBinding.rootNode.uuid,
|
||||
trackName = propBinding.path,
|
||||
bindingsByRoot = this._bindingsByRootAndName,
|
||||
bindingByName = bindingsByRoot[ rootUuid ],
|
||||
|
||||
lastInactiveBinding = bindings[ bindings.length - 1 ],
|
||||
cacheIndex = binding._cacheIndex;
|
||||
|
||||
lastInactiveBinding._cacheIndex = cacheIndex;
|
||||
bindings[ cacheIndex ] = lastInactiveBinding;
|
||||
bindings.pop();
|
||||
|
||||
delete bindingByName[ trackName ];
|
||||
|
||||
if ( Object.keys( bindingByName ).length === 0 ) {
|
||||
|
||||
delete bindingsByRoot[ rootUuid ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_lendBinding( binding ) {
|
||||
|
||||
const bindings = this._bindings,
|
||||
prevIndex = binding._cacheIndex,
|
||||
|
||||
lastActiveIndex = this._nActiveBindings ++,
|
||||
|
||||
firstInactiveBinding = bindings[ lastActiveIndex ];
|
||||
|
||||
binding._cacheIndex = lastActiveIndex;
|
||||
bindings[ lastActiveIndex ] = binding;
|
||||
|
||||
firstInactiveBinding._cacheIndex = prevIndex;
|
||||
bindings[ prevIndex ] = firstInactiveBinding;
|
||||
|
||||
}
|
||||
|
||||
_takeBackBinding( binding ) {
|
||||
|
||||
const bindings = this._bindings,
|
||||
prevIndex = binding._cacheIndex,
|
||||
|
||||
firstInactiveIndex = -- this._nActiveBindings,
|
||||
|
||||
lastActiveBinding = bindings[ firstInactiveIndex ];
|
||||
|
||||
binding._cacheIndex = firstInactiveIndex;
|
||||
bindings[ firstInactiveIndex ] = binding;
|
||||
|
||||
lastActiveBinding._cacheIndex = prevIndex;
|
||||
bindings[ prevIndex ] = lastActiveBinding;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Memory management of Interpolants for weight and time scale
|
||||
|
||||
_lendControlInterpolant() {
|
||||
|
||||
const interpolants = this._controlInterpolants,
|
||||
lastActiveIndex = this._nActiveControlInterpolants ++;
|
||||
|
||||
let interpolant = interpolants[ lastActiveIndex ];
|
||||
|
||||
if ( interpolant === undefined ) {
|
||||
|
||||
interpolant = new LinearInterpolant(
|
||||
new Float32Array( 2 ), new Float32Array( 2 ),
|
||||
1, _controlInterpolantsResultBuffer );
|
||||
|
||||
interpolant.__cacheIndex = lastActiveIndex;
|
||||
interpolants[ lastActiveIndex ] = interpolant;
|
||||
|
||||
}
|
||||
|
||||
return interpolant;
|
||||
|
||||
}
|
||||
|
||||
_takeBackControlInterpolant( interpolant ) {
|
||||
|
||||
const interpolants = this._controlInterpolants,
|
||||
prevIndex = interpolant.__cacheIndex,
|
||||
|
||||
firstInactiveIndex = -- this._nActiveControlInterpolants,
|
||||
|
||||
lastActiveInterpolant = interpolants[ firstInactiveIndex ];
|
||||
|
||||
interpolant.__cacheIndex = firstInactiveIndex;
|
||||
interpolants[ firstInactiveIndex ] = interpolant;
|
||||
|
||||
lastActiveInterpolant.__cacheIndex = prevIndex;
|
||||
interpolants[ prevIndex ] = lastActiveInterpolant;
|
||||
|
||||
}
|
||||
|
||||
// return an action for a clip optionally using a custom root target
|
||||
// object (this method allocates a lot of dynamic memory in case a
|
||||
// previously unknown clip/root combination is specified)
|
||||
clipAction( clip, optionalRoot, blendMode ) {
|
||||
|
||||
const root = optionalRoot || this._root,
|
||||
rootUuid = root.uuid;
|
||||
|
||||
let clipObject = typeof clip === 'string' ? AnimationClip.findByName( root, clip ) : clip;
|
||||
|
||||
const clipUuid = clipObject !== null ? clipObject.uuid : clip;
|
||||
|
||||
const actionsForClip = this._actionsByClip[ clipUuid ];
|
||||
let prototypeAction = null;
|
||||
|
||||
if ( blendMode === undefined ) {
|
||||
|
||||
if ( clipObject !== null ) {
|
||||
|
||||
blendMode = clipObject.blendMode;
|
||||
|
||||
} else {
|
||||
|
||||
blendMode = NormalAnimationBlendMode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( actionsForClip !== undefined ) {
|
||||
|
||||
const existingAction = actionsForClip.actionByRoot[ rootUuid ];
|
||||
|
||||
if ( existingAction !== undefined && existingAction.blendMode === blendMode ) {
|
||||
|
||||
return existingAction;
|
||||
|
||||
}
|
||||
|
||||
// we know the clip, so we don't have to parse all
|
||||
// the bindings again but can just copy
|
||||
prototypeAction = actionsForClip.knownActions[ 0 ];
|
||||
|
||||
// also, take the clip from the prototype action
|
||||
if ( clipObject === null )
|
||||
clipObject = prototypeAction._clip;
|
||||
|
||||
}
|
||||
|
||||
// clip must be known when specified via string
|
||||
if ( clipObject === null ) return null;
|
||||
|
||||
// allocate all resources required to run it
|
||||
const newAction = new AnimationAction( this, clipObject, optionalRoot, blendMode );
|
||||
|
||||
this._bindAction( newAction, prototypeAction );
|
||||
|
||||
// and make the action known to the memory manager
|
||||
this._addInactiveAction( newAction, clipUuid, rootUuid );
|
||||
|
||||
return newAction;
|
||||
|
||||
}
|
||||
|
||||
// get an existing action
|
||||
existingAction( clip, optionalRoot ) {
|
||||
|
||||
const root = optionalRoot || this._root,
|
||||
rootUuid = root.uuid,
|
||||
|
||||
clipObject = typeof clip === 'string' ?
|
||||
AnimationClip.findByName( root, clip ) : clip,
|
||||
|
||||
clipUuid = clipObject ? clipObject.uuid : clip,
|
||||
|
||||
actionsForClip = this._actionsByClip[ clipUuid ];
|
||||
|
||||
if ( actionsForClip !== undefined ) {
|
||||
|
||||
return actionsForClip.actionByRoot[ rootUuid ] || null;
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// deactivates all previously scheduled actions
|
||||
stopAllAction() {
|
||||
|
||||
const actions = this._actions,
|
||||
nActions = this._nActiveActions;
|
||||
|
||||
for ( let i = nActions - 1; i >= 0; -- i ) {
|
||||
|
||||
actions[ i ].stop();
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// advance the time and update apply the animation
|
||||
update( deltaTime ) {
|
||||
|
||||
deltaTime *= this.timeScale;
|
||||
|
||||
const actions = this._actions,
|
||||
nActions = this._nActiveActions,
|
||||
|
||||
time = this.time += deltaTime,
|
||||
timeDirection = Math.sign( deltaTime ),
|
||||
|
||||
accuIndex = this._accuIndex ^= 1;
|
||||
|
||||
// run active actions
|
||||
|
||||
for ( let i = 0; i !== nActions; ++ i ) {
|
||||
|
||||
const action = actions[ i ];
|
||||
|
||||
action._update( time, deltaTime, timeDirection, accuIndex );
|
||||
|
||||
}
|
||||
|
||||
// update scene graph
|
||||
|
||||
const bindings = this._bindings,
|
||||
nBindings = this._nActiveBindings;
|
||||
|
||||
for ( let i = 0; i !== nBindings; ++ i ) {
|
||||
|
||||
bindings[ i ].apply( accuIndex );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// Allows you to seek to a specific time in an animation.
|
||||
setTime( timeInSeconds ) {
|
||||
|
||||
this.time = 0; // Zero out time attribute for AnimationMixer object;
|
||||
for ( let i = 0; i < this._actions.length; i ++ ) {
|
||||
|
||||
this._actions[ i ].time = 0; // Zero out time attribute for all associated AnimationAction objects.
|
||||
|
||||
}
|
||||
|
||||
return this.update( timeInSeconds ); // Update used to set exact time. Returns "this" AnimationMixer object.
|
||||
|
||||
}
|
||||
|
||||
// return this mixer's root target object
|
||||
getRoot() {
|
||||
|
||||
return this._root;
|
||||
|
||||
}
|
||||
|
||||
// free all resources specific to a particular clip
|
||||
uncacheClip( clip ) {
|
||||
|
||||
const actions = this._actions,
|
||||
clipUuid = clip.uuid,
|
||||
actionsByClip = this._actionsByClip,
|
||||
actionsForClip = actionsByClip[ clipUuid ];
|
||||
|
||||
if ( actionsForClip !== undefined ) {
|
||||
|
||||
// note: just calling _removeInactiveAction would mess up the
|
||||
// iteration state and also require updating the state we can
|
||||
// just throw away
|
||||
|
||||
const actionsToRemove = actionsForClip.knownActions;
|
||||
|
||||
for ( let i = 0, n = actionsToRemove.length; i !== n; ++ i ) {
|
||||
|
||||
const action = actionsToRemove[ i ];
|
||||
|
||||
this._deactivateAction( action );
|
||||
|
||||
const cacheIndex = action._cacheIndex,
|
||||
lastInactiveAction = actions[ actions.length - 1 ];
|
||||
|
||||
action._cacheIndex = null;
|
||||
action._byClipCacheIndex = null;
|
||||
|
||||
lastInactiveAction._cacheIndex = cacheIndex;
|
||||
actions[ cacheIndex ] = lastInactiveAction;
|
||||
actions.pop();
|
||||
|
||||
this._removeInactiveBindingsForAction( action );
|
||||
|
||||
}
|
||||
|
||||
delete actionsByClip[ clipUuid ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// free all resources specific to a particular root target object
|
||||
uncacheRoot( root ) {
|
||||
|
||||
const rootUuid = root.uuid,
|
||||
actionsByClip = this._actionsByClip;
|
||||
|
||||
for ( const clipUuid in actionsByClip ) {
|
||||
|
||||
const actionByRoot = actionsByClip[ clipUuid ].actionByRoot,
|
||||
action = actionByRoot[ rootUuid ];
|
||||
|
||||
if ( action !== undefined ) {
|
||||
|
||||
this._deactivateAction( action );
|
||||
this._removeInactiveAction( action );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const bindingsByRoot = this._bindingsByRootAndName,
|
||||
bindingByName = bindingsByRoot[ rootUuid ];
|
||||
|
||||
if ( bindingByName !== undefined ) {
|
||||
|
||||
for ( const trackName in bindingByName ) {
|
||||
|
||||
const binding = bindingByName[ trackName ];
|
||||
binding.restoreOriginalState();
|
||||
this._removeInactiveBinding( binding );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remove a targeted clip from the cache
|
||||
uncacheAction( clip, optionalRoot ) {
|
||||
|
||||
const action = this.existingAction( clip, optionalRoot );
|
||||
|
||||
if ( action !== null ) {
|
||||
|
||||
this._deactivateAction( action );
|
||||
this._removeInactiveAction( action );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { AnimationMixer };
|
||||
387
network-visualization/node_modules/three/src/animation/AnimationObjectGroup.js
generated
vendored
Normal file
387
network-visualization/node_modules/three/src/animation/AnimationObjectGroup.js
generated
vendored
Normal file
@@ -0,0 +1,387 @@
|
||||
import { PropertyBinding } from './PropertyBinding.js';
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
|
||||
/**
|
||||
*
|
||||
* A group of objects that receives a shared animation state.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* - Add objects you would otherwise pass as 'root' to the
|
||||
* constructor or the .clipAction method of AnimationMixer.
|
||||
*
|
||||
* - Instead pass this object as 'root'.
|
||||
*
|
||||
* - You can also add and remove objects later when the mixer
|
||||
* is running.
|
||||
*
|
||||
* Note:
|
||||
*
|
||||
* Objects of this class appear as one object to the mixer,
|
||||
* so cache control of the individual objects must be done
|
||||
* on the group.
|
||||
*
|
||||
* Limitation:
|
||||
*
|
||||
* - The animated properties must be compatible among the
|
||||
* all objects in the group.
|
||||
*
|
||||
* - A single property can either be controlled through a
|
||||
* target group or directly, but not both.
|
||||
*/
|
||||
|
||||
class AnimationObjectGroup {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.isAnimationObjectGroup = true;
|
||||
|
||||
this.uuid = MathUtils.generateUUID();
|
||||
|
||||
// cached objects followed by the active ones
|
||||
this._objects = Array.prototype.slice.call( arguments );
|
||||
|
||||
this.nCachedObjects_ = 0; // threshold
|
||||
// note: read by PropertyBinding.Composite
|
||||
|
||||
const indices = {};
|
||||
this._indicesByUUID = indices; // for bookkeeping
|
||||
|
||||
for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
|
||||
|
||||
indices[ arguments[ i ].uuid ] = i;
|
||||
|
||||
}
|
||||
|
||||
this._paths = []; // inside: string
|
||||
this._parsedPaths = []; // inside: { we don't care, here }
|
||||
this._bindings = []; // inside: Array< PropertyBinding >
|
||||
this._bindingsIndicesByPath = {}; // inside: indices in these arrays
|
||||
|
||||
const scope = this;
|
||||
|
||||
this.stats = {
|
||||
|
||||
objects: {
|
||||
get total() {
|
||||
|
||||
return scope._objects.length;
|
||||
|
||||
},
|
||||
get inUse() {
|
||||
|
||||
return this.total - scope.nCachedObjects_;
|
||||
|
||||
}
|
||||
},
|
||||
get bindingsPerObject() {
|
||||
|
||||
return scope._bindings.length;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
add() {
|
||||
|
||||
const objects = this._objects,
|
||||
indicesByUUID = this._indicesByUUID,
|
||||
paths = this._paths,
|
||||
parsedPaths = this._parsedPaths,
|
||||
bindings = this._bindings,
|
||||
nBindings = bindings.length;
|
||||
|
||||
let knownObject = undefined,
|
||||
nObjects = objects.length,
|
||||
nCachedObjects = this.nCachedObjects_;
|
||||
|
||||
for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
|
||||
|
||||
const object = arguments[ i ],
|
||||
uuid = object.uuid;
|
||||
let index = indicesByUUID[ uuid ];
|
||||
|
||||
if ( index === undefined ) {
|
||||
|
||||
// unknown object -> add it to the ACTIVE region
|
||||
|
||||
index = nObjects ++;
|
||||
indicesByUUID[ uuid ] = index;
|
||||
objects.push( object );
|
||||
|
||||
// accounting is done, now do the same for all bindings
|
||||
|
||||
for ( let j = 0, m = nBindings; j !== m; ++ j ) {
|
||||
|
||||
bindings[ j ].push( new PropertyBinding( object, paths[ j ], parsedPaths[ j ] ) );
|
||||
|
||||
}
|
||||
|
||||
} else if ( index < nCachedObjects ) {
|
||||
|
||||
knownObject = objects[ index ];
|
||||
|
||||
// move existing object to the ACTIVE region
|
||||
|
||||
const firstActiveIndex = -- nCachedObjects,
|
||||
lastCachedObject = objects[ firstActiveIndex ];
|
||||
|
||||
indicesByUUID[ lastCachedObject.uuid ] = index;
|
||||
objects[ index ] = lastCachedObject;
|
||||
|
||||
indicesByUUID[ uuid ] = firstActiveIndex;
|
||||
objects[ firstActiveIndex ] = object;
|
||||
|
||||
// accounting is done, now do the same for all bindings
|
||||
|
||||
for ( let j = 0, m = nBindings; j !== m; ++ j ) {
|
||||
|
||||
const bindingsForPath = bindings[ j ],
|
||||
lastCached = bindingsForPath[ firstActiveIndex ];
|
||||
|
||||
let binding = bindingsForPath[ index ];
|
||||
|
||||
bindingsForPath[ index ] = lastCached;
|
||||
|
||||
if ( binding === undefined ) {
|
||||
|
||||
// since we do not bother to create new bindings
|
||||
// for objects that are cached, the binding may
|
||||
// or may not exist
|
||||
|
||||
binding = new PropertyBinding( object, paths[ j ], parsedPaths[ j ] );
|
||||
|
||||
}
|
||||
|
||||
bindingsForPath[ firstActiveIndex ] = binding;
|
||||
|
||||
}
|
||||
|
||||
} else if ( objects[ index ] !== knownObject ) {
|
||||
|
||||
console.error( 'THREE.AnimationObjectGroup: Different objects with the same UUID ' +
|
||||
'detected. Clean the caches or recreate your infrastructure when reloading scenes.' );
|
||||
|
||||
} // else the object is already where we want it to be
|
||||
|
||||
} // for arguments
|
||||
|
||||
this.nCachedObjects_ = nCachedObjects;
|
||||
|
||||
}
|
||||
|
||||
remove() {
|
||||
|
||||
const objects = this._objects,
|
||||
indicesByUUID = this._indicesByUUID,
|
||||
bindings = this._bindings,
|
||||
nBindings = bindings.length;
|
||||
|
||||
let nCachedObjects = this.nCachedObjects_;
|
||||
|
||||
for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
|
||||
|
||||
const object = arguments[ i ],
|
||||
uuid = object.uuid,
|
||||
index = indicesByUUID[ uuid ];
|
||||
|
||||
if ( index !== undefined && index >= nCachedObjects ) {
|
||||
|
||||
// move existing object into the CACHED region
|
||||
|
||||
const lastCachedIndex = nCachedObjects ++,
|
||||
firstActiveObject = objects[ lastCachedIndex ];
|
||||
|
||||
indicesByUUID[ firstActiveObject.uuid ] = index;
|
||||
objects[ index ] = firstActiveObject;
|
||||
|
||||
indicesByUUID[ uuid ] = lastCachedIndex;
|
||||
objects[ lastCachedIndex ] = object;
|
||||
|
||||
// accounting is done, now do the same for all bindings
|
||||
|
||||
for ( let j = 0, m = nBindings; j !== m; ++ j ) {
|
||||
|
||||
const bindingsForPath = bindings[ j ],
|
||||
firstActive = bindingsForPath[ lastCachedIndex ],
|
||||
binding = bindingsForPath[ index ];
|
||||
|
||||
bindingsForPath[ index ] = firstActive;
|
||||
bindingsForPath[ lastCachedIndex ] = binding;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // for arguments
|
||||
|
||||
this.nCachedObjects_ = nCachedObjects;
|
||||
|
||||
}
|
||||
|
||||
// remove & forget
|
||||
uncache() {
|
||||
|
||||
const objects = this._objects,
|
||||
indicesByUUID = this._indicesByUUID,
|
||||
bindings = this._bindings,
|
||||
nBindings = bindings.length;
|
||||
|
||||
let nCachedObjects = this.nCachedObjects_,
|
||||
nObjects = objects.length;
|
||||
|
||||
for ( let i = 0, n = arguments.length; i !== n; ++ i ) {
|
||||
|
||||
const object = arguments[ i ],
|
||||
uuid = object.uuid,
|
||||
index = indicesByUUID[ uuid ];
|
||||
|
||||
if ( index !== undefined ) {
|
||||
|
||||
delete indicesByUUID[ uuid ];
|
||||
|
||||
if ( index < nCachedObjects ) {
|
||||
|
||||
// object is cached, shrink the CACHED region
|
||||
|
||||
const firstActiveIndex = -- nCachedObjects,
|
||||
lastCachedObject = objects[ firstActiveIndex ],
|
||||
lastIndex = -- nObjects,
|
||||
lastObject = objects[ lastIndex ];
|
||||
|
||||
// last cached object takes this object's place
|
||||
indicesByUUID[ lastCachedObject.uuid ] = index;
|
||||
objects[ index ] = lastCachedObject;
|
||||
|
||||
// last object goes to the activated slot and pop
|
||||
indicesByUUID[ lastObject.uuid ] = firstActiveIndex;
|
||||
objects[ firstActiveIndex ] = lastObject;
|
||||
objects.pop();
|
||||
|
||||
// accounting is done, now do the same for all bindings
|
||||
|
||||
for ( let j = 0, m = nBindings; j !== m; ++ j ) {
|
||||
|
||||
const bindingsForPath = bindings[ j ],
|
||||
lastCached = bindingsForPath[ firstActiveIndex ],
|
||||
last = bindingsForPath[ lastIndex ];
|
||||
|
||||
bindingsForPath[ index ] = lastCached;
|
||||
bindingsForPath[ firstActiveIndex ] = last;
|
||||
bindingsForPath.pop();
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// object is active, just swap with the last and pop
|
||||
|
||||
const lastIndex = -- nObjects,
|
||||
lastObject = objects[ lastIndex ];
|
||||
|
||||
if ( lastIndex > 0 ) {
|
||||
|
||||
indicesByUUID[ lastObject.uuid ] = index;
|
||||
|
||||
}
|
||||
|
||||
objects[ index ] = lastObject;
|
||||
objects.pop();
|
||||
|
||||
// accounting is done, now do the same for all bindings
|
||||
|
||||
for ( let j = 0, m = nBindings; j !== m; ++ j ) {
|
||||
|
||||
const bindingsForPath = bindings[ j ];
|
||||
|
||||
bindingsForPath[ index ] = bindingsForPath[ lastIndex ];
|
||||
bindingsForPath.pop();
|
||||
|
||||
}
|
||||
|
||||
} // cached or active
|
||||
|
||||
} // if object is known
|
||||
|
||||
} // for arguments
|
||||
|
||||
this.nCachedObjects_ = nCachedObjects;
|
||||
|
||||
}
|
||||
|
||||
// Internal interface used by befriended PropertyBinding.Composite:
|
||||
|
||||
subscribe_( path, parsedPath ) {
|
||||
|
||||
// returns an array of bindings for the given path that is changed
|
||||
// according to the contained objects in the group
|
||||
|
||||
const indicesByPath = this._bindingsIndicesByPath;
|
||||
let index = indicesByPath[ path ];
|
||||
const bindings = this._bindings;
|
||||
|
||||
if ( index !== undefined ) return bindings[ index ];
|
||||
|
||||
const paths = this._paths,
|
||||
parsedPaths = this._parsedPaths,
|
||||
objects = this._objects,
|
||||
nObjects = objects.length,
|
||||
nCachedObjects = this.nCachedObjects_,
|
||||
bindingsForPath = new Array( nObjects );
|
||||
|
||||
index = bindings.length;
|
||||
|
||||
indicesByPath[ path ] = index;
|
||||
|
||||
paths.push( path );
|
||||
parsedPaths.push( parsedPath );
|
||||
bindings.push( bindingsForPath );
|
||||
|
||||
for ( let i = nCachedObjects, n = objects.length; i !== n; ++ i ) {
|
||||
|
||||
const object = objects[ i ];
|
||||
bindingsForPath[ i ] = new PropertyBinding( object, path, parsedPath );
|
||||
|
||||
}
|
||||
|
||||
return bindingsForPath;
|
||||
|
||||
}
|
||||
|
||||
unsubscribe_( path ) {
|
||||
|
||||
// tells the group to forget about a property path and no longer
|
||||
// update the array previously obtained with 'subscribe_'
|
||||
|
||||
const indicesByPath = this._bindingsIndicesByPath,
|
||||
index = indicesByPath[ path ];
|
||||
|
||||
if ( index !== undefined ) {
|
||||
|
||||
const paths = this._paths,
|
||||
parsedPaths = this._parsedPaths,
|
||||
bindings = this._bindings,
|
||||
lastBindingsIndex = bindings.length - 1,
|
||||
lastBindings = bindings[ lastBindingsIndex ],
|
||||
lastBindingsPath = path[ lastBindingsIndex ];
|
||||
|
||||
indicesByPath[ lastBindingsPath ] = index;
|
||||
|
||||
bindings[ index ] = lastBindings;
|
||||
bindings.pop();
|
||||
|
||||
parsedPaths[ index ] = parsedPaths[ lastBindingsIndex ];
|
||||
parsedPaths.pop();
|
||||
|
||||
paths[ index ] = paths[ lastBindingsIndex ];
|
||||
paths.pop();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { AnimationObjectGroup };
|
||||
356
network-visualization/node_modules/three/src/animation/AnimationUtils.js
generated
vendored
Normal file
356
network-visualization/node_modules/three/src/animation/AnimationUtils.js
generated
vendored
Normal file
@@ -0,0 +1,356 @@
|
||||
import { Quaternion } from '../math/Quaternion.js';
|
||||
import { AdditiveAnimationBlendMode } from '../constants.js';
|
||||
|
||||
// converts an array to a specific type
|
||||
function convertArray( array, type, forceClone ) {
|
||||
|
||||
if ( ! array || // let 'undefined' and 'null' pass
|
||||
! forceClone && array.constructor === type ) return array;
|
||||
|
||||
if ( typeof type.BYTES_PER_ELEMENT === 'number' ) {
|
||||
|
||||
return new type( array ); // create typed array
|
||||
|
||||
}
|
||||
|
||||
return Array.prototype.slice.call( array ); // create Array
|
||||
|
||||
}
|
||||
|
||||
function isTypedArray( object ) {
|
||||
|
||||
return ArrayBuffer.isView( object ) &&
|
||||
! ( object instanceof DataView );
|
||||
|
||||
}
|
||||
|
||||
// returns an array by which times and values can be sorted
|
||||
function getKeyframeOrder( times ) {
|
||||
|
||||
function compareTime( i, j ) {
|
||||
|
||||
return times[ i ] - times[ j ];
|
||||
|
||||
}
|
||||
|
||||
const n = times.length;
|
||||
const result = new Array( n );
|
||||
for ( let i = 0; i !== n; ++ i ) result[ i ] = i;
|
||||
|
||||
result.sort( compareTime );
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
// uses the array previously returned by 'getKeyframeOrder' to sort data
|
||||
function sortedArray( values, stride, order ) {
|
||||
|
||||
const nValues = values.length;
|
||||
const result = new values.constructor( nValues );
|
||||
|
||||
for ( let i = 0, dstOffset = 0; dstOffset !== nValues; ++ i ) {
|
||||
|
||||
const srcOffset = order[ i ] * stride;
|
||||
|
||||
for ( let j = 0; j !== stride; ++ j ) {
|
||||
|
||||
result[ dstOffset ++ ] = values[ srcOffset + j ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
// function for parsing AOS keyframe formats
|
||||
function flattenJSON( jsonKeys, times, values, valuePropertyName ) {
|
||||
|
||||
let i = 1, key = jsonKeys[ 0 ];
|
||||
|
||||
while ( key !== undefined && key[ valuePropertyName ] === undefined ) {
|
||||
|
||||
key = jsonKeys[ i ++ ];
|
||||
|
||||
}
|
||||
|
||||
if ( key === undefined ) return; // no data
|
||||
|
||||
let value = key[ valuePropertyName ];
|
||||
if ( value === undefined ) return; // no data
|
||||
|
||||
if ( Array.isArray( value ) ) {
|
||||
|
||||
do {
|
||||
|
||||
value = key[ valuePropertyName ];
|
||||
|
||||
if ( value !== undefined ) {
|
||||
|
||||
times.push( key.time );
|
||||
values.push.apply( values, value ); // push all elements
|
||||
|
||||
}
|
||||
|
||||
key = jsonKeys[ i ++ ];
|
||||
|
||||
} while ( key !== undefined );
|
||||
|
||||
} else if ( value.toArray !== undefined ) {
|
||||
|
||||
// ...assume THREE.Math-ish
|
||||
|
||||
do {
|
||||
|
||||
value = key[ valuePropertyName ];
|
||||
|
||||
if ( value !== undefined ) {
|
||||
|
||||
times.push( key.time );
|
||||
value.toArray( values, values.length );
|
||||
|
||||
}
|
||||
|
||||
key = jsonKeys[ i ++ ];
|
||||
|
||||
} while ( key !== undefined );
|
||||
|
||||
} else {
|
||||
|
||||
// otherwise push as-is
|
||||
|
||||
do {
|
||||
|
||||
value = key[ valuePropertyName ];
|
||||
|
||||
if ( value !== undefined ) {
|
||||
|
||||
times.push( key.time );
|
||||
values.push( value );
|
||||
|
||||
}
|
||||
|
||||
key = jsonKeys[ i ++ ];
|
||||
|
||||
} while ( key !== undefined );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function subclip( sourceClip, name, startFrame, endFrame, fps = 30 ) {
|
||||
|
||||
const clip = sourceClip.clone();
|
||||
|
||||
clip.name = name;
|
||||
|
||||
const tracks = [];
|
||||
|
||||
for ( let i = 0; i < clip.tracks.length; ++ i ) {
|
||||
|
||||
const track = clip.tracks[ i ];
|
||||
const valueSize = track.getValueSize();
|
||||
|
||||
const times = [];
|
||||
const values = [];
|
||||
|
||||
for ( let j = 0; j < track.times.length; ++ j ) {
|
||||
|
||||
const frame = track.times[ j ] * fps;
|
||||
|
||||
if ( frame < startFrame || frame >= endFrame ) continue;
|
||||
|
||||
times.push( track.times[ j ] );
|
||||
|
||||
for ( let k = 0; k < valueSize; ++ k ) {
|
||||
|
||||
values.push( track.values[ j * valueSize + k ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( times.length === 0 ) continue;
|
||||
|
||||
track.times = convertArray( times, track.times.constructor );
|
||||
track.values = convertArray( values, track.values.constructor );
|
||||
|
||||
tracks.push( track );
|
||||
|
||||
}
|
||||
|
||||
clip.tracks = tracks;
|
||||
|
||||
// find minimum .times value across all tracks in the trimmed clip
|
||||
|
||||
let minStartTime = Infinity;
|
||||
|
||||
for ( let i = 0; i < clip.tracks.length; ++ i ) {
|
||||
|
||||
if ( minStartTime > clip.tracks[ i ].times[ 0 ] ) {
|
||||
|
||||
minStartTime = clip.tracks[ i ].times[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// shift all tracks such that clip begins at t=0
|
||||
|
||||
for ( let i = 0; i < clip.tracks.length; ++ i ) {
|
||||
|
||||
clip.tracks[ i ].shift( - 1 * minStartTime );
|
||||
|
||||
}
|
||||
|
||||
clip.resetDuration();
|
||||
|
||||
return clip;
|
||||
|
||||
}
|
||||
|
||||
function makeClipAdditive( targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30 ) {
|
||||
|
||||
if ( fps <= 0 ) fps = 30;
|
||||
|
||||
const numTracks = referenceClip.tracks.length;
|
||||
const referenceTime = referenceFrame / fps;
|
||||
|
||||
// Make each track's values relative to the values at the reference frame
|
||||
for ( let i = 0; i < numTracks; ++ i ) {
|
||||
|
||||
const referenceTrack = referenceClip.tracks[ i ];
|
||||
const referenceTrackType = referenceTrack.ValueTypeName;
|
||||
|
||||
// Skip this track if it's non-numeric
|
||||
if ( referenceTrackType === 'bool' || referenceTrackType === 'string' ) continue;
|
||||
|
||||
// Find the track in the target clip whose name and type matches the reference track
|
||||
const targetTrack = targetClip.tracks.find( function ( track ) {
|
||||
|
||||
return track.name === referenceTrack.name
|
||||
&& track.ValueTypeName === referenceTrackType;
|
||||
|
||||
} );
|
||||
|
||||
if ( targetTrack === undefined ) continue;
|
||||
|
||||
let referenceOffset = 0;
|
||||
const referenceValueSize = referenceTrack.getValueSize();
|
||||
|
||||
if ( referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
|
||||
|
||||
referenceOffset = referenceValueSize / 3;
|
||||
|
||||
}
|
||||
|
||||
let targetOffset = 0;
|
||||
const targetValueSize = targetTrack.getValueSize();
|
||||
|
||||
if ( targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
|
||||
|
||||
targetOffset = targetValueSize / 3;
|
||||
|
||||
}
|
||||
|
||||
const lastIndex = referenceTrack.times.length - 1;
|
||||
let referenceValue;
|
||||
|
||||
// Find the value to subtract out of the track
|
||||
if ( referenceTime <= referenceTrack.times[ 0 ] ) {
|
||||
|
||||
// Reference frame is earlier than the first keyframe, so just use the first keyframe
|
||||
const startIndex = referenceOffset;
|
||||
const endIndex = referenceValueSize - referenceOffset;
|
||||
referenceValue = referenceTrack.values.slice( startIndex, endIndex );
|
||||
|
||||
} else if ( referenceTime >= referenceTrack.times[ lastIndex ] ) {
|
||||
|
||||
// Reference frame is after the last keyframe, so just use the last keyframe
|
||||
const startIndex = lastIndex * referenceValueSize + referenceOffset;
|
||||
const endIndex = startIndex + referenceValueSize - referenceOffset;
|
||||
referenceValue = referenceTrack.values.slice( startIndex, endIndex );
|
||||
|
||||
} else {
|
||||
|
||||
// Interpolate to the reference value
|
||||
const interpolant = referenceTrack.createInterpolant();
|
||||
const startIndex = referenceOffset;
|
||||
const endIndex = referenceValueSize - referenceOffset;
|
||||
interpolant.evaluate( referenceTime );
|
||||
referenceValue = interpolant.resultBuffer.slice( startIndex, endIndex );
|
||||
|
||||
}
|
||||
|
||||
// Conjugate the quaternion
|
||||
if ( referenceTrackType === 'quaternion' ) {
|
||||
|
||||
const referenceQuat = new Quaternion().fromArray( referenceValue ).normalize().conjugate();
|
||||
referenceQuat.toArray( referenceValue );
|
||||
|
||||
}
|
||||
|
||||
// Subtract the reference value from all of the track values
|
||||
|
||||
const numTimes = targetTrack.times.length;
|
||||
for ( let j = 0; j < numTimes; ++ j ) {
|
||||
|
||||
const valueStart = j * targetValueSize + targetOffset;
|
||||
|
||||
if ( referenceTrackType === 'quaternion' ) {
|
||||
|
||||
// Multiply the conjugate for quaternion track types
|
||||
Quaternion.multiplyQuaternionsFlat(
|
||||
targetTrack.values,
|
||||
valueStart,
|
||||
referenceValue,
|
||||
0,
|
||||
targetTrack.values,
|
||||
valueStart
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
const valueEnd = targetValueSize - targetOffset * 2;
|
||||
|
||||
// Subtract each value for all other numeric track types
|
||||
for ( let k = 0; k < valueEnd; ++ k ) {
|
||||
|
||||
targetTrack.values[ valueStart + k ] -= referenceValue[ k ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
targetClip.blendMode = AdditiveAnimationBlendMode;
|
||||
|
||||
return targetClip;
|
||||
|
||||
}
|
||||
|
||||
const AnimationUtils = {
|
||||
convertArray: convertArray,
|
||||
isTypedArray: isTypedArray,
|
||||
getKeyframeOrder: getKeyframeOrder,
|
||||
sortedArray: sortedArray,
|
||||
flattenJSON: flattenJSON,
|
||||
subclip: subclip,
|
||||
makeClipAdditive: makeClipAdditive
|
||||
};
|
||||
|
||||
export {
|
||||
convertArray,
|
||||
isTypedArray,
|
||||
getKeyframeOrder,
|
||||
sortedArray,
|
||||
flattenJSON,
|
||||
subclip,
|
||||
makeClipAdditive,
|
||||
AnimationUtils
|
||||
};
|
||||
462
network-visualization/node_modules/three/src/animation/KeyframeTrack.js
generated
vendored
Normal file
462
network-visualization/node_modules/three/src/animation/KeyframeTrack.js
generated
vendored
Normal file
@@ -0,0 +1,462 @@
|
||||
import {
|
||||
InterpolateLinear,
|
||||
InterpolateSmooth,
|
||||
InterpolateDiscrete
|
||||
} from '../constants.js';
|
||||
import { CubicInterpolant } from '../math/interpolants/CubicInterpolant.js';
|
||||
import { LinearInterpolant } from '../math/interpolants/LinearInterpolant.js';
|
||||
import { DiscreteInterpolant } from '../math/interpolants/DiscreteInterpolant.js';
|
||||
import * as AnimationUtils from './AnimationUtils.js';
|
||||
|
||||
class KeyframeTrack {
|
||||
|
||||
constructor( name, times, values, interpolation ) {
|
||||
|
||||
if ( name === undefined ) throw new Error( 'THREE.KeyframeTrack: track name is undefined' );
|
||||
if ( times === undefined || times.length === 0 ) throw new Error( 'THREE.KeyframeTrack: no keyframes in track named ' + name );
|
||||
|
||||
this.name = name;
|
||||
|
||||
this.times = AnimationUtils.convertArray( times, this.TimeBufferType );
|
||||
this.values = AnimationUtils.convertArray( values, this.ValueBufferType );
|
||||
|
||||
this.setInterpolation( interpolation || this.DefaultInterpolation );
|
||||
|
||||
}
|
||||
|
||||
// Serialization (in static context, because of constructor invocation
|
||||
// and automatic invocation of .toJSON):
|
||||
|
||||
static toJSON( track ) {
|
||||
|
||||
const trackType = track.constructor;
|
||||
|
||||
let json;
|
||||
|
||||
// derived classes can define a static toJSON method
|
||||
if ( trackType.toJSON !== this.toJSON ) {
|
||||
|
||||
json = trackType.toJSON( track );
|
||||
|
||||
} else {
|
||||
|
||||
// by default, we assume the data can be serialized as-is
|
||||
json = {
|
||||
|
||||
'name': track.name,
|
||||
'times': AnimationUtils.convertArray( track.times, Array ),
|
||||
'values': AnimationUtils.convertArray( track.values, Array )
|
||||
|
||||
};
|
||||
|
||||
const interpolation = track.getInterpolation();
|
||||
|
||||
if ( interpolation !== track.DefaultInterpolation ) {
|
||||
|
||||
json.interpolation = interpolation;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
json.type = track.ValueTypeName; // mandatory
|
||||
|
||||
return json;
|
||||
|
||||
}
|
||||
|
||||
InterpolantFactoryMethodDiscrete( result ) {
|
||||
|
||||
return new DiscreteInterpolant( this.times, this.values, this.getValueSize(), result );
|
||||
|
||||
}
|
||||
|
||||
InterpolantFactoryMethodLinear( result ) {
|
||||
|
||||
return new LinearInterpolant( this.times, this.values, this.getValueSize(), result );
|
||||
|
||||
}
|
||||
|
||||
InterpolantFactoryMethodSmooth( result ) {
|
||||
|
||||
return new CubicInterpolant( this.times, this.values, this.getValueSize(), result );
|
||||
|
||||
}
|
||||
|
||||
setInterpolation( interpolation ) {
|
||||
|
||||
let factoryMethod;
|
||||
|
||||
switch ( interpolation ) {
|
||||
|
||||
case InterpolateDiscrete:
|
||||
|
||||
factoryMethod = this.InterpolantFactoryMethodDiscrete;
|
||||
|
||||
break;
|
||||
|
||||
case InterpolateLinear:
|
||||
|
||||
factoryMethod = this.InterpolantFactoryMethodLinear;
|
||||
|
||||
break;
|
||||
|
||||
case InterpolateSmooth:
|
||||
|
||||
factoryMethod = this.InterpolantFactoryMethodSmooth;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( factoryMethod === undefined ) {
|
||||
|
||||
const message = 'unsupported interpolation for ' +
|
||||
this.ValueTypeName + ' keyframe track named ' + this.name;
|
||||
|
||||
if ( this.createInterpolant === undefined ) {
|
||||
|
||||
// fall back to default, unless the default itself is messed up
|
||||
if ( interpolation !== this.DefaultInterpolation ) {
|
||||
|
||||
this.setInterpolation( this.DefaultInterpolation );
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( message ); // fatal, in this case
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.warn( 'THREE.KeyframeTrack:', message );
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
this.createInterpolant = factoryMethod;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getInterpolation() {
|
||||
|
||||
switch ( this.createInterpolant ) {
|
||||
|
||||
case this.InterpolantFactoryMethodDiscrete:
|
||||
|
||||
return InterpolateDiscrete;
|
||||
|
||||
case this.InterpolantFactoryMethodLinear:
|
||||
|
||||
return InterpolateLinear;
|
||||
|
||||
case this.InterpolantFactoryMethodSmooth:
|
||||
|
||||
return InterpolateSmooth;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getValueSize() {
|
||||
|
||||
return this.values.length / this.times.length;
|
||||
|
||||
}
|
||||
|
||||
// move all keyframes either forwards or backwards in time
|
||||
shift( timeOffset ) {
|
||||
|
||||
if ( timeOffset !== 0.0 ) {
|
||||
|
||||
const times = this.times;
|
||||
|
||||
for ( let i = 0, n = times.length; i !== n; ++ i ) {
|
||||
|
||||
times[ i ] += timeOffset;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// scale all keyframe times by a factor (useful for frame <-> seconds conversions)
|
||||
scale( timeScale ) {
|
||||
|
||||
if ( timeScale !== 1.0 ) {
|
||||
|
||||
const times = this.times;
|
||||
|
||||
for ( let i = 0, n = times.length; i !== n; ++ i ) {
|
||||
|
||||
times[ i ] *= timeScale;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// removes keyframes before and after animation without changing any values within the range [startTime, endTime].
|
||||
// IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
|
||||
trim( startTime, endTime ) {
|
||||
|
||||
const times = this.times,
|
||||
nKeys = times.length;
|
||||
|
||||
let from = 0,
|
||||
to = nKeys - 1;
|
||||
|
||||
while ( from !== nKeys && times[ from ] < startTime ) {
|
||||
|
||||
++ from;
|
||||
|
||||
}
|
||||
|
||||
while ( to !== - 1 && times[ to ] > endTime ) {
|
||||
|
||||
-- to;
|
||||
|
||||
}
|
||||
|
||||
++ to; // inclusive -> exclusive bound
|
||||
|
||||
if ( from !== 0 || to !== nKeys ) {
|
||||
|
||||
// empty tracks are forbidden, so keep at least one keyframe
|
||||
if ( from >= to ) {
|
||||
|
||||
to = Math.max( to, 1 );
|
||||
from = to - 1;
|
||||
|
||||
}
|
||||
|
||||
const stride = this.getValueSize();
|
||||
this.times = times.slice( from, to );
|
||||
this.values = this.values.slice( from * stride, to * stride );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
|
||||
validate() {
|
||||
|
||||
let valid = true;
|
||||
|
||||
const valueSize = this.getValueSize();
|
||||
if ( valueSize - Math.floor( valueSize ) !== 0 ) {
|
||||
|
||||
console.error( 'THREE.KeyframeTrack: Invalid value size in track.', this );
|
||||
valid = false;
|
||||
|
||||
}
|
||||
|
||||
const times = this.times,
|
||||
values = this.values,
|
||||
|
||||
nKeys = times.length;
|
||||
|
||||
if ( nKeys === 0 ) {
|
||||
|
||||
console.error( 'THREE.KeyframeTrack: Track is empty.', this );
|
||||
valid = false;
|
||||
|
||||
}
|
||||
|
||||
let prevTime = null;
|
||||
|
||||
for ( let i = 0; i !== nKeys; i ++ ) {
|
||||
|
||||
const currTime = times[ i ];
|
||||
|
||||
if ( typeof currTime === 'number' && isNaN( currTime ) ) {
|
||||
|
||||
console.error( 'THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime );
|
||||
valid = false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( prevTime !== null && prevTime > currTime ) {
|
||||
|
||||
console.error( 'THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime );
|
||||
valid = false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
prevTime = currTime;
|
||||
|
||||
}
|
||||
|
||||
if ( values !== undefined ) {
|
||||
|
||||
if ( AnimationUtils.isTypedArray( values ) ) {
|
||||
|
||||
for ( let i = 0, n = values.length; i !== n; ++ i ) {
|
||||
|
||||
const value = values[ i ];
|
||||
|
||||
if ( isNaN( value ) ) {
|
||||
|
||||
console.error( 'THREE.KeyframeTrack: Value is not a valid number.', this, i, value );
|
||||
valid = false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return valid;
|
||||
|
||||
}
|
||||
|
||||
// removes equivalent sequential keys as common in morph target sequences
|
||||
// (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
|
||||
optimize() {
|
||||
|
||||
// times or values may be shared with other tracks, so overwriting is unsafe
|
||||
const times = this.times.slice(),
|
||||
values = this.values.slice(),
|
||||
stride = this.getValueSize(),
|
||||
|
||||
smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
|
||||
|
||||
lastIndex = times.length - 1;
|
||||
|
||||
let writeIndex = 1;
|
||||
|
||||
for ( let i = 1; i < lastIndex; ++ i ) {
|
||||
|
||||
let keep = false;
|
||||
|
||||
const time = times[ i ];
|
||||
const timeNext = times[ i + 1 ];
|
||||
|
||||
// remove adjacent keyframes scheduled at the same time
|
||||
|
||||
if ( time !== timeNext && ( i !== 1 || time !== times[ 0 ] ) ) {
|
||||
|
||||
if ( ! smoothInterpolation ) {
|
||||
|
||||
// remove unnecessary keyframes same as their neighbors
|
||||
|
||||
const offset = i * stride,
|
||||
offsetP = offset - stride,
|
||||
offsetN = offset + stride;
|
||||
|
||||
for ( let j = 0; j !== stride; ++ j ) {
|
||||
|
||||
const value = values[ offset + j ];
|
||||
|
||||
if ( value !== values[ offsetP + j ] ||
|
||||
value !== values[ offsetN + j ] ) {
|
||||
|
||||
keep = true;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
keep = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// in-place compaction
|
||||
|
||||
if ( keep ) {
|
||||
|
||||
if ( i !== writeIndex ) {
|
||||
|
||||
times[ writeIndex ] = times[ i ];
|
||||
|
||||
const readOffset = i * stride,
|
||||
writeOffset = writeIndex * stride;
|
||||
|
||||
for ( let j = 0; j !== stride; ++ j ) {
|
||||
|
||||
values[ writeOffset + j ] = values[ readOffset + j ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
++ writeIndex;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// flush last keyframe (compaction looks ahead)
|
||||
|
||||
if ( lastIndex > 0 ) {
|
||||
|
||||
times[ writeIndex ] = times[ lastIndex ];
|
||||
|
||||
for ( let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++ j ) {
|
||||
|
||||
values[ writeOffset + j ] = values[ readOffset + j ];
|
||||
|
||||
}
|
||||
|
||||
++ writeIndex;
|
||||
|
||||
}
|
||||
|
||||
if ( writeIndex !== times.length ) {
|
||||
|
||||
this.times = times.slice( 0, writeIndex );
|
||||
this.values = values.slice( 0, writeIndex * stride );
|
||||
|
||||
} else {
|
||||
|
||||
this.times = times;
|
||||
this.values = values;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
const times = this.times.slice();
|
||||
const values = this.values.slice();
|
||||
|
||||
const TypedKeyframeTrack = this.constructor;
|
||||
const track = new TypedKeyframeTrack( this.name, times, values );
|
||||
|
||||
// Interpolant argument to constructor is not saved, so copy the factory method directly.
|
||||
track.createInterpolant = this.createInterpolant;
|
||||
|
||||
return track;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
KeyframeTrack.prototype.TimeBufferType = Float32Array;
|
||||
KeyframeTrack.prototype.ValueBufferType = Float32Array;
|
||||
KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
|
||||
|
||||
export { KeyframeTrack };
|
||||
719
network-visualization/node_modules/three/src/animation/PropertyBinding.js
generated
vendored
Normal file
719
network-visualization/node_modules/three/src/animation/PropertyBinding.js
generated
vendored
Normal file
@@ -0,0 +1,719 @@
|
||||
// Characters [].:/ are reserved for track binding syntax.
|
||||
const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
|
||||
const _reservedRe = new RegExp( '[' + _RESERVED_CHARS_RE + ']', 'g' );
|
||||
|
||||
// Attempts to allow node names from any language. ES5's `\w` regexp matches
|
||||
// only latin characters, and the unicode \p{L} is not yet supported. So
|
||||
// instead, we exclude reserved characters and match everything else.
|
||||
const _wordChar = '[^' + _RESERVED_CHARS_RE + ']';
|
||||
const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace( '\\.', '' ) + ']';
|
||||
|
||||
// Parent directories, delimited by '/' or ':'. Currently unused, but must
|
||||
// be matched to parse the rest of the track name.
|
||||
const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace( 'WC', _wordChar );
|
||||
|
||||
// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
|
||||
const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace( 'WCOD', _wordCharOrDot );
|
||||
|
||||
// Object on target node, and accessor. May not contain reserved
|
||||
// characters. Accessor may contain any character except closing bracket.
|
||||
const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace( 'WC', _wordChar );
|
||||
|
||||
// Property and accessor. May not contain reserved characters. Accessor may
|
||||
// contain any non-bracket characters.
|
||||
const _propertyRe = /*@__PURE__*/ /\.(WC+)(?:\[(.+)\])?/.source.replace( 'WC', _wordChar );
|
||||
|
||||
const _trackRe = new RegExp( ''
|
||||
+ '^'
|
||||
+ _directoryRe
|
||||
+ _nodeRe
|
||||
+ _objectRe
|
||||
+ _propertyRe
|
||||
+ '$'
|
||||
);
|
||||
|
||||
const _supportedObjectNames = [ 'material', 'materials', 'bones', 'map' ];
|
||||
|
||||
class Composite {
|
||||
|
||||
constructor( targetGroup, path, optionalParsedPath ) {
|
||||
|
||||
const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName( path );
|
||||
|
||||
this._targetGroup = targetGroup;
|
||||
this._bindings = targetGroup.subscribe_( path, parsedPath );
|
||||
|
||||
}
|
||||
|
||||
getValue( array, offset ) {
|
||||
|
||||
this.bind(); // bind all binding
|
||||
|
||||
const firstValidIndex = this._targetGroup.nCachedObjects_,
|
||||
binding = this._bindings[ firstValidIndex ];
|
||||
|
||||
// and only call .getValue on the first
|
||||
if ( binding !== undefined ) binding.getValue( array, offset );
|
||||
|
||||
}
|
||||
|
||||
setValue( array, offset ) {
|
||||
|
||||
const bindings = this._bindings;
|
||||
|
||||
for ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
|
||||
|
||||
bindings[ i ].setValue( array, offset );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bind() {
|
||||
|
||||
const bindings = this._bindings;
|
||||
|
||||
for ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
|
||||
|
||||
bindings[ i ].bind();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unbind() {
|
||||
|
||||
const bindings = this._bindings;
|
||||
|
||||
for ( let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++ i ) {
|
||||
|
||||
bindings[ i ].unbind();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Note: This class uses a State pattern on a per-method basis:
|
||||
// 'bind' sets 'this.getValue' / 'setValue' and shadows the
|
||||
// prototype version of these methods with one that represents
|
||||
// the bound state. When the property is not found, the methods
|
||||
// become no-ops.
|
||||
class PropertyBinding {
|
||||
|
||||
constructor( rootNode, path, parsedPath ) {
|
||||
|
||||
this.path = path;
|
||||
this.parsedPath = parsedPath || PropertyBinding.parseTrackName( path );
|
||||
|
||||
this.node = PropertyBinding.findNode( rootNode, this.parsedPath.nodeName );
|
||||
|
||||
this.rootNode = rootNode;
|
||||
|
||||
// initial state of these methods that calls 'bind'
|
||||
this.getValue = this._getValue_unbound;
|
||||
this.setValue = this._setValue_unbound;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static create( root, path, parsedPath ) {
|
||||
|
||||
if ( ! ( root && root.isAnimationObjectGroup ) ) {
|
||||
|
||||
return new PropertyBinding( root, path, parsedPath );
|
||||
|
||||
} else {
|
||||
|
||||
return new PropertyBinding.Composite( root, path, parsedPath );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces spaces with underscores and removes unsupported characters from
|
||||
* node names, to ensure compatibility with parseTrackName().
|
||||
*
|
||||
* @param {string} name Node name to be sanitized.
|
||||
* @return {string}
|
||||
*/
|
||||
static sanitizeNodeName( name ) {
|
||||
|
||||
return name.replace( /\s/g, '_' ).replace( _reservedRe, '' );
|
||||
|
||||
}
|
||||
|
||||
static parseTrackName( trackName ) {
|
||||
|
||||
const matches = _trackRe.exec( trackName );
|
||||
|
||||
if ( matches === null ) {
|
||||
|
||||
throw new Error( 'PropertyBinding: Cannot parse trackName: ' + trackName );
|
||||
|
||||
}
|
||||
|
||||
const results = {
|
||||
// directoryName: matches[ 1 ], // (tschw) currently unused
|
||||
nodeName: matches[ 2 ],
|
||||
objectName: matches[ 3 ],
|
||||
objectIndex: matches[ 4 ],
|
||||
propertyName: matches[ 5 ], // required
|
||||
propertyIndex: matches[ 6 ]
|
||||
};
|
||||
|
||||
const lastDot = results.nodeName && results.nodeName.lastIndexOf( '.' );
|
||||
|
||||
if ( lastDot !== undefined && lastDot !== - 1 ) {
|
||||
|
||||
const objectName = results.nodeName.substring( lastDot + 1 );
|
||||
|
||||
// Object names must be checked against an allowlist. Otherwise, there
|
||||
// is no way to parse 'foo.bar.baz': 'baz' must be a property, but
|
||||
// 'bar' could be the objectName, or part of a nodeName (which can
|
||||
// include '.' characters).
|
||||
if ( _supportedObjectNames.indexOf( objectName ) !== - 1 ) {
|
||||
|
||||
results.nodeName = results.nodeName.substring( 0, lastDot );
|
||||
results.objectName = objectName;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( results.propertyName === null || results.propertyName.length === 0 ) {
|
||||
|
||||
throw new Error( 'PropertyBinding: can not parse propertyName from trackName: ' + trackName );
|
||||
|
||||
}
|
||||
|
||||
return results;
|
||||
|
||||
}
|
||||
|
||||
static findNode( root, nodeName ) {
|
||||
|
||||
if ( nodeName === undefined || nodeName === '' || nodeName === '.' || nodeName === - 1 || nodeName === root.name || nodeName === root.uuid ) {
|
||||
|
||||
return root;
|
||||
|
||||
}
|
||||
|
||||
// search into skeleton bones.
|
||||
if ( root.skeleton ) {
|
||||
|
||||
const bone = root.skeleton.getBoneByName( nodeName );
|
||||
|
||||
if ( bone !== undefined ) {
|
||||
|
||||
return bone;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// search into node subtree.
|
||||
if ( root.children ) {
|
||||
|
||||
const searchNodeSubtree = function ( children ) {
|
||||
|
||||
for ( let i = 0; i < children.length; i ++ ) {
|
||||
|
||||
const childNode = children[ i ];
|
||||
|
||||
if ( childNode.name === nodeName || childNode.uuid === nodeName ) {
|
||||
|
||||
return childNode;
|
||||
|
||||
}
|
||||
|
||||
const result = searchNodeSubtree( childNode.children );
|
||||
|
||||
if ( result ) return result;
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
};
|
||||
|
||||
const subTreeNode = searchNodeSubtree( root.children );
|
||||
|
||||
if ( subTreeNode ) {
|
||||
|
||||
return subTreeNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// these are used to "bind" a nonexistent property
|
||||
_getValue_unavailable() {}
|
||||
_setValue_unavailable() {}
|
||||
|
||||
// Getters
|
||||
|
||||
_getValue_direct( buffer, offset ) {
|
||||
|
||||
buffer[ offset ] = this.targetObject[ this.propertyName ];
|
||||
|
||||
}
|
||||
|
||||
_getValue_array( buffer, offset ) {
|
||||
|
||||
const source = this.resolvedProperty;
|
||||
|
||||
for ( let i = 0, n = source.length; i !== n; ++ i ) {
|
||||
|
||||
buffer[ offset ++ ] = source[ i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_getValue_arrayElement( buffer, offset ) {
|
||||
|
||||
buffer[ offset ] = this.resolvedProperty[ this.propertyIndex ];
|
||||
|
||||
}
|
||||
|
||||
_getValue_toArray( buffer, offset ) {
|
||||
|
||||
this.resolvedProperty.toArray( buffer, offset );
|
||||
|
||||
}
|
||||
|
||||
// Direct
|
||||
|
||||
_setValue_direct( buffer, offset ) {
|
||||
|
||||
this.targetObject[ this.propertyName ] = buffer[ offset ];
|
||||
|
||||
}
|
||||
|
||||
_setValue_direct_setNeedsUpdate( buffer, offset ) {
|
||||
|
||||
this.targetObject[ this.propertyName ] = buffer[ offset ];
|
||||
this.targetObject.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
_setValue_direct_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
||||
|
||||
this.targetObject[ this.propertyName ] = buffer[ offset ];
|
||||
this.targetObject.matrixWorldNeedsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
// EntireArray
|
||||
|
||||
_setValue_array( buffer, offset ) {
|
||||
|
||||
const dest = this.resolvedProperty;
|
||||
|
||||
for ( let i = 0, n = dest.length; i !== n; ++ i ) {
|
||||
|
||||
dest[ i ] = buffer[ offset ++ ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_setValue_array_setNeedsUpdate( buffer, offset ) {
|
||||
|
||||
const dest = this.resolvedProperty;
|
||||
|
||||
for ( let i = 0, n = dest.length; i !== n; ++ i ) {
|
||||
|
||||
dest[ i ] = buffer[ offset ++ ];
|
||||
|
||||
}
|
||||
|
||||
this.targetObject.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
_setValue_array_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
||||
|
||||
const dest = this.resolvedProperty;
|
||||
|
||||
for ( let i = 0, n = dest.length; i !== n; ++ i ) {
|
||||
|
||||
dest[ i ] = buffer[ offset ++ ];
|
||||
|
||||
}
|
||||
|
||||
this.targetObject.matrixWorldNeedsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
// ArrayElement
|
||||
|
||||
_setValue_arrayElement( buffer, offset ) {
|
||||
|
||||
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
|
||||
|
||||
}
|
||||
|
||||
_setValue_arrayElement_setNeedsUpdate( buffer, offset ) {
|
||||
|
||||
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
|
||||
this.targetObject.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
_setValue_arrayElement_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
||||
|
||||
this.resolvedProperty[ this.propertyIndex ] = buffer[ offset ];
|
||||
this.targetObject.matrixWorldNeedsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
// HasToFromArray
|
||||
|
||||
_setValue_fromArray( buffer, offset ) {
|
||||
|
||||
this.resolvedProperty.fromArray( buffer, offset );
|
||||
|
||||
}
|
||||
|
||||
_setValue_fromArray_setNeedsUpdate( buffer, offset ) {
|
||||
|
||||
this.resolvedProperty.fromArray( buffer, offset );
|
||||
this.targetObject.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
_setValue_fromArray_setMatrixWorldNeedsUpdate( buffer, offset ) {
|
||||
|
||||
this.resolvedProperty.fromArray( buffer, offset );
|
||||
this.targetObject.matrixWorldNeedsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
_getValue_unbound( targetArray, offset ) {
|
||||
|
||||
this.bind();
|
||||
this.getValue( targetArray, offset );
|
||||
|
||||
}
|
||||
|
||||
_setValue_unbound( sourceArray, offset ) {
|
||||
|
||||
this.bind();
|
||||
this.setValue( sourceArray, offset );
|
||||
|
||||
}
|
||||
|
||||
// create getter / setter pair for a property in the scene graph
|
||||
bind() {
|
||||
|
||||
let targetObject = this.node;
|
||||
const parsedPath = this.parsedPath;
|
||||
|
||||
const objectName = parsedPath.objectName;
|
||||
const propertyName = parsedPath.propertyName;
|
||||
let propertyIndex = parsedPath.propertyIndex;
|
||||
|
||||
if ( ! targetObject ) {
|
||||
|
||||
targetObject = PropertyBinding.findNode( this.rootNode, parsedPath.nodeName );
|
||||
|
||||
this.node = targetObject;
|
||||
|
||||
}
|
||||
|
||||
// set fail state so we can just 'return' on error
|
||||
this.getValue = this._getValue_unavailable;
|
||||
this.setValue = this._setValue_unavailable;
|
||||
|
||||
// ensure there is a value node
|
||||
if ( ! targetObject ) {
|
||||
|
||||
console.warn( 'THREE.PropertyBinding: No target node found for track: ' + this.path + '.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( objectName ) {
|
||||
|
||||
let objectIndex = parsedPath.objectIndex;
|
||||
|
||||
// special cases were we need to reach deeper into the hierarchy to get the face materials....
|
||||
switch ( objectName ) {
|
||||
|
||||
case 'materials':
|
||||
|
||||
if ( ! targetObject.material ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( ! targetObject.material.materials ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
targetObject = targetObject.material.materials;
|
||||
|
||||
break;
|
||||
|
||||
case 'bones':
|
||||
|
||||
if ( ! targetObject.skeleton ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// potential future optimization: skip this if propertyIndex is already an integer
|
||||
// and convert the integer string to a true integer.
|
||||
|
||||
targetObject = targetObject.skeleton.bones;
|
||||
|
||||
// support resolving morphTarget names into indices.
|
||||
for ( let i = 0; i < targetObject.length; i ++ ) {
|
||||
|
||||
if ( targetObject[ i ].name === objectIndex ) {
|
||||
|
||||
objectIndex = i;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'map':
|
||||
|
||||
if ( 'map' in targetObject ) {
|
||||
|
||||
targetObject = targetObject.map;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if ( ! targetObject.material ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to material as node does not have a material.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( ! targetObject.material.map ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
targetObject = targetObject.material.map;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
if ( targetObject[ objectName ] === undefined ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to objectName of node undefined.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
targetObject = targetObject[ objectName ];
|
||||
|
||||
}
|
||||
|
||||
|
||||
if ( objectIndex !== undefined ) {
|
||||
|
||||
if ( targetObject[ objectIndex ] === undefined ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
targetObject = targetObject[ objectIndex ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// resolve property
|
||||
const nodeProperty = targetObject[ propertyName ];
|
||||
|
||||
if ( nodeProperty === undefined ) {
|
||||
|
||||
const nodeName = parsedPath.nodeName;
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Trying to update property for track: ' + nodeName +
|
||||
'.' + propertyName + ' but it wasn\'t found.', targetObject );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// determine versioning scheme
|
||||
let versioning = this.Versioning.None;
|
||||
|
||||
this.targetObject = targetObject;
|
||||
|
||||
if ( targetObject.needsUpdate !== undefined ) { // material
|
||||
|
||||
versioning = this.Versioning.NeedsUpdate;
|
||||
|
||||
} else if ( targetObject.matrixWorldNeedsUpdate !== undefined ) { // node transform
|
||||
|
||||
versioning = this.Versioning.MatrixWorldNeedsUpdate;
|
||||
|
||||
}
|
||||
|
||||
// determine how the property gets bound
|
||||
let bindingType = this.BindingType.Direct;
|
||||
|
||||
if ( propertyIndex !== undefined ) {
|
||||
|
||||
// access a sub element of the property array (only primitives are supported right now)
|
||||
|
||||
if ( propertyName === 'morphTargetInfluences' ) {
|
||||
|
||||
// potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
|
||||
|
||||
// support resolving morphTarget names into indices.
|
||||
if ( ! targetObject.geometry ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( ! targetObject.geometry.morphAttributes ) {
|
||||
|
||||
console.error( 'THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( targetObject.morphTargetDictionary[ propertyIndex ] !== undefined ) {
|
||||
|
||||
propertyIndex = targetObject.morphTargetDictionary[ propertyIndex ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bindingType = this.BindingType.ArrayElement;
|
||||
|
||||
this.resolvedProperty = nodeProperty;
|
||||
this.propertyIndex = propertyIndex;
|
||||
|
||||
} else if ( nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined ) {
|
||||
|
||||
// must use copy for Object3D.Euler/Quaternion
|
||||
|
||||
bindingType = this.BindingType.HasFromToArray;
|
||||
|
||||
this.resolvedProperty = nodeProperty;
|
||||
|
||||
} else if ( Array.isArray( nodeProperty ) ) {
|
||||
|
||||
bindingType = this.BindingType.EntireArray;
|
||||
|
||||
this.resolvedProperty = nodeProperty;
|
||||
|
||||
} else {
|
||||
|
||||
this.propertyName = propertyName;
|
||||
|
||||
}
|
||||
|
||||
// select getter / setter
|
||||
this.getValue = this.GetterByBindingType[ bindingType ];
|
||||
this.setValue = this.SetterByBindingTypeAndVersioning[ bindingType ][ versioning ];
|
||||
|
||||
}
|
||||
|
||||
unbind() {
|
||||
|
||||
this.node = null;
|
||||
|
||||
// back to the prototype version of getValue / setValue
|
||||
// note: avoiding to mutate the shape of 'this' via 'delete'
|
||||
this.getValue = this._getValue_unbound;
|
||||
this.setValue = this._setValue_unbound;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PropertyBinding.Composite = Composite;
|
||||
|
||||
PropertyBinding.prototype.BindingType = {
|
||||
Direct: 0,
|
||||
EntireArray: 1,
|
||||
ArrayElement: 2,
|
||||
HasFromToArray: 3
|
||||
};
|
||||
|
||||
PropertyBinding.prototype.Versioning = {
|
||||
None: 0,
|
||||
NeedsUpdate: 1,
|
||||
MatrixWorldNeedsUpdate: 2
|
||||
};
|
||||
|
||||
PropertyBinding.prototype.GetterByBindingType = [
|
||||
|
||||
PropertyBinding.prototype._getValue_direct,
|
||||
PropertyBinding.prototype._getValue_array,
|
||||
PropertyBinding.prototype._getValue_arrayElement,
|
||||
PropertyBinding.prototype._getValue_toArray,
|
||||
|
||||
];
|
||||
|
||||
PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [
|
||||
|
||||
[
|
||||
// Direct
|
||||
PropertyBinding.prototype._setValue_direct,
|
||||
PropertyBinding.prototype._setValue_direct_setNeedsUpdate,
|
||||
PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate,
|
||||
|
||||
], [
|
||||
|
||||
// EntireArray
|
||||
|
||||
PropertyBinding.prototype._setValue_array,
|
||||
PropertyBinding.prototype._setValue_array_setNeedsUpdate,
|
||||
PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate,
|
||||
|
||||
], [
|
||||
|
||||
// ArrayElement
|
||||
PropertyBinding.prototype._setValue_arrayElement,
|
||||
PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate,
|
||||
PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate,
|
||||
|
||||
], [
|
||||
|
||||
// HasToFromArray
|
||||
PropertyBinding.prototype._setValue_fromArray,
|
||||
PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate,
|
||||
PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate,
|
||||
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
|
||||
export { PropertyBinding };
|
||||
318
network-visualization/node_modules/three/src/animation/PropertyMixer.js
generated
vendored
Normal file
318
network-visualization/node_modules/three/src/animation/PropertyMixer.js
generated
vendored
Normal file
@@ -0,0 +1,318 @@
|
||||
import { Quaternion } from '../math/Quaternion.js';
|
||||
|
||||
class PropertyMixer {
|
||||
|
||||
constructor( binding, typeName, valueSize ) {
|
||||
|
||||
this.binding = binding;
|
||||
this.valueSize = valueSize;
|
||||
|
||||
let mixFunction,
|
||||
mixFunctionAdditive,
|
||||
setIdentity;
|
||||
|
||||
// buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ]
|
||||
//
|
||||
// interpolators can use .buffer as their .result
|
||||
// the data then goes to 'incoming'
|
||||
//
|
||||
// 'accu0' and 'accu1' are used frame-interleaved for
|
||||
// the cumulative result and are compared to detect
|
||||
// changes
|
||||
//
|
||||
// 'orig' stores the original state of the property
|
||||
//
|
||||
// 'add' is used for additive cumulative results
|
||||
//
|
||||
// 'work' is optional and is only present for quaternion types. It is used
|
||||
// to store intermediate quaternion multiplication results
|
||||
|
||||
switch ( typeName ) {
|
||||
|
||||
case 'quaternion':
|
||||
mixFunction = this._slerp;
|
||||
mixFunctionAdditive = this._slerpAdditive;
|
||||
setIdentity = this._setAdditiveIdentityQuaternion;
|
||||
|
||||
this.buffer = new Float64Array( valueSize * 6 );
|
||||
this._workIndex = 5;
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
case 'bool':
|
||||
mixFunction = this._select;
|
||||
|
||||
// Use the regular mix function and for additive on these types,
|
||||
// additive is not relevant for non-numeric types
|
||||
mixFunctionAdditive = this._select;
|
||||
|
||||
setIdentity = this._setAdditiveIdentityOther;
|
||||
|
||||
this.buffer = new Array( valueSize * 5 );
|
||||
break;
|
||||
|
||||
default:
|
||||
mixFunction = this._lerp;
|
||||
mixFunctionAdditive = this._lerpAdditive;
|
||||
setIdentity = this._setAdditiveIdentityNumeric;
|
||||
|
||||
this.buffer = new Float64Array( valueSize * 5 );
|
||||
|
||||
}
|
||||
|
||||
this._mixBufferRegion = mixFunction;
|
||||
this._mixBufferRegionAdditive = mixFunctionAdditive;
|
||||
this._setIdentity = setIdentity;
|
||||
this._origIndex = 3;
|
||||
this._addIndex = 4;
|
||||
|
||||
this.cumulativeWeight = 0;
|
||||
this.cumulativeWeightAdditive = 0;
|
||||
|
||||
this.useCount = 0;
|
||||
this.referenceCount = 0;
|
||||
|
||||
}
|
||||
|
||||
// accumulate data in the 'incoming' region into 'accu<i>'
|
||||
accumulate( accuIndex, weight ) {
|
||||
|
||||
// note: happily accumulating nothing when weight = 0, the caller knows
|
||||
// the weight and shouldn't have made the call in the first place
|
||||
|
||||
const buffer = this.buffer,
|
||||
stride = this.valueSize,
|
||||
offset = accuIndex * stride + stride;
|
||||
|
||||
let currentWeight = this.cumulativeWeight;
|
||||
|
||||
if ( currentWeight === 0 ) {
|
||||
|
||||
// accuN := incoming * weight
|
||||
|
||||
for ( let i = 0; i !== stride; ++ i ) {
|
||||
|
||||
buffer[ offset + i ] = buffer[ i ];
|
||||
|
||||
}
|
||||
|
||||
currentWeight = weight;
|
||||
|
||||
} else {
|
||||
|
||||
// accuN := accuN + incoming * weight
|
||||
|
||||
currentWeight += weight;
|
||||
const mix = weight / currentWeight;
|
||||
this._mixBufferRegion( buffer, offset, 0, mix, stride );
|
||||
|
||||
}
|
||||
|
||||
this.cumulativeWeight = currentWeight;
|
||||
|
||||
}
|
||||
|
||||
// accumulate data in the 'incoming' region into 'add'
|
||||
accumulateAdditive( weight ) {
|
||||
|
||||
const buffer = this.buffer,
|
||||
stride = this.valueSize,
|
||||
offset = stride * this._addIndex;
|
||||
|
||||
if ( this.cumulativeWeightAdditive === 0 ) {
|
||||
|
||||
// add = identity
|
||||
|
||||
this._setIdentity();
|
||||
|
||||
}
|
||||
|
||||
// add := add + incoming * weight
|
||||
|
||||
this._mixBufferRegionAdditive( buffer, offset, 0, weight, stride );
|
||||
this.cumulativeWeightAdditive += weight;
|
||||
|
||||
}
|
||||
|
||||
// apply the state of 'accu<i>' to the binding when accus differ
|
||||
apply( accuIndex ) {
|
||||
|
||||
const stride = this.valueSize,
|
||||
buffer = this.buffer,
|
||||
offset = accuIndex * stride + stride,
|
||||
|
||||
weight = this.cumulativeWeight,
|
||||
weightAdditive = this.cumulativeWeightAdditive,
|
||||
|
||||
binding = this.binding;
|
||||
|
||||
this.cumulativeWeight = 0;
|
||||
this.cumulativeWeightAdditive = 0;
|
||||
|
||||
if ( weight < 1 ) {
|
||||
|
||||
// accuN := accuN + original * ( 1 - cumulativeWeight )
|
||||
|
||||
const originalValueOffset = stride * this._origIndex;
|
||||
|
||||
this._mixBufferRegion(
|
||||
buffer, offset, originalValueOffset, 1 - weight, stride );
|
||||
|
||||
}
|
||||
|
||||
if ( weightAdditive > 0 ) {
|
||||
|
||||
// accuN := accuN + additive accuN
|
||||
|
||||
this._mixBufferRegionAdditive( buffer, offset, this._addIndex * stride, 1, stride );
|
||||
|
||||
}
|
||||
|
||||
for ( let i = stride, e = stride + stride; i !== e; ++ i ) {
|
||||
|
||||
if ( buffer[ i ] !== buffer[ i + stride ] ) {
|
||||
|
||||
// value has changed -> update scene graph
|
||||
|
||||
binding.setValue( buffer, offset );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// remember the state of the bound property and copy it to both accus
|
||||
saveOriginalState() {
|
||||
|
||||
const binding = this.binding;
|
||||
|
||||
const buffer = this.buffer,
|
||||
stride = this.valueSize,
|
||||
|
||||
originalValueOffset = stride * this._origIndex;
|
||||
|
||||
binding.getValue( buffer, originalValueOffset );
|
||||
|
||||
// accu[0..1] := orig -- initially detect changes against the original
|
||||
for ( let i = stride, e = originalValueOffset; i !== e; ++ i ) {
|
||||
|
||||
buffer[ i ] = buffer[ originalValueOffset + ( i % stride ) ];
|
||||
|
||||
}
|
||||
|
||||
// Add to identity for additive
|
||||
this._setIdentity();
|
||||
|
||||
this.cumulativeWeight = 0;
|
||||
this.cumulativeWeightAdditive = 0;
|
||||
|
||||
}
|
||||
|
||||
// apply the state previously taken via 'saveOriginalState' to the binding
|
||||
restoreOriginalState() {
|
||||
|
||||
const originalValueOffset = this.valueSize * 3;
|
||||
this.binding.setValue( this.buffer, originalValueOffset );
|
||||
|
||||
}
|
||||
|
||||
_setAdditiveIdentityNumeric() {
|
||||
|
||||
const startIndex = this._addIndex * this.valueSize;
|
||||
const endIndex = startIndex + this.valueSize;
|
||||
|
||||
for ( let i = startIndex; i < endIndex; i ++ ) {
|
||||
|
||||
this.buffer[ i ] = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_setAdditiveIdentityQuaternion() {
|
||||
|
||||
this._setAdditiveIdentityNumeric();
|
||||
this.buffer[ this._addIndex * this.valueSize + 3 ] = 1;
|
||||
|
||||
}
|
||||
|
||||
_setAdditiveIdentityOther() {
|
||||
|
||||
const startIndex = this._origIndex * this.valueSize;
|
||||
const targetIndex = this._addIndex * this.valueSize;
|
||||
|
||||
for ( let i = 0; i < this.valueSize; i ++ ) {
|
||||
|
||||
this.buffer[ targetIndex + i ] = this.buffer[ startIndex + i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// mix functions
|
||||
|
||||
_select( buffer, dstOffset, srcOffset, t, stride ) {
|
||||
|
||||
if ( t >= 0.5 ) {
|
||||
|
||||
for ( let i = 0; i !== stride; ++ i ) {
|
||||
|
||||
buffer[ dstOffset + i ] = buffer[ srcOffset + i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_slerp( buffer, dstOffset, srcOffset, t ) {
|
||||
|
||||
Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t );
|
||||
|
||||
}
|
||||
|
||||
_slerpAdditive( buffer, dstOffset, srcOffset, t, stride ) {
|
||||
|
||||
const workOffset = this._workIndex * stride;
|
||||
|
||||
// Store result in intermediate buffer offset
|
||||
Quaternion.multiplyQuaternionsFlat( buffer, workOffset, buffer, dstOffset, buffer, srcOffset );
|
||||
|
||||
// Slerp to the intermediate result
|
||||
Quaternion.slerpFlat( buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t );
|
||||
|
||||
}
|
||||
|
||||
_lerp( buffer, dstOffset, srcOffset, t, stride ) {
|
||||
|
||||
const s = 1 - t;
|
||||
|
||||
for ( let i = 0; i !== stride; ++ i ) {
|
||||
|
||||
const j = dstOffset + i;
|
||||
|
||||
buffer[ j ] = buffer[ j ] * s + buffer[ srcOffset + i ] * t;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_lerpAdditive( buffer, dstOffset, srcOffset, t, stride ) {
|
||||
|
||||
for ( let i = 0; i !== stride; ++ i ) {
|
||||
|
||||
const j = dstOffset + i;
|
||||
|
||||
buffer[ j ] = buffer[ j ] + buffer[ srcOffset + i ] * t;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { PropertyMixer };
|
||||
19
network-visualization/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js
generated
vendored
Normal file
19
network-visualization/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { InterpolateDiscrete } from '../../constants.js';
|
||||
import { KeyframeTrack } from '../KeyframeTrack.js';
|
||||
|
||||
/**
|
||||
* A Track of Boolean keyframe values.
|
||||
*/
|
||||
class BooleanKeyframeTrack extends KeyframeTrack {}
|
||||
|
||||
BooleanKeyframeTrack.prototype.ValueTypeName = 'bool';
|
||||
BooleanKeyframeTrack.prototype.ValueBufferType = Array;
|
||||
BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
|
||||
BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
|
||||
BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
|
||||
|
||||
// Note: Actually this track could have a optimized / compressed
|
||||
// representation of a single value and a custom interpolant that
|
||||
// computes "firstValue ^ isOdd( index )".
|
||||
|
||||
export { BooleanKeyframeTrack };
|
||||
15
network-visualization/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js
generated
vendored
Normal file
15
network-visualization/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { KeyframeTrack } from '../KeyframeTrack.js';
|
||||
|
||||
/**
|
||||
* A Track of keyframe values that represent color.
|
||||
*/
|
||||
class ColorKeyframeTrack extends KeyframeTrack {}
|
||||
|
||||
ColorKeyframeTrack.prototype.ValueTypeName = 'color';
|
||||
// ValueBufferType is inherited
|
||||
// DefaultInterpolation is inherited
|
||||
|
||||
// Note: Very basic implementation and nothing special yet.
|
||||
// However, this is the place for color space parameterization.
|
||||
|
||||
export { ColorKeyframeTrack };
|
||||
12
network-visualization/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js
generated
vendored
Normal file
12
network-visualization/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { KeyframeTrack } from '../KeyframeTrack.js';
|
||||
|
||||
/**
|
||||
* A Track of numeric keyframe values.
|
||||
*/
|
||||
class NumberKeyframeTrack extends KeyframeTrack {}
|
||||
|
||||
NumberKeyframeTrack.prototype.ValueTypeName = 'number';
|
||||
// ValueBufferType is inherited
|
||||
// DefaultInterpolation is inherited
|
||||
|
||||
export { NumberKeyframeTrack };
|
||||
23
network-visualization/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js
generated
vendored
Normal file
23
network-visualization/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { InterpolateLinear } from '../../constants.js';
|
||||
import { KeyframeTrack } from '../KeyframeTrack.js';
|
||||
import { QuaternionLinearInterpolant } from '../../math/interpolants/QuaternionLinearInterpolant.js';
|
||||
|
||||
/**
|
||||
* A Track of quaternion keyframe values.
|
||||
*/
|
||||
class QuaternionKeyframeTrack extends KeyframeTrack {
|
||||
|
||||
InterpolantFactoryMethodLinear( result ) {
|
||||
|
||||
return new QuaternionLinearInterpolant( this.times, this.values, this.getValueSize(), result );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion';
|
||||
// ValueBufferType is inherited
|
||||
QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
|
||||
QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
|
||||
|
||||
export { QuaternionKeyframeTrack };
|
||||
15
network-visualization/node_modules/three/src/animation/tracks/StringKeyframeTrack.js
generated
vendored
Normal file
15
network-visualization/node_modules/three/src/animation/tracks/StringKeyframeTrack.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { InterpolateDiscrete } from '../../constants.js';
|
||||
import { KeyframeTrack } from '../KeyframeTrack.js';
|
||||
|
||||
/**
|
||||
* A Track that interpolates Strings
|
||||
*/
|
||||
class StringKeyframeTrack extends KeyframeTrack {}
|
||||
|
||||
StringKeyframeTrack.prototype.ValueTypeName = 'string';
|
||||
StringKeyframeTrack.prototype.ValueBufferType = Array;
|
||||
StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
|
||||
StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
|
||||
StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
|
||||
|
||||
export { StringKeyframeTrack };
|
||||
12
network-visualization/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js
generated
vendored
Normal file
12
network-visualization/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { KeyframeTrack } from '../KeyframeTrack.js';
|
||||
|
||||
/**
|
||||
* A Track of vectored keyframe values.
|
||||
*/
|
||||
class VectorKeyframeTrack extends KeyframeTrack {}
|
||||
|
||||
VectorKeyframeTrack.prototype.ValueTypeName = 'vector';
|
||||
// ValueBufferType is inherited
|
||||
// DefaultInterpolation is inherited
|
||||
|
||||
export { VectorKeyframeTrack };
|
||||
402
network-visualization/node_modules/three/src/audio/Audio.js
generated
vendored
Normal file
402
network-visualization/node_modules/three/src/audio/Audio.js
generated
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
|
||||
class Audio extends Object3D {
|
||||
|
||||
constructor( listener ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'Audio';
|
||||
|
||||
this.listener = listener;
|
||||
this.context = listener.context;
|
||||
|
||||
this.gain = this.context.createGain();
|
||||
this.gain.connect( listener.getInput() );
|
||||
|
||||
this.autoplay = false;
|
||||
|
||||
this.buffer = null;
|
||||
this.detune = 0;
|
||||
this.loop = false;
|
||||
this.loopStart = 0;
|
||||
this.loopEnd = 0;
|
||||
this.offset = 0;
|
||||
this.duration = undefined;
|
||||
this.playbackRate = 1;
|
||||
this.isPlaying = false;
|
||||
this.hasPlaybackControl = true;
|
||||
this.source = null;
|
||||
this.sourceType = 'empty';
|
||||
|
||||
this._startedAt = 0;
|
||||
this._progress = 0;
|
||||
this._connected = false;
|
||||
|
||||
this.filters = [];
|
||||
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
|
||||
return this.gain;
|
||||
|
||||
}
|
||||
|
||||
setNodeSource( audioNode ) {
|
||||
|
||||
this.hasPlaybackControl = false;
|
||||
this.sourceType = 'audioNode';
|
||||
this.source = audioNode;
|
||||
this.connect();
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setMediaElementSource( mediaElement ) {
|
||||
|
||||
this.hasPlaybackControl = false;
|
||||
this.sourceType = 'mediaNode';
|
||||
this.source = this.context.createMediaElementSource( mediaElement );
|
||||
this.connect();
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setMediaStreamSource( mediaStream ) {
|
||||
|
||||
this.hasPlaybackControl = false;
|
||||
this.sourceType = 'mediaStreamNode';
|
||||
this.source = this.context.createMediaStreamSource( mediaStream );
|
||||
this.connect();
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setBuffer( audioBuffer ) {
|
||||
|
||||
this.buffer = audioBuffer;
|
||||
this.sourceType = 'buffer';
|
||||
|
||||
if ( this.autoplay ) this.play();
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
play( delay = 0 ) {
|
||||
|
||||
if ( this.isPlaying === true ) {
|
||||
|
||||
console.warn( 'THREE.Audio: Audio is already playing.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( this.hasPlaybackControl === false ) {
|
||||
|
||||
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
this._startedAt = this.context.currentTime + delay;
|
||||
|
||||
const source = this.context.createBufferSource();
|
||||
source.buffer = this.buffer;
|
||||
source.loop = this.loop;
|
||||
source.loopStart = this.loopStart;
|
||||
source.loopEnd = this.loopEnd;
|
||||
source.onended = this.onEnded.bind( this );
|
||||
source.start( this._startedAt, this._progress + this.offset, this.duration );
|
||||
|
||||
this.isPlaying = true;
|
||||
|
||||
this.source = source;
|
||||
|
||||
this.setDetune( this.detune );
|
||||
this.setPlaybackRate( this.playbackRate );
|
||||
|
||||
return this.connect();
|
||||
|
||||
}
|
||||
|
||||
pause() {
|
||||
|
||||
if ( this.hasPlaybackControl === false ) {
|
||||
|
||||
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( this.isPlaying === true ) {
|
||||
|
||||
// update current progress
|
||||
|
||||
this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate;
|
||||
|
||||
if ( this.loop === true ) {
|
||||
|
||||
// ensure _progress does not exceed duration with looped audios
|
||||
|
||||
this._progress = this._progress % ( this.duration || this.buffer.duration );
|
||||
|
||||
}
|
||||
|
||||
this.source.stop();
|
||||
this.source.onended = null;
|
||||
|
||||
this.isPlaying = false;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
||||
if ( this.hasPlaybackControl === false ) {
|
||||
|
||||
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
this._progress = 0;
|
||||
|
||||
if ( this.source !== null ) {
|
||||
|
||||
this.source.stop();
|
||||
this.source.onended = null;
|
||||
|
||||
}
|
||||
|
||||
this.isPlaying = false;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
connect() {
|
||||
|
||||
if ( this.filters.length > 0 ) {
|
||||
|
||||
this.source.connect( this.filters[ 0 ] );
|
||||
|
||||
for ( let i = 1, l = this.filters.length; i < l; i ++ ) {
|
||||
|
||||
this.filters[ i - 1 ].connect( this.filters[ i ] );
|
||||
|
||||
}
|
||||
|
||||
this.filters[ this.filters.length - 1 ].connect( this.getOutput() );
|
||||
|
||||
} else {
|
||||
|
||||
this.source.connect( this.getOutput() );
|
||||
|
||||
}
|
||||
|
||||
this._connected = true;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
|
||||
if ( this._connected === false ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( this.filters.length > 0 ) {
|
||||
|
||||
this.source.disconnect( this.filters[ 0 ] );
|
||||
|
||||
for ( let i = 1, l = this.filters.length; i < l; i ++ ) {
|
||||
|
||||
this.filters[ i - 1 ].disconnect( this.filters[ i ] );
|
||||
|
||||
}
|
||||
|
||||
this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() );
|
||||
|
||||
} else {
|
||||
|
||||
this.source.disconnect( this.getOutput() );
|
||||
|
||||
}
|
||||
|
||||
this._connected = false;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getFilters() {
|
||||
|
||||
return this.filters;
|
||||
|
||||
}
|
||||
|
||||
setFilters( value ) {
|
||||
|
||||
if ( ! value ) value = [];
|
||||
|
||||
if ( this._connected === true ) {
|
||||
|
||||
this.disconnect();
|
||||
this.filters = value.slice();
|
||||
this.connect();
|
||||
|
||||
} else {
|
||||
|
||||
this.filters = value.slice();
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setDetune( value ) {
|
||||
|
||||
this.detune = value;
|
||||
|
||||
if ( this.source.detune === undefined ) return; // only set detune when available
|
||||
|
||||
if ( this.isPlaying === true ) {
|
||||
|
||||
this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getDetune() {
|
||||
|
||||
return this.detune;
|
||||
|
||||
}
|
||||
|
||||
getFilter() {
|
||||
|
||||
return this.getFilters()[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
setFilter( filter ) {
|
||||
|
||||
return this.setFilters( filter ? [ filter ] : [] );
|
||||
|
||||
}
|
||||
|
||||
setPlaybackRate( value ) {
|
||||
|
||||
if ( this.hasPlaybackControl === false ) {
|
||||
|
||||
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
this.playbackRate = value;
|
||||
|
||||
if ( this.isPlaying === true ) {
|
||||
|
||||
this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getPlaybackRate() {
|
||||
|
||||
return this.playbackRate;
|
||||
|
||||
}
|
||||
|
||||
onEnded() {
|
||||
|
||||
this.isPlaying = false;
|
||||
|
||||
}
|
||||
|
||||
getLoop() {
|
||||
|
||||
if ( this.hasPlaybackControl === false ) {
|
||||
|
||||
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return this.loop;
|
||||
|
||||
}
|
||||
|
||||
setLoop( value ) {
|
||||
|
||||
if ( this.hasPlaybackControl === false ) {
|
||||
|
||||
console.warn( 'THREE.Audio: this Audio has no playback control.' );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
this.loop = value;
|
||||
|
||||
if ( this.isPlaying === true ) {
|
||||
|
||||
this.source.loop = this.loop;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setLoopStart( value ) {
|
||||
|
||||
this.loopStart = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setLoopEnd( value ) {
|
||||
|
||||
this.loopEnd = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getVolume() {
|
||||
|
||||
return this.gain.gain.value;
|
||||
|
||||
}
|
||||
|
||||
setVolume( value ) {
|
||||
|
||||
this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Audio };
|
||||
40
network-visualization/node_modules/three/src/audio/AudioAnalyser.js
generated
vendored
Normal file
40
network-visualization/node_modules/three/src/audio/AudioAnalyser.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
class AudioAnalyser {
|
||||
|
||||
constructor( audio, fftSize = 2048 ) {
|
||||
|
||||
this.analyser = audio.context.createAnalyser();
|
||||
this.analyser.fftSize = fftSize;
|
||||
|
||||
this.data = new Uint8Array( this.analyser.frequencyBinCount );
|
||||
|
||||
audio.getOutput().connect( this.analyser );
|
||||
|
||||
}
|
||||
|
||||
|
||||
getFrequencyData() {
|
||||
|
||||
this.analyser.getByteFrequencyData( this.data );
|
||||
|
||||
return this.data;
|
||||
|
||||
}
|
||||
|
||||
getAverageFrequency() {
|
||||
|
||||
let value = 0;
|
||||
const data = this.getFrequencyData();
|
||||
|
||||
for ( let i = 0; i < data.length; i ++ ) {
|
||||
|
||||
value += data[ i ];
|
||||
|
||||
}
|
||||
|
||||
return value / data.length;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { AudioAnalyser };
|
||||
25
network-visualization/node_modules/three/src/audio/AudioContext.js
generated
vendored
Normal file
25
network-visualization/node_modules/three/src/audio/AudioContext.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
let _context;
|
||||
|
||||
class AudioContext {
|
||||
|
||||
static getContext() {
|
||||
|
||||
if ( _context === undefined ) {
|
||||
|
||||
_context = new ( window.AudioContext || window.webkitAudioContext )();
|
||||
|
||||
}
|
||||
|
||||
return _context;
|
||||
|
||||
}
|
||||
|
||||
static setContext( value ) {
|
||||
|
||||
_context = value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { AudioContext };
|
||||
137
network-visualization/node_modules/three/src/audio/AudioListener.js
generated
vendored
Normal file
137
network-visualization/node_modules/three/src/audio/AudioListener.js
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Quaternion } from '../math/Quaternion.js';
|
||||
import { Clock } from '../core/Clock.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { AudioContext } from './AudioContext.js';
|
||||
|
||||
const _position = /*@__PURE__*/ new Vector3();
|
||||
const _quaternion = /*@__PURE__*/ new Quaternion();
|
||||
const _scale = /*@__PURE__*/ new Vector3();
|
||||
const _orientation = /*@__PURE__*/ new Vector3();
|
||||
|
||||
class AudioListener extends Object3D {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'AudioListener';
|
||||
|
||||
this.context = AudioContext.getContext();
|
||||
|
||||
this.gain = this.context.createGain();
|
||||
this.gain.connect( this.context.destination );
|
||||
|
||||
this.filter = null;
|
||||
|
||||
this.timeDelta = 0;
|
||||
|
||||
// private
|
||||
|
||||
this._clock = new Clock();
|
||||
|
||||
}
|
||||
|
||||
getInput() {
|
||||
|
||||
return this.gain;
|
||||
|
||||
}
|
||||
|
||||
removeFilter() {
|
||||
|
||||
if ( this.filter !== null ) {
|
||||
|
||||
this.gain.disconnect( this.filter );
|
||||
this.filter.disconnect( this.context.destination );
|
||||
this.gain.connect( this.context.destination );
|
||||
this.filter = null;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getFilter() {
|
||||
|
||||
return this.filter;
|
||||
|
||||
}
|
||||
|
||||
setFilter( value ) {
|
||||
|
||||
if ( this.filter !== null ) {
|
||||
|
||||
this.gain.disconnect( this.filter );
|
||||
this.filter.disconnect( this.context.destination );
|
||||
|
||||
} else {
|
||||
|
||||
this.gain.disconnect( this.context.destination );
|
||||
|
||||
}
|
||||
|
||||
this.filter = value;
|
||||
this.gain.connect( this.filter );
|
||||
this.filter.connect( this.context.destination );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getMasterVolume() {
|
||||
|
||||
return this.gain.gain.value;
|
||||
|
||||
}
|
||||
|
||||
setMasterVolume( value ) {
|
||||
|
||||
this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld( force ) {
|
||||
|
||||
super.updateMatrixWorld( force );
|
||||
|
||||
const listener = this.context.listener;
|
||||
const up = this.up;
|
||||
|
||||
this.timeDelta = this._clock.getDelta();
|
||||
|
||||
this.matrixWorld.decompose( _position, _quaternion, _scale );
|
||||
|
||||
_orientation.set( 0, 0, - 1 ).applyQuaternion( _quaternion );
|
||||
|
||||
if ( listener.positionX ) {
|
||||
|
||||
// code path for Chrome (see #14393)
|
||||
|
||||
const endTime = this.context.currentTime + this.timeDelta;
|
||||
|
||||
listener.positionX.linearRampToValueAtTime( _position.x, endTime );
|
||||
listener.positionY.linearRampToValueAtTime( _position.y, endTime );
|
||||
listener.positionZ.linearRampToValueAtTime( _position.z, endTime );
|
||||
listener.forwardX.linearRampToValueAtTime( _orientation.x, endTime );
|
||||
listener.forwardY.linearRampToValueAtTime( _orientation.y, endTime );
|
||||
listener.forwardZ.linearRampToValueAtTime( _orientation.z, endTime );
|
||||
listener.upX.linearRampToValueAtTime( up.x, endTime );
|
||||
listener.upY.linearRampToValueAtTime( up.y, endTime );
|
||||
listener.upZ.linearRampToValueAtTime( up.z, endTime );
|
||||
|
||||
} else {
|
||||
|
||||
listener.setPosition( _position.x, _position.y, _position.z );
|
||||
listener.setOrientation( _orientation.x, _orientation.y, _orientation.z, up.x, up.y, up.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { AudioListener };
|
||||
146
network-visualization/node_modules/three/src/audio/PositionalAudio.js
generated
vendored
Normal file
146
network-visualization/node_modules/three/src/audio/PositionalAudio.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Quaternion } from '../math/Quaternion.js';
|
||||
import { Audio } from './Audio.js';
|
||||
|
||||
const _position = /*@__PURE__*/ new Vector3();
|
||||
const _quaternion = /*@__PURE__*/ new Quaternion();
|
||||
const _scale = /*@__PURE__*/ new Vector3();
|
||||
const _orientation = /*@__PURE__*/ new Vector3();
|
||||
|
||||
class PositionalAudio extends Audio {
|
||||
|
||||
constructor( listener ) {
|
||||
|
||||
super( listener );
|
||||
|
||||
this.panner = this.context.createPanner();
|
||||
this.panner.panningModel = 'HRTF';
|
||||
this.panner.connect( this.gain );
|
||||
|
||||
}
|
||||
|
||||
connect() {
|
||||
|
||||
super.connect();
|
||||
|
||||
this.panner.connect( this.gain );
|
||||
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
|
||||
super.disconnect();
|
||||
|
||||
this.panner.disconnect( this.gain );
|
||||
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
|
||||
return this.panner;
|
||||
|
||||
}
|
||||
|
||||
getRefDistance() {
|
||||
|
||||
return this.panner.refDistance;
|
||||
|
||||
}
|
||||
|
||||
setRefDistance( value ) {
|
||||
|
||||
this.panner.refDistance = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getRolloffFactor() {
|
||||
|
||||
return this.panner.rolloffFactor;
|
||||
|
||||
}
|
||||
|
||||
setRolloffFactor( value ) {
|
||||
|
||||
this.panner.rolloffFactor = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getDistanceModel() {
|
||||
|
||||
return this.panner.distanceModel;
|
||||
|
||||
}
|
||||
|
||||
setDistanceModel( value ) {
|
||||
|
||||
this.panner.distanceModel = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getMaxDistance() {
|
||||
|
||||
return this.panner.maxDistance;
|
||||
|
||||
}
|
||||
|
||||
setMaxDistance( value ) {
|
||||
|
||||
this.panner.maxDistance = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setDirectionalCone( coneInnerAngle, coneOuterAngle, coneOuterGain ) {
|
||||
|
||||
this.panner.coneInnerAngle = coneInnerAngle;
|
||||
this.panner.coneOuterAngle = coneOuterAngle;
|
||||
this.panner.coneOuterGain = coneOuterGain;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld( force ) {
|
||||
|
||||
super.updateMatrixWorld( force );
|
||||
|
||||
if ( this.hasPlaybackControl === true && this.isPlaying === false ) return;
|
||||
|
||||
this.matrixWorld.decompose( _position, _quaternion, _scale );
|
||||
|
||||
_orientation.set( 0, 0, 1 ).applyQuaternion( _quaternion );
|
||||
|
||||
const panner = this.panner;
|
||||
|
||||
if ( panner.positionX ) {
|
||||
|
||||
// code path for Chrome and Firefox (see #14393)
|
||||
|
||||
const endTime = this.context.currentTime + this.listener.timeDelta;
|
||||
|
||||
panner.positionX.linearRampToValueAtTime( _position.x, endTime );
|
||||
panner.positionY.linearRampToValueAtTime( _position.y, endTime );
|
||||
panner.positionZ.linearRampToValueAtTime( _position.z, endTime );
|
||||
panner.orientationX.linearRampToValueAtTime( _orientation.x, endTime );
|
||||
panner.orientationY.linearRampToValueAtTime( _orientation.y, endTime );
|
||||
panner.orientationZ.linearRampToValueAtTime( _orientation.z, endTime );
|
||||
|
||||
} else {
|
||||
|
||||
panner.setPosition( _position.x, _position.y, _position.z );
|
||||
panner.setOrientation( _orientation.x, _orientation.y, _orientation.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { PositionalAudio };
|
||||
17
network-visualization/node_modules/three/src/cameras/ArrayCamera.js
generated
vendored
Normal file
17
network-visualization/node_modules/three/src/cameras/ArrayCamera.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { PerspectiveCamera } from './PerspectiveCamera.js';
|
||||
|
||||
class ArrayCamera extends PerspectiveCamera {
|
||||
|
||||
constructor( array = [] ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isArrayCamera = true;
|
||||
|
||||
this.cameras = array;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { ArrayCamera };
|
||||
69
network-visualization/node_modules/three/src/cameras/Camera.js
generated
vendored
Normal file
69
network-visualization/node_modules/three/src/cameras/Camera.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
import { WebGLCoordinateSystem } from '../constants.js';
|
||||
import { Matrix4 } from '../math/Matrix4.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
|
||||
class Camera extends Object3D {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
this.isCamera = true;
|
||||
|
||||
this.type = 'Camera';
|
||||
|
||||
this.matrixWorldInverse = new Matrix4();
|
||||
|
||||
this.projectionMatrix = new Matrix4();
|
||||
this.projectionMatrixInverse = new Matrix4();
|
||||
|
||||
this.coordinateSystem = WebGLCoordinateSystem;
|
||||
|
||||
}
|
||||
|
||||
copy( source, recursive ) {
|
||||
|
||||
super.copy( source, recursive );
|
||||
|
||||
this.matrixWorldInverse.copy( source.matrixWorldInverse );
|
||||
|
||||
this.projectionMatrix.copy( source.projectionMatrix );
|
||||
this.projectionMatrixInverse.copy( source.projectionMatrixInverse );
|
||||
|
||||
this.coordinateSystem = source.coordinateSystem;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getWorldDirection( target ) {
|
||||
|
||||
return super.getWorldDirection( target ).negate();
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld( force ) {
|
||||
|
||||
super.updateMatrixWorld( force );
|
||||
|
||||
this.matrixWorldInverse.copy( this.matrixWorld ).invert();
|
||||
|
||||
}
|
||||
|
||||
updateWorldMatrix( updateParents, updateChildren ) {
|
||||
|
||||
super.updateWorldMatrix( updateParents, updateChildren );
|
||||
|
||||
this.matrixWorldInverse.copy( this.matrixWorld ).invert();
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Camera };
|
||||
173
network-visualization/node_modules/three/src/cameras/CubeCamera.js
generated
vendored
Normal file
173
network-visualization/node_modules/three/src/cameras/CubeCamera.js
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
import { WebGLCoordinateSystem, WebGPUCoordinateSystem } from '../constants.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { PerspectiveCamera } from './PerspectiveCamera.js';
|
||||
|
||||
const fov = - 90; // negative fov is not an error
|
||||
const aspect = 1;
|
||||
|
||||
class CubeCamera extends Object3D {
|
||||
|
||||
constructor( near, far, renderTarget ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'CubeCamera';
|
||||
|
||||
this.renderTarget = renderTarget;
|
||||
this.coordinateSystem = null;
|
||||
this.activeMipmapLevel = 0;
|
||||
|
||||
const cameraPX = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraPX.layers = this.layers;
|
||||
this.add( cameraPX );
|
||||
|
||||
const cameraNX = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraNX.layers = this.layers;
|
||||
this.add( cameraNX );
|
||||
|
||||
const cameraPY = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraPY.layers = this.layers;
|
||||
this.add( cameraPY );
|
||||
|
||||
const cameraNY = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraNY.layers = this.layers;
|
||||
this.add( cameraNY );
|
||||
|
||||
const cameraPZ = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraPZ.layers = this.layers;
|
||||
this.add( cameraPZ );
|
||||
|
||||
const cameraNZ = new PerspectiveCamera( fov, aspect, near, far );
|
||||
cameraNZ.layers = this.layers;
|
||||
this.add( cameraNZ );
|
||||
|
||||
}
|
||||
|
||||
updateCoordinateSystem() {
|
||||
|
||||
const coordinateSystem = this.coordinateSystem;
|
||||
|
||||
const cameras = this.children.concat();
|
||||
|
||||
const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = cameras;
|
||||
|
||||
for ( const camera of cameras ) this.remove( camera );
|
||||
|
||||
if ( coordinateSystem === WebGLCoordinateSystem ) {
|
||||
|
||||
cameraPX.up.set( 0, 1, 0 );
|
||||
cameraPX.lookAt( 1, 0, 0 );
|
||||
|
||||
cameraNX.up.set( 0, 1, 0 );
|
||||
cameraNX.lookAt( - 1, 0, 0 );
|
||||
|
||||
cameraPY.up.set( 0, 0, - 1 );
|
||||
cameraPY.lookAt( 0, 1, 0 );
|
||||
|
||||
cameraNY.up.set( 0, 0, 1 );
|
||||
cameraNY.lookAt( 0, - 1, 0 );
|
||||
|
||||
cameraPZ.up.set( 0, 1, 0 );
|
||||
cameraPZ.lookAt( 0, 0, 1 );
|
||||
|
||||
cameraNZ.up.set( 0, 1, 0 );
|
||||
cameraNZ.lookAt( 0, 0, - 1 );
|
||||
|
||||
} else if ( coordinateSystem === WebGPUCoordinateSystem ) {
|
||||
|
||||
cameraPX.up.set( 0, - 1, 0 );
|
||||
cameraPX.lookAt( - 1, 0, 0 );
|
||||
|
||||
cameraNX.up.set( 0, - 1, 0 );
|
||||
cameraNX.lookAt( 1, 0, 0 );
|
||||
|
||||
cameraPY.up.set( 0, 0, 1 );
|
||||
cameraPY.lookAt( 0, 1, 0 );
|
||||
|
||||
cameraNY.up.set( 0, 0, - 1 );
|
||||
cameraNY.lookAt( 0, - 1, 0 );
|
||||
|
||||
cameraPZ.up.set( 0, - 1, 0 );
|
||||
cameraPZ.lookAt( 0, 0, 1 );
|
||||
|
||||
cameraNZ.up.set( 0, - 1, 0 );
|
||||
cameraNZ.lookAt( 0, 0, - 1 );
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( 'THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: ' + coordinateSystem );
|
||||
|
||||
}
|
||||
|
||||
for ( const camera of cameras ) {
|
||||
|
||||
this.add( camera );
|
||||
|
||||
camera.updateMatrixWorld();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update( renderer, scene ) {
|
||||
|
||||
if ( this.parent === null ) this.updateMatrixWorld();
|
||||
|
||||
const { renderTarget, activeMipmapLevel } = this;
|
||||
|
||||
if ( this.coordinateSystem !== renderer.coordinateSystem ) {
|
||||
|
||||
this.coordinateSystem = renderer.coordinateSystem;
|
||||
|
||||
this.updateCoordinateSystem();
|
||||
|
||||
}
|
||||
|
||||
const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children;
|
||||
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const currentActiveCubeFace = renderer.getActiveCubeFace();
|
||||
const currentActiveMipmapLevel = renderer.getActiveMipmapLevel();
|
||||
|
||||
const currentXrEnabled = renderer.xr.enabled;
|
||||
|
||||
renderer.xr.enabled = false;
|
||||
|
||||
const generateMipmaps = renderTarget.texture.generateMipmaps;
|
||||
|
||||
renderTarget.texture.generateMipmaps = false;
|
||||
|
||||
renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel );
|
||||
renderer.render( scene, cameraPX );
|
||||
|
||||
renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel );
|
||||
renderer.render( scene, cameraNX );
|
||||
|
||||
renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel );
|
||||
renderer.render( scene, cameraPY );
|
||||
|
||||
renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel );
|
||||
renderer.render( scene, cameraNY );
|
||||
|
||||
renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel );
|
||||
renderer.render( scene, cameraPZ );
|
||||
|
||||
// mipmaps are generated during the last call of render()
|
||||
// at this point, all sides of the cube render target are defined
|
||||
|
||||
renderTarget.texture.generateMipmaps = generateMipmaps;
|
||||
|
||||
renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel );
|
||||
renderer.render( scene, cameraNZ );
|
||||
|
||||
renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel );
|
||||
|
||||
renderer.xr.enabled = currentXrEnabled;
|
||||
|
||||
renderTarget.texture.needsPMREMUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { CubeCamera };
|
||||
136
network-visualization/node_modules/three/src/cameras/OrthographicCamera.js
generated
vendored
Executable file
136
network-visualization/node_modules/three/src/cameras/OrthographicCamera.js
generated
vendored
Executable file
@@ -0,0 +1,136 @@
|
||||
import { Camera } from './Camera.js';
|
||||
|
||||
class OrthographicCamera extends Camera {
|
||||
|
||||
constructor( left = - 1, right = 1, top = 1, bottom = - 1, near = 0.1, far = 2000 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isOrthographicCamera = true;
|
||||
|
||||
this.type = 'OrthographicCamera';
|
||||
|
||||
this.zoom = 1;
|
||||
this.view = null;
|
||||
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.top = top;
|
||||
this.bottom = bottom;
|
||||
|
||||
this.near = near;
|
||||
this.far = far;
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
copy( source, recursive ) {
|
||||
|
||||
super.copy( source, recursive );
|
||||
|
||||
this.left = source.left;
|
||||
this.right = source.right;
|
||||
this.top = source.top;
|
||||
this.bottom = source.bottom;
|
||||
this.near = source.near;
|
||||
this.far = source.far;
|
||||
|
||||
this.zoom = source.zoom;
|
||||
this.view = source.view === null ? null : Object.assign( {}, source.view );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setViewOffset( fullWidth, fullHeight, x, y, width, height ) {
|
||||
|
||||
if ( this.view === null ) {
|
||||
|
||||
this.view = {
|
||||
enabled: true,
|
||||
fullWidth: 1,
|
||||
fullHeight: 1,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
width: 1,
|
||||
height: 1
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
this.view.enabled = true;
|
||||
this.view.fullWidth = fullWidth;
|
||||
this.view.fullHeight = fullHeight;
|
||||
this.view.offsetX = x;
|
||||
this.view.offsetY = y;
|
||||
this.view.width = width;
|
||||
this.view.height = height;
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
clearViewOffset() {
|
||||
|
||||
if ( this.view !== null ) {
|
||||
|
||||
this.view.enabled = false;
|
||||
|
||||
}
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
updateProjectionMatrix() {
|
||||
|
||||
const dx = ( this.right - this.left ) / ( 2 * this.zoom );
|
||||
const dy = ( this.top - this.bottom ) / ( 2 * this.zoom );
|
||||
const cx = ( this.right + this.left ) / 2;
|
||||
const cy = ( this.top + this.bottom ) / 2;
|
||||
|
||||
let left = cx - dx;
|
||||
let right = cx + dx;
|
||||
let top = cy + dy;
|
||||
let bottom = cy - dy;
|
||||
|
||||
if ( this.view !== null && this.view.enabled ) {
|
||||
|
||||
const scaleW = ( this.right - this.left ) / this.view.fullWidth / this.zoom;
|
||||
const scaleH = ( this.top - this.bottom ) / this.view.fullHeight / this.zoom;
|
||||
|
||||
left += scaleW * this.view.offsetX;
|
||||
right = left + scaleW * this.view.width;
|
||||
top -= scaleH * this.view.offsetY;
|
||||
bottom = top - scaleH * this.view.height;
|
||||
|
||||
}
|
||||
|
||||
this.projectionMatrix.makeOrthographic( left, right, top, bottom, this.near, this.far, this.coordinateSystem );
|
||||
|
||||
this.projectionMatrixInverse.copy( this.projectionMatrix ).invert();
|
||||
|
||||
}
|
||||
|
||||
toJSON( meta ) {
|
||||
|
||||
const data = super.toJSON( meta );
|
||||
|
||||
data.object.zoom = this.zoom;
|
||||
data.object.left = this.left;
|
||||
data.object.right = this.right;
|
||||
data.object.top = this.top;
|
||||
data.object.bottom = this.bottom;
|
||||
data.object.near = this.near;
|
||||
data.object.far = this.far;
|
||||
|
||||
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { OrthographicCamera };
|
||||
233
network-visualization/node_modules/three/src/cameras/PerspectiveCamera.js
generated
vendored
Normal file
233
network-visualization/node_modules/three/src/cameras/PerspectiveCamera.js
generated
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
import { Camera } from './Camera.js';
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
|
||||
class PerspectiveCamera extends Camera {
|
||||
|
||||
constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isPerspectiveCamera = true;
|
||||
|
||||
this.type = 'PerspectiveCamera';
|
||||
|
||||
this.fov = fov;
|
||||
this.zoom = 1;
|
||||
|
||||
this.near = near;
|
||||
this.far = far;
|
||||
this.focus = 10;
|
||||
|
||||
this.aspect = aspect;
|
||||
this.view = null;
|
||||
|
||||
this.filmGauge = 35; // width of the film (default in millimeters)
|
||||
this.filmOffset = 0; // horizontal film offset (same unit as gauge)
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
copy( source, recursive ) {
|
||||
|
||||
super.copy( source, recursive );
|
||||
|
||||
this.fov = source.fov;
|
||||
this.zoom = source.zoom;
|
||||
|
||||
this.near = source.near;
|
||||
this.far = source.far;
|
||||
this.focus = source.focus;
|
||||
|
||||
this.aspect = source.aspect;
|
||||
this.view = source.view === null ? null : Object.assign( {}, source.view );
|
||||
|
||||
this.filmGauge = source.filmGauge;
|
||||
this.filmOffset = source.filmOffset;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the FOV by focal length in respect to the current .filmGauge.
|
||||
*
|
||||
* The default film gauge is 35, so that the focal length can be specified for
|
||||
* a 35mm (full frame) camera.
|
||||
*
|
||||
* Values for focal length and film gauge must have the same unit.
|
||||
*/
|
||||
setFocalLength( focalLength ) {
|
||||
|
||||
/** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */
|
||||
const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
|
||||
|
||||
this.fov = MathUtils.RAD2DEG * 2 * Math.atan( vExtentSlope );
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the focal length from the current .fov and .filmGauge.
|
||||
*/
|
||||
getFocalLength() {
|
||||
|
||||
const vExtentSlope = Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov );
|
||||
|
||||
return 0.5 * this.getFilmHeight() / vExtentSlope;
|
||||
|
||||
}
|
||||
|
||||
getEffectiveFOV() {
|
||||
|
||||
return MathUtils.RAD2DEG * 2 * Math.atan(
|
||||
Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom );
|
||||
|
||||
}
|
||||
|
||||
getFilmWidth() {
|
||||
|
||||
// film not completely covered in portrait format (aspect < 1)
|
||||
return this.filmGauge * Math.min( this.aspect, 1 );
|
||||
|
||||
}
|
||||
|
||||
getFilmHeight() {
|
||||
|
||||
// film not completely covered in landscape format (aspect > 1)
|
||||
return this.filmGauge / Math.max( this.aspect, 1 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an offset in a larger frustum. This is useful for multi-window or
|
||||
* multi-monitor/multi-machine setups.
|
||||
*
|
||||
* For example, if you have 3x2 monitors and each monitor is 1920x1080 and
|
||||
* the monitors are in grid like this
|
||||
*
|
||||
* +---+---+---+
|
||||
* | A | B | C |
|
||||
* +---+---+---+
|
||||
* | D | E | F |
|
||||
* +---+---+---+
|
||||
*
|
||||
* then for each monitor you would call it like this
|
||||
*
|
||||
* const w = 1920;
|
||||
* const h = 1080;
|
||||
* const fullWidth = w * 3;
|
||||
* const fullHeight = h * 2;
|
||||
*
|
||||
* --A--
|
||||
* camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
|
||||
* --B--
|
||||
* camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
|
||||
* --C--
|
||||
* camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
|
||||
* --D--
|
||||
* camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
|
||||
* --E--
|
||||
* camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
|
||||
* --F--
|
||||
* camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
|
||||
*
|
||||
* Note there is no reason monitors have to be the same size or in a grid.
|
||||
*/
|
||||
setViewOffset( fullWidth, fullHeight, x, y, width, height ) {
|
||||
|
||||
this.aspect = fullWidth / fullHeight;
|
||||
|
||||
if ( this.view === null ) {
|
||||
|
||||
this.view = {
|
||||
enabled: true,
|
||||
fullWidth: 1,
|
||||
fullHeight: 1,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
width: 1,
|
||||
height: 1
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
this.view.enabled = true;
|
||||
this.view.fullWidth = fullWidth;
|
||||
this.view.fullHeight = fullHeight;
|
||||
this.view.offsetX = x;
|
||||
this.view.offsetY = y;
|
||||
this.view.width = width;
|
||||
this.view.height = height;
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
clearViewOffset() {
|
||||
|
||||
if ( this.view !== null ) {
|
||||
|
||||
this.view.enabled = false;
|
||||
|
||||
}
|
||||
|
||||
this.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
updateProjectionMatrix() {
|
||||
|
||||
const near = this.near;
|
||||
let top = near * Math.tan( MathUtils.DEG2RAD * 0.5 * this.fov ) / this.zoom;
|
||||
let height = 2 * top;
|
||||
let width = this.aspect * height;
|
||||
let left = - 0.5 * width;
|
||||
const view = this.view;
|
||||
|
||||
if ( this.view !== null && this.view.enabled ) {
|
||||
|
||||
const fullWidth = view.fullWidth,
|
||||
fullHeight = view.fullHeight;
|
||||
|
||||
left += view.offsetX * width / fullWidth;
|
||||
top -= view.offsetY * height / fullHeight;
|
||||
width *= view.width / fullWidth;
|
||||
height *= view.height / fullHeight;
|
||||
|
||||
}
|
||||
|
||||
const skew = this.filmOffset;
|
||||
if ( skew !== 0 ) left += near * skew / this.getFilmWidth();
|
||||
|
||||
this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far, this.coordinateSystem );
|
||||
|
||||
this.projectionMatrixInverse.copy( this.projectionMatrix ).invert();
|
||||
|
||||
}
|
||||
|
||||
toJSON( meta ) {
|
||||
|
||||
const data = super.toJSON( meta );
|
||||
|
||||
data.object.fov = this.fov;
|
||||
data.object.zoom = this.zoom;
|
||||
|
||||
data.object.near = this.near;
|
||||
data.object.far = this.far;
|
||||
data.object.focus = this.focus;
|
||||
|
||||
data.object.aspect = this.aspect;
|
||||
|
||||
if ( this.view !== null ) data.object.view = Object.assign( {}, this.view );
|
||||
|
||||
data.object.filmGauge = this.filmGauge;
|
||||
data.object.filmOffset = this.filmOffset;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { PerspectiveCamera };
|
||||
100
network-visualization/node_modules/three/src/cameras/StereoCamera.js
generated
vendored
Normal file
100
network-visualization/node_modules/three/src/cameras/StereoCamera.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
import { Matrix4 } from '../math/Matrix4.js';
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
import { PerspectiveCamera } from './PerspectiveCamera.js';
|
||||
|
||||
const _eyeRight = /*@__PURE__*/ new Matrix4();
|
||||
const _eyeLeft = /*@__PURE__*/ new Matrix4();
|
||||
const _projectionMatrix = /*@__PURE__*/ new Matrix4();
|
||||
|
||||
class StereoCamera {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.type = 'StereoCamera';
|
||||
|
||||
this.aspect = 1;
|
||||
|
||||
this.eyeSep = 0.064;
|
||||
|
||||
this.cameraL = new PerspectiveCamera();
|
||||
this.cameraL.layers.enable( 1 );
|
||||
this.cameraL.matrixAutoUpdate = false;
|
||||
|
||||
this.cameraR = new PerspectiveCamera();
|
||||
this.cameraR.layers.enable( 2 );
|
||||
this.cameraR.matrixAutoUpdate = false;
|
||||
|
||||
this._cache = {
|
||||
focus: null,
|
||||
fov: null,
|
||||
aspect: null,
|
||||
near: null,
|
||||
far: null,
|
||||
zoom: null,
|
||||
eyeSep: null
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
update( camera ) {
|
||||
|
||||
const cache = this._cache;
|
||||
|
||||
const needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov ||
|
||||
cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near ||
|
||||
cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep;
|
||||
|
||||
if ( needsUpdate ) {
|
||||
|
||||
cache.focus = camera.focus;
|
||||
cache.fov = camera.fov;
|
||||
cache.aspect = camera.aspect * this.aspect;
|
||||
cache.near = camera.near;
|
||||
cache.far = camera.far;
|
||||
cache.zoom = camera.zoom;
|
||||
cache.eyeSep = this.eyeSep;
|
||||
|
||||
// Off-axis stereoscopic effect based on
|
||||
// http://paulbourke.net/stereographics/stereorender/
|
||||
|
||||
_projectionMatrix.copy( camera.projectionMatrix );
|
||||
const eyeSepHalf = cache.eyeSep / 2;
|
||||
const eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus;
|
||||
const ymax = ( cache.near * Math.tan( MathUtils.DEG2RAD * cache.fov * 0.5 ) ) / cache.zoom;
|
||||
let xmin, xmax;
|
||||
|
||||
// translate xOffset
|
||||
|
||||
_eyeLeft.elements[ 12 ] = - eyeSepHalf;
|
||||
_eyeRight.elements[ 12 ] = eyeSepHalf;
|
||||
|
||||
// for left eye
|
||||
|
||||
xmin = - ymax * cache.aspect + eyeSepOnProjection;
|
||||
xmax = ymax * cache.aspect + eyeSepOnProjection;
|
||||
|
||||
_projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
|
||||
_projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
|
||||
|
||||
this.cameraL.projectionMatrix.copy( _projectionMatrix );
|
||||
|
||||
// for right eye
|
||||
|
||||
xmin = - ymax * cache.aspect - eyeSepOnProjection;
|
||||
xmax = ymax * cache.aspect - eyeSepOnProjection;
|
||||
|
||||
_projectionMatrix.elements[ 0 ] = 2 * cache.near / ( xmax - xmin );
|
||||
_projectionMatrix.elements[ 8 ] = ( xmax + xmin ) / ( xmax - xmin );
|
||||
|
||||
this.cameraR.projectionMatrix.copy( _projectionMatrix );
|
||||
|
||||
}
|
||||
|
||||
this.cameraL.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeLeft );
|
||||
this.cameraR.matrixWorld.copy( camera.matrixWorld ).multiply( _eyeRight );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { StereoCamera };
|
||||
216
network-visualization/node_modules/three/src/constants.js
generated
vendored
Normal file
216
network-visualization/node_modules/three/src/constants.js
generated
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
export const REVISION = '158';
|
||||
|
||||
export const MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2, ROTATE: 0, DOLLY: 1, PAN: 2 };
|
||||
export const TOUCH = { ROTATE: 0, PAN: 1, DOLLY_PAN: 2, DOLLY_ROTATE: 3 };
|
||||
export const CullFaceNone = 0;
|
||||
export const CullFaceBack = 1;
|
||||
export const CullFaceFront = 2;
|
||||
export const CullFaceFrontBack = 3;
|
||||
export const BasicShadowMap = 0;
|
||||
export const PCFShadowMap = 1;
|
||||
export const PCFSoftShadowMap = 2;
|
||||
export const VSMShadowMap = 3;
|
||||
export const FrontSide = 0;
|
||||
export const BackSide = 1;
|
||||
export const DoubleSide = 2;
|
||||
export const TwoPassDoubleSide = 2; // r149
|
||||
export const NoBlending = 0;
|
||||
export const NormalBlending = 1;
|
||||
export const AdditiveBlending = 2;
|
||||
export const SubtractiveBlending = 3;
|
||||
export const MultiplyBlending = 4;
|
||||
export const CustomBlending = 5;
|
||||
export const AddEquation = 100;
|
||||
export const SubtractEquation = 101;
|
||||
export const ReverseSubtractEquation = 102;
|
||||
export const MinEquation = 103;
|
||||
export const MaxEquation = 104;
|
||||
export const ZeroFactor = 200;
|
||||
export const OneFactor = 201;
|
||||
export const SrcColorFactor = 202;
|
||||
export const OneMinusSrcColorFactor = 203;
|
||||
export const SrcAlphaFactor = 204;
|
||||
export const OneMinusSrcAlphaFactor = 205;
|
||||
export const DstAlphaFactor = 206;
|
||||
export const OneMinusDstAlphaFactor = 207;
|
||||
export const DstColorFactor = 208;
|
||||
export const OneMinusDstColorFactor = 209;
|
||||
export const SrcAlphaSaturateFactor = 210;
|
||||
export const ConstantColorFactor = 211;
|
||||
export const OneMinusConstantColorFactor = 212;
|
||||
export const ConstantAlphaFactor = 213;
|
||||
export const OneMinusConstantAlphaFactor = 214;
|
||||
export const NeverDepth = 0;
|
||||
export const AlwaysDepth = 1;
|
||||
export const LessDepth = 2;
|
||||
export const LessEqualDepth = 3;
|
||||
export const EqualDepth = 4;
|
||||
export const GreaterEqualDepth = 5;
|
||||
export const GreaterDepth = 6;
|
||||
export const NotEqualDepth = 7;
|
||||
export const MultiplyOperation = 0;
|
||||
export const MixOperation = 1;
|
||||
export const AddOperation = 2;
|
||||
export const NoToneMapping = 0;
|
||||
export const LinearToneMapping = 1;
|
||||
export const ReinhardToneMapping = 2;
|
||||
export const CineonToneMapping = 3;
|
||||
export const ACESFilmicToneMapping = 4;
|
||||
export const CustomToneMapping = 5;
|
||||
export const AttachedBindMode = 'attached';
|
||||
export const DetachedBindMode = 'detached';
|
||||
|
||||
export const UVMapping = 300;
|
||||
export const CubeReflectionMapping = 301;
|
||||
export const CubeRefractionMapping = 302;
|
||||
export const EquirectangularReflectionMapping = 303;
|
||||
export const EquirectangularRefractionMapping = 304;
|
||||
export const CubeUVReflectionMapping = 306;
|
||||
export const RepeatWrapping = 1000;
|
||||
export const ClampToEdgeWrapping = 1001;
|
||||
export const MirroredRepeatWrapping = 1002;
|
||||
export const NearestFilter = 1003;
|
||||
export const NearestMipmapNearestFilter = 1004;
|
||||
export const NearestMipMapNearestFilter = 1004;
|
||||
export const NearestMipmapLinearFilter = 1005;
|
||||
export const NearestMipMapLinearFilter = 1005;
|
||||
export const LinearFilter = 1006;
|
||||
export const LinearMipmapNearestFilter = 1007;
|
||||
export const LinearMipMapNearestFilter = 1007;
|
||||
export const LinearMipmapLinearFilter = 1008;
|
||||
export const LinearMipMapLinearFilter = 1008;
|
||||
export const UnsignedByteType = 1009;
|
||||
export const ByteType = 1010;
|
||||
export const ShortType = 1011;
|
||||
export const UnsignedShortType = 1012;
|
||||
export const IntType = 1013;
|
||||
export const UnsignedIntType = 1014;
|
||||
export const FloatType = 1015;
|
||||
export const HalfFloatType = 1016;
|
||||
export const UnsignedShort4444Type = 1017;
|
||||
export const UnsignedShort5551Type = 1018;
|
||||
export const UnsignedInt248Type = 1020;
|
||||
export const AlphaFormat = 1021;
|
||||
export const RGBAFormat = 1023;
|
||||
export const LuminanceFormat = 1024;
|
||||
export const LuminanceAlphaFormat = 1025;
|
||||
export const DepthFormat = 1026;
|
||||
export const DepthStencilFormat = 1027;
|
||||
export const RedFormat = 1028;
|
||||
export const RedIntegerFormat = 1029;
|
||||
export const RGFormat = 1030;
|
||||
export const RGIntegerFormat = 1031;
|
||||
export const RGBAIntegerFormat = 1033;
|
||||
|
||||
export const RGB_S3TC_DXT1_Format = 33776;
|
||||
export const RGBA_S3TC_DXT1_Format = 33777;
|
||||
export const RGBA_S3TC_DXT3_Format = 33778;
|
||||
export const RGBA_S3TC_DXT5_Format = 33779;
|
||||
export const RGB_PVRTC_4BPPV1_Format = 35840;
|
||||
export const RGB_PVRTC_2BPPV1_Format = 35841;
|
||||
export const RGBA_PVRTC_4BPPV1_Format = 35842;
|
||||
export const RGBA_PVRTC_2BPPV1_Format = 35843;
|
||||
export const RGB_ETC1_Format = 36196;
|
||||
export const RGB_ETC2_Format = 37492;
|
||||
export const RGBA_ETC2_EAC_Format = 37496;
|
||||
export const RGBA_ASTC_4x4_Format = 37808;
|
||||
export const RGBA_ASTC_5x4_Format = 37809;
|
||||
export const RGBA_ASTC_5x5_Format = 37810;
|
||||
export const RGBA_ASTC_6x5_Format = 37811;
|
||||
export const RGBA_ASTC_6x6_Format = 37812;
|
||||
export const RGBA_ASTC_8x5_Format = 37813;
|
||||
export const RGBA_ASTC_8x6_Format = 37814;
|
||||
export const RGBA_ASTC_8x8_Format = 37815;
|
||||
export const RGBA_ASTC_10x5_Format = 37816;
|
||||
export const RGBA_ASTC_10x6_Format = 37817;
|
||||
export const RGBA_ASTC_10x8_Format = 37818;
|
||||
export const RGBA_ASTC_10x10_Format = 37819;
|
||||
export const RGBA_ASTC_12x10_Format = 37820;
|
||||
export const RGBA_ASTC_12x12_Format = 37821;
|
||||
export const RGBA_BPTC_Format = 36492;
|
||||
export const RGB_BPTC_SIGNED_Format = 36494;
|
||||
export const RGB_BPTC_UNSIGNED_Format = 36495;
|
||||
export const RED_RGTC1_Format = 36283;
|
||||
export const SIGNED_RED_RGTC1_Format = 36284;
|
||||
export const RED_GREEN_RGTC2_Format = 36285;
|
||||
export const SIGNED_RED_GREEN_RGTC2_Format = 36286;
|
||||
export const LoopOnce = 2200;
|
||||
export const LoopRepeat = 2201;
|
||||
export const LoopPingPong = 2202;
|
||||
export const InterpolateDiscrete = 2300;
|
||||
export const InterpolateLinear = 2301;
|
||||
export const InterpolateSmooth = 2302;
|
||||
export const ZeroCurvatureEnding = 2400;
|
||||
export const ZeroSlopeEnding = 2401;
|
||||
export const WrapAroundEnding = 2402;
|
||||
export const NormalAnimationBlendMode = 2500;
|
||||
export const AdditiveAnimationBlendMode = 2501;
|
||||
export const TrianglesDrawMode = 0;
|
||||
export const TriangleStripDrawMode = 1;
|
||||
export const TriangleFanDrawMode = 2;
|
||||
/** @deprecated Use LinearSRGBColorSpace or NoColorSpace in three.js r152+. */
|
||||
export const LinearEncoding = 3000;
|
||||
/** @deprecated Use SRGBColorSpace in three.js r152+. */
|
||||
export const sRGBEncoding = 3001;
|
||||
export const BasicDepthPacking = 3200;
|
||||
export const RGBADepthPacking = 3201;
|
||||
export const TangentSpaceNormalMap = 0;
|
||||
export const ObjectSpaceNormalMap = 1;
|
||||
|
||||
// Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available.
|
||||
export const NoColorSpace = '';
|
||||
export const SRGBColorSpace = 'srgb';
|
||||
export const LinearSRGBColorSpace = 'srgb-linear';
|
||||
export const DisplayP3ColorSpace = 'display-p3';
|
||||
export const LinearDisplayP3ColorSpace = 'display-p3-linear';
|
||||
|
||||
export const LinearTransfer = 'linear';
|
||||
export const SRGBTransfer = 'srgb';
|
||||
|
||||
export const Rec709Primaries = 'rec709';
|
||||
export const P3Primaries = 'p3';
|
||||
|
||||
export const ZeroStencilOp = 0;
|
||||
export const KeepStencilOp = 7680;
|
||||
export const ReplaceStencilOp = 7681;
|
||||
export const IncrementStencilOp = 7682;
|
||||
export const DecrementStencilOp = 7683;
|
||||
export const IncrementWrapStencilOp = 34055;
|
||||
export const DecrementWrapStencilOp = 34056;
|
||||
export const InvertStencilOp = 5386;
|
||||
|
||||
export const NeverStencilFunc = 512;
|
||||
export const LessStencilFunc = 513;
|
||||
export const EqualStencilFunc = 514;
|
||||
export const LessEqualStencilFunc = 515;
|
||||
export const GreaterStencilFunc = 516;
|
||||
export const NotEqualStencilFunc = 517;
|
||||
export const GreaterEqualStencilFunc = 518;
|
||||
export const AlwaysStencilFunc = 519;
|
||||
|
||||
export const NeverCompare = 512;
|
||||
export const LessCompare = 513;
|
||||
export const EqualCompare = 514;
|
||||
export const LessEqualCompare = 515;
|
||||
export const GreaterCompare = 516;
|
||||
export const NotEqualCompare = 517;
|
||||
export const GreaterEqualCompare = 518;
|
||||
export const AlwaysCompare = 519;
|
||||
|
||||
export const StaticDrawUsage = 35044;
|
||||
export const DynamicDrawUsage = 35048;
|
||||
export const StreamDrawUsage = 35040;
|
||||
export const StaticReadUsage = 35045;
|
||||
export const DynamicReadUsage = 35049;
|
||||
export const StreamReadUsage = 35041;
|
||||
export const StaticCopyUsage = 35046;
|
||||
export const DynamicCopyUsage = 35050;
|
||||
export const StreamCopyUsage = 35042;
|
||||
|
||||
export const GLSL1 = '100';
|
||||
export const GLSL3 = '300 es';
|
||||
|
||||
export const _SRGBAFormat = 1035; // fallback for WebGL 1
|
||||
|
||||
export const WebGLCoordinateSystem = 2000;
|
||||
export const WebGPUCoordinateSystem = 2001;
|
||||
630
network-visualization/node_modules/three/src/core/BufferAttribute.js
generated
vendored
Normal file
630
network-visualization/node_modules/three/src/core/BufferAttribute.js
generated
vendored
Normal file
@@ -0,0 +1,630 @@
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
import { denormalize, normalize } from '../math/MathUtils.js';
|
||||
import { StaticDrawUsage, FloatType } from '../constants.js';
|
||||
import { fromHalfFloat, toHalfFloat } from '../extras/DataUtils.js';
|
||||
|
||||
const _vector = /*@__PURE__*/ new Vector3();
|
||||
const _vector2 = /*@__PURE__*/ new Vector2();
|
||||
|
||||
class BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized = false ) {
|
||||
|
||||
if ( Array.isArray( array ) ) {
|
||||
|
||||
throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' );
|
||||
|
||||
}
|
||||
|
||||
this.isBufferAttribute = true;
|
||||
|
||||
this.name = '';
|
||||
|
||||
this.array = array;
|
||||
this.itemSize = itemSize;
|
||||
this.count = array !== undefined ? array.length / itemSize : 0;
|
||||
this.normalized = normalized;
|
||||
|
||||
this.usage = StaticDrawUsage;
|
||||
this.updateRange = { offset: 0, count: - 1 };
|
||||
this.gpuType = FloatType;
|
||||
|
||||
this.version = 0;
|
||||
|
||||
}
|
||||
|
||||
onUploadCallback() {}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) this.version ++;
|
||||
|
||||
}
|
||||
|
||||
setUsage( value ) {
|
||||
|
||||
this.usage = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
this.name = source.name;
|
||||
this.array = new source.array.constructor( source.array );
|
||||
this.itemSize = source.itemSize;
|
||||
this.count = source.count;
|
||||
this.normalized = source.normalized;
|
||||
|
||||
this.usage = source.usage;
|
||||
this.gpuType = source.gpuType;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copyAt( index1, attribute, index2 ) {
|
||||
|
||||
index1 *= this.itemSize;
|
||||
index2 *= attribute.itemSize;
|
||||
|
||||
for ( let i = 0, l = this.itemSize; i < l; i ++ ) {
|
||||
|
||||
this.array[ index1 + i ] = attribute.array[ index2 + i ];
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copyArray( array ) {
|
||||
|
||||
this.array.set( array );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
applyMatrix3( m ) {
|
||||
|
||||
if ( this.itemSize === 2 ) {
|
||||
|
||||
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
||||
|
||||
_vector2.fromBufferAttribute( this, i );
|
||||
_vector2.applyMatrix3( m );
|
||||
|
||||
this.setXY( i, _vector2.x, _vector2.y );
|
||||
|
||||
}
|
||||
|
||||
} else if ( this.itemSize === 3 ) {
|
||||
|
||||
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
||||
|
||||
_vector.fromBufferAttribute( this, i );
|
||||
_vector.applyMatrix3( m );
|
||||
|
||||
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
applyMatrix4( m ) {
|
||||
|
||||
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
||||
|
||||
_vector.fromBufferAttribute( this, i );
|
||||
|
||||
_vector.applyMatrix4( m );
|
||||
|
||||
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
applyNormalMatrix( m ) {
|
||||
|
||||
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
||||
|
||||
_vector.fromBufferAttribute( this, i );
|
||||
|
||||
_vector.applyNormalMatrix( m );
|
||||
|
||||
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
transformDirection( m ) {
|
||||
|
||||
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
||||
|
||||
_vector.fromBufferAttribute( this, i );
|
||||
|
||||
_vector.transformDirection( m );
|
||||
|
||||
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
set( value, offset = 0 ) {
|
||||
|
||||
// Matching BufferAttribute constructor, do not normalize the array.
|
||||
this.array.set( value, offset );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getComponent( index, component ) {
|
||||
|
||||
let value = this.array[ index * this.itemSize + component ];
|
||||
|
||||
if ( this.normalized ) value = denormalize( value, this.array );
|
||||
|
||||
return value;
|
||||
|
||||
}
|
||||
|
||||
setComponent( index, component, value ) {
|
||||
|
||||
if ( this.normalized ) value = normalize( value, this.array );
|
||||
|
||||
this.array[ index * this.itemSize + component ] = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getX( index ) {
|
||||
|
||||
let x = this.array[ index * this.itemSize ];
|
||||
|
||||
if ( this.normalized ) x = denormalize( x, this.array );
|
||||
|
||||
return x;
|
||||
|
||||
}
|
||||
|
||||
setX( index, x ) {
|
||||
|
||||
if ( this.normalized ) x = normalize( x, this.array );
|
||||
|
||||
this.array[ index * this.itemSize ] = x;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getY( index ) {
|
||||
|
||||
let y = this.array[ index * this.itemSize + 1 ];
|
||||
|
||||
if ( this.normalized ) y = denormalize( y, this.array );
|
||||
|
||||
return y;
|
||||
|
||||
}
|
||||
|
||||
setY( index, y ) {
|
||||
|
||||
if ( this.normalized ) y = normalize( y, this.array );
|
||||
|
||||
this.array[ index * this.itemSize + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getZ( index ) {
|
||||
|
||||
let z = this.array[ index * this.itemSize + 2 ];
|
||||
|
||||
if ( this.normalized ) z = denormalize( z, this.array );
|
||||
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
setZ( index, z ) {
|
||||
|
||||
if ( this.normalized ) z = normalize( z, this.array );
|
||||
|
||||
this.array[ index * this.itemSize + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getW( index ) {
|
||||
|
||||
let w = this.array[ index * this.itemSize + 3 ];
|
||||
|
||||
if ( this.normalized ) w = denormalize( w, this.array );
|
||||
|
||||
return w;
|
||||
|
||||
}
|
||||
|
||||
setW( index, w ) {
|
||||
|
||||
if ( this.normalized ) w = normalize( w, this.array );
|
||||
|
||||
this.array[ index * this.itemSize + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXY( index, x, y ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.array[ index + 0 ] = x;
|
||||
this.array[ index + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXYZ( index, x, y, z ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
z = normalize( z, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.array[ index + 0 ] = x;
|
||||
this.array[ index + 1 ] = y;
|
||||
this.array[ index + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXYZW( index, x, y, z, w ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
z = normalize( z, this.array );
|
||||
w = normalize( w, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.array[ index + 0 ] = x;
|
||||
this.array[ index + 1 ] = y;
|
||||
this.array[ index + 2 ] = z;
|
||||
this.array[ index + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
onUpload( callback ) {
|
||||
|
||||
this.onUploadCallback = callback;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return new this.constructor( this.array, this.itemSize ).copy( this );
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = {
|
||||
itemSize: this.itemSize,
|
||||
type: this.array.constructor.name,
|
||||
array: Array.from( this.array ),
|
||||
normalized: this.normalized
|
||||
};
|
||||
|
||||
if ( this.name !== '' ) data.name = this.name;
|
||||
if ( this.usage !== StaticDrawUsage ) data.usage = this.usage;
|
||||
if ( this.updateRange.offset !== 0 || this.updateRange.count !== - 1 ) data.updateRange = this.updateRange;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
class Int8BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Int8Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Uint8BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Uint8Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Uint8ClampedBufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Uint8ClampedArray( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Int16BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Int16Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Uint16BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Uint16Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Int32BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Int32Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Uint32BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Uint32Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Float16BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Uint16Array( array ), itemSize, normalized );
|
||||
|
||||
this.isFloat16BufferAttribute = true;
|
||||
|
||||
}
|
||||
|
||||
getX( index ) {
|
||||
|
||||
let x = fromHalfFloat( this.array[ index * this.itemSize ] );
|
||||
|
||||
if ( this.normalized ) x = denormalize( x, this.array );
|
||||
|
||||
return x;
|
||||
|
||||
}
|
||||
|
||||
setX( index, x ) {
|
||||
|
||||
if ( this.normalized ) x = normalize( x, this.array );
|
||||
|
||||
this.array[ index * this.itemSize ] = toHalfFloat( x );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getY( index ) {
|
||||
|
||||
let y = fromHalfFloat( this.array[ index * this.itemSize + 1 ] );
|
||||
|
||||
if ( this.normalized ) y = denormalize( y, this.array );
|
||||
|
||||
return y;
|
||||
|
||||
}
|
||||
|
||||
setY( index, y ) {
|
||||
|
||||
if ( this.normalized ) y = normalize( y, this.array );
|
||||
|
||||
this.array[ index * this.itemSize + 1 ] = toHalfFloat( y );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getZ( index ) {
|
||||
|
||||
let z = fromHalfFloat( this.array[ index * this.itemSize + 2 ] );
|
||||
|
||||
if ( this.normalized ) z = denormalize( z, this.array );
|
||||
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
setZ( index, z ) {
|
||||
|
||||
if ( this.normalized ) z = normalize( z, this.array );
|
||||
|
||||
this.array[ index * this.itemSize + 2 ] = toHalfFloat( z );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getW( index ) {
|
||||
|
||||
let w = fromHalfFloat( this.array[ index * this.itemSize + 3 ] );
|
||||
|
||||
if ( this.normalized ) w = denormalize( w, this.array );
|
||||
|
||||
return w;
|
||||
|
||||
}
|
||||
|
||||
setW( index, w ) {
|
||||
|
||||
if ( this.normalized ) w = normalize( w, this.array );
|
||||
|
||||
this.array[ index * this.itemSize + 3 ] = toHalfFloat( w );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXY( index, x, y ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.array[ index + 0 ] = toHalfFloat( x );
|
||||
this.array[ index + 1 ] = toHalfFloat( y );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXYZ( index, x, y, z ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
z = normalize( z, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.array[ index + 0 ] = toHalfFloat( x );
|
||||
this.array[ index + 1 ] = toHalfFloat( y );
|
||||
this.array[ index + 2 ] = toHalfFloat( z );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXYZW( index, x, y, z, w ) {
|
||||
|
||||
index *= this.itemSize;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
z = normalize( z, this.array );
|
||||
w = normalize( w, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.array[ index + 0 ] = toHalfFloat( x );
|
||||
this.array[ index + 1 ] = toHalfFloat( y );
|
||||
this.array[ index + 2 ] = toHalfFloat( z );
|
||||
this.array[ index + 3 ] = toHalfFloat( w );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Float32BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Float32Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Float64BufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized ) {
|
||||
|
||||
super( new Float64Array( array ), itemSize, normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
export {
|
||||
Float64BufferAttribute,
|
||||
Float32BufferAttribute,
|
||||
Float16BufferAttribute,
|
||||
Uint32BufferAttribute,
|
||||
Int32BufferAttribute,
|
||||
Uint16BufferAttribute,
|
||||
Int16BufferAttribute,
|
||||
Uint8ClampedBufferAttribute,
|
||||
Uint8BufferAttribute,
|
||||
Int8BufferAttribute,
|
||||
BufferAttribute
|
||||
};
|
||||
1079
network-visualization/node_modules/three/src/core/BufferGeometry.js
generated
vendored
Normal file
1079
network-visualization/node_modules/three/src/core/BufferGeometry.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
74
network-visualization/node_modules/three/src/core/Clock.js
generated
vendored
Normal file
74
network-visualization/node_modules/three/src/core/Clock.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
class Clock {
|
||||
|
||||
constructor( autoStart = true ) {
|
||||
|
||||
this.autoStart = autoStart;
|
||||
|
||||
this.startTime = 0;
|
||||
this.oldTime = 0;
|
||||
this.elapsedTime = 0;
|
||||
|
||||
this.running = false;
|
||||
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
this.startTime = now();
|
||||
|
||||
this.oldTime = this.startTime;
|
||||
this.elapsedTime = 0;
|
||||
this.running = true;
|
||||
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
||||
this.getElapsedTime();
|
||||
this.running = false;
|
||||
this.autoStart = false;
|
||||
|
||||
}
|
||||
|
||||
getElapsedTime() {
|
||||
|
||||
this.getDelta();
|
||||
return this.elapsedTime;
|
||||
|
||||
}
|
||||
|
||||
getDelta() {
|
||||
|
||||
let diff = 0;
|
||||
|
||||
if ( this.autoStart && ! this.running ) {
|
||||
|
||||
this.start();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if ( this.running ) {
|
||||
|
||||
const newTime = now();
|
||||
|
||||
diff = ( newTime - this.oldTime ) / 1000;
|
||||
this.oldTime = newTime;
|
||||
|
||||
this.elapsedTime += diff;
|
||||
|
||||
}
|
||||
|
||||
return diff;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function now() {
|
||||
|
||||
return ( typeof performance === 'undefined' ? Date : performance ).now(); // see #10732
|
||||
|
||||
}
|
||||
|
||||
export { Clock };
|
||||
87
network-visualization/node_modules/three/src/core/EventDispatcher.js
generated
vendored
Normal file
87
network-visualization/node_modules/three/src/core/EventDispatcher.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* https://github.com/mrdoob/eventdispatcher.js/
|
||||
*/
|
||||
|
||||
class EventDispatcher {
|
||||
|
||||
addEventListener( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) this._listeners = {};
|
||||
|
||||
const listeners = this._listeners;
|
||||
|
||||
if ( listeners[ type ] === undefined ) {
|
||||
|
||||
listeners[ type ] = [];
|
||||
|
||||
}
|
||||
|
||||
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
|
||||
|
||||
listeners[ type ].push( listener );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
hasEventListener( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) return false;
|
||||
|
||||
const listeners = this._listeners;
|
||||
|
||||
return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
|
||||
|
||||
}
|
||||
|
||||
removeEventListener( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) return;
|
||||
|
||||
const listeners = this._listeners;
|
||||
const listenerArray = listeners[ type ];
|
||||
|
||||
if ( listenerArray !== undefined ) {
|
||||
|
||||
const index = listenerArray.indexOf( listener );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
listenerArray.splice( index, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispatchEvent( event ) {
|
||||
|
||||
if ( this._listeners === undefined ) return;
|
||||
|
||||
const listeners = this._listeners;
|
||||
const listenerArray = listeners[ event.type ];
|
||||
|
||||
if ( listenerArray !== undefined ) {
|
||||
|
||||
event.target = this;
|
||||
|
||||
// Make a copy, in case listeners are removed while iterating.
|
||||
const array = listenerArray.slice( 0 );
|
||||
|
||||
for ( let i = 0, l = array.length; i < l; i ++ ) {
|
||||
|
||||
array[ i ].call( this, event );
|
||||
|
||||
}
|
||||
|
||||
event.target = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { EventDispatcher };
|
||||
60
network-visualization/node_modules/three/src/core/GLBufferAttribute.js
generated
vendored
Normal file
60
network-visualization/node_modules/three/src/core/GLBufferAttribute.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
class GLBufferAttribute {
|
||||
|
||||
constructor( buffer, type, itemSize, elementSize, count ) {
|
||||
|
||||
this.isGLBufferAttribute = true;
|
||||
|
||||
this.name = '';
|
||||
|
||||
this.buffer = buffer;
|
||||
this.type = type;
|
||||
this.itemSize = itemSize;
|
||||
this.elementSize = elementSize;
|
||||
this.count = count;
|
||||
|
||||
this.version = 0;
|
||||
|
||||
}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) this.version ++;
|
||||
|
||||
}
|
||||
|
||||
setBuffer( buffer ) {
|
||||
|
||||
this.buffer = buffer;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setType( type, elementSize ) {
|
||||
|
||||
this.type = type;
|
||||
this.elementSize = elementSize;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setItemSize( itemSize ) {
|
||||
|
||||
this.itemSize = itemSize;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setCount( count ) {
|
||||
|
||||
this.count = count;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { GLBufferAttribute };
|
||||
39
network-visualization/node_modules/three/src/core/InstancedBufferAttribute.js
generated
vendored
Normal file
39
network-visualization/node_modules/three/src/core/InstancedBufferAttribute.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { BufferAttribute } from './BufferAttribute.js';
|
||||
|
||||
class InstancedBufferAttribute extends BufferAttribute {
|
||||
|
||||
constructor( array, itemSize, normalized, meshPerAttribute = 1 ) {
|
||||
|
||||
super( array, itemSize, normalized );
|
||||
|
||||
this.isInstancedBufferAttribute = true;
|
||||
|
||||
this.meshPerAttribute = meshPerAttribute;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.meshPerAttribute = source.meshPerAttribute;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.meshPerAttribute = this.meshPerAttribute;
|
||||
|
||||
data.isInstancedBufferAttribute = true;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { InstancedBufferAttribute };
|
||||
40
network-visualization/node_modules/three/src/core/InstancedBufferGeometry.js
generated
vendored
Normal file
40
network-visualization/node_modules/three/src/core/InstancedBufferGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import { BufferGeometry } from './BufferGeometry.js';
|
||||
|
||||
class InstancedBufferGeometry extends BufferGeometry {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
this.isInstancedBufferGeometry = true;
|
||||
|
||||
this.type = 'InstancedBufferGeometry';
|
||||
this.instanceCount = Infinity;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.instanceCount = source.instanceCount;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.instanceCount = this.instanceCount;
|
||||
|
||||
data.isInstancedBufferGeometry = true;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { InstancedBufferGeometry };
|
||||
48
network-visualization/node_modules/three/src/core/InstancedInterleavedBuffer.js
generated
vendored
Normal file
48
network-visualization/node_modules/three/src/core/InstancedInterleavedBuffer.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
import { InterleavedBuffer } from './InterleavedBuffer.js';
|
||||
|
||||
class InstancedInterleavedBuffer extends InterleavedBuffer {
|
||||
|
||||
constructor( array, stride, meshPerAttribute = 1 ) {
|
||||
|
||||
super( array, stride );
|
||||
|
||||
this.isInstancedInterleavedBuffer = true;
|
||||
|
||||
this.meshPerAttribute = meshPerAttribute;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.meshPerAttribute = source.meshPerAttribute;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clone( data ) {
|
||||
|
||||
const ib = super.clone( data );
|
||||
|
||||
ib.meshPerAttribute = this.meshPerAttribute;
|
||||
|
||||
return ib;
|
||||
|
||||
}
|
||||
|
||||
toJSON( data ) {
|
||||
|
||||
const json = super.toJSON( data );
|
||||
|
||||
json.isInstancedInterleavedBuffer = true;
|
||||
json.meshPerAttribute = this.meshPerAttribute;
|
||||
|
||||
return json;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { InstancedInterleavedBuffer };
|
||||
145
network-visualization/node_modules/three/src/core/InterleavedBuffer.js
generated
vendored
Normal file
145
network-visualization/node_modules/three/src/core/InterleavedBuffer.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
import { StaticDrawUsage } from '../constants.js';
|
||||
|
||||
class InterleavedBuffer {
|
||||
|
||||
constructor( array, stride ) {
|
||||
|
||||
this.isInterleavedBuffer = true;
|
||||
|
||||
this.array = array;
|
||||
this.stride = stride;
|
||||
this.count = array !== undefined ? array.length / stride : 0;
|
||||
|
||||
this.usage = StaticDrawUsage;
|
||||
this.updateRange = { offset: 0, count: - 1 };
|
||||
|
||||
this.version = 0;
|
||||
|
||||
this.uuid = MathUtils.generateUUID();
|
||||
|
||||
}
|
||||
|
||||
onUploadCallback() {}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
if ( value === true ) this.version ++;
|
||||
|
||||
}
|
||||
|
||||
setUsage( value ) {
|
||||
|
||||
this.usage = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
this.array = new source.array.constructor( source.array );
|
||||
this.count = source.count;
|
||||
this.stride = source.stride;
|
||||
this.usage = source.usage;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copyAt( index1, attribute, index2 ) {
|
||||
|
||||
index1 *= this.stride;
|
||||
index2 *= attribute.stride;
|
||||
|
||||
for ( let i = 0, l = this.stride; i < l; i ++ ) {
|
||||
|
||||
this.array[ index1 + i ] = attribute.array[ index2 + i ];
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
set( value, offset = 0 ) {
|
||||
|
||||
this.array.set( value, offset );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clone( data ) {
|
||||
|
||||
if ( data.arrayBuffers === undefined ) {
|
||||
|
||||
data.arrayBuffers = {};
|
||||
|
||||
}
|
||||
|
||||
if ( this.array.buffer._uuid === undefined ) {
|
||||
|
||||
this.array.buffer._uuid = MathUtils.generateUUID();
|
||||
|
||||
}
|
||||
|
||||
if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
|
||||
|
||||
data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer;
|
||||
|
||||
}
|
||||
|
||||
const array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] );
|
||||
|
||||
const ib = new this.constructor( array, this.stride );
|
||||
ib.setUsage( this.usage );
|
||||
|
||||
return ib;
|
||||
|
||||
}
|
||||
|
||||
onUpload( callback ) {
|
||||
|
||||
this.onUploadCallback = callback;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON( data ) {
|
||||
|
||||
if ( data.arrayBuffers === undefined ) {
|
||||
|
||||
data.arrayBuffers = {};
|
||||
|
||||
}
|
||||
|
||||
// generate UUID for array buffer if necessary
|
||||
|
||||
if ( this.array.buffer._uuid === undefined ) {
|
||||
|
||||
this.array.buffer._uuid = MathUtils.generateUUID();
|
||||
|
||||
}
|
||||
|
||||
if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) {
|
||||
|
||||
data.arrayBuffers[ this.array.buffer._uuid ] = Array.from( new Uint32Array( this.array.buffer ) );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
return {
|
||||
uuid: this.uuid,
|
||||
buffer: this.array.buffer._uuid,
|
||||
type: this.array.constructor.name,
|
||||
stride: this.stride
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { InterleavedBuffer };
|
||||
331
network-visualization/node_modules/three/src/core/InterleavedBufferAttribute.js
generated
vendored
Normal file
331
network-visualization/node_modules/three/src/core/InterleavedBufferAttribute.js
generated
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { BufferAttribute } from './BufferAttribute.js';
|
||||
import { denormalize, normalize } from '../math/MathUtils.js';
|
||||
|
||||
const _vector = /*@__PURE__*/ new Vector3();
|
||||
|
||||
class InterleavedBufferAttribute {
|
||||
|
||||
constructor( interleavedBuffer, itemSize, offset, normalized = false ) {
|
||||
|
||||
this.isInterleavedBufferAttribute = true;
|
||||
|
||||
this.name = '';
|
||||
|
||||
this.data = interleavedBuffer;
|
||||
this.itemSize = itemSize;
|
||||
this.offset = offset;
|
||||
|
||||
this.normalized = normalized;
|
||||
|
||||
}
|
||||
|
||||
get count() {
|
||||
|
||||
return this.data.count;
|
||||
|
||||
}
|
||||
|
||||
get array() {
|
||||
|
||||
return this.data.array;
|
||||
|
||||
}
|
||||
|
||||
set needsUpdate( value ) {
|
||||
|
||||
this.data.needsUpdate = value;
|
||||
|
||||
}
|
||||
|
||||
applyMatrix4( m ) {
|
||||
|
||||
for ( let i = 0, l = this.data.count; i < l; i ++ ) {
|
||||
|
||||
_vector.fromBufferAttribute( this, i );
|
||||
|
||||
_vector.applyMatrix4( m );
|
||||
|
||||
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
applyNormalMatrix( m ) {
|
||||
|
||||
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
||||
|
||||
_vector.fromBufferAttribute( this, i );
|
||||
|
||||
_vector.applyNormalMatrix( m );
|
||||
|
||||
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
transformDirection( m ) {
|
||||
|
||||
for ( let i = 0, l = this.count; i < l; i ++ ) {
|
||||
|
||||
_vector.fromBufferAttribute( this, i );
|
||||
|
||||
_vector.transformDirection( m );
|
||||
|
||||
this.setXYZ( i, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setX( index, x ) {
|
||||
|
||||
if ( this.normalized ) x = normalize( x, this.array );
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset ] = x;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setY( index, y ) {
|
||||
|
||||
if ( this.normalized ) y = normalize( y, this.array );
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setZ( index, z ) {
|
||||
|
||||
if ( this.normalized ) z = normalize( z, this.array );
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setW( index, w ) {
|
||||
|
||||
if ( this.normalized ) w = normalize( w, this.array );
|
||||
|
||||
this.data.array[ index * this.data.stride + this.offset + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getX( index ) {
|
||||
|
||||
let x = this.data.array[ index * this.data.stride + this.offset ];
|
||||
|
||||
if ( this.normalized ) x = denormalize( x, this.array );
|
||||
|
||||
return x;
|
||||
|
||||
}
|
||||
|
||||
getY( index ) {
|
||||
|
||||
let y = this.data.array[ index * this.data.stride + this.offset + 1 ];
|
||||
|
||||
if ( this.normalized ) y = denormalize( y, this.array );
|
||||
|
||||
return y;
|
||||
|
||||
}
|
||||
|
||||
getZ( index ) {
|
||||
|
||||
let z = this.data.array[ index * this.data.stride + this.offset + 2 ];
|
||||
|
||||
if ( this.normalized ) z = denormalize( z, this.array );
|
||||
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
getW( index ) {
|
||||
|
||||
let w = this.data.array[ index * this.data.stride + this.offset + 3 ];
|
||||
|
||||
if ( this.normalized ) w = denormalize( w, this.array );
|
||||
|
||||
return w;
|
||||
|
||||
}
|
||||
|
||||
setXY( index, x, y ) {
|
||||
|
||||
index = index * this.data.stride + this.offset;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.data.array[ index + 0 ] = x;
|
||||
this.data.array[ index + 1 ] = y;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXYZ( index, x, y, z ) {
|
||||
|
||||
index = index * this.data.stride + this.offset;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
z = normalize( z, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.data.array[ index + 0 ] = x;
|
||||
this.data.array[ index + 1 ] = y;
|
||||
this.data.array[ index + 2 ] = z;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setXYZW( index, x, y, z, w ) {
|
||||
|
||||
index = index * this.data.stride + this.offset;
|
||||
|
||||
if ( this.normalized ) {
|
||||
|
||||
x = normalize( x, this.array );
|
||||
y = normalize( y, this.array );
|
||||
z = normalize( z, this.array );
|
||||
w = normalize( w, this.array );
|
||||
|
||||
}
|
||||
|
||||
this.data.array[ index + 0 ] = x;
|
||||
this.data.array[ index + 1 ] = y;
|
||||
this.data.array[ index + 2 ] = z;
|
||||
this.data.array[ index + 3 ] = w;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clone( data ) {
|
||||
|
||||
if ( data === undefined ) {
|
||||
|
||||
console.log( 'THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' );
|
||||
|
||||
const array = [];
|
||||
|
||||
for ( let i = 0; i < this.count; i ++ ) {
|
||||
|
||||
const index = i * this.data.stride + this.offset;
|
||||
|
||||
for ( let j = 0; j < this.itemSize; j ++ ) {
|
||||
|
||||
array.push( this.data.array[ index + j ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized );
|
||||
|
||||
} else {
|
||||
|
||||
if ( data.interleavedBuffers === undefined ) {
|
||||
|
||||
data.interleavedBuffers = {};
|
||||
|
||||
}
|
||||
|
||||
if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
|
||||
|
||||
data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data );
|
||||
|
||||
}
|
||||
|
||||
return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
toJSON( data ) {
|
||||
|
||||
if ( data === undefined ) {
|
||||
|
||||
console.log( 'THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' );
|
||||
|
||||
const array = [];
|
||||
|
||||
for ( let i = 0; i < this.count; i ++ ) {
|
||||
|
||||
const index = i * this.data.stride + this.offset;
|
||||
|
||||
for ( let j = 0; j < this.itemSize; j ++ ) {
|
||||
|
||||
array.push( this.data.array[ index + j ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// de-interleave data and save it as an ordinary buffer attribute for now
|
||||
|
||||
return {
|
||||
itemSize: this.itemSize,
|
||||
type: this.array.constructor.name,
|
||||
array: array,
|
||||
normalized: this.normalized
|
||||
};
|
||||
|
||||
} else {
|
||||
|
||||
// save as true interleaved attribute
|
||||
|
||||
if ( data.interleavedBuffers === undefined ) {
|
||||
|
||||
data.interleavedBuffers = {};
|
||||
|
||||
}
|
||||
|
||||
if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) {
|
||||
|
||||
data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data );
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
isInterleavedBufferAttribute: true,
|
||||
itemSize: this.itemSize,
|
||||
data: this.data.uuid,
|
||||
offset: this.offset,
|
||||
normalized: this.normalized
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { InterleavedBufferAttribute };
|
||||
60
network-visualization/node_modules/three/src/core/Layers.js
generated
vendored
Normal file
60
network-visualization/node_modules/three/src/core/Layers.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
class Layers {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.mask = 1 | 0;
|
||||
|
||||
}
|
||||
|
||||
set( channel ) {
|
||||
|
||||
this.mask = ( 1 << channel | 0 ) >>> 0;
|
||||
|
||||
}
|
||||
|
||||
enable( channel ) {
|
||||
|
||||
this.mask |= 1 << channel | 0;
|
||||
|
||||
}
|
||||
|
||||
enableAll() {
|
||||
|
||||
this.mask = 0xffffffff | 0;
|
||||
|
||||
}
|
||||
|
||||
toggle( channel ) {
|
||||
|
||||
this.mask ^= 1 << channel | 0;
|
||||
|
||||
}
|
||||
|
||||
disable( channel ) {
|
||||
|
||||
this.mask &= ~ ( 1 << channel | 0 );
|
||||
|
||||
}
|
||||
|
||||
disableAll() {
|
||||
|
||||
this.mask = 0;
|
||||
|
||||
}
|
||||
|
||||
test( layers ) {
|
||||
|
||||
return ( this.mask & layers.mask ) !== 0;
|
||||
|
||||
}
|
||||
|
||||
isEnabled( channel ) {
|
||||
|
||||
return ( this.mask & ( 1 << channel | 0 ) ) !== 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { Layers };
|
||||
960
network-visualization/node_modules/three/src/core/Object3D.js
generated
vendored
Normal file
960
network-visualization/node_modules/three/src/core/Object3D.js
generated
vendored
Normal file
@@ -0,0 +1,960 @@
|
||||
import { Quaternion } from '../math/Quaternion.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Matrix4 } from '../math/Matrix4.js';
|
||||
import { EventDispatcher } from './EventDispatcher.js';
|
||||
import { Euler } from '../math/Euler.js';
|
||||
import { Layers } from './Layers.js';
|
||||
import { Matrix3 } from '../math/Matrix3.js';
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
|
||||
let _object3DId = 0;
|
||||
|
||||
const _v1 = /*@__PURE__*/ new Vector3();
|
||||
const _q1 = /*@__PURE__*/ new Quaternion();
|
||||
const _m1 = /*@__PURE__*/ new Matrix4();
|
||||
const _target = /*@__PURE__*/ new Vector3();
|
||||
|
||||
const _position = /*@__PURE__*/ new Vector3();
|
||||
const _scale = /*@__PURE__*/ new Vector3();
|
||||
const _quaternion = /*@__PURE__*/ new Quaternion();
|
||||
|
||||
const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 );
|
||||
const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 );
|
||||
const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 );
|
||||
|
||||
const _addedEvent = { type: 'added' };
|
||||
const _removedEvent = { type: 'removed' };
|
||||
|
||||
class Object3D extends EventDispatcher {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
this.isObject3D = true;
|
||||
|
||||
Object.defineProperty( this, 'id', { value: _object3DId ++ } );
|
||||
|
||||
this.uuid = MathUtils.generateUUID();
|
||||
|
||||
this.name = '';
|
||||
this.type = 'Object3D';
|
||||
|
||||
this.parent = null;
|
||||
this.children = [];
|
||||
|
||||
this.up = Object3D.DEFAULT_UP.clone();
|
||||
|
||||
const position = new Vector3();
|
||||
const rotation = new Euler();
|
||||
const quaternion = new Quaternion();
|
||||
const scale = new Vector3( 1, 1, 1 );
|
||||
|
||||
function onRotationChange() {
|
||||
|
||||
quaternion.setFromEuler( rotation, false );
|
||||
|
||||
}
|
||||
|
||||
function onQuaternionChange() {
|
||||
|
||||
rotation.setFromQuaternion( quaternion, undefined, false );
|
||||
|
||||
}
|
||||
|
||||
rotation._onChange( onRotationChange );
|
||||
quaternion._onChange( onQuaternionChange );
|
||||
|
||||
Object.defineProperties( this, {
|
||||
position: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: position
|
||||
},
|
||||
rotation: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: rotation
|
||||
},
|
||||
quaternion: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: quaternion
|
||||
},
|
||||
scale: {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: scale
|
||||
},
|
||||
modelViewMatrix: {
|
||||
value: new Matrix4()
|
||||
},
|
||||
normalMatrix: {
|
||||
value: new Matrix3()
|
||||
}
|
||||
} );
|
||||
|
||||
this.matrix = new Matrix4();
|
||||
this.matrixWorld = new Matrix4();
|
||||
|
||||
this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE;
|
||||
this.matrixWorldNeedsUpdate = false;
|
||||
|
||||
this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer
|
||||
|
||||
this.layers = new Layers();
|
||||
this.visible = true;
|
||||
|
||||
this.castShadow = false;
|
||||
this.receiveShadow = false;
|
||||
|
||||
this.frustumCulled = true;
|
||||
this.renderOrder = 0;
|
||||
|
||||
this.animations = [];
|
||||
|
||||
this.userData = {};
|
||||
|
||||
}
|
||||
|
||||
onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {}
|
||||
|
||||
onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {}
|
||||
|
||||
applyMatrix4( matrix ) {
|
||||
|
||||
if ( this.matrixAutoUpdate ) this.updateMatrix();
|
||||
|
||||
this.matrix.premultiply( matrix );
|
||||
|
||||
this.matrix.decompose( this.position, this.quaternion, this.scale );
|
||||
|
||||
}
|
||||
|
||||
applyQuaternion( q ) {
|
||||
|
||||
this.quaternion.premultiply( q );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setRotationFromAxisAngle( axis, angle ) {
|
||||
|
||||
// assumes axis is normalized
|
||||
|
||||
this.quaternion.setFromAxisAngle( axis, angle );
|
||||
|
||||
}
|
||||
|
||||
setRotationFromEuler( euler ) {
|
||||
|
||||
this.quaternion.setFromEuler( euler, true );
|
||||
|
||||
}
|
||||
|
||||
setRotationFromMatrix( m ) {
|
||||
|
||||
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
|
||||
|
||||
this.quaternion.setFromRotationMatrix( m );
|
||||
|
||||
}
|
||||
|
||||
setRotationFromQuaternion( q ) {
|
||||
|
||||
// assumes q is normalized
|
||||
|
||||
this.quaternion.copy( q );
|
||||
|
||||
}
|
||||
|
||||
rotateOnAxis( axis, angle ) {
|
||||
|
||||
// rotate object on axis in object space
|
||||
// axis is assumed to be normalized
|
||||
|
||||
_q1.setFromAxisAngle( axis, angle );
|
||||
|
||||
this.quaternion.multiply( _q1 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
rotateOnWorldAxis( axis, angle ) {
|
||||
|
||||
// rotate object on axis in world space
|
||||
// axis is assumed to be normalized
|
||||
// method assumes no rotated parent
|
||||
|
||||
_q1.setFromAxisAngle( axis, angle );
|
||||
|
||||
this.quaternion.premultiply( _q1 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
rotateX( angle ) {
|
||||
|
||||
return this.rotateOnAxis( _xAxis, angle );
|
||||
|
||||
}
|
||||
|
||||
rotateY( angle ) {
|
||||
|
||||
return this.rotateOnAxis( _yAxis, angle );
|
||||
|
||||
}
|
||||
|
||||
rotateZ( angle ) {
|
||||
|
||||
return this.rotateOnAxis( _zAxis, angle );
|
||||
|
||||
}
|
||||
|
||||
translateOnAxis( axis, distance ) {
|
||||
|
||||
// translate object by distance along axis in object space
|
||||
// axis is assumed to be normalized
|
||||
|
||||
_v1.copy( axis ).applyQuaternion( this.quaternion );
|
||||
|
||||
this.position.add( _v1.multiplyScalar( distance ) );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
translateX( distance ) {
|
||||
|
||||
return this.translateOnAxis( _xAxis, distance );
|
||||
|
||||
}
|
||||
|
||||
translateY( distance ) {
|
||||
|
||||
return this.translateOnAxis( _yAxis, distance );
|
||||
|
||||
}
|
||||
|
||||
translateZ( distance ) {
|
||||
|
||||
return this.translateOnAxis( _zAxis, distance );
|
||||
|
||||
}
|
||||
|
||||
localToWorld( vector ) {
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
return vector.applyMatrix4( this.matrixWorld );
|
||||
|
||||
}
|
||||
|
||||
worldToLocal( vector ) {
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
return vector.applyMatrix4( _m1.copy( this.matrixWorld ).invert() );
|
||||
|
||||
}
|
||||
|
||||
lookAt( x, y, z ) {
|
||||
|
||||
// This method does not support objects having non-uniformly-scaled parent(s)
|
||||
|
||||
if ( x.isVector3 ) {
|
||||
|
||||
_target.copy( x );
|
||||
|
||||
} else {
|
||||
|
||||
_target.set( x, y, z );
|
||||
|
||||
}
|
||||
|
||||
const parent = this.parent;
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
_position.setFromMatrixPosition( this.matrixWorld );
|
||||
|
||||
if ( this.isCamera || this.isLight ) {
|
||||
|
||||
_m1.lookAt( _position, _target, this.up );
|
||||
|
||||
} else {
|
||||
|
||||
_m1.lookAt( _target, _position, this.up );
|
||||
|
||||
}
|
||||
|
||||
this.quaternion.setFromRotationMatrix( _m1 );
|
||||
|
||||
if ( parent ) {
|
||||
|
||||
_m1.extractRotation( parent.matrixWorld );
|
||||
_q1.setFromRotationMatrix( _m1 );
|
||||
this.quaternion.premultiply( _q1.invert() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
add( object ) {
|
||||
|
||||
if ( arguments.length > 1 ) {
|
||||
|
||||
for ( let i = 0; i < arguments.length; i ++ ) {
|
||||
|
||||
this.add( arguments[ i ] );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
if ( object === this ) {
|
||||
|
||||
console.error( 'THREE.Object3D.add: object can\'t be added as a child of itself.', object );
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
if ( object && object.isObject3D ) {
|
||||
|
||||
if ( object.parent !== null ) {
|
||||
|
||||
object.parent.remove( object );
|
||||
|
||||
}
|
||||
|
||||
object.parent = this;
|
||||
this.children.push( object );
|
||||
|
||||
object.dispatchEvent( _addedEvent );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'THREE.Object3D.add: object not an instance of THREE.Object3D.', object );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
remove( object ) {
|
||||
|
||||
if ( arguments.length > 1 ) {
|
||||
|
||||
for ( let i = 0; i < arguments.length; i ++ ) {
|
||||
|
||||
this.remove( arguments[ i ] );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
const index = this.children.indexOf( object );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
object.parent = null;
|
||||
this.children.splice( index, 1 );
|
||||
|
||||
object.dispatchEvent( _removedEvent );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
removeFromParent() {
|
||||
|
||||
const parent = this.parent;
|
||||
|
||||
if ( parent !== null ) {
|
||||
|
||||
parent.remove( this );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
||||
return this.remove( ... this.children );
|
||||
|
||||
}
|
||||
|
||||
attach( object ) {
|
||||
|
||||
// adds object as a child of this, while maintaining the object's world transform
|
||||
|
||||
// Note: This method does not support scene graphs having non-uniformly-scaled nodes(s)
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
_m1.copy( this.matrixWorld ).invert();
|
||||
|
||||
if ( object.parent !== null ) {
|
||||
|
||||
object.parent.updateWorldMatrix( true, false );
|
||||
|
||||
_m1.multiply( object.parent.matrixWorld );
|
||||
|
||||
}
|
||||
|
||||
object.applyMatrix4( _m1 );
|
||||
|
||||
this.add( object );
|
||||
|
||||
object.updateWorldMatrix( false, true );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getObjectById( id ) {
|
||||
|
||||
return this.getObjectByProperty( 'id', id );
|
||||
|
||||
}
|
||||
|
||||
getObjectByName( name ) {
|
||||
|
||||
return this.getObjectByProperty( 'name', name );
|
||||
|
||||
}
|
||||
|
||||
getObjectByProperty( name, value ) {
|
||||
|
||||
if ( this[ name ] === value ) return this;
|
||||
|
||||
for ( let i = 0, l = this.children.length; i < l; i ++ ) {
|
||||
|
||||
const child = this.children[ i ];
|
||||
const object = child.getObjectByProperty( name, value );
|
||||
|
||||
if ( object !== undefined ) {
|
||||
|
||||
return object;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
}
|
||||
|
||||
getObjectsByProperty( name, value ) {
|
||||
|
||||
let result = [];
|
||||
|
||||
if ( this[ name ] === value ) result.push( this );
|
||||
|
||||
for ( let i = 0, l = this.children.length; i < l; i ++ ) {
|
||||
|
||||
const childResult = this.children[ i ].getObjectsByProperty( name, value );
|
||||
|
||||
if ( childResult.length > 0 ) {
|
||||
|
||||
result = result.concat( childResult );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
getWorldPosition( target ) {
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
return target.setFromMatrixPosition( this.matrixWorld );
|
||||
|
||||
}
|
||||
|
||||
getWorldQuaternion( target ) {
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
this.matrixWorld.decompose( _position, target, _scale );
|
||||
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
getWorldScale( target ) {
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
this.matrixWorld.decompose( _position, _quaternion, target );
|
||||
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
getWorldDirection( target ) {
|
||||
|
||||
this.updateWorldMatrix( true, false );
|
||||
|
||||
const e = this.matrixWorld.elements;
|
||||
|
||||
return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
|
||||
|
||||
}
|
||||
|
||||
raycast( /* raycaster, intersects */ ) {}
|
||||
|
||||
traverse( callback ) {
|
||||
|
||||
callback( this );
|
||||
|
||||
const children = this.children;
|
||||
|
||||
for ( let i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
children[ i ].traverse( callback );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
traverseVisible( callback ) {
|
||||
|
||||
if ( this.visible === false ) return;
|
||||
|
||||
callback( this );
|
||||
|
||||
const children = this.children;
|
||||
|
||||
for ( let i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
children[ i ].traverseVisible( callback );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
traverseAncestors( callback ) {
|
||||
|
||||
const parent = this.parent;
|
||||
|
||||
if ( parent !== null ) {
|
||||
|
||||
callback( parent );
|
||||
|
||||
parent.traverseAncestors( callback );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateMatrix() {
|
||||
|
||||
this.matrix.compose( this.position, this.quaternion, this.scale );
|
||||
|
||||
this.matrixWorldNeedsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld( force ) {
|
||||
|
||||
if ( this.matrixAutoUpdate ) this.updateMatrix();
|
||||
|
||||
if ( this.matrixWorldNeedsUpdate || force ) {
|
||||
|
||||
if ( this.parent === null ) {
|
||||
|
||||
this.matrixWorld.copy( this.matrix );
|
||||
|
||||
} else {
|
||||
|
||||
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
|
||||
|
||||
}
|
||||
|
||||
this.matrixWorldNeedsUpdate = false;
|
||||
|
||||
force = true;
|
||||
|
||||
}
|
||||
|
||||
// update children
|
||||
|
||||
const children = this.children;
|
||||
|
||||
for ( let i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
const child = children[ i ];
|
||||
|
||||
if ( child.matrixWorldAutoUpdate === true || force === true ) {
|
||||
|
||||
child.updateMatrixWorld( force );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateWorldMatrix( updateParents, updateChildren ) {
|
||||
|
||||
const parent = this.parent;
|
||||
|
||||
if ( updateParents === true && parent !== null && parent.matrixWorldAutoUpdate === true ) {
|
||||
|
||||
parent.updateWorldMatrix( true, false );
|
||||
|
||||
}
|
||||
|
||||
if ( this.matrixAutoUpdate ) this.updateMatrix();
|
||||
|
||||
if ( this.parent === null ) {
|
||||
|
||||
this.matrixWorld.copy( this.matrix );
|
||||
|
||||
} else {
|
||||
|
||||
this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
|
||||
|
||||
}
|
||||
|
||||
// update children
|
||||
|
||||
if ( updateChildren === true ) {
|
||||
|
||||
const children = this.children;
|
||||
|
||||
for ( let i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
const child = children[ i ];
|
||||
|
||||
if ( child.matrixWorldAutoUpdate === true ) {
|
||||
|
||||
child.updateWorldMatrix( false, true );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
toJSON( meta ) {
|
||||
|
||||
// meta is a string when called from JSON.stringify
|
||||
const isRootObject = ( meta === undefined || typeof meta === 'string' );
|
||||
|
||||
const output = {};
|
||||
|
||||
// meta is a hash used to collect geometries, materials.
|
||||
// not providing it implies that this is the root object
|
||||
// being serialized.
|
||||
if ( isRootObject ) {
|
||||
|
||||
// initialize meta obj
|
||||
meta = {
|
||||
geometries: {},
|
||||
materials: {},
|
||||
textures: {},
|
||||
images: {},
|
||||
shapes: {},
|
||||
skeletons: {},
|
||||
animations: {},
|
||||
nodes: {}
|
||||
};
|
||||
|
||||
output.metadata = {
|
||||
version: 4.6,
|
||||
type: 'Object',
|
||||
generator: 'Object3D.toJSON'
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// standard Object3D serialization
|
||||
|
||||
const object = {};
|
||||
|
||||
object.uuid = this.uuid;
|
||||
object.type = this.type;
|
||||
|
||||
if ( this.name !== '' ) object.name = this.name;
|
||||
if ( this.castShadow === true ) object.castShadow = true;
|
||||
if ( this.receiveShadow === true ) object.receiveShadow = true;
|
||||
if ( this.visible === false ) object.visible = false;
|
||||
if ( this.frustumCulled === false ) object.frustumCulled = false;
|
||||
if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
|
||||
if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData;
|
||||
|
||||
object.layers = this.layers.mask;
|
||||
object.matrix = this.matrix.toArray();
|
||||
object.up = this.up.toArray();
|
||||
|
||||
if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;
|
||||
|
||||
// object specific properties
|
||||
|
||||
if ( this.isInstancedMesh ) {
|
||||
|
||||
object.type = 'InstancedMesh';
|
||||
object.count = this.count;
|
||||
object.instanceMatrix = this.instanceMatrix.toJSON();
|
||||
if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function serialize( library, element ) {
|
||||
|
||||
if ( library[ element.uuid ] === undefined ) {
|
||||
|
||||
library[ element.uuid ] = element.toJSON( meta );
|
||||
|
||||
}
|
||||
|
||||
return element.uuid;
|
||||
|
||||
}
|
||||
|
||||
if ( this.isScene ) {
|
||||
|
||||
if ( this.background ) {
|
||||
|
||||
if ( this.background.isColor ) {
|
||||
|
||||
object.background = this.background.toJSON();
|
||||
|
||||
} else if ( this.background.isTexture ) {
|
||||
|
||||
object.background = this.background.toJSON( meta ).uuid;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) {
|
||||
|
||||
object.environment = this.environment.toJSON( meta ).uuid;
|
||||
|
||||
}
|
||||
|
||||
} else if ( this.isMesh || this.isLine || this.isPoints ) {
|
||||
|
||||
object.geometry = serialize( meta.geometries, this.geometry );
|
||||
|
||||
const parameters = this.geometry.parameters;
|
||||
|
||||
if ( parameters !== undefined && parameters.shapes !== undefined ) {
|
||||
|
||||
const shapes = parameters.shapes;
|
||||
|
||||
if ( Array.isArray( shapes ) ) {
|
||||
|
||||
for ( let i = 0, l = shapes.length; i < l; i ++ ) {
|
||||
|
||||
const shape = shapes[ i ];
|
||||
|
||||
serialize( meta.shapes, shape );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
serialize( meta.shapes, shapes );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( this.isSkinnedMesh ) {
|
||||
|
||||
object.bindMode = this.bindMode;
|
||||
object.bindMatrix = this.bindMatrix.toArray();
|
||||
|
||||
if ( this.skeleton !== undefined ) {
|
||||
|
||||
serialize( meta.skeletons, this.skeleton );
|
||||
|
||||
object.skeleton = this.skeleton.uuid;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( this.material !== undefined ) {
|
||||
|
||||
if ( Array.isArray( this.material ) ) {
|
||||
|
||||
const uuids = [];
|
||||
|
||||
for ( let i = 0, l = this.material.length; i < l; i ++ ) {
|
||||
|
||||
uuids.push( serialize( meta.materials, this.material[ i ] ) );
|
||||
|
||||
}
|
||||
|
||||
object.material = uuids;
|
||||
|
||||
} else {
|
||||
|
||||
object.material = serialize( meta.materials, this.material );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if ( this.children.length > 0 ) {
|
||||
|
||||
object.children = [];
|
||||
|
||||
for ( let i = 0; i < this.children.length; i ++ ) {
|
||||
|
||||
object.children.push( this.children[ i ].toJSON( meta ).object );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if ( this.animations.length > 0 ) {
|
||||
|
||||
object.animations = [];
|
||||
|
||||
for ( let i = 0; i < this.animations.length; i ++ ) {
|
||||
|
||||
const animation = this.animations[ i ];
|
||||
|
||||
object.animations.push( serialize( meta.animations, animation ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( isRootObject ) {
|
||||
|
||||
const geometries = extractFromCache( meta.geometries );
|
||||
const materials = extractFromCache( meta.materials );
|
||||
const textures = extractFromCache( meta.textures );
|
||||
const images = extractFromCache( meta.images );
|
||||
const shapes = extractFromCache( meta.shapes );
|
||||
const skeletons = extractFromCache( meta.skeletons );
|
||||
const animations = extractFromCache( meta.animations );
|
||||
const nodes = extractFromCache( meta.nodes );
|
||||
|
||||
if ( geometries.length > 0 ) output.geometries = geometries;
|
||||
if ( materials.length > 0 ) output.materials = materials;
|
||||
if ( textures.length > 0 ) output.textures = textures;
|
||||
if ( images.length > 0 ) output.images = images;
|
||||
if ( shapes.length > 0 ) output.shapes = shapes;
|
||||
if ( skeletons.length > 0 ) output.skeletons = skeletons;
|
||||
if ( animations.length > 0 ) output.animations = animations;
|
||||
if ( nodes.length > 0 ) output.nodes = nodes;
|
||||
|
||||
}
|
||||
|
||||
output.object = object;
|
||||
|
||||
return output;
|
||||
|
||||
// extract data from the cache hash
|
||||
// remove metadata on each item
|
||||
// and return as array
|
||||
function extractFromCache( cache ) {
|
||||
|
||||
const values = [];
|
||||
for ( const key in cache ) {
|
||||
|
||||
const data = cache[ key ];
|
||||
delete data.metadata;
|
||||
values.push( data );
|
||||
|
||||
}
|
||||
|
||||
return values;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
clone( recursive ) {
|
||||
|
||||
return new this.constructor().copy( this, recursive );
|
||||
|
||||
}
|
||||
|
||||
copy( source, recursive = true ) {
|
||||
|
||||
this.name = source.name;
|
||||
|
||||
this.up.copy( source.up );
|
||||
|
||||
this.position.copy( source.position );
|
||||
this.rotation.order = source.rotation.order;
|
||||
this.quaternion.copy( source.quaternion );
|
||||
this.scale.copy( source.scale );
|
||||
|
||||
this.matrix.copy( source.matrix );
|
||||
this.matrixWorld.copy( source.matrixWorld );
|
||||
|
||||
this.matrixAutoUpdate = source.matrixAutoUpdate;
|
||||
this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
|
||||
|
||||
this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate;
|
||||
|
||||
this.layers.mask = source.layers.mask;
|
||||
this.visible = source.visible;
|
||||
|
||||
this.castShadow = source.castShadow;
|
||||
this.receiveShadow = source.receiveShadow;
|
||||
|
||||
this.frustumCulled = source.frustumCulled;
|
||||
this.renderOrder = source.renderOrder;
|
||||
|
||||
this.animations = source.animations.slice();
|
||||
|
||||
this.userData = JSON.parse( JSON.stringify( source.userData ) );
|
||||
|
||||
if ( recursive === true ) {
|
||||
|
||||
for ( let i = 0; i < source.children.length; i ++ ) {
|
||||
|
||||
const child = source.children[ i ];
|
||||
this.add( child.clone() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 );
|
||||
Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true;
|
||||
Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true;
|
||||
|
||||
export { Object3D };
|
||||
110
network-visualization/node_modules/three/src/core/Raycaster.js
generated
vendored
Normal file
110
network-visualization/node_modules/three/src/core/Raycaster.js
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
import { Ray } from '../math/Ray.js';
|
||||
import { Layers } from './Layers.js';
|
||||
|
||||
class Raycaster {
|
||||
|
||||
constructor( origin, direction, near = 0, far = Infinity ) {
|
||||
|
||||
this.ray = new Ray( origin, direction );
|
||||
// direction is assumed to be normalized (for accurate distance calculations)
|
||||
|
||||
this.near = near;
|
||||
this.far = far;
|
||||
this.camera = null;
|
||||
this.layers = new Layers();
|
||||
|
||||
this.params = {
|
||||
Mesh: {},
|
||||
Line: { threshold: 1 },
|
||||
LOD: {},
|
||||
Points: { threshold: 1 },
|
||||
Sprite: {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
set( origin, direction ) {
|
||||
|
||||
// direction is assumed to be normalized (for accurate distance calculations)
|
||||
|
||||
this.ray.set( origin, direction );
|
||||
|
||||
}
|
||||
|
||||
setFromCamera( coords, camera ) {
|
||||
|
||||
if ( camera.isPerspectiveCamera ) {
|
||||
|
||||
this.ray.origin.setFromMatrixPosition( camera.matrixWorld );
|
||||
this.ray.direction.set( coords.x, coords.y, 0.5 ).unproject( camera ).sub( this.ray.origin ).normalize();
|
||||
this.camera = camera;
|
||||
|
||||
} else if ( camera.isOrthographicCamera ) {
|
||||
|
||||
this.ray.origin.set( coords.x, coords.y, ( camera.near + camera.far ) / ( camera.near - camera.far ) ).unproject( camera ); // set origin in plane of camera
|
||||
this.ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
|
||||
this.camera = camera;
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'THREE.Raycaster: Unsupported camera type: ' + camera.type );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
intersectObject( object, recursive = true, intersects = [] ) {
|
||||
|
||||
intersectObject( object, this, intersects, recursive );
|
||||
|
||||
intersects.sort( ascSort );
|
||||
|
||||
return intersects;
|
||||
|
||||
}
|
||||
|
||||
intersectObjects( objects, recursive = true, intersects = [] ) {
|
||||
|
||||
for ( let i = 0, l = objects.length; i < l; i ++ ) {
|
||||
|
||||
intersectObject( objects[ i ], this, intersects, recursive );
|
||||
|
||||
}
|
||||
|
||||
intersects.sort( ascSort );
|
||||
|
||||
return intersects;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ascSort( a, b ) {
|
||||
|
||||
return a.distance - b.distance;
|
||||
|
||||
}
|
||||
|
||||
function intersectObject( object, raycaster, intersects, recursive ) {
|
||||
|
||||
if ( object.layers.test( raycaster.layers ) ) {
|
||||
|
||||
object.raycast( raycaster, intersects );
|
||||
|
||||
}
|
||||
|
||||
if ( recursive === true ) {
|
||||
|
||||
const children = object.children;
|
||||
|
||||
for ( let i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
intersectObject( children[ i ], raycaster, intersects, true );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Raycaster };
|
||||
131
network-visualization/node_modules/three/src/core/RenderTarget.js
generated
vendored
Normal file
131
network-visualization/node_modules/three/src/core/RenderTarget.js
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
import { EventDispatcher } from './EventDispatcher.js';
|
||||
import { Texture } from '../textures/Texture.js';
|
||||
import { LinearFilter, NoColorSpace, SRGBColorSpace, sRGBEncoding } from '../constants.js';
|
||||
import { Vector4 } from '../math/Vector4.js';
|
||||
import { Source } from '../textures/Source.js';
|
||||
import { warnOnce } from '../utils.js';
|
||||
|
||||
/*
|
||||
In options, we can specify:
|
||||
* Texture parameters for an auto-generated target texture
|
||||
* depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
|
||||
*/
|
||||
class RenderTarget extends EventDispatcher {
|
||||
|
||||
constructor( width = 1, height = 1, options = {} ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isRenderTarget = true;
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.depth = 1;
|
||||
|
||||
this.scissor = new Vector4( 0, 0, width, height );
|
||||
this.scissorTest = false;
|
||||
|
||||
this.viewport = new Vector4( 0, 0, width, height );
|
||||
|
||||
const image = { width: width, height: height, depth: 1 };
|
||||
|
||||
if ( options.encoding !== undefined ) {
|
||||
|
||||
// @deprecated, r152
|
||||
warnOnce( 'THREE.WebGLRenderTarget: option.encoding has been replaced by option.colorSpace.' );
|
||||
options.colorSpace = options.encoding === sRGBEncoding ? SRGBColorSpace : NoColorSpace;
|
||||
|
||||
}
|
||||
|
||||
options = Object.assign( {
|
||||
generateMipmaps: false,
|
||||
internalFormat: null,
|
||||
minFilter: LinearFilter,
|
||||
depthBuffer: true,
|
||||
stencilBuffer: false,
|
||||
depthTexture: null,
|
||||
samples: 0
|
||||
}, options );
|
||||
|
||||
this.texture = new Texture( image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace );
|
||||
this.texture.isRenderTargetTexture = true;
|
||||
|
||||
this.texture.flipY = false;
|
||||
this.texture.generateMipmaps = options.generateMipmaps;
|
||||
this.texture.internalFormat = options.internalFormat;
|
||||
|
||||
this.depthBuffer = options.depthBuffer;
|
||||
this.stencilBuffer = options.stencilBuffer;
|
||||
|
||||
this.depthTexture = options.depthTexture;
|
||||
|
||||
this.samples = options.samples;
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height, depth = 1 ) {
|
||||
|
||||
if ( this.width !== width || this.height !== height || this.depth !== depth ) {
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.depth = depth;
|
||||
|
||||
this.texture.image.width = width;
|
||||
this.texture.image.height = height;
|
||||
this.texture.image.depth = depth;
|
||||
|
||||
this.dispose();
|
||||
|
||||
}
|
||||
|
||||
this.viewport.set( 0, 0, width, height );
|
||||
this.scissor.set( 0, 0, width, height );
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
this.width = source.width;
|
||||
this.height = source.height;
|
||||
this.depth = source.depth;
|
||||
|
||||
this.scissor.copy( source.scissor );
|
||||
this.scissorTest = source.scissorTest;
|
||||
|
||||
this.viewport.copy( source.viewport );
|
||||
|
||||
this.texture = source.texture.clone();
|
||||
this.texture.isRenderTargetTexture = true;
|
||||
|
||||
// ensure image object is not shared, see #20328
|
||||
|
||||
const image = Object.assign( {}, source.texture.image );
|
||||
this.texture.source = new Source( image );
|
||||
|
||||
this.depthBuffer = source.depthBuffer;
|
||||
this.stencilBuffer = source.stencilBuffer;
|
||||
|
||||
if ( source.depthTexture !== null ) this.depthTexture = source.depthTexture.clone();
|
||||
|
||||
this.samples = source.samples;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.dispatchEvent( { type: 'dispose' } );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { RenderTarget };
|
||||
17
network-visualization/node_modules/three/src/core/Uniform.js
generated
vendored
Normal file
17
network-visualization/node_modules/three/src/core/Uniform.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
class Uniform {
|
||||
|
||||
constructor( value ) {
|
||||
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return new Uniform( this.value.clone === undefined ? this.value : this.value.clone() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Uniform };
|
||||
92
network-visualization/node_modules/three/src/core/UniformsGroup.js
generated
vendored
Normal file
92
network-visualization/node_modules/three/src/core/UniformsGroup.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import { EventDispatcher } from './EventDispatcher.js';
|
||||
import { StaticDrawUsage } from '../constants.js';
|
||||
|
||||
let _id = 0;
|
||||
|
||||
class UniformsGroup extends EventDispatcher {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
this.isUniformsGroup = true;
|
||||
|
||||
Object.defineProperty( this, 'id', { value: _id ++ } );
|
||||
|
||||
this.name = '';
|
||||
|
||||
this.usage = StaticDrawUsage;
|
||||
this.uniforms = [];
|
||||
|
||||
}
|
||||
|
||||
add( uniform ) {
|
||||
|
||||
this.uniforms.push( uniform );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
remove( uniform ) {
|
||||
|
||||
const index = this.uniforms.indexOf( uniform );
|
||||
|
||||
if ( index !== - 1 ) this.uniforms.splice( index, 1 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setName( name ) {
|
||||
|
||||
this.name = name;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
setUsage( value ) {
|
||||
|
||||
this.usage = value;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.dispatchEvent( { type: 'dispose' } );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
this.name = source.name;
|
||||
this.usage = source.usage;
|
||||
|
||||
const uniformsSource = source.uniforms;
|
||||
|
||||
this.uniforms.length = 0;
|
||||
|
||||
for ( let i = 0, l = uniformsSource.length; i < l; i ++ ) {
|
||||
|
||||
this.uniforms.push( uniformsSource[ i ].clone() );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { UniformsGroup };
|
||||
176
network-visualization/node_modules/three/src/extras/DataUtils.js
generated
vendored
Normal file
176
network-visualization/node_modules/three/src/extras/DataUtils.js
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
import { clamp } from '../math/MathUtils.js';
|
||||
|
||||
// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
|
||||
|
||||
const _tables = /*@__PURE__*/ _generateTables();
|
||||
|
||||
function _generateTables() {
|
||||
|
||||
// float32 to float16 helpers
|
||||
|
||||
const buffer = new ArrayBuffer( 4 );
|
||||
const floatView = new Float32Array( buffer );
|
||||
const uint32View = new Uint32Array( buffer );
|
||||
|
||||
const baseTable = new Uint32Array( 512 );
|
||||
const shiftTable = new Uint32Array( 512 );
|
||||
|
||||
for ( let i = 0; i < 256; ++ i ) {
|
||||
|
||||
const e = i - 127;
|
||||
|
||||
// very small number (0, -0)
|
||||
|
||||
if ( e < - 27 ) {
|
||||
|
||||
baseTable[ i ] = 0x0000;
|
||||
baseTable[ i | 0x100 ] = 0x8000;
|
||||
shiftTable[ i ] = 24;
|
||||
shiftTable[ i | 0x100 ] = 24;
|
||||
|
||||
// small number (denorm)
|
||||
|
||||
} else if ( e < - 14 ) {
|
||||
|
||||
baseTable[ i ] = 0x0400 >> ( - e - 14 );
|
||||
baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000;
|
||||
shiftTable[ i ] = - e - 1;
|
||||
shiftTable[ i | 0x100 ] = - e - 1;
|
||||
|
||||
// normal number
|
||||
|
||||
} else if ( e <= 15 ) {
|
||||
|
||||
baseTable[ i ] = ( e + 15 ) << 10;
|
||||
baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000;
|
||||
shiftTable[ i ] = 13;
|
||||
shiftTable[ i | 0x100 ] = 13;
|
||||
|
||||
// large number (Infinity, -Infinity)
|
||||
|
||||
} else if ( e < 128 ) {
|
||||
|
||||
baseTable[ i ] = 0x7c00;
|
||||
baseTable[ i | 0x100 ] = 0xfc00;
|
||||
shiftTable[ i ] = 24;
|
||||
shiftTable[ i | 0x100 ] = 24;
|
||||
|
||||
// stay (NaN, Infinity, -Infinity)
|
||||
|
||||
} else {
|
||||
|
||||
baseTable[ i ] = 0x7c00;
|
||||
baseTable[ i | 0x100 ] = 0xfc00;
|
||||
shiftTable[ i ] = 13;
|
||||
shiftTable[ i | 0x100 ] = 13;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// float16 to float32 helpers
|
||||
|
||||
const mantissaTable = new Uint32Array( 2048 );
|
||||
const exponentTable = new Uint32Array( 64 );
|
||||
const offsetTable = new Uint32Array( 64 );
|
||||
|
||||
for ( let i = 1; i < 1024; ++ i ) {
|
||||
|
||||
let m = i << 13; // zero pad mantissa bits
|
||||
let e = 0; // zero exponent
|
||||
|
||||
// normalized
|
||||
while ( ( m & 0x00800000 ) === 0 ) {
|
||||
|
||||
m <<= 1;
|
||||
e -= 0x00800000; // decrement exponent
|
||||
|
||||
}
|
||||
|
||||
m &= ~ 0x00800000; // clear leading 1 bit
|
||||
e += 0x38800000; // adjust bias
|
||||
|
||||
mantissaTable[ i ] = m | e;
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 1024; i < 2048; ++ i ) {
|
||||
|
||||
mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 );
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 1; i < 31; ++ i ) {
|
||||
|
||||
exponentTable[ i ] = i << 23;
|
||||
|
||||
}
|
||||
|
||||
exponentTable[ 31 ] = 0x47800000;
|
||||
exponentTable[ 32 ] = 0x80000000;
|
||||
|
||||
for ( let i = 33; i < 63; ++ i ) {
|
||||
|
||||
exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 );
|
||||
|
||||
}
|
||||
|
||||
exponentTable[ 63 ] = 0xc7800000;
|
||||
|
||||
for ( let i = 1; i < 64; ++ i ) {
|
||||
|
||||
if ( i !== 32 ) {
|
||||
|
||||
offsetTable[ i ] = 1024;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
floatView: floatView,
|
||||
uint32View: uint32View,
|
||||
baseTable: baseTable,
|
||||
shiftTable: shiftTable,
|
||||
mantissaTable: mantissaTable,
|
||||
exponentTable: exponentTable,
|
||||
offsetTable: offsetTable
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// float32 to float16
|
||||
|
||||
function toHalfFloat( val ) {
|
||||
|
||||
if ( Math.abs( val ) > 65504 ) console.warn( 'THREE.DataUtils.toHalfFloat(): Value out of range.' );
|
||||
|
||||
val = clamp( val, - 65504, 65504 );
|
||||
|
||||
_tables.floatView[ 0 ] = val;
|
||||
const f = _tables.uint32View[ 0 ];
|
||||
const e = ( f >> 23 ) & 0x1ff;
|
||||
return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] );
|
||||
|
||||
}
|
||||
|
||||
// float16 to float32
|
||||
|
||||
function fromHalfFloat( val ) {
|
||||
|
||||
const m = val >> 10;
|
||||
_tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ];
|
||||
return _tables.floatView[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
const DataUtils = {
|
||||
toHalfFloat: toHalfFloat,
|
||||
fromHalfFloat: fromHalfFloat,
|
||||
};
|
||||
|
||||
export {
|
||||
toHalfFloat,
|
||||
fromHalfFloat,
|
||||
DataUtils
|
||||
};
|
||||
789
network-visualization/node_modules/three/src/extras/Earcut.js
generated
vendored
Normal file
789
network-visualization/node_modules/three/src/extras/Earcut.js
generated
vendored
Normal file
@@ -0,0 +1,789 @@
|
||||
/**
|
||||
* Port from https://github.com/mapbox/earcut (v2.2.4)
|
||||
*/
|
||||
|
||||
const Earcut = {
|
||||
|
||||
triangulate: function ( data, holeIndices, dim = 2 ) {
|
||||
|
||||
const hasHoles = holeIndices && holeIndices.length;
|
||||
const outerLen = hasHoles ? holeIndices[ 0 ] * dim : data.length;
|
||||
let outerNode = linkedList( data, 0, outerLen, dim, true );
|
||||
const triangles = [];
|
||||
|
||||
if ( ! outerNode || outerNode.next === outerNode.prev ) return triangles;
|
||||
|
||||
let minX, minY, maxX, maxY, x, y, invSize;
|
||||
|
||||
if ( hasHoles ) outerNode = eliminateHoles( data, holeIndices, outerNode, dim );
|
||||
|
||||
// if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
|
||||
if ( data.length > 80 * dim ) {
|
||||
|
||||
minX = maxX = data[ 0 ];
|
||||
minY = maxY = data[ 1 ];
|
||||
|
||||
for ( let i = dim; i < outerLen; i += dim ) {
|
||||
|
||||
x = data[ i ];
|
||||
y = data[ i + 1 ];
|
||||
if ( x < minX ) minX = x;
|
||||
if ( y < minY ) minY = y;
|
||||
if ( x > maxX ) maxX = x;
|
||||
if ( y > maxY ) maxY = y;
|
||||
|
||||
}
|
||||
|
||||
// minX, minY and invSize are later used to transform coords into integers for z-order calculation
|
||||
invSize = Math.max( maxX - minX, maxY - minY );
|
||||
invSize = invSize !== 0 ? 32767 / invSize : 0;
|
||||
|
||||
}
|
||||
|
||||
earcutLinked( outerNode, triangles, dim, minX, minY, invSize, 0 );
|
||||
|
||||
return triangles;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// create a circular doubly linked list from polygon points in the specified winding order
|
||||
function linkedList( data, start, end, dim, clockwise ) {
|
||||
|
||||
let i, last;
|
||||
|
||||
if ( clockwise === ( signedArea( data, start, end, dim ) > 0 ) ) {
|
||||
|
||||
for ( i = start; i < end; i += dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );
|
||||
|
||||
} else {
|
||||
|
||||
for ( i = end - dim; i >= start; i -= dim ) last = insertNode( i, data[ i ], data[ i + 1 ], last );
|
||||
|
||||
}
|
||||
|
||||
if ( last && equals( last, last.next ) ) {
|
||||
|
||||
removeNode( last );
|
||||
last = last.next;
|
||||
|
||||
}
|
||||
|
||||
return last;
|
||||
|
||||
}
|
||||
|
||||
// eliminate colinear or duplicate points
|
||||
function filterPoints( start, end ) {
|
||||
|
||||
if ( ! start ) return start;
|
||||
if ( ! end ) end = start;
|
||||
|
||||
let p = start,
|
||||
again;
|
||||
do {
|
||||
|
||||
again = false;
|
||||
|
||||
if ( ! p.steiner && ( equals( p, p.next ) || area( p.prev, p, p.next ) === 0 ) ) {
|
||||
|
||||
removeNode( p );
|
||||
p = end = p.prev;
|
||||
if ( p === p.next ) break;
|
||||
again = true;
|
||||
|
||||
} else {
|
||||
|
||||
p = p.next;
|
||||
|
||||
}
|
||||
|
||||
} while ( again || p !== end );
|
||||
|
||||
return end;
|
||||
|
||||
}
|
||||
|
||||
// main ear slicing loop which triangulates a polygon (given as a linked list)
|
||||
function earcutLinked( ear, triangles, dim, minX, minY, invSize, pass ) {
|
||||
|
||||
if ( ! ear ) return;
|
||||
|
||||
// interlink polygon nodes in z-order
|
||||
if ( ! pass && invSize ) indexCurve( ear, minX, minY, invSize );
|
||||
|
||||
let stop = ear,
|
||||
prev, next;
|
||||
|
||||
// iterate through ears, slicing them one by one
|
||||
while ( ear.prev !== ear.next ) {
|
||||
|
||||
prev = ear.prev;
|
||||
next = ear.next;
|
||||
|
||||
if ( invSize ? isEarHashed( ear, minX, minY, invSize ) : isEar( ear ) ) {
|
||||
|
||||
// cut off the triangle
|
||||
triangles.push( prev.i / dim | 0 );
|
||||
triangles.push( ear.i / dim | 0 );
|
||||
triangles.push( next.i / dim | 0 );
|
||||
|
||||
removeNode( ear );
|
||||
|
||||
// skipping the next vertex leads to less sliver triangles
|
||||
ear = next.next;
|
||||
stop = next.next;
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
ear = next;
|
||||
|
||||
// if we looped through the whole remaining polygon and can't find any more ears
|
||||
if ( ear === stop ) {
|
||||
|
||||
// try filtering points and slicing again
|
||||
if ( ! pass ) {
|
||||
|
||||
earcutLinked( filterPoints( ear ), triangles, dim, minX, minY, invSize, 1 );
|
||||
|
||||
// if this didn't work, try curing all small self-intersections locally
|
||||
|
||||
} else if ( pass === 1 ) {
|
||||
|
||||
ear = cureLocalIntersections( filterPoints( ear ), triangles, dim );
|
||||
earcutLinked( ear, triangles, dim, minX, minY, invSize, 2 );
|
||||
|
||||
// as a last resort, try splitting the remaining polygon into two
|
||||
|
||||
} else if ( pass === 2 ) {
|
||||
|
||||
splitEarcut( ear, triangles, dim, minX, minY, invSize );
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check whether a polygon node forms a valid ear with adjacent nodes
|
||||
function isEar( ear ) {
|
||||
|
||||
const a = ear.prev,
|
||||
b = ear,
|
||||
c = ear.next;
|
||||
|
||||
if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear
|
||||
|
||||
// now make sure we don't have other points inside the potential ear
|
||||
const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
|
||||
|
||||
// triangle bbox; min & max are calculated like this for speed
|
||||
const x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ),
|
||||
y0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ),
|
||||
x1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ),
|
||||
y1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy );
|
||||
|
||||
let p = c.next;
|
||||
while ( p !== a ) {
|
||||
|
||||
if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&
|
||||
pointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) &&
|
||||
area( p.prev, p, p.next ) >= 0 ) return false;
|
||||
p = p.next;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function isEarHashed( ear, minX, minY, invSize ) {
|
||||
|
||||
const a = ear.prev,
|
||||
b = ear,
|
||||
c = ear.next;
|
||||
|
||||
if ( area( a, b, c ) >= 0 ) return false; // reflex, can't be an ear
|
||||
|
||||
const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
|
||||
|
||||
// triangle bbox; min & max are calculated like this for speed
|
||||
const x0 = ax < bx ? ( ax < cx ? ax : cx ) : ( bx < cx ? bx : cx ),
|
||||
y0 = ay < by ? ( ay < cy ? ay : cy ) : ( by < cy ? by : cy ),
|
||||
x1 = ax > bx ? ( ax > cx ? ax : cx ) : ( bx > cx ? bx : cx ),
|
||||
y1 = ay > by ? ( ay > cy ? ay : cy ) : ( by > cy ? by : cy );
|
||||
|
||||
// z-order range for the current triangle bbox;
|
||||
const minZ = zOrder( x0, y0, minX, minY, invSize ),
|
||||
maxZ = zOrder( x1, y1, minX, minY, invSize );
|
||||
|
||||
let p = ear.prevZ,
|
||||
n = ear.nextZ;
|
||||
|
||||
// look for points inside the triangle in both directions
|
||||
while ( p && p.z >= minZ && n && n.z <= maxZ ) {
|
||||
|
||||
if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
|
||||
pointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false;
|
||||
p = p.prevZ;
|
||||
|
||||
if ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
|
||||
pointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false;
|
||||
n = n.nextZ;
|
||||
|
||||
}
|
||||
|
||||
// look for remaining points in decreasing z-order
|
||||
while ( p && p.z >= minZ ) {
|
||||
|
||||
if ( p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&
|
||||
pointInTriangle( ax, ay, bx, by, cx, cy, p.x, p.y ) && area( p.prev, p, p.next ) >= 0 ) return false;
|
||||
p = p.prevZ;
|
||||
|
||||
}
|
||||
|
||||
// look for remaining points in increasing z-order
|
||||
while ( n && n.z <= maxZ ) {
|
||||
|
||||
if ( n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&
|
||||
pointInTriangle( ax, ay, bx, by, cx, cy, n.x, n.y ) && area( n.prev, n, n.next ) >= 0 ) return false;
|
||||
n = n.nextZ;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// go through all polygon nodes and cure small local self-intersections
|
||||
function cureLocalIntersections( start, triangles, dim ) {
|
||||
|
||||
let p = start;
|
||||
do {
|
||||
|
||||
const a = p.prev,
|
||||
b = p.next.next;
|
||||
|
||||
if ( ! equals( a, b ) && intersects( a, p, p.next, b ) && locallyInside( a, b ) && locallyInside( b, a ) ) {
|
||||
|
||||
triangles.push( a.i / dim | 0 );
|
||||
triangles.push( p.i / dim | 0 );
|
||||
triangles.push( b.i / dim | 0 );
|
||||
|
||||
// remove two nodes involved
|
||||
removeNode( p );
|
||||
removeNode( p.next );
|
||||
|
||||
p = start = b;
|
||||
|
||||
}
|
||||
|
||||
p = p.next;
|
||||
|
||||
} while ( p !== start );
|
||||
|
||||
return filterPoints( p );
|
||||
|
||||
}
|
||||
|
||||
// try splitting polygon into two and triangulate them independently
|
||||
function splitEarcut( start, triangles, dim, minX, minY, invSize ) {
|
||||
|
||||
// look for a valid diagonal that divides the polygon into two
|
||||
let a = start;
|
||||
do {
|
||||
|
||||
let b = a.next.next;
|
||||
while ( b !== a.prev ) {
|
||||
|
||||
if ( a.i !== b.i && isValidDiagonal( a, b ) ) {
|
||||
|
||||
// split the polygon in two by the diagonal
|
||||
let c = splitPolygon( a, b );
|
||||
|
||||
// filter colinear points around the cuts
|
||||
a = filterPoints( a, a.next );
|
||||
c = filterPoints( c, c.next );
|
||||
|
||||
// run earcut on each half
|
||||
earcutLinked( a, triangles, dim, minX, minY, invSize, 0 );
|
||||
earcutLinked( c, triangles, dim, minX, minY, invSize, 0 );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
b = b.next;
|
||||
|
||||
}
|
||||
|
||||
a = a.next;
|
||||
|
||||
} while ( a !== start );
|
||||
|
||||
}
|
||||
|
||||
// link every hole into the outer loop, producing a single-ring polygon without holes
|
||||
function eliminateHoles( data, holeIndices, outerNode, dim ) {
|
||||
|
||||
const queue = [];
|
||||
let i, len, start, end, list;
|
||||
|
||||
for ( i = 0, len = holeIndices.length; i < len; i ++ ) {
|
||||
|
||||
start = holeIndices[ i ] * dim;
|
||||
end = i < len - 1 ? holeIndices[ i + 1 ] * dim : data.length;
|
||||
list = linkedList( data, start, end, dim, false );
|
||||
if ( list === list.next ) list.steiner = true;
|
||||
queue.push( getLeftmost( list ) );
|
||||
|
||||
}
|
||||
|
||||
queue.sort( compareX );
|
||||
|
||||
// process holes from left to right
|
||||
for ( i = 0; i < queue.length; i ++ ) {
|
||||
|
||||
outerNode = eliminateHole( queue[ i ], outerNode );
|
||||
|
||||
}
|
||||
|
||||
return outerNode;
|
||||
|
||||
}
|
||||
|
||||
function compareX( a, b ) {
|
||||
|
||||
return a.x - b.x;
|
||||
|
||||
}
|
||||
|
||||
// find a bridge between vertices that connects hole with an outer ring and link it
|
||||
function eliminateHole( hole, outerNode ) {
|
||||
|
||||
const bridge = findHoleBridge( hole, outerNode );
|
||||
if ( ! bridge ) {
|
||||
|
||||
return outerNode;
|
||||
|
||||
}
|
||||
|
||||
const bridgeReverse = splitPolygon( bridge, hole );
|
||||
|
||||
// filter collinear points around the cuts
|
||||
filterPoints( bridgeReverse, bridgeReverse.next );
|
||||
return filterPoints( bridge, bridge.next );
|
||||
|
||||
}
|
||||
|
||||
// David Eberly's algorithm for finding a bridge between hole and outer polygon
|
||||
function findHoleBridge( hole, outerNode ) {
|
||||
|
||||
let p = outerNode,
|
||||
qx = - Infinity,
|
||||
m;
|
||||
|
||||
const hx = hole.x, hy = hole.y;
|
||||
|
||||
// find a segment intersected by a ray from the hole's leftmost point to the left;
|
||||
// segment's endpoint with lesser x will be potential connection point
|
||||
do {
|
||||
|
||||
if ( hy <= p.y && hy >= p.next.y && p.next.y !== p.y ) {
|
||||
|
||||
const x = p.x + ( hy - p.y ) * ( p.next.x - p.x ) / ( p.next.y - p.y );
|
||||
if ( x <= hx && x > qx ) {
|
||||
|
||||
qx = x;
|
||||
m = p.x < p.next.x ? p : p.next;
|
||||
if ( x === hx ) return m; // hole touches outer segment; pick leftmost endpoint
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
p = p.next;
|
||||
|
||||
} while ( p !== outerNode );
|
||||
|
||||
if ( ! m ) return null;
|
||||
|
||||
// look for points inside the triangle of hole point, segment intersection and endpoint;
|
||||
// if there are no points found, we have a valid connection;
|
||||
// otherwise choose the point of the minimum angle with the ray as connection point
|
||||
|
||||
const stop = m,
|
||||
mx = m.x,
|
||||
my = m.y;
|
||||
let tanMin = Infinity, tan;
|
||||
|
||||
p = m;
|
||||
|
||||
do {
|
||||
|
||||
if ( hx >= p.x && p.x >= mx && hx !== p.x &&
|
||||
pointInTriangle( hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y ) ) {
|
||||
|
||||
tan = Math.abs( hy - p.y ) / ( hx - p.x ); // tangential
|
||||
|
||||
if ( locallyInside( p, hole ) && ( tan < tanMin || ( tan === tanMin && ( p.x > m.x || ( p.x === m.x && sectorContainsSector( m, p ) ) ) ) ) ) {
|
||||
|
||||
m = p;
|
||||
tanMin = tan;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
p = p.next;
|
||||
|
||||
} while ( p !== stop );
|
||||
|
||||
return m;
|
||||
|
||||
}
|
||||
|
||||
// whether sector in vertex m contains sector in vertex p in the same coordinates
|
||||
function sectorContainsSector( m, p ) {
|
||||
|
||||
return area( m.prev, m, p.prev ) < 0 && area( p.next, m, m.next ) < 0;
|
||||
|
||||
}
|
||||
|
||||
// interlink polygon nodes in z-order
|
||||
function indexCurve( start, minX, minY, invSize ) {
|
||||
|
||||
let p = start;
|
||||
do {
|
||||
|
||||
if ( p.z === 0 ) p.z = zOrder( p.x, p.y, minX, minY, invSize );
|
||||
p.prevZ = p.prev;
|
||||
p.nextZ = p.next;
|
||||
p = p.next;
|
||||
|
||||
} while ( p !== start );
|
||||
|
||||
p.prevZ.nextZ = null;
|
||||
p.prevZ = null;
|
||||
|
||||
sortLinked( p );
|
||||
|
||||
}
|
||||
|
||||
// Simon Tatham's linked list merge sort algorithm
|
||||
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
|
||||
function sortLinked( list ) {
|
||||
|
||||
let i, p, q, e, tail, numMerges, pSize, qSize,
|
||||
inSize = 1;
|
||||
|
||||
do {
|
||||
|
||||
p = list;
|
||||
list = null;
|
||||
tail = null;
|
||||
numMerges = 0;
|
||||
|
||||
while ( p ) {
|
||||
|
||||
numMerges ++;
|
||||
q = p;
|
||||
pSize = 0;
|
||||
for ( i = 0; i < inSize; i ++ ) {
|
||||
|
||||
pSize ++;
|
||||
q = q.nextZ;
|
||||
if ( ! q ) break;
|
||||
|
||||
}
|
||||
|
||||
qSize = inSize;
|
||||
|
||||
while ( pSize > 0 || ( qSize > 0 && q ) ) {
|
||||
|
||||
if ( pSize !== 0 && ( qSize === 0 || ! q || p.z <= q.z ) ) {
|
||||
|
||||
e = p;
|
||||
p = p.nextZ;
|
||||
pSize --;
|
||||
|
||||
} else {
|
||||
|
||||
e = q;
|
||||
q = q.nextZ;
|
||||
qSize --;
|
||||
|
||||
}
|
||||
|
||||
if ( tail ) tail.nextZ = e;
|
||||
else list = e;
|
||||
|
||||
e.prevZ = tail;
|
||||
tail = e;
|
||||
|
||||
}
|
||||
|
||||
p = q;
|
||||
|
||||
}
|
||||
|
||||
tail.nextZ = null;
|
||||
inSize *= 2;
|
||||
|
||||
} while ( numMerges > 1 );
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
// z-order of a point given coords and inverse of the longer side of data bbox
|
||||
function zOrder( x, y, minX, minY, invSize ) {
|
||||
|
||||
// coords are transformed into non-negative 15-bit integer range
|
||||
x = ( x - minX ) * invSize | 0;
|
||||
y = ( y - minY ) * invSize | 0;
|
||||
|
||||
x = ( x | ( x << 8 ) ) & 0x00FF00FF;
|
||||
x = ( x | ( x << 4 ) ) & 0x0F0F0F0F;
|
||||
x = ( x | ( x << 2 ) ) & 0x33333333;
|
||||
x = ( x | ( x << 1 ) ) & 0x55555555;
|
||||
|
||||
y = ( y | ( y << 8 ) ) & 0x00FF00FF;
|
||||
y = ( y | ( y << 4 ) ) & 0x0F0F0F0F;
|
||||
y = ( y | ( y << 2 ) ) & 0x33333333;
|
||||
y = ( y | ( y << 1 ) ) & 0x55555555;
|
||||
|
||||
return x | ( y << 1 );
|
||||
|
||||
}
|
||||
|
||||
// find the leftmost node of a polygon ring
|
||||
function getLeftmost( start ) {
|
||||
|
||||
let p = start,
|
||||
leftmost = start;
|
||||
do {
|
||||
|
||||
if ( p.x < leftmost.x || ( p.x === leftmost.x && p.y < leftmost.y ) ) leftmost = p;
|
||||
p = p.next;
|
||||
|
||||
} while ( p !== start );
|
||||
|
||||
return leftmost;
|
||||
|
||||
}
|
||||
|
||||
// check if a point lies within a convex triangle
|
||||
function pointInTriangle( ax, ay, bx, by, cx, cy, px, py ) {
|
||||
|
||||
return ( cx - px ) * ( ay - py ) >= ( ax - px ) * ( cy - py ) &&
|
||||
( ax - px ) * ( by - py ) >= ( bx - px ) * ( ay - py ) &&
|
||||
( bx - px ) * ( cy - py ) >= ( cx - px ) * ( by - py );
|
||||
|
||||
}
|
||||
|
||||
// check if a diagonal between two polygon nodes is valid (lies in polygon interior)
|
||||
function isValidDiagonal( a, b ) {
|
||||
|
||||
return a.next.i !== b.i && a.prev.i !== b.i && ! intersectsPolygon( a, b ) && // dones't intersect other edges
|
||||
( locallyInside( a, b ) && locallyInside( b, a ) && middleInside( a, b ) && // locally visible
|
||||
( area( a.prev, a, b.prev ) || area( a, b.prev, b ) ) || // does not create opposite-facing sectors
|
||||
equals( a, b ) && area( a.prev, a, a.next ) > 0 && area( b.prev, b, b.next ) > 0 ); // special zero-length case
|
||||
|
||||
}
|
||||
|
||||
// signed area of a triangle
|
||||
function area( p, q, r ) {
|
||||
|
||||
return ( q.y - p.y ) * ( r.x - q.x ) - ( q.x - p.x ) * ( r.y - q.y );
|
||||
|
||||
}
|
||||
|
||||
// check if two points are equal
|
||||
function equals( p1, p2 ) {
|
||||
|
||||
return p1.x === p2.x && p1.y === p2.y;
|
||||
|
||||
}
|
||||
|
||||
// check if two segments intersect
|
||||
function intersects( p1, q1, p2, q2 ) {
|
||||
|
||||
const o1 = sign( area( p1, q1, p2 ) );
|
||||
const o2 = sign( area( p1, q1, q2 ) );
|
||||
const o3 = sign( area( p2, q2, p1 ) );
|
||||
const o4 = sign( area( p2, q2, q1 ) );
|
||||
|
||||
if ( o1 !== o2 && o3 !== o4 ) return true; // general case
|
||||
|
||||
if ( o1 === 0 && onSegment( p1, p2, q1 ) ) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
|
||||
if ( o2 === 0 && onSegment( p1, q2, q1 ) ) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
|
||||
if ( o3 === 0 && onSegment( p2, p1, q2 ) ) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
|
||||
if ( o4 === 0 && onSegment( p2, q1, q2 ) ) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// for collinear points p, q, r, check if point q lies on segment pr
|
||||
function onSegment( p, q, r ) {
|
||||
|
||||
return q.x <= Math.max( p.x, r.x ) && q.x >= Math.min( p.x, r.x ) && q.y <= Math.max( p.y, r.y ) && q.y >= Math.min( p.y, r.y );
|
||||
|
||||
}
|
||||
|
||||
function sign( num ) {
|
||||
|
||||
return num > 0 ? 1 : num < 0 ? - 1 : 0;
|
||||
|
||||
}
|
||||
|
||||
// check if a polygon diagonal intersects any polygon segments
|
||||
function intersectsPolygon( a, b ) {
|
||||
|
||||
let p = a;
|
||||
do {
|
||||
|
||||
if ( p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&
|
||||
intersects( p, p.next, a, b ) ) return true;
|
||||
p = p.next;
|
||||
|
||||
} while ( p !== a );
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// check if a polygon diagonal is locally inside the polygon
|
||||
function locallyInside( a, b ) {
|
||||
|
||||
return area( a.prev, a, a.next ) < 0 ?
|
||||
area( a, b, a.next ) >= 0 && area( a, a.prev, b ) >= 0 :
|
||||
area( a, b, a.prev ) < 0 || area( a, a.next, b ) < 0;
|
||||
|
||||
}
|
||||
|
||||
// check if the middle point of a polygon diagonal is inside the polygon
|
||||
function middleInside( a, b ) {
|
||||
|
||||
let p = a,
|
||||
inside = false;
|
||||
const px = ( a.x + b.x ) / 2,
|
||||
py = ( a.y + b.y ) / 2;
|
||||
do {
|
||||
|
||||
if ( ( ( p.y > py ) !== ( p.next.y > py ) ) && p.next.y !== p.y &&
|
||||
( px < ( p.next.x - p.x ) * ( py - p.y ) / ( p.next.y - p.y ) + p.x ) )
|
||||
inside = ! inside;
|
||||
p = p.next;
|
||||
|
||||
} while ( p !== a );
|
||||
|
||||
return inside;
|
||||
|
||||
}
|
||||
|
||||
// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
|
||||
// if one belongs to the outer ring and another to a hole, it merges it into a single ring
|
||||
function splitPolygon( a, b ) {
|
||||
|
||||
const a2 = new Node( a.i, a.x, a.y ),
|
||||
b2 = new Node( b.i, b.x, b.y ),
|
||||
an = a.next,
|
||||
bp = b.prev;
|
||||
|
||||
a.next = b;
|
||||
b.prev = a;
|
||||
|
||||
a2.next = an;
|
||||
an.prev = a2;
|
||||
|
||||
b2.next = a2;
|
||||
a2.prev = b2;
|
||||
|
||||
bp.next = b2;
|
||||
b2.prev = bp;
|
||||
|
||||
return b2;
|
||||
|
||||
}
|
||||
|
||||
// create a node and optionally link it with previous one (in a circular doubly linked list)
|
||||
function insertNode( i, x, y, last ) {
|
||||
|
||||
const p = new Node( i, x, y );
|
||||
|
||||
if ( ! last ) {
|
||||
|
||||
p.prev = p;
|
||||
p.next = p;
|
||||
|
||||
} else {
|
||||
|
||||
p.next = last.next;
|
||||
p.prev = last;
|
||||
last.next.prev = p;
|
||||
last.next = p;
|
||||
|
||||
}
|
||||
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
function removeNode( p ) {
|
||||
|
||||
p.next.prev = p.prev;
|
||||
p.prev.next = p.next;
|
||||
|
||||
if ( p.prevZ ) p.prevZ.nextZ = p.nextZ;
|
||||
if ( p.nextZ ) p.nextZ.prevZ = p.prevZ;
|
||||
|
||||
}
|
||||
|
||||
function Node( i, x, y ) {
|
||||
|
||||
// vertex index in coordinates array
|
||||
this.i = i;
|
||||
|
||||
// vertex coordinates
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
// previous and next vertex nodes in a polygon ring
|
||||
this.prev = null;
|
||||
this.next = null;
|
||||
|
||||
// z-order curve value
|
||||
this.z = 0;
|
||||
|
||||
// previous and next nodes in z-order
|
||||
this.prevZ = null;
|
||||
this.nextZ = null;
|
||||
|
||||
// indicates whether this is a steiner point
|
||||
this.steiner = false;
|
||||
|
||||
}
|
||||
|
||||
function signedArea( data, start, end, dim ) {
|
||||
|
||||
let sum = 0;
|
||||
for ( let i = start, j = end - dim; i < end; i += dim ) {
|
||||
|
||||
sum += ( data[ j ] - data[ i ] ) * ( data[ i + 1 ] + data[ j + 1 ] );
|
||||
j = i;
|
||||
|
||||
}
|
||||
|
||||
return sum;
|
||||
|
||||
}
|
||||
|
||||
export { Earcut };
|
||||
129
network-visualization/node_modules/three/src/extras/ImageUtils.js
generated
vendored
Normal file
129
network-visualization/node_modules/three/src/extras/ImageUtils.js
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
import { createElementNS } from '../utils.js';
|
||||
import { SRGBToLinear } from '../math/ColorManagement.js';
|
||||
|
||||
let _canvas;
|
||||
|
||||
class ImageUtils {
|
||||
|
||||
static getDataURL( image ) {
|
||||
|
||||
if ( /^data:/i.test( image.src ) ) {
|
||||
|
||||
return image.src;
|
||||
|
||||
}
|
||||
|
||||
if ( typeof HTMLCanvasElement === 'undefined' ) {
|
||||
|
||||
return image.src;
|
||||
|
||||
}
|
||||
|
||||
let canvas;
|
||||
|
||||
if ( image instanceof HTMLCanvasElement ) {
|
||||
|
||||
canvas = image;
|
||||
|
||||
} else {
|
||||
|
||||
if ( _canvas === undefined ) _canvas = createElementNS( 'canvas' );
|
||||
|
||||
_canvas.width = image.width;
|
||||
_canvas.height = image.height;
|
||||
|
||||
const context = _canvas.getContext( '2d' );
|
||||
|
||||
if ( image instanceof ImageData ) {
|
||||
|
||||
context.putImageData( image, 0, 0 );
|
||||
|
||||
} else {
|
||||
|
||||
context.drawImage( image, 0, 0, image.width, image.height );
|
||||
|
||||
}
|
||||
|
||||
canvas = _canvas;
|
||||
|
||||
}
|
||||
|
||||
if ( canvas.width > 2048 || canvas.height > 2048 ) {
|
||||
|
||||
console.warn( 'THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image );
|
||||
|
||||
return canvas.toDataURL( 'image/jpeg', 0.6 );
|
||||
|
||||
} else {
|
||||
|
||||
return canvas.toDataURL( 'image/png' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static sRGBToLinear( image ) {
|
||||
|
||||
if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
|
||||
( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
|
||||
( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
|
||||
|
||||
const canvas = createElementNS( 'canvas' );
|
||||
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
|
||||
const context = canvas.getContext( '2d' );
|
||||
context.drawImage( image, 0, 0, image.width, image.height );
|
||||
|
||||
const imageData = context.getImageData( 0, 0, image.width, image.height );
|
||||
const data = imageData.data;
|
||||
|
||||
for ( let i = 0; i < data.length; i ++ ) {
|
||||
|
||||
data[ i ] = SRGBToLinear( data[ i ] / 255 ) * 255;
|
||||
|
||||
}
|
||||
|
||||
context.putImageData( imageData, 0, 0 );
|
||||
|
||||
return canvas;
|
||||
|
||||
} else if ( image.data ) {
|
||||
|
||||
const data = image.data.slice( 0 );
|
||||
|
||||
for ( let i = 0; i < data.length; i ++ ) {
|
||||
|
||||
if ( data instanceof Uint8Array || data instanceof Uint8ClampedArray ) {
|
||||
|
||||
data[ i ] = Math.floor( SRGBToLinear( data[ i ] / 255 ) * 255 );
|
||||
|
||||
} else {
|
||||
|
||||
// assuming float
|
||||
|
||||
data[ i ] = SRGBToLinear( data[ i ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
data: data,
|
||||
width: image.width,
|
||||
height: image.height
|
||||
};
|
||||
|
||||
} else {
|
||||
|
||||
console.warn( 'THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.' );
|
||||
return image;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { ImageUtils };
|
||||
906
network-visualization/node_modules/three/src/extras/PMREMGenerator.js
generated
vendored
Normal file
906
network-visualization/node_modules/three/src/extras/PMREMGenerator.js
generated
vendored
Normal file
@@ -0,0 +1,906 @@
|
||||
import {
|
||||
CubeReflectionMapping,
|
||||
CubeRefractionMapping,
|
||||
CubeUVReflectionMapping,
|
||||
LinearFilter,
|
||||
NoToneMapping,
|
||||
NoBlending,
|
||||
RGBAFormat,
|
||||
HalfFloatType,
|
||||
BackSide,
|
||||
LinearSRGBColorSpace
|
||||
} from '../constants.js';
|
||||
|
||||
import { BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Mesh } from '../objects/Mesh.js';
|
||||
import { OrthographicCamera } from '../cameras/OrthographicCamera.js';
|
||||
import { PerspectiveCamera } from '../cameras/PerspectiveCamera.js';
|
||||
import { ShaderMaterial } from '../materials/ShaderMaterial.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
import { WebGLRenderTarget } from '../renderers/WebGLRenderTarget.js';
|
||||
import { MeshBasicMaterial } from '../materials/MeshBasicMaterial.js';
|
||||
import { BoxGeometry } from '../geometries/BoxGeometry.js';
|
||||
|
||||
const LOD_MIN = 4;
|
||||
|
||||
// The standard deviations (radians) associated with the extra mips. These are
|
||||
// chosen to approximate a Trowbridge-Reitz distribution function times the
|
||||
// geometric shadowing function. These sigma values squared must match the
|
||||
// variance #defines in cube_uv_reflection_fragment.glsl.js.
|
||||
const EXTRA_LOD_SIGMA = [ 0.125, 0.215, 0.35, 0.446, 0.526, 0.582 ];
|
||||
|
||||
// The maximum length of the blur for loop. Smaller sigmas will use fewer
|
||||
// samples and exit early, but not recompile the shader.
|
||||
const MAX_SAMPLES = 20;
|
||||
|
||||
const _flatCamera = /*@__PURE__*/ new OrthographicCamera();
|
||||
const _clearColor = /*@__PURE__*/ new Color();
|
||||
let _oldTarget = null;
|
||||
let _oldActiveCubeFace = 0;
|
||||
let _oldActiveMipmapLevel = 0;
|
||||
|
||||
// Golden Ratio
|
||||
const PHI = ( 1 + Math.sqrt( 5 ) ) / 2;
|
||||
const INV_PHI = 1 / PHI;
|
||||
|
||||
// Vertices of a dodecahedron (except the opposites, which represent the
|
||||
// same axis), used as axis directions evenly spread on a sphere.
|
||||
const _axisDirections = [
|
||||
/*@__PURE__*/ new Vector3( 1, 1, 1 ),
|
||||
/*@__PURE__*/ new Vector3( - 1, 1, 1 ),
|
||||
/*@__PURE__*/ new Vector3( 1, 1, - 1 ),
|
||||
/*@__PURE__*/ new Vector3( - 1, 1, - 1 ),
|
||||
/*@__PURE__*/ new Vector3( 0, PHI, INV_PHI ),
|
||||
/*@__PURE__*/ new Vector3( 0, PHI, - INV_PHI ),
|
||||
/*@__PURE__*/ new Vector3( INV_PHI, 0, PHI ),
|
||||
/*@__PURE__*/ new Vector3( - INV_PHI, 0, PHI ),
|
||||
/*@__PURE__*/ new Vector3( PHI, INV_PHI, 0 ),
|
||||
/*@__PURE__*/ new Vector3( - PHI, INV_PHI, 0 ) ];
|
||||
|
||||
/**
|
||||
* This class generates a Prefiltered, Mipmapped Radiance Environment Map
|
||||
* (PMREM) from a cubeMap environment texture. This allows different levels of
|
||||
* blur to be quickly accessed based on material roughness. It is packed into a
|
||||
* special CubeUV format that allows us to perform custom interpolation so that
|
||||
* we can support nonlinear formats such as RGBE. Unlike a traditional mipmap
|
||||
* chain, it only goes down to the LOD_MIN level (above), and then creates extra
|
||||
* even more filtered 'mips' at the same LOD_MIN resolution, associated with
|
||||
* higher roughness levels. In this way we maintain resolution to smoothly
|
||||
* interpolate diffuse lighting while limiting sampling computation.
|
||||
*
|
||||
* Paper: Fast, Accurate Image-Based Lighting
|
||||
* https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view
|
||||
*/
|
||||
|
||||
class PMREMGenerator {
|
||||
|
||||
constructor( renderer ) {
|
||||
|
||||
this._renderer = renderer;
|
||||
this._pingPongRenderTarget = null;
|
||||
|
||||
this._lodMax = 0;
|
||||
this._cubeSize = 0;
|
||||
this._lodPlanes = [];
|
||||
this._sizeLods = [];
|
||||
this._sigmas = [];
|
||||
|
||||
this._blurMaterial = null;
|
||||
this._cubemapMaterial = null;
|
||||
this._equirectMaterial = null;
|
||||
|
||||
this._compileMaterial( this._blurMaterial );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PMREM from a supplied Scene, which can be faster than using an
|
||||
* image if networking bandwidth is low. Optional sigma specifies a blur radius
|
||||
* in radians to be applied to the scene before PMREM generation. Optional near
|
||||
* and far planes ensure the scene is rendered in its entirety (the cubeCamera
|
||||
* is placed at the origin).
|
||||
*/
|
||||
fromScene( scene, sigma = 0, near = 0.1, far = 100 ) {
|
||||
|
||||
_oldTarget = this._renderer.getRenderTarget();
|
||||
_oldActiveCubeFace = this._renderer.getActiveCubeFace();
|
||||
_oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
|
||||
|
||||
this._setSize( 256 );
|
||||
|
||||
const cubeUVRenderTarget = this._allocateTargets();
|
||||
cubeUVRenderTarget.depthBuffer = true;
|
||||
|
||||
this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget );
|
||||
|
||||
if ( sigma > 0 ) {
|
||||
|
||||
this._blur( cubeUVRenderTarget, 0, 0, sigma );
|
||||
|
||||
}
|
||||
|
||||
this._applyPMREM( cubeUVRenderTarget );
|
||||
this._cleanup( cubeUVRenderTarget );
|
||||
|
||||
return cubeUVRenderTarget;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PMREM from an equirectangular texture, which can be either LDR
|
||||
* or HDR. The ideal input image size is 1k (1024 x 512),
|
||||
* as this matches best with the 256 x 256 cubemap output.
|
||||
*/
|
||||
fromEquirectangular( equirectangular, renderTarget = null ) {
|
||||
|
||||
return this._fromTexture( equirectangular, renderTarget );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PMREM from an cubemap texture, which can be either LDR
|
||||
* or HDR. The ideal input cube size is 256 x 256,
|
||||
* as this matches best with the 256 x 256 cubemap output.
|
||||
*/
|
||||
fromCubemap( cubemap, renderTarget = null ) {
|
||||
|
||||
return this._fromTexture( cubemap, renderTarget );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
|
||||
* your texture's network fetch for increased concurrency.
|
||||
*/
|
||||
compileCubemapShader() {
|
||||
|
||||
if ( this._cubemapMaterial === null ) {
|
||||
|
||||
this._cubemapMaterial = _getCubemapMaterial();
|
||||
this._compileMaterial( this._cubemapMaterial );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
|
||||
* your texture's network fetch for increased concurrency.
|
||||
*/
|
||||
compileEquirectangularShader() {
|
||||
|
||||
if ( this._equirectMaterial === null ) {
|
||||
|
||||
this._equirectMaterial = _getEquirectMaterial();
|
||||
this._compileMaterial( this._equirectMaterial );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
|
||||
* so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
|
||||
* one of them will cause any others to also become unusable.
|
||||
*/
|
||||
dispose() {
|
||||
|
||||
this._dispose();
|
||||
|
||||
if ( this._cubemapMaterial !== null ) this._cubemapMaterial.dispose();
|
||||
if ( this._equirectMaterial !== null ) this._equirectMaterial.dispose();
|
||||
|
||||
}
|
||||
|
||||
// private interface
|
||||
|
||||
_setSize( cubeSize ) {
|
||||
|
||||
this._lodMax = Math.floor( Math.log2( cubeSize ) );
|
||||
this._cubeSize = Math.pow( 2, this._lodMax );
|
||||
|
||||
}
|
||||
|
||||
_dispose() {
|
||||
|
||||
if ( this._blurMaterial !== null ) this._blurMaterial.dispose();
|
||||
|
||||
if ( this._pingPongRenderTarget !== null ) this._pingPongRenderTarget.dispose();
|
||||
|
||||
for ( let i = 0; i < this._lodPlanes.length; i ++ ) {
|
||||
|
||||
this._lodPlanes[ i ].dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_cleanup( outputTarget ) {
|
||||
|
||||
this._renderer.setRenderTarget( _oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel );
|
||||
outputTarget.scissorTest = false;
|
||||
_setViewport( outputTarget, 0, 0, outputTarget.width, outputTarget.height );
|
||||
|
||||
}
|
||||
|
||||
_fromTexture( texture, renderTarget ) {
|
||||
|
||||
if ( texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping ) {
|
||||
|
||||
this._setSize( texture.image.length === 0 ? 16 : ( texture.image[ 0 ].width || texture.image[ 0 ].image.width ) );
|
||||
|
||||
} else { // Equirectangular
|
||||
|
||||
this._setSize( texture.image.width / 4 );
|
||||
|
||||
}
|
||||
|
||||
_oldTarget = this._renderer.getRenderTarget();
|
||||
_oldActiveCubeFace = this._renderer.getActiveCubeFace();
|
||||
_oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
|
||||
|
||||
const cubeUVRenderTarget = renderTarget || this._allocateTargets();
|
||||
this._textureToCubeUV( texture, cubeUVRenderTarget );
|
||||
this._applyPMREM( cubeUVRenderTarget );
|
||||
this._cleanup( cubeUVRenderTarget );
|
||||
|
||||
return cubeUVRenderTarget;
|
||||
|
||||
}
|
||||
|
||||
_allocateTargets() {
|
||||
|
||||
const width = 3 * Math.max( this._cubeSize, 16 * 7 );
|
||||
const height = 4 * this._cubeSize;
|
||||
|
||||
const params = {
|
||||
magFilter: LinearFilter,
|
||||
minFilter: LinearFilter,
|
||||
generateMipmaps: false,
|
||||
type: HalfFloatType,
|
||||
format: RGBAFormat,
|
||||
colorSpace: LinearSRGBColorSpace,
|
||||
depthBuffer: false
|
||||
};
|
||||
|
||||
const cubeUVRenderTarget = _createRenderTarget( width, height, params );
|
||||
|
||||
if ( this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height ) {
|
||||
|
||||
if ( this._pingPongRenderTarget !== null ) {
|
||||
|
||||
this._dispose();
|
||||
|
||||
}
|
||||
|
||||
this._pingPongRenderTarget = _createRenderTarget( width, height, params );
|
||||
|
||||
const { _lodMax } = this;
|
||||
( { sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes( _lodMax ) );
|
||||
|
||||
this._blurMaterial = _getBlurShader( _lodMax, width, height );
|
||||
|
||||
}
|
||||
|
||||
return cubeUVRenderTarget;
|
||||
|
||||
}
|
||||
|
||||
_compileMaterial( material ) {
|
||||
|
||||
const tmpMesh = new Mesh( this._lodPlanes[ 0 ], material );
|
||||
this._renderer.compile( tmpMesh, _flatCamera );
|
||||
|
||||
}
|
||||
|
||||
_sceneToCubeUV( scene, near, far, cubeUVRenderTarget ) {
|
||||
|
||||
const fov = 90;
|
||||
const aspect = 1;
|
||||
const cubeCamera = new PerspectiveCamera( fov, aspect, near, far );
|
||||
const upSign = [ 1, - 1, 1, 1, 1, 1 ];
|
||||
const forwardSign = [ 1, 1, 1, - 1, - 1, - 1 ];
|
||||
const renderer = this._renderer;
|
||||
|
||||
const originalAutoClear = renderer.autoClear;
|
||||
const toneMapping = renderer.toneMapping;
|
||||
renderer.getClearColor( _clearColor );
|
||||
|
||||
renderer.toneMapping = NoToneMapping;
|
||||
renderer.autoClear = false;
|
||||
|
||||
const backgroundMaterial = new MeshBasicMaterial( {
|
||||
name: 'PMREM.Background',
|
||||
side: BackSide,
|
||||
depthWrite: false,
|
||||
depthTest: false,
|
||||
} );
|
||||
|
||||
const backgroundBox = new Mesh( new BoxGeometry(), backgroundMaterial );
|
||||
|
||||
let useSolidColor = false;
|
||||
const background = scene.background;
|
||||
|
||||
if ( background ) {
|
||||
|
||||
if ( background.isColor ) {
|
||||
|
||||
backgroundMaterial.color.copy( background );
|
||||
scene.background = null;
|
||||
useSolidColor = true;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
backgroundMaterial.color.copy( _clearColor );
|
||||
useSolidColor = true;
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i < 6; i ++ ) {
|
||||
|
||||
const col = i % 3;
|
||||
|
||||
if ( col === 0 ) {
|
||||
|
||||
cubeCamera.up.set( 0, upSign[ i ], 0 );
|
||||
cubeCamera.lookAt( forwardSign[ i ], 0, 0 );
|
||||
|
||||
} else if ( col === 1 ) {
|
||||
|
||||
cubeCamera.up.set( 0, 0, upSign[ i ] );
|
||||
cubeCamera.lookAt( 0, forwardSign[ i ], 0 );
|
||||
|
||||
} else {
|
||||
|
||||
cubeCamera.up.set( 0, upSign[ i ], 0 );
|
||||
cubeCamera.lookAt( 0, 0, forwardSign[ i ] );
|
||||
|
||||
}
|
||||
|
||||
const size = this._cubeSize;
|
||||
|
||||
_setViewport( cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size );
|
||||
|
||||
renderer.setRenderTarget( cubeUVRenderTarget );
|
||||
|
||||
if ( useSolidColor ) {
|
||||
|
||||
renderer.render( backgroundBox, cubeCamera );
|
||||
|
||||
}
|
||||
|
||||
renderer.render( scene, cubeCamera );
|
||||
|
||||
}
|
||||
|
||||
backgroundBox.geometry.dispose();
|
||||
backgroundBox.material.dispose();
|
||||
|
||||
renderer.toneMapping = toneMapping;
|
||||
renderer.autoClear = originalAutoClear;
|
||||
scene.background = background;
|
||||
|
||||
}
|
||||
|
||||
_textureToCubeUV( texture, cubeUVRenderTarget ) {
|
||||
|
||||
const renderer = this._renderer;
|
||||
|
||||
const isCubeTexture = ( texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping );
|
||||
|
||||
if ( isCubeTexture ) {
|
||||
|
||||
if ( this._cubemapMaterial === null ) {
|
||||
|
||||
this._cubemapMaterial = _getCubemapMaterial();
|
||||
|
||||
}
|
||||
|
||||
this._cubemapMaterial.uniforms.flipEnvMap.value = ( texture.isRenderTargetTexture === false ) ? - 1 : 1;
|
||||
|
||||
} else {
|
||||
|
||||
if ( this._equirectMaterial === null ) {
|
||||
|
||||
this._equirectMaterial = _getEquirectMaterial();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial;
|
||||
const mesh = new Mesh( this._lodPlanes[ 0 ], material );
|
||||
|
||||
const uniforms = material.uniforms;
|
||||
|
||||
uniforms[ 'envMap' ].value = texture;
|
||||
|
||||
const size = this._cubeSize;
|
||||
|
||||
_setViewport( cubeUVRenderTarget, 0, 0, 3 * size, 2 * size );
|
||||
|
||||
renderer.setRenderTarget( cubeUVRenderTarget );
|
||||
renderer.render( mesh, _flatCamera );
|
||||
|
||||
}
|
||||
|
||||
_applyPMREM( cubeUVRenderTarget ) {
|
||||
|
||||
const renderer = this._renderer;
|
||||
const autoClear = renderer.autoClear;
|
||||
renderer.autoClear = false;
|
||||
|
||||
for ( let i = 1; i < this._lodPlanes.length; i ++ ) {
|
||||
|
||||
const sigma = Math.sqrt( this._sigmas[ i ] * this._sigmas[ i ] - this._sigmas[ i - 1 ] * this._sigmas[ i - 1 ] );
|
||||
|
||||
const poleAxis = _axisDirections[ ( i - 1 ) % _axisDirections.length ];
|
||||
|
||||
this._blur( cubeUVRenderTarget, i - 1, i, sigma, poleAxis );
|
||||
|
||||
}
|
||||
|
||||
renderer.autoClear = autoClear;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a two-pass Gaussian blur for a cubemap. Normally this is done
|
||||
* vertically and horizontally, but this breaks down on a cube. Here we apply
|
||||
* the blur latitudinally (around the poles), and then longitudinally (towards
|
||||
* the poles) to approximate the orthogonally-separable blur. It is least
|
||||
* accurate at the poles, but still does a decent job.
|
||||
*/
|
||||
_blur( cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis ) {
|
||||
|
||||
const pingPongRenderTarget = this._pingPongRenderTarget;
|
||||
|
||||
this._halfBlur(
|
||||
cubeUVRenderTarget,
|
||||
pingPongRenderTarget,
|
||||
lodIn,
|
||||
lodOut,
|
||||
sigma,
|
||||
'latitudinal',
|
||||
poleAxis );
|
||||
|
||||
this._halfBlur(
|
||||
pingPongRenderTarget,
|
||||
cubeUVRenderTarget,
|
||||
lodOut,
|
||||
lodOut,
|
||||
sigma,
|
||||
'longitudinal',
|
||||
poleAxis );
|
||||
|
||||
}
|
||||
|
||||
_halfBlur( targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis ) {
|
||||
|
||||
const renderer = this._renderer;
|
||||
const blurMaterial = this._blurMaterial;
|
||||
|
||||
if ( direction !== 'latitudinal' && direction !== 'longitudinal' ) {
|
||||
|
||||
console.error(
|
||||
'blur direction must be either latitudinal or longitudinal!' );
|
||||
|
||||
}
|
||||
|
||||
// Number of standard deviations at which to cut off the discrete approximation.
|
||||
const STANDARD_DEVIATIONS = 3;
|
||||
|
||||
const blurMesh = new Mesh( this._lodPlanes[ lodOut ], blurMaterial );
|
||||
const blurUniforms = blurMaterial.uniforms;
|
||||
|
||||
const pixels = this._sizeLods[ lodIn ] - 1;
|
||||
const radiansPerPixel = isFinite( sigmaRadians ) ? Math.PI / ( 2 * pixels ) : 2 * Math.PI / ( 2 * MAX_SAMPLES - 1 );
|
||||
const sigmaPixels = sigmaRadians / radiansPerPixel;
|
||||
const samples = isFinite( sigmaRadians ) ? 1 + Math.floor( STANDARD_DEVIATIONS * sigmaPixels ) : MAX_SAMPLES;
|
||||
|
||||
if ( samples > MAX_SAMPLES ) {
|
||||
|
||||
console.warn( `sigmaRadians, ${
|
||||
sigmaRadians}, is too large and will clip, as it requested ${
|
||||
samples} samples when the maximum is set to ${MAX_SAMPLES}` );
|
||||
|
||||
}
|
||||
|
||||
const weights = [];
|
||||
let sum = 0;
|
||||
|
||||
for ( let i = 0; i < MAX_SAMPLES; ++ i ) {
|
||||
|
||||
const x = i / sigmaPixels;
|
||||
const weight = Math.exp( - x * x / 2 );
|
||||
weights.push( weight );
|
||||
|
||||
if ( i === 0 ) {
|
||||
|
||||
sum += weight;
|
||||
|
||||
} else if ( i < samples ) {
|
||||
|
||||
sum += 2 * weight;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i < weights.length; i ++ ) {
|
||||
|
||||
weights[ i ] = weights[ i ] / sum;
|
||||
|
||||
}
|
||||
|
||||
blurUniforms[ 'envMap' ].value = targetIn.texture;
|
||||
blurUniforms[ 'samples' ].value = samples;
|
||||
blurUniforms[ 'weights' ].value = weights;
|
||||
blurUniforms[ 'latitudinal' ].value = direction === 'latitudinal';
|
||||
|
||||
if ( poleAxis ) {
|
||||
|
||||
blurUniforms[ 'poleAxis' ].value = poleAxis;
|
||||
|
||||
}
|
||||
|
||||
const { _lodMax } = this;
|
||||
blurUniforms[ 'dTheta' ].value = radiansPerPixel;
|
||||
blurUniforms[ 'mipInt' ].value = _lodMax - lodIn;
|
||||
|
||||
const outputSize = this._sizeLods[ lodOut ];
|
||||
const x = 3 * outputSize * ( lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0 );
|
||||
const y = 4 * ( this._cubeSize - outputSize );
|
||||
|
||||
_setViewport( targetOut, x, y, 3 * outputSize, 2 * outputSize );
|
||||
renderer.setRenderTarget( targetOut );
|
||||
renderer.render( blurMesh, _flatCamera );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function _createPlanes( lodMax ) {
|
||||
|
||||
const lodPlanes = [];
|
||||
const sizeLods = [];
|
||||
const sigmas = [];
|
||||
|
||||
let lod = lodMax;
|
||||
|
||||
const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;
|
||||
|
||||
for ( let i = 0; i < totalLods; i ++ ) {
|
||||
|
||||
const sizeLod = Math.pow( 2, lod );
|
||||
sizeLods.push( sizeLod );
|
||||
let sigma = 1.0 / sizeLod;
|
||||
|
||||
if ( i > lodMax - LOD_MIN ) {
|
||||
|
||||
sigma = EXTRA_LOD_SIGMA[ i - lodMax + LOD_MIN - 1 ];
|
||||
|
||||
} else if ( i === 0 ) {
|
||||
|
||||
sigma = 0;
|
||||
|
||||
}
|
||||
|
||||
sigmas.push( sigma );
|
||||
|
||||
const texelSize = 1.0 / ( sizeLod - 2 );
|
||||
const min = - texelSize;
|
||||
const max = 1 + texelSize;
|
||||
const uv1 = [ min, min, max, min, max, max, min, min, max, max, min, max ];
|
||||
|
||||
const cubeFaces = 6;
|
||||
const vertices = 6;
|
||||
const positionSize = 3;
|
||||
const uvSize = 2;
|
||||
const faceIndexSize = 1;
|
||||
|
||||
const position = new Float32Array( positionSize * vertices * cubeFaces );
|
||||
const uv = new Float32Array( uvSize * vertices * cubeFaces );
|
||||
const faceIndex = new Float32Array( faceIndexSize * vertices * cubeFaces );
|
||||
|
||||
for ( let face = 0; face < cubeFaces; face ++ ) {
|
||||
|
||||
const x = ( face % 3 ) * 2 / 3 - 1;
|
||||
const y = face > 2 ? 0 : - 1;
|
||||
const coordinates = [
|
||||
x, y, 0,
|
||||
x + 2 / 3, y, 0,
|
||||
x + 2 / 3, y + 1, 0,
|
||||
x, y, 0,
|
||||
x + 2 / 3, y + 1, 0,
|
||||
x, y + 1, 0
|
||||
];
|
||||
position.set( coordinates, positionSize * vertices * face );
|
||||
uv.set( uv1, uvSize * vertices * face );
|
||||
const fill = [ face, face, face, face, face, face ];
|
||||
faceIndex.set( fill, faceIndexSize * vertices * face );
|
||||
|
||||
}
|
||||
|
||||
const planes = new BufferGeometry();
|
||||
planes.setAttribute( 'position', new BufferAttribute( position, positionSize ) );
|
||||
planes.setAttribute( 'uv', new BufferAttribute( uv, uvSize ) );
|
||||
planes.setAttribute( 'faceIndex', new BufferAttribute( faceIndex, faceIndexSize ) );
|
||||
lodPlanes.push( planes );
|
||||
|
||||
if ( lod > LOD_MIN ) {
|
||||
|
||||
lod --;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return { lodPlanes, sizeLods, sigmas };
|
||||
|
||||
}
|
||||
|
||||
function _createRenderTarget( width, height, params ) {
|
||||
|
||||
const cubeUVRenderTarget = new WebGLRenderTarget( width, height, params );
|
||||
cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
|
||||
cubeUVRenderTarget.texture.name = 'PMREM.cubeUv';
|
||||
cubeUVRenderTarget.scissorTest = true;
|
||||
return cubeUVRenderTarget;
|
||||
|
||||
}
|
||||
|
||||
function _setViewport( target, x, y, width, height ) {
|
||||
|
||||
target.viewport.set( x, y, width, height );
|
||||
target.scissor.set( x, y, width, height );
|
||||
|
||||
}
|
||||
|
||||
function _getBlurShader( lodMax, width, height ) {
|
||||
|
||||
const weights = new Float32Array( MAX_SAMPLES );
|
||||
const poleAxis = new Vector3( 0, 1, 0 );
|
||||
const shaderMaterial = new ShaderMaterial( {
|
||||
|
||||
name: 'SphericalGaussianBlur',
|
||||
|
||||
defines: {
|
||||
'n': MAX_SAMPLES,
|
||||
'CUBEUV_TEXEL_WIDTH': 1.0 / width,
|
||||
'CUBEUV_TEXEL_HEIGHT': 1.0 / height,
|
||||
'CUBEUV_MAX_MIP': `${lodMax}.0`,
|
||||
},
|
||||
|
||||
uniforms: {
|
||||
'envMap': { value: null },
|
||||
'samples': { value: 1 },
|
||||
'weights': { value: weights },
|
||||
'latitudinal': { value: false },
|
||||
'dTheta': { value: 0 },
|
||||
'mipInt': { value: 0 },
|
||||
'poleAxis': { value: poleAxis }
|
||||
},
|
||||
|
||||
vertexShader: _getCommonVertexShader(),
|
||||
|
||||
fragmentShader: /* glsl */`
|
||||
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
|
||||
varying vec3 vOutputDirection;
|
||||
|
||||
uniform sampler2D envMap;
|
||||
uniform int samples;
|
||||
uniform float weights[ n ];
|
||||
uniform bool latitudinal;
|
||||
uniform float dTheta;
|
||||
uniform float mipInt;
|
||||
uniform vec3 poleAxis;
|
||||
|
||||
#define ENVMAP_TYPE_CUBE_UV
|
||||
#include <cube_uv_reflection_fragment>
|
||||
|
||||
vec3 getSample( float theta, vec3 axis ) {
|
||||
|
||||
float cosTheta = cos( theta );
|
||||
// Rodrigues' axis-angle rotation
|
||||
vec3 sampleDirection = vOutputDirection * cosTheta
|
||||
+ cross( axis, vOutputDirection ) * sin( theta )
|
||||
+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );
|
||||
|
||||
return bilinearCubeUV( envMap, sampleDirection, mipInt );
|
||||
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );
|
||||
|
||||
if ( all( equal( axis, vec3( 0.0 ) ) ) ) {
|
||||
|
||||
axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );
|
||||
|
||||
}
|
||||
|
||||
axis = normalize( axis );
|
||||
|
||||
gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
|
||||
gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );
|
||||
|
||||
for ( int i = 1; i < n; i++ ) {
|
||||
|
||||
if ( i >= samples ) {
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
float theta = dTheta * float( i );
|
||||
gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
|
||||
gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
`,
|
||||
|
||||
blending: NoBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false
|
||||
|
||||
} );
|
||||
|
||||
return shaderMaterial;
|
||||
|
||||
}
|
||||
|
||||
function _getEquirectMaterial() {
|
||||
|
||||
return new ShaderMaterial( {
|
||||
|
||||
name: 'EquirectangularToCubeUV',
|
||||
|
||||
uniforms: {
|
||||
'envMap': { value: null }
|
||||
},
|
||||
|
||||
vertexShader: _getCommonVertexShader(),
|
||||
|
||||
fragmentShader: /* glsl */`
|
||||
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
|
||||
varying vec3 vOutputDirection;
|
||||
|
||||
uniform sampler2D envMap;
|
||||
|
||||
#include <common>
|
||||
|
||||
void main() {
|
||||
|
||||
vec3 outputDirection = normalize( vOutputDirection );
|
||||
vec2 uv = equirectUv( outputDirection );
|
||||
|
||||
gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );
|
||||
|
||||
}
|
||||
`,
|
||||
|
||||
blending: NoBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
function _getCubemapMaterial() {
|
||||
|
||||
return new ShaderMaterial( {
|
||||
|
||||
name: 'CubemapToCubeUV',
|
||||
|
||||
uniforms: {
|
||||
'envMap': { value: null },
|
||||
'flipEnvMap': { value: - 1 }
|
||||
},
|
||||
|
||||
vertexShader: _getCommonVertexShader(),
|
||||
|
||||
fragmentShader: /* glsl */`
|
||||
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
|
||||
uniform float flipEnvMap;
|
||||
|
||||
varying vec3 vOutputDirection;
|
||||
|
||||
uniform samplerCube envMap;
|
||||
|
||||
void main() {
|
||||
|
||||
gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );
|
||||
|
||||
}
|
||||
`,
|
||||
|
||||
blending: NoBlending,
|
||||
depthTest: false,
|
||||
depthWrite: false
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
function _getCommonVertexShader() {
|
||||
|
||||
return /* glsl */`
|
||||
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
|
||||
attribute float faceIndex;
|
||||
|
||||
varying vec3 vOutputDirection;
|
||||
|
||||
// RH coordinate system; PMREM face-indexing convention
|
||||
vec3 getDirection( vec2 uv, float face ) {
|
||||
|
||||
uv = 2.0 * uv - 1.0;
|
||||
|
||||
vec3 direction = vec3( uv, 1.0 );
|
||||
|
||||
if ( face == 0.0 ) {
|
||||
|
||||
direction = direction.zyx; // ( 1, v, u ) pos x
|
||||
|
||||
} else if ( face == 1.0 ) {
|
||||
|
||||
direction = direction.xzy;
|
||||
direction.xz *= -1.0; // ( -u, 1, -v ) pos y
|
||||
|
||||
} else if ( face == 2.0 ) {
|
||||
|
||||
direction.x *= -1.0; // ( -u, v, 1 ) pos z
|
||||
|
||||
} else if ( face == 3.0 ) {
|
||||
|
||||
direction = direction.zyx;
|
||||
direction.xz *= -1.0; // ( -1, v, -u ) neg x
|
||||
|
||||
} else if ( face == 4.0 ) {
|
||||
|
||||
direction = direction.xzy;
|
||||
direction.xy *= -1.0; // ( -u, -1, v ) neg y
|
||||
|
||||
} else if ( face == 5.0 ) {
|
||||
|
||||
direction.z *= -1.0; // ( u, v, -1 ) neg z
|
||||
|
||||
}
|
||||
|
||||
return direction;
|
||||
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
vOutputDirection = getDirection( uv, faceIndex );
|
||||
gl_Position = vec4( position, 1.0 );
|
||||
|
||||
}
|
||||
`;
|
||||
|
||||
}
|
||||
|
||||
export { PMREMGenerator };
|
||||
92
network-visualization/node_modules/three/src/extras/ShapeUtils.js
generated
vendored
Normal file
92
network-visualization/node_modules/three/src/extras/ShapeUtils.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import { Earcut } from './Earcut.js';
|
||||
|
||||
class ShapeUtils {
|
||||
|
||||
// calculate area of the contour polygon
|
||||
|
||||
static area( contour ) {
|
||||
|
||||
const n = contour.length;
|
||||
let a = 0.0;
|
||||
|
||||
for ( let p = n - 1, q = 0; q < n; p = q ++ ) {
|
||||
|
||||
a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
|
||||
|
||||
}
|
||||
|
||||
return a * 0.5;
|
||||
|
||||
}
|
||||
|
||||
static isClockWise( pts ) {
|
||||
|
||||
return ShapeUtils.area( pts ) < 0;
|
||||
|
||||
}
|
||||
|
||||
static triangulateShape( contour, holes ) {
|
||||
|
||||
const vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ]
|
||||
const holeIndices = []; // array of hole indices
|
||||
const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ]
|
||||
|
||||
removeDupEndPts( contour );
|
||||
addContour( vertices, contour );
|
||||
|
||||
//
|
||||
|
||||
let holeIndex = contour.length;
|
||||
|
||||
holes.forEach( removeDupEndPts );
|
||||
|
||||
for ( let i = 0; i < holes.length; i ++ ) {
|
||||
|
||||
holeIndices.push( holeIndex );
|
||||
holeIndex += holes[ i ].length;
|
||||
addContour( vertices, holes[ i ] );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const triangles = Earcut.triangulate( vertices, holeIndices );
|
||||
|
||||
//
|
||||
|
||||
for ( let i = 0; i < triangles.length; i += 3 ) {
|
||||
|
||||
faces.push( triangles.slice( i, i + 3 ) );
|
||||
|
||||
}
|
||||
|
||||
return faces;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function removeDupEndPts( points ) {
|
||||
|
||||
const l = points.length;
|
||||
|
||||
if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
|
||||
|
||||
points.pop();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function addContour( vertices, contour ) {
|
||||
|
||||
for ( let i = 0; i < contour.length; i ++ ) {
|
||||
|
||||
vertices.push( contour[ i ].x );
|
||||
vertices.push( contour[ i ].y );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { ShapeUtils };
|
||||
416
network-visualization/node_modules/three/src/extras/core/Curve.js
generated
vendored
Normal file
416
network-visualization/node_modules/three/src/extras/core/Curve.js
generated
vendored
Normal file
@@ -0,0 +1,416 @@
|
||||
import * as MathUtils from '../../math/MathUtils.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
import { Matrix4 } from '../../math/Matrix4.js';
|
||||
|
||||
/**
|
||||
* Extensible curve object.
|
||||
*
|
||||
* Some common of curve methods:
|
||||
* .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )
|
||||
* .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )
|
||||
* .getPoints(), .getSpacedPoints()
|
||||
* .getLength()
|
||||
* .updateArcLengths()
|
||||
*
|
||||
* This following curves inherit from THREE.Curve:
|
||||
*
|
||||
* -- 2D curves --
|
||||
* THREE.ArcCurve
|
||||
* THREE.CubicBezierCurve
|
||||
* THREE.EllipseCurve
|
||||
* THREE.LineCurve
|
||||
* THREE.QuadraticBezierCurve
|
||||
* THREE.SplineCurve
|
||||
*
|
||||
* -- 3D curves --
|
||||
* THREE.CatmullRomCurve3
|
||||
* THREE.CubicBezierCurve3
|
||||
* THREE.LineCurve3
|
||||
* THREE.QuadraticBezierCurve3
|
||||
*
|
||||
* A series of curves can be represented as a THREE.CurvePath.
|
||||
*
|
||||
**/
|
||||
|
||||
class Curve {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.type = 'Curve';
|
||||
|
||||
this.arcLengthDivisions = 200;
|
||||
|
||||
}
|
||||
|
||||
// Virtual base class method to overwrite and implement in subclasses
|
||||
// - t [0 .. 1]
|
||||
|
||||
getPoint( /* t, optionalTarget */ ) {
|
||||
|
||||
console.warn( 'THREE.Curve: .getPoint() not implemented.' );
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// Get point at relative position in curve according to arc length
|
||||
// - u [0 .. 1]
|
||||
|
||||
getPointAt( u, optionalTarget ) {
|
||||
|
||||
const t = this.getUtoTmapping( u );
|
||||
return this.getPoint( t, optionalTarget );
|
||||
|
||||
}
|
||||
|
||||
// Get sequence of points using getPoint( t )
|
||||
|
||||
getPoints( divisions = 5 ) {
|
||||
|
||||
const points = [];
|
||||
|
||||
for ( let d = 0; d <= divisions; d ++ ) {
|
||||
|
||||
points.push( this.getPoint( d / divisions ) );
|
||||
|
||||
}
|
||||
|
||||
return points;
|
||||
|
||||
}
|
||||
|
||||
// Get sequence of points using getPointAt( u )
|
||||
|
||||
getSpacedPoints( divisions = 5 ) {
|
||||
|
||||
const points = [];
|
||||
|
||||
for ( let d = 0; d <= divisions; d ++ ) {
|
||||
|
||||
points.push( this.getPointAt( d / divisions ) );
|
||||
|
||||
}
|
||||
|
||||
return points;
|
||||
|
||||
}
|
||||
|
||||
// Get total curve arc length
|
||||
|
||||
getLength() {
|
||||
|
||||
const lengths = this.getLengths();
|
||||
return lengths[ lengths.length - 1 ];
|
||||
|
||||
}
|
||||
|
||||
// Get list of cumulative segment lengths
|
||||
|
||||
getLengths( divisions = this.arcLengthDivisions ) {
|
||||
|
||||
if ( this.cacheArcLengths &&
|
||||
( this.cacheArcLengths.length === divisions + 1 ) &&
|
||||
! this.needsUpdate ) {
|
||||
|
||||
return this.cacheArcLengths;
|
||||
|
||||
}
|
||||
|
||||
this.needsUpdate = false;
|
||||
|
||||
const cache = [];
|
||||
let current, last = this.getPoint( 0 );
|
||||
let sum = 0;
|
||||
|
||||
cache.push( 0 );
|
||||
|
||||
for ( let p = 1; p <= divisions; p ++ ) {
|
||||
|
||||
current = this.getPoint( p / divisions );
|
||||
sum += current.distanceTo( last );
|
||||
cache.push( sum );
|
||||
last = current;
|
||||
|
||||
}
|
||||
|
||||
this.cacheArcLengths = cache;
|
||||
|
||||
return cache; // { sums: cache, sum: sum }; Sum is in the last element.
|
||||
|
||||
}
|
||||
|
||||
updateArcLengths() {
|
||||
|
||||
this.needsUpdate = true;
|
||||
this.getLengths();
|
||||
|
||||
}
|
||||
|
||||
// Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
|
||||
|
||||
getUtoTmapping( u, distance ) {
|
||||
|
||||
const arcLengths = this.getLengths();
|
||||
|
||||
let i = 0;
|
||||
const il = arcLengths.length;
|
||||
|
||||
let targetArcLength; // The targeted u distance value to get
|
||||
|
||||
if ( distance ) {
|
||||
|
||||
targetArcLength = distance;
|
||||
|
||||
} else {
|
||||
|
||||
targetArcLength = u * arcLengths[ il - 1 ];
|
||||
|
||||
}
|
||||
|
||||
// binary search for the index with largest value smaller than target u distance
|
||||
|
||||
let low = 0, high = il - 1, comparison;
|
||||
|
||||
while ( low <= high ) {
|
||||
|
||||
i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
|
||||
|
||||
comparison = arcLengths[ i ] - targetArcLength;
|
||||
|
||||
if ( comparison < 0 ) {
|
||||
|
||||
low = i + 1;
|
||||
|
||||
} else if ( comparison > 0 ) {
|
||||
|
||||
high = i - 1;
|
||||
|
||||
} else {
|
||||
|
||||
high = i;
|
||||
break;
|
||||
|
||||
// DONE
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
i = high;
|
||||
|
||||
if ( arcLengths[ i ] === targetArcLength ) {
|
||||
|
||||
return i / ( il - 1 );
|
||||
|
||||
}
|
||||
|
||||
// we could get finer grain at lengths, or use simple interpolation between two points
|
||||
|
||||
const lengthBefore = arcLengths[ i ];
|
||||
const lengthAfter = arcLengths[ i + 1 ];
|
||||
|
||||
const segmentLength = lengthAfter - lengthBefore;
|
||||
|
||||
// determine where we are between the 'before' and 'after' points
|
||||
|
||||
const segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
|
||||
|
||||
// add that fractional amount to t
|
||||
|
||||
const t = ( i + segmentFraction ) / ( il - 1 );
|
||||
|
||||
return t;
|
||||
|
||||
}
|
||||
|
||||
// Returns a unit vector tangent at t
|
||||
// In case any sub curve does not implement its tangent derivation,
|
||||
// 2 points a small delta apart will be used to find its gradient
|
||||
// which seems to give a reasonable approximation
|
||||
|
||||
getTangent( t, optionalTarget ) {
|
||||
|
||||
const delta = 0.0001;
|
||||
let t1 = t - delta;
|
||||
let t2 = t + delta;
|
||||
|
||||
// Capping in case of danger
|
||||
|
||||
if ( t1 < 0 ) t1 = 0;
|
||||
if ( t2 > 1 ) t2 = 1;
|
||||
|
||||
const pt1 = this.getPoint( t1 );
|
||||
const pt2 = this.getPoint( t2 );
|
||||
|
||||
const tangent = optionalTarget || ( ( pt1.isVector2 ) ? new Vector2() : new Vector3() );
|
||||
|
||||
tangent.copy( pt2 ).sub( pt1 ).normalize();
|
||||
|
||||
return tangent;
|
||||
|
||||
}
|
||||
|
||||
getTangentAt( u, optionalTarget ) {
|
||||
|
||||
const t = this.getUtoTmapping( u );
|
||||
return this.getTangent( t, optionalTarget );
|
||||
|
||||
}
|
||||
|
||||
computeFrenetFrames( segments, closed ) {
|
||||
|
||||
// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
|
||||
|
||||
const normal = new Vector3();
|
||||
|
||||
const tangents = [];
|
||||
const normals = [];
|
||||
const binormals = [];
|
||||
|
||||
const vec = new Vector3();
|
||||
const mat = new Matrix4();
|
||||
|
||||
// compute the tangent vectors for each segment on the curve
|
||||
|
||||
for ( let i = 0; i <= segments; i ++ ) {
|
||||
|
||||
const u = i / segments;
|
||||
|
||||
tangents[ i ] = this.getTangentAt( u, new Vector3() );
|
||||
|
||||
}
|
||||
|
||||
// select an initial normal vector perpendicular to the first tangent vector,
|
||||
// and in the direction of the minimum tangent xyz component
|
||||
|
||||
normals[ 0 ] = new Vector3();
|
||||
binormals[ 0 ] = new Vector3();
|
||||
let min = Number.MAX_VALUE;
|
||||
const tx = Math.abs( tangents[ 0 ].x );
|
||||
const ty = Math.abs( tangents[ 0 ].y );
|
||||
const tz = Math.abs( tangents[ 0 ].z );
|
||||
|
||||
if ( tx <= min ) {
|
||||
|
||||
min = tx;
|
||||
normal.set( 1, 0, 0 );
|
||||
|
||||
}
|
||||
|
||||
if ( ty <= min ) {
|
||||
|
||||
min = ty;
|
||||
normal.set( 0, 1, 0 );
|
||||
|
||||
}
|
||||
|
||||
if ( tz <= min ) {
|
||||
|
||||
normal.set( 0, 0, 1 );
|
||||
|
||||
}
|
||||
|
||||
vec.crossVectors( tangents[ 0 ], normal ).normalize();
|
||||
|
||||
normals[ 0 ].crossVectors( tangents[ 0 ], vec );
|
||||
binormals[ 0 ].crossVectors( tangents[ 0 ], normals[ 0 ] );
|
||||
|
||||
|
||||
// compute the slowly-varying normal and binormal vectors for each segment on the curve
|
||||
|
||||
for ( let i = 1; i <= segments; i ++ ) {
|
||||
|
||||
normals[ i ] = normals[ i - 1 ].clone();
|
||||
|
||||
binormals[ i ] = binormals[ i - 1 ].clone();
|
||||
|
||||
vec.crossVectors( tangents[ i - 1 ], tangents[ i ] );
|
||||
|
||||
if ( vec.length() > Number.EPSILON ) {
|
||||
|
||||
vec.normalize();
|
||||
|
||||
const theta = Math.acos( MathUtils.clamp( tangents[ i - 1 ].dot( tangents[ i ] ), - 1, 1 ) ); // clamp for floating pt errors
|
||||
|
||||
normals[ i ].applyMatrix4( mat.makeRotationAxis( vec, theta ) );
|
||||
|
||||
}
|
||||
|
||||
binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
|
||||
|
||||
}
|
||||
|
||||
// if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
|
||||
|
||||
if ( closed === true ) {
|
||||
|
||||
let theta = Math.acos( MathUtils.clamp( normals[ 0 ].dot( normals[ segments ] ), - 1, 1 ) );
|
||||
theta /= segments;
|
||||
|
||||
if ( tangents[ 0 ].dot( vec.crossVectors( normals[ 0 ], normals[ segments ] ) ) > 0 ) {
|
||||
|
||||
theta = - theta;
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 1; i <= segments; i ++ ) {
|
||||
|
||||
// twist a little...
|
||||
normals[ i ].applyMatrix4( mat.makeRotationAxis( tangents[ i ], theta * i ) );
|
||||
binormals[ i ].crossVectors( tangents[ i ], normals[ i ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
tangents: tangents,
|
||||
normals: normals,
|
||||
binormals: binormals
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return new this.constructor().copy( this );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
this.arcLengthDivisions = source.arcLengthDivisions;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = {
|
||||
metadata: {
|
||||
version: 4.6,
|
||||
type: 'Curve',
|
||||
generator: 'Curve.toJSON'
|
||||
}
|
||||
};
|
||||
|
||||
data.arcLengthDivisions = this.arcLengthDivisions;
|
||||
data.type = this.type;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
this.arcLengthDivisions = json.arcLengthDivisions;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { Curve };
|
||||
255
network-visualization/node_modules/three/src/extras/core/CurvePath.js
generated
vendored
Normal file
255
network-visualization/node_modules/three/src/extras/core/CurvePath.js
generated
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
import { Curve } from './Curve.js';
|
||||
import * as Curves from '../curves/Curves.js';
|
||||
|
||||
/**************************************************************
|
||||
* Curved Path - a curve path is simply a array of connected
|
||||
* curves, but retains the api of a curve
|
||||
**************************************************************/
|
||||
|
||||
class CurvePath extends Curve {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'CurvePath';
|
||||
|
||||
this.curves = [];
|
||||
this.autoClose = false; // Automatically closes the path
|
||||
|
||||
}
|
||||
|
||||
add( curve ) {
|
||||
|
||||
this.curves.push( curve );
|
||||
|
||||
}
|
||||
|
||||
closePath() {
|
||||
|
||||
// Add a line curve if start and end of lines are not connected
|
||||
const startPoint = this.curves[ 0 ].getPoint( 0 );
|
||||
const endPoint = this.curves[ this.curves.length - 1 ].getPoint( 1 );
|
||||
|
||||
if ( ! startPoint.equals( endPoint ) ) {
|
||||
|
||||
const lineType = ( startPoint.isVector2 === true ) ? 'LineCurve' : 'LineCurve3';
|
||||
this.curves.push( new Curves[ lineType ]( endPoint, startPoint ) );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
// To get accurate point with reference to
|
||||
// entire path distance at time t,
|
||||
// following has to be done:
|
||||
|
||||
// 1. Length of each sub path have to be known
|
||||
// 2. Locate and identify type of curve
|
||||
// 3. Get t for the curve
|
||||
// 4. Return curve.getPointAt(t')
|
||||
|
||||
getPoint( t, optionalTarget ) {
|
||||
|
||||
const d = t * this.getLength();
|
||||
const curveLengths = this.getCurveLengths();
|
||||
let i = 0;
|
||||
|
||||
// To think about boundaries points.
|
||||
|
||||
while ( i < curveLengths.length ) {
|
||||
|
||||
if ( curveLengths[ i ] >= d ) {
|
||||
|
||||
const diff = curveLengths[ i ] - d;
|
||||
const curve = this.curves[ i ];
|
||||
|
||||
const segmentLength = curve.getLength();
|
||||
const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
|
||||
|
||||
return curve.getPointAt( u, optionalTarget );
|
||||
|
||||
}
|
||||
|
||||
i ++;
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
// loop where sum != 0, sum > d , sum+1 <d
|
||||
|
||||
}
|
||||
|
||||
// We cannot use the default THREE.Curve getPoint() with getLength() because in
|
||||
// THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
|
||||
// getPoint() depends on getLength
|
||||
|
||||
getLength() {
|
||||
|
||||
const lens = this.getCurveLengths();
|
||||
return lens[ lens.length - 1 ];
|
||||
|
||||
}
|
||||
|
||||
// cacheLengths must be recalculated.
|
||||
updateArcLengths() {
|
||||
|
||||
this.needsUpdate = true;
|
||||
this.cacheLengths = null;
|
||||
this.getCurveLengths();
|
||||
|
||||
}
|
||||
|
||||
// Compute lengths and cache them
|
||||
// We cannot overwrite getLengths() because UtoT mapping uses it.
|
||||
|
||||
getCurveLengths() {
|
||||
|
||||
// We use cache values if curves and cache array are same length
|
||||
|
||||
if ( this.cacheLengths && this.cacheLengths.length === this.curves.length ) {
|
||||
|
||||
return this.cacheLengths;
|
||||
|
||||
}
|
||||
|
||||
// Get length of sub-curve
|
||||
// Push sums into cached array
|
||||
|
||||
const lengths = [];
|
||||
let sums = 0;
|
||||
|
||||
for ( let i = 0, l = this.curves.length; i < l; i ++ ) {
|
||||
|
||||
sums += this.curves[ i ].getLength();
|
||||
lengths.push( sums );
|
||||
|
||||
}
|
||||
|
||||
this.cacheLengths = lengths;
|
||||
|
||||
return lengths;
|
||||
|
||||
}
|
||||
|
||||
getSpacedPoints( divisions = 40 ) {
|
||||
|
||||
const points = [];
|
||||
|
||||
for ( let i = 0; i <= divisions; i ++ ) {
|
||||
|
||||
points.push( this.getPoint( i / divisions ) );
|
||||
|
||||
}
|
||||
|
||||
if ( this.autoClose ) {
|
||||
|
||||
points.push( points[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
return points;
|
||||
|
||||
}
|
||||
|
||||
getPoints( divisions = 12 ) {
|
||||
|
||||
const points = [];
|
||||
let last;
|
||||
|
||||
for ( let i = 0, curves = this.curves; i < curves.length; i ++ ) {
|
||||
|
||||
const curve = curves[ i ];
|
||||
const resolution = curve.isEllipseCurve ? divisions * 2
|
||||
: ( curve.isLineCurve || curve.isLineCurve3 ) ? 1
|
||||
: curve.isSplineCurve ? divisions * curve.points.length
|
||||
: divisions;
|
||||
|
||||
const pts = curve.getPoints( resolution );
|
||||
|
||||
for ( let j = 0; j < pts.length; j ++ ) {
|
||||
|
||||
const point = pts[ j ];
|
||||
|
||||
if ( last && last.equals( point ) ) continue; // ensures no consecutive points are duplicates
|
||||
|
||||
points.push( point );
|
||||
last = point;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( this.autoClose && points.length > 1 && ! points[ points.length - 1 ].equals( points[ 0 ] ) ) {
|
||||
|
||||
points.push( points[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
return points;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.curves = [];
|
||||
|
||||
for ( let i = 0, l = source.curves.length; i < l; i ++ ) {
|
||||
|
||||
const curve = source.curves[ i ];
|
||||
|
||||
this.curves.push( curve.clone() );
|
||||
|
||||
}
|
||||
|
||||
this.autoClose = source.autoClose;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.autoClose = this.autoClose;
|
||||
data.curves = [];
|
||||
|
||||
for ( let i = 0, l = this.curves.length; i < l; i ++ ) {
|
||||
|
||||
const curve = this.curves[ i ];
|
||||
data.curves.push( curve.toJSON() );
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.autoClose = json.autoClose;
|
||||
this.curves = [];
|
||||
|
||||
for ( let i = 0, l = json.curves.length; i < l; i ++ ) {
|
||||
|
||||
const curve = json.curves[ i ];
|
||||
this.curves.push( new Curves[ curve.type ]().fromJSON( curve ) );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { CurvePath };
|
||||
79
network-visualization/node_modules/three/src/extras/core/Interpolations.js
generated
vendored
Normal file
79
network-visualization/node_modules/three/src/extras/core/Interpolations.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Bezier Curves formulas obtained from
|
||||
* https://en.wikipedia.org/wiki/B%C3%A9zier_curve
|
||||
*/
|
||||
|
||||
function CatmullRom( t, p0, p1, p2, p3 ) {
|
||||
|
||||
const v0 = ( p2 - p0 ) * 0.5;
|
||||
const v1 = ( p3 - p1 ) * 0.5;
|
||||
const t2 = t * t;
|
||||
const t3 = t * t2;
|
||||
return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function QuadraticBezierP0( t, p ) {
|
||||
|
||||
const k = 1 - t;
|
||||
return k * k * p;
|
||||
|
||||
}
|
||||
|
||||
function QuadraticBezierP1( t, p ) {
|
||||
|
||||
return 2 * ( 1 - t ) * t * p;
|
||||
|
||||
}
|
||||
|
||||
function QuadraticBezierP2( t, p ) {
|
||||
|
||||
return t * t * p;
|
||||
|
||||
}
|
||||
|
||||
function QuadraticBezier( t, p0, p1, p2 ) {
|
||||
|
||||
return QuadraticBezierP0( t, p0 ) + QuadraticBezierP1( t, p1 ) +
|
||||
QuadraticBezierP2( t, p2 );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function CubicBezierP0( t, p ) {
|
||||
|
||||
const k = 1 - t;
|
||||
return k * k * k * p;
|
||||
|
||||
}
|
||||
|
||||
function CubicBezierP1( t, p ) {
|
||||
|
||||
const k = 1 - t;
|
||||
return 3 * k * k * t * p;
|
||||
|
||||
}
|
||||
|
||||
function CubicBezierP2( t, p ) {
|
||||
|
||||
return 3 * ( 1 - t ) * t * t * p;
|
||||
|
||||
}
|
||||
|
||||
function CubicBezierP3( t, p ) {
|
||||
|
||||
return t * t * t * p;
|
||||
|
||||
}
|
||||
|
||||
function CubicBezier( t, p0, p1, p2, p3 ) {
|
||||
|
||||
return CubicBezierP0( t, p0 ) + CubicBezierP1( t, p1 ) + CubicBezierP2( t, p2 ) +
|
||||
CubicBezierP3( t, p3 );
|
||||
|
||||
}
|
||||
|
||||
export { CatmullRom, QuadraticBezier, CubicBezier };
|
||||
196
network-visualization/node_modules/three/src/extras/core/Path.js
generated
vendored
Normal file
196
network-visualization/node_modules/three/src/extras/core/Path.js
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
import { CurvePath } from './CurvePath.js';
|
||||
import { EllipseCurve } from '../curves/EllipseCurve.js';
|
||||
import { SplineCurve } from '../curves/SplineCurve.js';
|
||||
import { CubicBezierCurve } from '../curves/CubicBezierCurve.js';
|
||||
import { QuadraticBezierCurve } from '../curves/QuadraticBezierCurve.js';
|
||||
import { LineCurve } from '../curves/LineCurve.js';
|
||||
|
||||
class Path extends CurvePath {
|
||||
|
||||
constructor( points ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'Path';
|
||||
|
||||
this.currentPoint = new Vector2();
|
||||
|
||||
if ( points ) {
|
||||
|
||||
this.setFromPoints( points );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setFromPoints( points ) {
|
||||
|
||||
this.moveTo( points[ 0 ].x, points[ 0 ].y );
|
||||
|
||||
for ( let i = 1, l = points.length; i < l; i ++ ) {
|
||||
|
||||
this.lineTo( points[ i ].x, points[ i ].y );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
moveTo( x, y ) {
|
||||
|
||||
this.currentPoint.set( x, y ); // TODO consider referencing vectors instead of copying?
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
lineTo( x, y ) {
|
||||
|
||||
const curve = new LineCurve( this.currentPoint.clone(), new Vector2( x, y ) );
|
||||
this.curves.push( curve );
|
||||
|
||||
this.currentPoint.set( x, y );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
quadraticCurveTo( aCPx, aCPy, aX, aY ) {
|
||||
|
||||
const curve = new QuadraticBezierCurve(
|
||||
this.currentPoint.clone(),
|
||||
new Vector2( aCPx, aCPy ),
|
||||
new Vector2( aX, aY )
|
||||
);
|
||||
|
||||
this.curves.push( curve );
|
||||
|
||||
this.currentPoint.set( aX, aY );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
|
||||
|
||||
const curve = new CubicBezierCurve(
|
||||
this.currentPoint.clone(),
|
||||
new Vector2( aCP1x, aCP1y ),
|
||||
new Vector2( aCP2x, aCP2y ),
|
||||
new Vector2( aX, aY )
|
||||
);
|
||||
|
||||
this.curves.push( curve );
|
||||
|
||||
this.currentPoint.set( aX, aY );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
splineThru( pts /*Array of Vector*/ ) {
|
||||
|
||||
const npts = [ this.currentPoint.clone() ].concat( pts );
|
||||
|
||||
const curve = new SplineCurve( npts );
|
||||
this.curves.push( curve );
|
||||
|
||||
this.currentPoint.copy( pts[ pts.length - 1 ] );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
arc( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
|
||||
|
||||
const x0 = this.currentPoint.x;
|
||||
const y0 = this.currentPoint.y;
|
||||
|
||||
this.absarc( aX + x0, aY + y0, aRadius,
|
||||
aStartAngle, aEndAngle, aClockwise );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
absarc( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
|
||||
|
||||
this.absellipse( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
ellipse( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
|
||||
|
||||
const x0 = this.currentPoint.x;
|
||||
const y0 = this.currentPoint.y;
|
||||
|
||||
this.absellipse( aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
absellipse( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
|
||||
|
||||
const curve = new EllipseCurve( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation );
|
||||
|
||||
if ( this.curves.length > 0 ) {
|
||||
|
||||
// if a previous curve is present, attempt to join
|
||||
const firstPoint = curve.getPoint( 0 );
|
||||
|
||||
if ( ! firstPoint.equals( this.currentPoint ) ) {
|
||||
|
||||
this.lineTo( firstPoint.x, firstPoint.y );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.curves.push( curve );
|
||||
|
||||
const lastPoint = curve.getPoint( 1 );
|
||||
this.currentPoint.copy( lastPoint );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.currentPoint.copy( source.currentPoint );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.currentPoint = this.currentPoint.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.currentPoint.fromArray( json.currentPoint );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { Path };
|
||||
102
network-visualization/node_modules/three/src/extras/core/Shape.js
generated
vendored
Normal file
102
network-visualization/node_modules/three/src/extras/core/Shape.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
import { Path } from './Path.js';
|
||||
import * as MathUtils from '../../math/MathUtils.js';
|
||||
|
||||
class Shape extends Path {
|
||||
|
||||
constructor( points ) {
|
||||
|
||||
super( points );
|
||||
|
||||
this.uuid = MathUtils.generateUUID();
|
||||
|
||||
this.type = 'Shape';
|
||||
|
||||
this.holes = [];
|
||||
|
||||
}
|
||||
|
||||
getPointsHoles( divisions ) {
|
||||
|
||||
const holesPts = [];
|
||||
|
||||
for ( let i = 0, l = this.holes.length; i < l; i ++ ) {
|
||||
|
||||
holesPts[ i ] = this.holes[ i ].getPoints( divisions );
|
||||
|
||||
}
|
||||
|
||||
return holesPts;
|
||||
|
||||
}
|
||||
|
||||
// get points of shape and holes (keypoints based on segments parameter)
|
||||
|
||||
extractPoints( divisions ) {
|
||||
|
||||
return {
|
||||
|
||||
shape: this.getPoints( divisions ),
|
||||
holes: this.getPointsHoles( divisions )
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.holes = [];
|
||||
|
||||
for ( let i = 0, l = source.holes.length; i < l; i ++ ) {
|
||||
|
||||
const hole = source.holes[ i ];
|
||||
|
||||
this.holes.push( hole.clone() );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.uuid = this.uuid;
|
||||
data.holes = [];
|
||||
|
||||
for ( let i = 0, l = this.holes.length; i < l; i ++ ) {
|
||||
|
||||
const hole = this.holes[ i ];
|
||||
data.holes.push( hole.toJSON() );
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.uuid = json.uuid;
|
||||
this.holes = [];
|
||||
|
||||
for ( let i = 0, l = json.holes.length; i < l; i ++ ) {
|
||||
|
||||
const hole = json.holes[ i ];
|
||||
this.holes.push( new Path().fromJSON( hole ) );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { Shape };
|
||||
291
network-visualization/node_modules/three/src/extras/core/ShapePath.js
generated
vendored
Normal file
291
network-visualization/node_modules/three/src/extras/core/ShapePath.js
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
import { Color } from '../../math/Color.js';
|
||||
import { Path } from './Path.js';
|
||||
import { Shape } from './Shape.js';
|
||||
import { ShapeUtils } from '../ShapeUtils.js';
|
||||
|
||||
class ShapePath {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.type = 'ShapePath';
|
||||
|
||||
this.color = new Color();
|
||||
|
||||
this.subPaths = [];
|
||||
this.currentPath = null;
|
||||
|
||||
}
|
||||
|
||||
moveTo( x, y ) {
|
||||
|
||||
this.currentPath = new Path();
|
||||
this.subPaths.push( this.currentPath );
|
||||
this.currentPath.moveTo( x, y );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
lineTo( x, y ) {
|
||||
|
||||
this.currentPath.lineTo( x, y );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
quadraticCurveTo( aCPx, aCPy, aX, aY ) {
|
||||
|
||||
this.currentPath.quadraticCurveTo( aCPx, aCPy, aX, aY );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY ) {
|
||||
|
||||
this.currentPath.bezierCurveTo( aCP1x, aCP1y, aCP2x, aCP2y, aX, aY );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
splineThru( pts ) {
|
||||
|
||||
this.currentPath.splineThru( pts );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toShapes( isCCW ) {
|
||||
|
||||
function toShapesNoHoles( inSubpaths ) {
|
||||
|
||||
const shapes = [];
|
||||
|
||||
for ( let i = 0, l = inSubpaths.length; i < l; i ++ ) {
|
||||
|
||||
const tmpPath = inSubpaths[ i ];
|
||||
|
||||
const tmpShape = new Shape();
|
||||
tmpShape.curves = tmpPath.curves;
|
||||
|
||||
shapes.push( tmpShape );
|
||||
|
||||
}
|
||||
|
||||
return shapes;
|
||||
|
||||
}
|
||||
|
||||
function isPointInsidePolygon( inPt, inPolygon ) {
|
||||
|
||||
const polyLen = inPolygon.length;
|
||||
|
||||
// inPt on polygon contour => immediate success or
|
||||
// toggling of inside/outside at every single! intersection point of an edge
|
||||
// with the horizontal line through inPt, left of inPt
|
||||
// not counting lowerY endpoints of edges and whole edges on that line
|
||||
let inside = false;
|
||||
for ( let p = polyLen - 1, q = 0; q < polyLen; p = q ++ ) {
|
||||
|
||||
let edgeLowPt = inPolygon[ p ];
|
||||
let edgeHighPt = inPolygon[ q ];
|
||||
|
||||
let edgeDx = edgeHighPt.x - edgeLowPt.x;
|
||||
let edgeDy = edgeHighPt.y - edgeLowPt.y;
|
||||
|
||||
if ( Math.abs( edgeDy ) > Number.EPSILON ) {
|
||||
|
||||
// not parallel
|
||||
if ( edgeDy < 0 ) {
|
||||
|
||||
edgeLowPt = inPolygon[ q ]; edgeDx = - edgeDx;
|
||||
edgeHighPt = inPolygon[ p ]; edgeDy = - edgeDy;
|
||||
|
||||
}
|
||||
|
||||
if ( ( inPt.y < edgeLowPt.y ) || ( inPt.y > edgeHighPt.y ) ) continue;
|
||||
|
||||
if ( inPt.y === edgeLowPt.y ) {
|
||||
|
||||
if ( inPt.x === edgeLowPt.x ) return true; // inPt is on contour ?
|
||||
// continue; // no intersection or edgeLowPt => doesn't count !!!
|
||||
|
||||
} else {
|
||||
|
||||
const perpEdge = edgeDy * ( inPt.x - edgeLowPt.x ) - edgeDx * ( inPt.y - edgeLowPt.y );
|
||||
if ( perpEdge === 0 ) return true; // inPt is on contour ?
|
||||
if ( perpEdge < 0 ) continue;
|
||||
inside = ! inside; // true intersection left of inPt
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// parallel or collinear
|
||||
if ( inPt.y !== edgeLowPt.y ) continue; // parallel
|
||||
// edge lies on the same horizontal line as inPt
|
||||
if ( ( ( edgeHighPt.x <= inPt.x ) && ( inPt.x <= edgeLowPt.x ) ) ||
|
||||
( ( edgeLowPt.x <= inPt.x ) && ( inPt.x <= edgeHighPt.x ) ) ) return true; // inPt: Point on contour !
|
||||
// continue;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return inside;
|
||||
|
||||
}
|
||||
|
||||
const isClockWise = ShapeUtils.isClockWise;
|
||||
|
||||
const subPaths = this.subPaths;
|
||||
if ( subPaths.length === 0 ) return [];
|
||||
|
||||
let solid, tmpPath, tmpShape;
|
||||
const shapes = [];
|
||||
|
||||
if ( subPaths.length === 1 ) {
|
||||
|
||||
tmpPath = subPaths[ 0 ];
|
||||
tmpShape = new Shape();
|
||||
tmpShape.curves = tmpPath.curves;
|
||||
shapes.push( tmpShape );
|
||||
return shapes;
|
||||
|
||||
}
|
||||
|
||||
let holesFirst = ! isClockWise( subPaths[ 0 ].getPoints() );
|
||||
holesFirst = isCCW ? ! holesFirst : holesFirst;
|
||||
|
||||
// console.log("Holes first", holesFirst);
|
||||
|
||||
const betterShapeHoles = [];
|
||||
const newShapes = [];
|
||||
let newShapeHoles = [];
|
||||
let mainIdx = 0;
|
||||
let tmpPoints;
|
||||
|
||||
newShapes[ mainIdx ] = undefined;
|
||||
newShapeHoles[ mainIdx ] = [];
|
||||
|
||||
for ( let i = 0, l = subPaths.length; i < l; i ++ ) {
|
||||
|
||||
tmpPath = subPaths[ i ];
|
||||
tmpPoints = tmpPath.getPoints();
|
||||
solid = isClockWise( tmpPoints );
|
||||
solid = isCCW ? ! solid : solid;
|
||||
|
||||
if ( solid ) {
|
||||
|
||||
if ( ( ! holesFirst ) && ( newShapes[ mainIdx ] ) ) mainIdx ++;
|
||||
|
||||
newShapes[ mainIdx ] = { s: new Shape(), p: tmpPoints };
|
||||
newShapes[ mainIdx ].s.curves = tmpPath.curves;
|
||||
|
||||
if ( holesFirst ) mainIdx ++;
|
||||
newShapeHoles[ mainIdx ] = [];
|
||||
|
||||
//console.log('cw', i);
|
||||
|
||||
} else {
|
||||
|
||||
newShapeHoles[ mainIdx ].push( { h: tmpPath, p: tmpPoints[ 0 ] } );
|
||||
|
||||
//console.log('ccw', i);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// only Holes? -> probably all Shapes with wrong orientation
|
||||
if ( ! newShapes[ 0 ] ) return toShapesNoHoles( subPaths );
|
||||
|
||||
|
||||
if ( newShapes.length > 1 ) {
|
||||
|
||||
let ambiguous = false;
|
||||
let toChange = 0;
|
||||
|
||||
for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
|
||||
|
||||
betterShapeHoles[ sIdx ] = [];
|
||||
|
||||
}
|
||||
|
||||
for ( let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx ++ ) {
|
||||
|
||||
const sho = newShapeHoles[ sIdx ];
|
||||
|
||||
for ( let hIdx = 0; hIdx < sho.length; hIdx ++ ) {
|
||||
|
||||
const ho = sho[ hIdx ];
|
||||
let hole_unassigned = true;
|
||||
|
||||
for ( let s2Idx = 0; s2Idx < newShapes.length; s2Idx ++ ) {
|
||||
|
||||
if ( isPointInsidePolygon( ho.p, newShapes[ s2Idx ].p ) ) {
|
||||
|
||||
if ( sIdx !== s2Idx ) toChange ++;
|
||||
|
||||
if ( hole_unassigned ) {
|
||||
|
||||
hole_unassigned = false;
|
||||
betterShapeHoles[ s2Idx ].push( ho );
|
||||
|
||||
} else {
|
||||
|
||||
ambiguous = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( hole_unassigned ) {
|
||||
|
||||
betterShapeHoles[ sIdx ].push( ho );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( toChange > 0 && ambiguous === false ) {
|
||||
|
||||
newShapeHoles = betterShapeHoles;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let tmpHoles;
|
||||
|
||||
for ( let i = 0, il = newShapes.length; i < il; i ++ ) {
|
||||
|
||||
tmpShape = newShapes[ i ].s;
|
||||
shapes.push( tmpShape );
|
||||
tmpHoles = newShapeHoles[ i ];
|
||||
|
||||
for ( let j = 0, jl = tmpHoles.length; j < jl; j ++ ) {
|
||||
|
||||
tmpShape.holes.push( tmpHoles[ j ].h );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//console.log("shape", shapes);
|
||||
|
||||
return shapes;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { ShapePath };
|
||||
17
network-visualization/node_modules/three/src/extras/curves/ArcCurve.js
generated
vendored
Normal file
17
network-visualization/node_modules/three/src/extras/curves/ArcCurve.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { EllipseCurve } from './EllipseCurve.js';
|
||||
|
||||
class ArcCurve extends EllipseCurve {
|
||||
|
||||
constructor( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
|
||||
|
||||
super( aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
|
||||
|
||||
this.isArcCurve = true;
|
||||
|
||||
this.type = 'ArcCurve';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { ArcCurve };
|
||||
255
network-visualization/node_modules/three/src/extras/curves/CatmullRomCurve3.js
generated
vendored
Normal file
255
network-visualization/node_modules/three/src/extras/curves/CatmullRomCurve3.js
generated
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
import { Curve } from '../core/Curve.js';
|
||||
|
||||
/**
|
||||
* Centripetal CatmullRom Curve - which is useful for avoiding
|
||||
* cusps and self-intersections in non-uniform catmull rom curves.
|
||||
* http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
|
||||
*
|
||||
* curve.type accepts centripetal(default), chordal and catmullrom
|
||||
* curve.tension is used for catmullrom which defaults to 0.5
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Based on an optimized c++ solution in
|
||||
- http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
|
||||
- http://ideone.com/NoEbVM
|
||||
|
||||
This CubicPoly class could be used for reusing some variables and calculations,
|
||||
but for three.js curve use, it could be possible inlined and flatten into a single function call
|
||||
which can be placed in CurveUtils.
|
||||
*/
|
||||
|
||||
function CubicPoly() {
|
||||
|
||||
let c0 = 0, c1 = 0, c2 = 0, c3 = 0;
|
||||
|
||||
/*
|
||||
* Compute coefficients for a cubic polynomial
|
||||
* p(s) = c0 + c1*s + c2*s^2 + c3*s^3
|
||||
* such that
|
||||
* p(0) = x0, p(1) = x1
|
||||
* and
|
||||
* p'(0) = t0, p'(1) = t1.
|
||||
*/
|
||||
function init( x0, x1, t0, t1 ) {
|
||||
|
||||
c0 = x0;
|
||||
c1 = t0;
|
||||
c2 = - 3 * x0 + 3 * x1 - 2 * t0 - t1;
|
||||
c3 = 2 * x0 - 2 * x1 + t0 + t1;
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
initCatmullRom: function ( x0, x1, x2, x3, tension ) {
|
||||
|
||||
init( x1, x2, tension * ( x2 - x0 ), tension * ( x3 - x1 ) );
|
||||
|
||||
},
|
||||
|
||||
initNonuniformCatmullRom: function ( x0, x1, x2, x3, dt0, dt1, dt2 ) {
|
||||
|
||||
// compute tangents when parameterized in [t1,t2]
|
||||
let t1 = ( x1 - x0 ) / dt0 - ( x2 - x0 ) / ( dt0 + dt1 ) + ( x2 - x1 ) / dt1;
|
||||
let t2 = ( x2 - x1 ) / dt1 - ( x3 - x1 ) / ( dt1 + dt2 ) + ( x3 - x2 ) / dt2;
|
||||
|
||||
// rescale tangents for parametrization in [0,1]
|
||||
t1 *= dt1;
|
||||
t2 *= dt1;
|
||||
|
||||
init( x1, x2, t1, t2 );
|
||||
|
||||
},
|
||||
|
||||
calc: function ( t ) {
|
||||
|
||||
const t2 = t * t;
|
||||
const t3 = t2 * t;
|
||||
return c0 + c1 * t + c2 * t2 + c3 * t3;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const tmp = /*@__PURE__*/ new Vector3();
|
||||
const px = /*@__PURE__*/ new CubicPoly();
|
||||
const py = /*@__PURE__*/ new CubicPoly();
|
||||
const pz = /*@__PURE__*/ new CubicPoly();
|
||||
|
||||
class CatmullRomCurve3 extends Curve {
|
||||
|
||||
constructor( points = [], closed = false, curveType = 'centripetal', tension = 0.5 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isCatmullRomCurve3 = true;
|
||||
|
||||
this.type = 'CatmullRomCurve3';
|
||||
|
||||
this.points = points;
|
||||
this.closed = closed;
|
||||
this.curveType = curveType;
|
||||
this.tension = tension;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget = new Vector3() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
const points = this.points;
|
||||
const l = points.length;
|
||||
|
||||
const p = ( l - ( this.closed ? 0 : 1 ) ) * t;
|
||||
let intPoint = Math.floor( p );
|
||||
let weight = p - intPoint;
|
||||
|
||||
if ( this.closed ) {
|
||||
|
||||
intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / l ) + 1 ) * l;
|
||||
|
||||
} else if ( weight === 0 && intPoint === l - 1 ) {
|
||||
|
||||
intPoint = l - 2;
|
||||
weight = 1;
|
||||
|
||||
}
|
||||
|
||||
let p0, p3; // 4 points (p1 & p2 defined below)
|
||||
|
||||
if ( this.closed || intPoint > 0 ) {
|
||||
|
||||
p0 = points[ ( intPoint - 1 ) % l ];
|
||||
|
||||
} else {
|
||||
|
||||
// extrapolate first point
|
||||
tmp.subVectors( points[ 0 ], points[ 1 ] ).add( points[ 0 ] );
|
||||
p0 = tmp;
|
||||
|
||||
}
|
||||
|
||||
const p1 = points[ intPoint % l ];
|
||||
const p2 = points[ ( intPoint + 1 ) % l ];
|
||||
|
||||
if ( this.closed || intPoint + 2 < l ) {
|
||||
|
||||
p3 = points[ ( intPoint + 2 ) % l ];
|
||||
|
||||
} else {
|
||||
|
||||
// extrapolate last point
|
||||
tmp.subVectors( points[ l - 1 ], points[ l - 2 ] ).add( points[ l - 1 ] );
|
||||
p3 = tmp;
|
||||
|
||||
}
|
||||
|
||||
if ( this.curveType === 'centripetal' || this.curveType === 'chordal' ) {
|
||||
|
||||
// init Centripetal / Chordal Catmull-Rom
|
||||
const pow = this.curveType === 'chordal' ? 0.5 : 0.25;
|
||||
let dt0 = Math.pow( p0.distanceToSquared( p1 ), pow );
|
||||
let dt1 = Math.pow( p1.distanceToSquared( p2 ), pow );
|
||||
let dt2 = Math.pow( p2.distanceToSquared( p3 ), pow );
|
||||
|
||||
// safety check for repeated points
|
||||
if ( dt1 < 1e-4 ) dt1 = 1.0;
|
||||
if ( dt0 < 1e-4 ) dt0 = dt1;
|
||||
if ( dt2 < 1e-4 ) dt2 = dt1;
|
||||
|
||||
px.initNonuniformCatmullRom( p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2 );
|
||||
py.initNonuniformCatmullRom( p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2 );
|
||||
pz.initNonuniformCatmullRom( p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2 );
|
||||
|
||||
} else if ( this.curveType === 'catmullrom' ) {
|
||||
|
||||
px.initCatmullRom( p0.x, p1.x, p2.x, p3.x, this.tension );
|
||||
py.initCatmullRom( p0.y, p1.y, p2.y, p3.y, this.tension );
|
||||
pz.initCatmullRom( p0.z, p1.z, p2.z, p3.z, this.tension );
|
||||
|
||||
}
|
||||
|
||||
point.set(
|
||||
px.calc( weight ),
|
||||
py.calc( weight ),
|
||||
pz.calc( weight )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( let i = 0, l = source.points.length; i < l; i ++ ) {
|
||||
|
||||
const point = source.points[ i ];
|
||||
|
||||
this.points.push( point.clone() );
|
||||
|
||||
}
|
||||
|
||||
this.closed = source.closed;
|
||||
this.curveType = source.curveType;
|
||||
this.tension = source.tension;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.points = [];
|
||||
|
||||
for ( let i = 0, l = this.points.length; i < l; i ++ ) {
|
||||
|
||||
const point = this.points[ i ];
|
||||
data.points.push( point.toArray() );
|
||||
|
||||
}
|
||||
|
||||
data.closed = this.closed;
|
||||
data.curveType = this.curveType;
|
||||
data.tension = this.tension;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( let i = 0, l = json.points.length; i < l; i ++ ) {
|
||||
|
||||
const point = json.points[ i ];
|
||||
this.points.push( new Vector3().fromArray( point ) );
|
||||
|
||||
}
|
||||
|
||||
this.closed = json.closed;
|
||||
this.curveType = json.curveType;
|
||||
this.tension = json.tension;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { CatmullRomCurve3 };
|
||||
78
network-visualization/node_modules/three/src/extras/curves/CubicBezierCurve.js
generated
vendored
Normal file
78
network-visualization/node_modules/three/src/extras/curves/CubicBezierCurve.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { CubicBezier } from '../core/Interpolations.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
class CubicBezierCurve extends Curve {
|
||||
|
||||
constructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isCubicBezierCurve = true;
|
||||
|
||||
this.type = 'CubicBezierCurve';
|
||||
|
||||
this.v0 = v0;
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
this.v3 = v3;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget = new Vector2() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
const v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
|
||||
|
||||
point.set(
|
||||
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
|
||||
CubicBezier( t, v0.y, v1.y, v2.y, v3.y )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
this.v3.copy( source.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
data.v3 = this.v3.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
this.v3.fromArray( json.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { CubicBezierCurve };
|
||||
79
network-visualization/node_modules/three/src/extras/curves/CubicBezierCurve3.js
generated
vendored
Normal file
79
network-visualization/node_modules/three/src/extras/curves/CubicBezierCurve3.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { CubicBezier } from '../core/Interpolations.js';
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
|
||||
class CubicBezierCurve3 extends Curve {
|
||||
|
||||
constructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isCubicBezierCurve3 = true;
|
||||
|
||||
this.type = 'CubicBezierCurve3';
|
||||
|
||||
this.v0 = v0;
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
this.v3 = v3;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget = new Vector3() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
const v0 = this.v0, v1 = this.v1, v2 = this.v2, v3 = this.v3;
|
||||
|
||||
point.set(
|
||||
CubicBezier( t, v0.x, v1.x, v2.x, v3.x ),
|
||||
CubicBezier( t, v0.y, v1.y, v2.y, v3.y ),
|
||||
CubicBezier( t, v0.z, v1.z, v2.z, v3.z )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
this.v3.copy( source.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
data.v3 = this.v3.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
this.v3.fromArray( json.v3 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { CubicBezierCurve3 };
|
||||
10
network-visualization/node_modules/three/src/extras/curves/Curves.js
generated
vendored
Normal file
10
network-visualization/node_modules/three/src/extras/curves/Curves.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export { ArcCurve } from './ArcCurve.js';
|
||||
export { CatmullRomCurve3 } from './CatmullRomCurve3.js';
|
||||
export { CubicBezierCurve } from './CubicBezierCurve.js';
|
||||
export { CubicBezierCurve3 } from './CubicBezierCurve3.js';
|
||||
export { EllipseCurve } from './EllipseCurve.js';
|
||||
export { LineCurve } from './LineCurve.js';
|
||||
export { LineCurve3 } from './LineCurve3.js';
|
||||
export { QuadraticBezierCurve } from './QuadraticBezierCurve.js';
|
||||
export { QuadraticBezierCurve3 } from './QuadraticBezierCurve3.js';
|
||||
export { SplineCurve } from './SplineCurve.js';
|
||||
156
network-visualization/node_modules/three/src/extras/curves/EllipseCurve.js
generated
vendored
Normal file
156
network-visualization/node_modules/three/src/extras/curves/EllipseCurve.js
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
class EllipseCurve extends Curve {
|
||||
|
||||
constructor( aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isEllipseCurve = true;
|
||||
|
||||
this.type = 'EllipseCurve';
|
||||
|
||||
this.aX = aX;
|
||||
this.aY = aY;
|
||||
|
||||
this.xRadius = xRadius;
|
||||
this.yRadius = yRadius;
|
||||
|
||||
this.aStartAngle = aStartAngle;
|
||||
this.aEndAngle = aEndAngle;
|
||||
|
||||
this.aClockwise = aClockwise;
|
||||
|
||||
this.aRotation = aRotation;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget ) {
|
||||
|
||||
const point = optionalTarget || new Vector2();
|
||||
|
||||
const twoPi = Math.PI * 2;
|
||||
let deltaAngle = this.aEndAngle - this.aStartAngle;
|
||||
const samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
|
||||
|
||||
// ensures that deltaAngle is 0 .. 2 PI
|
||||
while ( deltaAngle < 0 ) deltaAngle += twoPi;
|
||||
while ( deltaAngle > twoPi ) deltaAngle -= twoPi;
|
||||
|
||||
if ( deltaAngle < Number.EPSILON ) {
|
||||
|
||||
if ( samePoints ) {
|
||||
|
||||
deltaAngle = 0;
|
||||
|
||||
} else {
|
||||
|
||||
deltaAngle = twoPi;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( this.aClockwise === true && ! samePoints ) {
|
||||
|
||||
if ( deltaAngle === twoPi ) {
|
||||
|
||||
deltaAngle = - twoPi;
|
||||
|
||||
} else {
|
||||
|
||||
deltaAngle = deltaAngle - twoPi;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const angle = this.aStartAngle + t * deltaAngle;
|
||||
let x = this.aX + this.xRadius * Math.cos( angle );
|
||||
let y = this.aY + this.yRadius * Math.sin( angle );
|
||||
|
||||
if ( this.aRotation !== 0 ) {
|
||||
|
||||
const cos = Math.cos( this.aRotation );
|
||||
const sin = Math.sin( this.aRotation );
|
||||
|
||||
const tx = x - this.aX;
|
||||
const ty = y - this.aY;
|
||||
|
||||
// Rotate the point about the center of the ellipse.
|
||||
x = tx * cos - ty * sin + this.aX;
|
||||
y = tx * sin + ty * cos + this.aY;
|
||||
|
||||
}
|
||||
|
||||
return point.set( x, y );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.aX = source.aX;
|
||||
this.aY = source.aY;
|
||||
|
||||
this.xRadius = source.xRadius;
|
||||
this.yRadius = source.yRadius;
|
||||
|
||||
this.aStartAngle = source.aStartAngle;
|
||||
this.aEndAngle = source.aEndAngle;
|
||||
|
||||
this.aClockwise = source.aClockwise;
|
||||
|
||||
this.aRotation = source.aRotation;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.aX = this.aX;
|
||||
data.aY = this.aY;
|
||||
|
||||
data.xRadius = this.xRadius;
|
||||
data.yRadius = this.yRadius;
|
||||
|
||||
data.aStartAngle = this.aStartAngle;
|
||||
data.aEndAngle = this.aEndAngle;
|
||||
|
||||
data.aClockwise = this.aClockwise;
|
||||
|
||||
data.aRotation = this.aRotation;
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.aX = json.aX;
|
||||
this.aY = json.aY;
|
||||
|
||||
this.xRadius = json.xRadius;
|
||||
this.yRadius = json.yRadius;
|
||||
|
||||
this.aStartAngle = json.aStartAngle;
|
||||
this.aEndAngle = json.aEndAngle;
|
||||
|
||||
this.aClockwise = json.aClockwise;
|
||||
|
||||
this.aRotation = json.aRotation;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { EllipseCurve };
|
||||
92
network-visualization/node_modules/three/src/extras/curves/LineCurve.js
generated
vendored
Normal file
92
network-visualization/node_modules/three/src/extras/curves/LineCurve.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
import { Curve } from '../core/Curve.js';
|
||||
|
||||
class LineCurve extends Curve {
|
||||
|
||||
constructor( v1 = new Vector2(), v2 = new Vector2() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isLineCurve = true;
|
||||
|
||||
this.type = 'LineCurve';
|
||||
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget = new Vector2() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
if ( t === 1 ) {
|
||||
|
||||
point.copy( this.v2 );
|
||||
|
||||
} else {
|
||||
|
||||
point.copy( this.v2 ).sub( this.v1 );
|
||||
point.multiplyScalar( t ).add( this.v1 );
|
||||
|
||||
}
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
|
||||
// Line curve is linear, so we can overwrite default getPointAt
|
||||
getPointAt( u, optionalTarget ) {
|
||||
|
||||
return this.getPoint( u, optionalTarget );
|
||||
|
||||
}
|
||||
|
||||
getTangent( t, optionalTarget = new Vector2() ) {
|
||||
|
||||
return optionalTarget.subVectors( this.v2, this.v1 ).normalize();
|
||||
|
||||
}
|
||||
|
||||
getTangentAt( u, optionalTarget ) {
|
||||
|
||||
return this.getTangent( u, optionalTarget );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { LineCurve };
|
||||
88
network-visualization/node_modules/three/src/extras/curves/LineCurve3.js
generated
vendored
Normal file
88
network-visualization/node_modules/three/src/extras/curves/LineCurve3.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
import { Curve } from '../core/Curve.js';
|
||||
|
||||
class LineCurve3 extends Curve {
|
||||
|
||||
constructor( v1 = new Vector3(), v2 = new Vector3() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isLineCurve3 = true;
|
||||
|
||||
this.type = 'LineCurve3';
|
||||
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
|
||||
}
|
||||
getPoint( t, optionalTarget = new Vector3() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
if ( t === 1 ) {
|
||||
|
||||
point.copy( this.v2 );
|
||||
|
||||
} else {
|
||||
|
||||
point.copy( this.v2 ).sub( this.v1 );
|
||||
point.multiplyScalar( t ).add( this.v1 );
|
||||
|
||||
}
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
// Line curve is linear, so we can overwrite default getPointAt
|
||||
getPointAt( u, optionalTarget ) {
|
||||
|
||||
return this.getPoint( u, optionalTarget );
|
||||
|
||||
}
|
||||
|
||||
getTangent( t, optionalTarget = new Vector3() ) {
|
||||
|
||||
return optionalTarget.subVectors( this.v2, this.v1 ).normalize();
|
||||
|
||||
}
|
||||
|
||||
getTangentAt( u, optionalTarget ) {
|
||||
|
||||
return this.getTangent( u, optionalTarget );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { LineCurve3 };
|
||||
74
network-visualization/node_modules/three/src/extras/curves/QuadraticBezierCurve.js
generated
vendored
Normal file
74
network-visualization/node_modules/three/src/extras/curves/QuadraticBezierCurve.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { QuadraticBezier } from '../core/Interpolations.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
class QuadraticBezierCurve extends Curve {
|
||||
|
||||
constructor( v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isQuadraticBezierCurve = true;
|
||||
|
||||
this.type = 'QuadraticBezierCurve';
|
||||
|
||||
this.v0 = v0;
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget = new Vector2() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
const v0 = this.v0, v1 = this.v1, v2 = this.v2;
|
||||
|
||||
point.set(
|
||||
QuadraticBezier( t, v0.x, v1.x, v2.x ),
|
||||
QuadraticBezier( t, v0.y, v1.y, v2.y )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { QuadraticBezierCurve };
|
||||
75
network-visualization/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js
generated
vendored
Normal file
75
network-visualization/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { QuadraticBezier } from '../core/Interpolations.js';
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
|
||||
class QuadraticBezierCurve3 extends Curve {
|
||||
|
||||
constructor( v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3() ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isQuadraticBezierCurve3 = true;
|
||||
|
||||
this.type = 'QuadraticBezierCurve3';
|
||||
|
||||
this.v0 = v0;
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget = new Vector3() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
const v0 = this.v0, v1 = this.v1, v2 = this.v2;
|
||||
|
||||
point.set(
|
||||
QuadraticBezier( t, v0.x, v1.x, v2.x ),
|
||||
QuadraticBezier( t, v0.y, v1.y, v2.y ),
|
||||
QuadraticBezier( t, v0.z, v1.z, v2.z )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.v0.copy( source.v0 );
|
||||
this.v1.copy( source.v1 );
|
||||
this.v2.copy( source.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.v0 = this.v0.toArray();
|
||||
data.v1 = this.v1.toArray();
|
||||
data.v2 = this.v2.toArray();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.v0.fromArray( json.v0 );
|
||||
this.v1.fromArray( json.v1 );
|
||||
this.v2.fromArray( json.v2 );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { QuadraticBezierCurve3 };
|
||||
97
network-visualization/node_modules/three/src/extras/curves/SplineCurve.js
generated
vendored
Normal file
97
network-visualization/node_modules/three/src/extras/curves/SplineCurve.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
import { Curve } from '../core/Curve.js';
|
||||
import { CatmullRom } from '../core/Interpolations.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
class SplineCurve extends Curve {
|
||||
|
||||
constructor( points = [] ) {
|
||||
|
||||
super();
|
||||
|
||||
this.isSplineCurve = true;
|
||||
|
||||
this.type = 'SplineCurve';
|
||||
|
||||
this.points = points;
|
||||
|
||||
}
|
||||
|
||||
getPoint( t, optionalTarget = new Vector2() ) {
|
||||
|
||||
const point = optionalTarget;
|
||||
|
||||
const points = this.points;
|
||||
const p = ( points.length - 1 ) * t;
|
||||
|
||||
const intPoint = Math.floor( p );
|
||||
const weight = p - intPoint;
|
||||
|
||||
const p0 = points[ intPoint === 0 ? intPoint : intPoint - 1 ];
|
||||
const p1 = points[ intPoint ];
|
||||
const p2 = points[ intPoint > points.length - 2 ? points.length - 1 : intPoint + 1 ];
|
||||
const p3 = points[ intPoint > points.length - 3 ? points.length - 1 : intPoint + 2 ];
|
||||
|
||||
point.set(
|
||||
CatmullRom( weight, p0.x, p1.x, p2.x, p3.x ),
|
||||
CatmullRom( weight, p0.y, p1.y, p2.y, p3.y )
|
||||
);
|
||||
|
||||
return point;
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( let i = 0, l = source.points.length; i < l; i ++ ) {
|
||||
|
||||
const point = source.points[ i ];
|
||||
|
||||
this.points.push( point.clone() );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.points = [];
|
||||
|
||||
for ( let i = 0, l = this.points.length; i < l; i ++ ) {
|
||||
|
||||
const point = this.points[ i ];
|
||||
data.points.push( point.toArray() );
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
fromJSON( json ) {
|
||||
|
||||
super.fromJSON( json );
|
||||
|
||||
this.points = [];
|
||||
|
||||
for ( let i = 0, l = json.points.length; i < l; i ++ ) {
|
||||
|
||||
const point = json.points[ i ];
|
||||
this.points.push( new Vector2().fromArray( point ) );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { SplineCurve };
|
||||
180
network-visualization/node_modules/three/src/geometries/BoxGeometry.js
generated
vendored
Normal file
180
network-visualization/node_modules/three/src/geometries/BoxGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
class BoxGeometry extends BufferGeometry {
|
||||
|
||||
constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'BoxGeometry';
|
||||
|
||||
this.parameters = {
|
||||
width: width,
|
||||
height: height,
|
||||
depth: depth,
|
||||
widthSegments: widthSegments,
|
||||
heightSegments: heightSegments,
|
||||
depthSegments: depthSegments
|
||||
};
|
||||
|
||||
const scope = this;
|
||||
|
||||
// segments
|
||||
|
||||
widthSegments = Math.floor( widthSegments );
|
||||
heightSegments = Math.floor( heightSegments );
|
||||
depthSegments = Math.floor( depthSegments );
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// helper variables
|
||||
|
||||
let numberOfVertices = 0;
|
||||
let groupStart = 0;
|
||||
|
||||
// build each side of the box geometry
|
||||
|
||||
buildPlane( 'z', 'y', 'x', - 1, - 1, depth, height, width, depthSegments, heightSegments, 0 ); // px
|
||||
buildPlane( 'z', 'y', 'x', 1, - 1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx
|
||||
buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py
|
||||
buildPlane( 'x', 'z', 'y', 1, - 1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny
|
||||
buildPlane( 'x', 'y', 'z', 1, - 1, width, height, depth, widthSegments, heightSegments, 4 ); // pz
|
||||
buildPlane( 'x', 'y', 'z', - 1, - 1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) {
|
||||
|
||||
const segmentWidth = width / gridX;
|
||||
const segmentHeight = height / gridY;
|
||||
|
||||
const widthHalf = width / 2;
|
||||
const heightHalf = height / 2;
|
||||
const depthHalf = depth / 2;
|
||||
|
||||
const gridX1 = gridX + 1;
|
||||
const gridY1 = gridY + 1;
|
||||
|
||||
let vertexCounter = 0;
|
||||
let groupCount = 0;
|
||||
|
||||
const vector = new Vector3();
|
||||
|
||||
// generate vertices, normals and uvs
|
||||
|
||||
for ( let iy = 0; iy < gridY1; iy ++ ) {
|
||||
|
||||
const y = iy * segmentHeight - heightHalf;
|
||||
|
||||
for ( let ix = 0; ix < gridX1; ix ++ ) {
|
||||
|
||||
const x = ix * segmentWidth - widthHalf;
|
||||
|
||||
// set values to correct vector component
|
||||
|
||||
vector[ u ] = x * udir;
|
||||
vector[ v ] = y * vdir;
|
||||
vector[ w ] = depthHalf;
|
||||
|
||||
// now apply vector to vertex buffer
|
||||
|
||||
vertices.push( vector.x, vector.y, vector.z );
|
||||
|
||||
// set values to correct vector component
|
||||
|
||||
vector[ u ] = 0;
|
||||
vector[ v ] = 0;
|
||||
vector[ w ] = depth > 0 ? 1 : - 1;
|
||||
|
||||
// now apply vector to normal buffer
|
||||
|
||||
normals.push( vector.x, vector.y, vector.z );
|
||||
|
||||
// uvs
|
||||
|
||||
uvs.push( ix / gridX );
|
||||
uvs.push( 1 - ( iy / gridY ) );
|
||||
|
||||
// counters
|
||||
|
||||
vertexCounter += 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// indices
|
||||
|
||||
// 1. you need three indices to draw a single face
|
||||
// 2. a single segment consists of two faces
|
||||
// 3. so we need to generate six (2*3) indices per segment
|
||||
|
||||
for ( let iy = 0; iy < gridY; iy ++ ) {
|
||||
|
||||
for ( let ix = 0; ix < gridX; ix ++ ) {
|
||||
|
||||
const a = numberOfVertices + ix + gridX1 * iy;
|
||||
const b = numberOfVertices + ix + gridX1 * ( iy + 1 );
|
||||
const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 );
|
||||
const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy;
|
||||
|
||||
// faces
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( b, c, d );
|
||||
|
||||
// increase counter
|
||||
|
||||
groupCount += 6;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// add a group to the geometry. this will ensure multi material support
|
||||
|
||||
scope.addGroup( groupStart, groupCount, materialIndex );
|
||||
|
||||
// calculate new start value for groups
|
||||
|
||||
groupStart += groupCount;
|
||||
|
||||
// update total number of vertices
|
||||
|
||||
numberOfVertices += vertexCounter;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { BoxGeometry };
|
||||
33
network-visualization/node_modules/three/src/geometries/CapsuleGeometry.js
generated
vendored
Normal file
33
network-visualization/node_modules/three/src/geometries/CapsuleGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Path } from '../extras/core/Path.js';
|
||||
import { LatheGeometry } from './LatheGeometry.js';
|
||||
|
||||
class CapsuleGeometry extends LatheGeometry {
|
||||
|
||||
constructor( radius = 1, length = 1, capSegments = 4, radialSegments = 8 ) {
|
||||
|
||||
const path = new Path();
|
||||
path.absarc( 0, - length / 2, radius, Math.PI * 1.5, 0 );
|
||||
path.absarc( 0, length / 2, radius, 0, Math.PI * 0.5 );
|
||||
|
||||
super( path.getPoints( capSegments ), radialSegments );
|
||||
|
||||
this.type = 'CapsuleGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
length: length,
|
||||
capSegments: capSegments,
|
||||
radialSegments: radialSegments,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new CapsuleGeometry( data.radius, data.length, data.capSegments, data.radialSegments );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { CapsuleGeometry };
|
||||
101
network-visualization/node_modules/three/src/geometries/CircleGeometry.js
generated
vendored
Normal file
101
network-visualization/node_modules/three/src/geometries/CircleGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
|
||||
class CircleGeometry extends BufferGeometry {
|
||||
|
||||
constructor( radius = 1, segments = 32, thetaStart = 0, thetaLength = Math.PI * 2 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'CircleGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
segments: segments,
|
||||
thetaStart: thetaStart,
|
||||
thetaLength: thetaLength
|
||||
};
|
||||
|
||||
segments = Math.max( 3, segments );
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// helper variables
|
||||
|
||||
const vertex = new Vector3();
|
||||
const uv = new Vector2();
|
||||
|
||||
// center point
|
||||
|
||||
vertices.push( 0, 0, 0 );
|
||||
normals.push( 0, 0, 1 );
|
||||
uvs.push( 0.5, 0.5 );
|
||||
|
||||
for ( let s = 0, i = 3; s <= segments; s ++, i += 3 ) {
|
||||
|
||||
const segment = thetaStart + s / segments * thetaLength;
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = radius * Math.cos( segment );
|
||||
vertex.y = radius * Math.sin( segment );
|
||||
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// normal
|
||||
|
||||
normals.push( 0, 0, 1 );
|
||||
|
||||
// uvs
|
||||
|
||||
uv.x = ( vertices[ i ] / radius + 1 ) / 2;
|
||||
uv.y = ( vertices[ i + 1 ] / radius + 1 ) / 2;
|
||||
|
||||
uvs.push( uv.x, uv.y );
|
||||
|
||||
}
|
||||
|
||||
// indices
|
||||
|
||||
for ( let i = 1; i <= segments; i ++ ) {
|
||||
|
||||
indices.push( i, i + 1, 0 );
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new CircleGeometry( data.radius, data.segments, data.thetaStart, data.thetaLength );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { CircleGeometry };
|
||||
31
network-visualization/node_modules/three/src/geometries/ConeGeometry.js
generated
vendored
Normal file
31
network-visualization/node_modules/three/src/geometries/ConeGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import { CylinderGeometry } from './CylinderGeometry.js';
|
||||
|
||||
class ConeGeometry extends CylinderGeometry {
|
||||
|
||||
constructor( radius = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) {
|
||||
|
||||
super( 0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength );
|
||||
|
||||
this.type = 'ConeGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
height: height,
|
||||
radialSegments: radialSegments,
|
||||
heightSegments: heightSegments,
|
||||
openEnded: openEnded,
|
||||
thetaStart: thetaStart,
|
||||
thetaLength: thetaLength
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new ConeGeometry( data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { ConeGeometry };
|
||||
286
network-visualization/node_modules/three/src/geometries/CylinderGeometry.js
generated
vendored
Normal file
286
network-visualization/node_modules/three/src/geometries/CylinderGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
|
||||
class CylinderGeometry extends BufferGeometry {
|
||||
|
||||
constructor( radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 32, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'CylinderGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radiusTop: radiusTop,
|
||||
radiusBottom: radiusBottom,
|
||||
height: height,
|
||||
radialSegments: radialSegments,
|
||||
heightSegments: heightSegments,
|
||||
openEnded: openEnded,
|
||||
thetaStart: thetaStart,
|
||||
thetaLength: thetaLength
|
||||
};
|
||||
|
||||
const scope = this;
|
||||
|
||||
radialSegments = Math.floor( radialSegments );
|
||||
heightSegments = Math.floor( heightSegments );
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// helper variables
|
||||
|
||||
let index = 0;
|
||||
const indexArray = [];
|
||||
const halfHeight = height / 2;
|
||||
let groupStart = 0;
|
||||
|
||||
// generate geometry
|
||||
|
||||
generateTorso();
|
||||
|
||||
if ( openEnded === false ) {
|
||||
|
||||
if ( radiusTop > 0 ) generateCap( true );
|
||||
if ( radiusBottom > 0 ) generateCap( false );
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
function generateTorso() {
|
||||
|
||||
const normal = new Vector3();
|
||||
const vertex = new Vector3();
|
||||
|
||||
let groupCount = 0;
|
||||
|
||||
// this will be used to calculate the normal
|
||||
const slope = ( radiusBottom - radiusTop ) / height;
|
||||
|
||||
// generate vertices, normals and uvs
|
||||
|
||||
for ( let y = 0; y <= heightSegments; y ++ ) {
|
||||
|
||||
const indexRow = [];
|
||||
|
||||
const v = y / heightSegments;
|
||||
|
||||
// calculate the radius of the current row
|
||||
|
||||
const radius = v * ( radiusBottom - radiusTop ) + radiusTop;
|
||||
|
||||
for ( let x = 0; x <= radialSegments; x ++ ) {
|
||||
|
||||
const u = x / radialSegments;
|
||||
|
||||
const theta = u * thetaLength + thetaStart;
|
||||
|
||||
const sinTheta = Math.sin( theta );
|
||||
const cosTheta = Math.cos( theta );
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = radius * sinTheta;
|
||||
vertex.y = - v * height + halfHeight;
|
||||
vertex.z = radius * cosTheta;
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// normal
|
||||
|
||||
normal.set( sinTheta, slope, cosTheta ).normalize();
|
||||
normals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
// uv
|
||||
|
||||
uvs.push( u, 1 - v );
|
||||
|
||||
// save index of vertex in respective row
|
||||
|
||||
indexRow.push( index ++ );
|
||||
|
||||
}
|
||||
|
||||
// now save vertices of the row in our index array
|
||||
|
||||
indexArray.push( indexRow );
|
||||
|
||||
}
|
||||
|
||||
// generate indices
|
||||
|
||||
for ( let x = 0; x < radialSegments; x ++ ) {
|
||||
|
||||
for ( let y = 0; y < heightSegments; y ++ ) {
|
||||
|
||||
// we use the index array to access the correct indices
|
||||
|
||||
const a = indexArray[ y ][ x ];
|
||||
const b = indexArray[ y + 1 ][ x ];
|
||||
const c = indexArray[ y + 1 ][ x + 1 ];
|
||||
const d = indexArray[ y ][ x + 1 ];
|
||||
|
||||
// faces
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( b, c, d );
|
||||
|
||||
// update group counter
|
||||
|
||||
groupCount += 6;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// add a group to the geometry. this will ensure multi material support
|
||||
|
||||
scope.addGroup( groupStart, groupCount, 0 );
|
||||
|
||||
// calculate new start value for groups
|
||||
|
||||
groupStart += groupCount;
|
||||
|
||||
}
|
||||
|
||||
function generateCap( top ) {
|
||||
|
||||
// save the index of the first center vertex
|
||||
const centerIndexStart = index;
|
||||
|
||||
const uv = new Vector2();
|
||||
const vertex = new Vector3();
|
||||
|
||||
let groupCount = 0;
|
||||
|
||||
const radius = ( top === true ) ? radiusTop : radiusBottom;
|
||||
const sign = ( top === true ) ? 1 : - 1;
|
||||
|
||||
// first we generate the center vertex data of the cap.
|
||||
// because the geometry needs one set of uvs per face,
|
||||
// we must generate a center vertex per face/segment
|
||||
|
||||
for ( let x = 1; x <= radialSegments; x ++ ) {
|
||||
|
||||
// vertex
|
||||
|
||||
vertices.push( 0, halfHeight * sign, 0 );
|
||||
|
||||
// normal
|
||||
|
||||
normals.push( 0, sign, 0 );
|
||||
|
||||
// uv
|
||||
|
||||
uvs.push( 0.5, 0.5 );
|
||||
|
||||
// increase index
|
||||
|
||||
index ++;
|
||||
|
||||
}
|
||||
|
||||
// save the index of the last center vertex
|
||||
const centerIndexEnd = index;
|
||||
|
||||
// now we generate the surrounding vertices, normals and uvs
|
||||
|
||||
for ( let x = 0; x <= radialSegments; x ++ ) {
|
||||
|
||||
const u = x / radialSegments;
|
||||
const theta = u * thetaLength + thetaStart;
|
||||
|
||||
const cosTheta = Math.cos( theta );
|
||||
const sinTheta = Math.sin( theta );
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = radius * sinTheta;
|
||||
vertex.y = halfHeight * sign;
|
||||
vertex.z = radius * cosTheta;
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// normal
|
||||
|
||||
normals.push( 0, sign, 0 );
|
||||
|
||||
// uv
|
||||
|
||||
uv.x = ( cosTheta * 0.5 ) + 0.5;
|
||||
uv.y = ( sinTheta * 0.5 * sign ) + 0.5;
|
||||
uvs.push( uv.x, uv.y );
|
||||
|
||||
// increase index
|
||||
|
||||
index ++;
|
||||
|
||||
}
|
||||
|
||||
// generate indices
|
||||
|
||||
for ( let x = 0; x < radialSegments; x ++ ) {
|
||||
|
||||
const c = centerIndexStart + x;
|
||||
const i = centerIndexEnd + x;
|
||||
|
||||
if ( top === true ) {
|
||||
|
||||
// face top
|
||||
|
||||
indices.push( i, i + 1, c );
|
||||
|
||||
} else {
|
||||
|
||||
// face bottom
|
||||
|
||||
indices.push( i + 1, i, c );
|
||||
|
||||
}
|
||||
|
||||
groupCount += 3;
|
||||
|
||||
}
|
||||
|
||||
// add a group to the geometry. this will ensure multi material support
|
||||
|
||||
scope.addGroup( groupStart, groupCount, top === true ? 1 : 2 );
|
||||
|
||||
// calculate new start value for groups
|
||||
|
||||
groupStart += groupCount;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new CylinderGeometry( data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { CylinderGeometry };
|
||||
66
network-visualization/node_modules/three/src/geometries/DodecahedronGeometry.js
generated
vendored
Normal file
66
network-visualization/node_modules/three/src/geometries/DodecahedronGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
import { PolyhedronGeometry } from './PolyhedronGeometry.js';
|
||||
|
||||
class DodecahedronGeometry extends PolyhedronGeometry {
|
||||
|
||||
constructor( radius = 1, detail = 0 ) {
|
||||
|
||||
const t = ( 1 + Math.sqrt( 5 ) ) / 2;
|
||||
const r = 1 / t;
|
||||
|
||||
const vertices = [
|
||||
|
||||
// (±1, ±1, ±1)
|
||||
- 1, - 1, - 1, - 1, - 1, 1,
|
||||
- 1, 1, - 1, - 1, 1, 1,
|
||||
1, - 1, - 1, 1, - 1, 1,
|
||||
1, 1, - 1, 1, 1, 1,
|
||||
|
||||
// (0, ±1/φ, ±φ)
|
||||
0, - r, - t, 0, - r, t,
|
||||
0, r, - t, 0, r, t,
|
||||
|
||||
// (±1/φ, ±φ, 0)
|
||||
- r, - t, 0, - r, t, 0,
|
||||
r, - t, 0, r, t, 0,
|
||||
|
||||
// (±φ, 0, ±1/φ)
|
||||
- t, 0, - r, t, 0, - r,
|
||||
- t, 0, r, t, 0, r
|
||||
];
|
||||
|
||||
const indices = [
|
||||
3, 11, 7, 3, 7, 15, 3, 15, 13,
|
||||
7, 19, 17, 7, 17, 6, 7, 6, 15,
|
||||
17, 4, 8, 17, 8, 10, 17, 10, 6,
|
||||
8, 0, 16, 8, 16, 2, 8, 2, 10,
|
||||
0, 12, 1, 0, 1, 18, 0, 18, 16,
|
||||
6, 10, 2, 6, 2, 13, 6, 13, 15,
|
||||
2, 16, 18, 2, 18, 3, 2, 3, 13,
|
||||
18, 1, 9, 18, 9, 11, 18, 11, 3,
|
||||
4, 14, 12, 4, 12, 0, 4, 0, 8,
|
||||
11, 9, 5, 11, 5, 19, 11, 19, 7,
|
||||
19, 5, 14, 19, 14, 4, 19, 4, 17,
|
||||
1, 12, 14, 1, 14, 5, 1, 5, 9
|
||||
];
|
||||
|
||||
super( vertices, indices, radius, detail );
|
||||
|
||||
this.type = 'DodecahedronGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
detail: detail
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new DodecahedronGeometry( data.radius, data.detail );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { DodecahedronGeometry };
|
||||
152
network-visualization/node_modules/three/src/geometries/EdgesGeometry.js
generated
vendored
Normal file
152
network-visualization/node_modules/three/src/geometries/EdgesGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
import { Triangle } from '../math/Triangle.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
const _v0 = /*@__PURE__*/ new Vector3();
|
||||
const _v1 = /*@__PURE__*/ new Vector3();
|
||||
const _normal = /*@__PURE__*/ new Vector3();
|
||||
const _triangle = /*@__PURE__*/ new Triangle();
|
||||
|
||||
class EdgesGeometry extends BufferGeometry {
|
||||
|
||||
constructor( geometry = null, thresholdAngle = 1 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'EdgesGeometry';
|
||||
|
||||
this.parameters = {
|
||||
geometry: geometry,
|
||||
thresholdAngle: thresholdAngle
|
||||
};
|
||||
|
||||
if ( geometry !== null ) {
|
||||
|
||||
const precisionPoints = 4;
|
||||
const precision = Math.pow( 10, precisionPoints );
|
||||
const thresholdDot = Math.cos( MathUtils.DEG2RAD * thresholdAngle );
|
||||
|
||||
const indexAttr = geometry.getIndex();
|
||||
const positionAttr = geometry.getAttribute( 'position' );
|
||||
const indexCount = indexAttr ? indexAttr.count : positionAttr.count;
|
||||
|
||||
const indexArr = [ 0, 0, 0 ];
|
||||
const vertKeys = [ 'a', 'b', 'c' ];
|
||||
const hashes = new Array( 3 );
|
||||
|
||||
const edgeData = {};
|
||||
const vertices = [];
|
||||
for ( let i = 0; i < indexCount; i += 3 ) {
|
||||
|
||||
if ( indexAttr ) {
|
||||
|
||||
indexArr[ 0 ] = indexAttr.getX( i );
|
||||
indexArr[ 1 ] = indexAttr.getX( i + 1 );
|
||||
indexArr[ 2 ] = indexAttr.getX( i + 2 );
|
||||
|
||||
} else {
|
||||
|
||||
indexArr[ 0 ] = i;
|
||||
indexArr[ 1 ] = i + 1;
|
||||
indexArr[ 2 ] = i + 2;
|
||||
|
||||
}
|
||||
|
||||
const { a, b, c } = _triangle;
|
||||
a.fromBufferAttribute( positionAttr, indexArr[ 0 ] );
|
||||
b.fromBufferAttribute( positionAttr, indexArr[ 1 ] );
|
||||
c.fromBufferAttribute( positionAttr, indexArr[ 2 ] );
|
||||
_triangle.getNormal( _normal );
|
||||
|
||||
// create hashes for the edge from the vertices
|
||||
hashes[ 0 ] = `${ Math.round( a.x * precision ) },${ Math.round( a.y * precision ) },${ Math.round( a.z * precision ) }`;
|
||||
hashes[ 1 ] = `${ Math.round( b.x * precision ) },${ Math.round( b.y * precision ) },${ Math.round( b.z * precision ) }`;
|
||||
hashes[ 2 ] = `${ Math.round( c.x * precision ) },${ Math.round( c.y * precision ) },${ Math.round( c.z * precision ) }`;
|
||||
|
||||
// skip degenerate triangles
|
||||
if ( hashes[ 0 ] === hashes[ 1 ] || hashes[ 1 ] === hashes[ 2 ] || hashes[ 2 ] === hashes[ 0 ] ) {
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// iterate over every edge
|
||||
for ( let j = 0; j < 3; j ++ ) {
|
||||
|
||||
// get the first and next vertex making up the edge
|
||||
const jNext = ( j + 1 ) % 3;
|
||||
const vecHash0 = hashes[ j ];
|
||||
const vecHash1 = hashes[ jNext ];
|
||||
const v0 = _triangle[ vertKeys[ j ] ];
|
||||
const v1 = _triangle[ vertKeys[ jNext ] ];
|
||||
|
||||
const hash = `${ vecHash0 }_${ vecHash1 }`;
|
||||
const reverseHash = `${ vecHash1 }_${ vecHash0 }`;
|
||||
|
||||
if ( reverseHash in edgeData && edgeData[ reverseHash ] ) {
|
||||
|
||||
// if we found a sibling edge add it into the vertex array if
|
||||
// it meets the angle threshold and delete the edge from the map.
|
||||
if ( _normal.dot( edgeData[ reverseHash ].normal ) <= thresholdDot ) {
|
||||
|
||||
vertices.push( v0.x, v0.y, v0.z );
|
||||
vertices.push( v1.x, v1.y, v1.z );
|
||||
|
||||
}
|
||||
|
||||
edgeData[ reverseHash ] = null;
|
||||
|
||||
} else if ( ! ( hash in edgeData ) ) {
|
||||
|
||||
// if we've already got an edge here then skip adding a new one
|
||||
edgeData[ hash ] = {
|
||||
|
||||
index0: indexArr[ j ],
|
||||
index1: indexArr[ jNext ],
|
||||
normal: _normal.clone(),
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// iterate over all remaining, unmatched edges and add them to the vertex array
|
||||
for ( const key in edgeData ) {
|
||||
|
||||
if ( edgeData[ key ] ) {
|
||||
|
||||
const { index0, index1 } = edgeData[ key ];
|
||||
_v0.fromBufferAttribute( positionAttr, index0 );
|
||||
_v1.fromBufferAttribute( positionAttr, index1 );
|
||||
|
||||
vertices.push( _v0.x, _v0.y, _v0.z );
|
||||
vertices.push( _v1.x, _v1.y, _v1.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { EdgesGeometry };
|
||||
814
network-visualization/node_modules/three/src/geometries/ExtrudeGeometry.js
generated
vendored
Normal file
814
network-visualization/node_modules/three/src/geometries/ExtrudeGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,814 @@
|
||||
/**
|
||||
* Creates extruded geometry from a path shape.
|
||||
*
|
||||
* parameters = {
|
||||
*
|
||||
* curveSegments: <int>, // number of points on the curves
|
||||
* steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
|
||||
* depth: <float>, // Depth to extrude the shape
|
||||
*
|
||||
* bevelEnabled: <bool>, // turn on bevel
|
||||
* bevelThickness: <float>, // how deep into the original shape bevel goes
|
||||
* bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel
|
||||
* bevelOffset: <float>, // how far from shape outline does bevel start
|
||||
* bevelSegments: <int>, // number of bevel layers
|
||||
*
|
||||
* extrudePath: <THREE.Curve> // curve to extrude shape along
|
||||
*
|
||||
* UVGenerator: <Object> // object that provides UV generator functions
|
||||
*
|
||||
* }
|
||||
*/
|
||||
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import * as Curves from '../extras/curves/Curves.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Shape } from '../extras/core/Shape.js';
|
||||
import { ShapeUtils } from '../extras/ShapeUtils.js';
|
||||
|
||||
class ExtrudeGeometry extends BufferGeometry {
|
||||
|
||||
constructor( shapes = new Shape( [ new Vector2( 0.5, 0.5 ), new Vector2( - 0.5, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), options = {} ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'ExtrudeGeometry';
|
||||
|
||||
this.parameters = {
|
||||
shapes: shapes,
|
||||
options: options
|
||||
};
|
||||
|
||||
shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
|
||||
|
||||
const scope = this;
|
||||
|
||||
const verticesArray = [];
|
||||
const uvArray = [];
|
||||
|
||||
for ( let i = 0, l = shapes.length; i < l; i ++ ) {
|
||||
|
||||
const shape = shapes[ i ];
|
||||
addShape( shape );
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );
|
||||
|
||||
this.computeVertexNormals();
|
||||
|
||||
// functions
|
||||
|
||||
function addShape( shape ) {
|
||||
|
||||
const placeholder = [];
|
||||
|
||||
// options
|
||||
|
||||
const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
|
||||
const steps = options.steps !== undefined ? options.steps : 1;
|
||||
const depth = options.depth !== undefined ? options.depth : 1;
|
||||
|
||||
let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
|
||||
let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2;
|
||||
let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1;
|
||||
let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;
|
||||
let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
|
||||
|
||||
const extrudePath = options.extrudePath;
|
||||
|
||||
const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator;
|
||||
|
||||
//
|
||||
|
||||
let extrudePts, extrudeByPath = false;
|
||||
let splineTube, binormal, normal, position2;
|
||||
|
||||
if ( extrudePath ) {
|
||||
|
||||
extrudePts = extrudePath.getSpacedPoints( steps );
|
||||
|
||||
extrudeByPath = true;
|
||||
bevelEnabled = false; // bevels not supported for path extrusion
|
||||
|
||||
// SETUP TNB variables
|
||||
|
||||
// TODO1 - have a .isClosed in spline?
|
||||
|
||||
splineTube = extrudePath.computeFrenetFrames( steps, false );
|
||||
|
||||
// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
|
||||
|
||||
binormal = new Vector3();
|
||||
normal = new Vector3();
|
||||
position2 = new Vector3();
|
||||
|
||||
}
|
||||
|
||||
// Safeguards if bevels are not enabled
|
||||
|
||||
if ( ! bevelEnabled ) {
|
||||
|
||||
bevelSegments = 0;
|
||||
bevelThickness = 0;
|
||||
bevelSize = 0;
|
||||
bevelOffset = 0;
|
||||
|
||||
}
|
||||
|
||||
// Variables initialization
|
||||
|
||||
const shapePoints = shape.extractPoints( curveSegments );
|
||||
|
||||
let vertices = shapePoints.shape;
|
||||
const holes = shapePoints.holes;
|
||||
|
||||
const reverse = ! ShapeUtils.isClockWise( vertices );
|
||||
|
||||
if ( reverse ) {
|
||||
|
||||
vertices = vertices.reverse();
|
||||
|
||||
// Maybe we should also check if holes are in the opposite direction, just to be safe ...
|
||||
|
||||
for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
|
||||
|
||||
const ahole = holes[ h ];
|
||||
|
||||
if ( ShapeUtils.isClockWise( ahole ) ) {
|
||||
|
||||
holes[ h ] = ahole.reverse();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
const faces = ShapeUtils.triangulateShape( vertices, holes );
|
||||
|
||||
/* Vertices */
|
||||
|
||||
const contour = vertices; // vertices has all points but contour has only points of circumference
|
||||
|
||||
for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
|
||||
|
||||
const ahole = holes[ h ];
|
||||
|
||||
vertices = vertices.concat( ahole );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function scalePt2( pt, vec, size ) {
|
||||
|
||||
if ( ! vec ) console.error( 'THREE.ExtrudeGeometry: vec does not exist' );
|
||||
|
||||
return pt.clone().addScaledVector( vec, size );
|
||||
|
||||
}
|
||||
|
||||
const vlen = vertices.length, flen = faces.length;
|
||||
|
||||
|
||||
// Find directions for point movement
|
||||
|
||||
|
||||
function getBevelVec( inPt, inPrev, inNext ) {
|
||||
|
||||
// computes for inPt the corresponding point inPt' on a new contour
|
||||
// shifted by 1 unit (length of normalized vector) to the left
|
||||
// if we walk along contour clockwise, this new contour is outside the old one
|
||||
//
|
||||
// inPt' is the intersection of the two lines parallel to the two
|
||||
// adjacent edges of inPt at a distance of 1 unit on the left side.
|
||||
|
||||
let v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
|
||||
|
||||
// good reading for geometry algorithms (here: line-line intersection)
|
||||
// http://geomalgorithms.com/a05-_intersect-1.html
|
||||
|
||||
const v_prev_x = inPt.x - inPrev.x,
|
||||
v_prev_y = inPt.y - inPrev.y;
|
||||
const v_next_x = inNext.x - inPt.x,
|
||||
v_next_y = inNext.y - inPt.y;
|
||||
|
||||
const v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
|
||||
|
||||
// check for collinear edges
|
||||
const collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
|
||||
|
||||
if ( Math.abs( collinear0 ) > Number.EPSILON ) {
|
||||
|
||||
// not collinear
|
||||
|
||||
// length of vectors for normalizing
|
||||
|
||||
const v_prev_len = Math.sqrt( v_prev_lensq );
|
||||
const v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
|
||||
|
||||
// shift adjacent points by unit vectors to the left
|
||||
|
||||
const ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
|
||||
const ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
|
||||
|
||||
const ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
|
||||
const ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
|
||||
|
||||
// scaling factor for v_prev to intersection point
|
||||
|
||||
const sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
|
||||
( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
|
||||
( v_prev_x * v_next_y - v_prev_y * v_next_x );
|
||||
|
||||
// vector from inPt to intersection point
|
||||
|
||||
v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
|
||||
v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
|
||||
|
||||
// Don't normalize!, otherwise sharp corners become ugly
|
||||
// but prevent crazy spikes
|
||||
const v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
|
||||
if ( v_trans_lensq <= 2 ) {
|
||||
|
||||
return new Vector2( v_trans_x, v_trans_y );
|
||||
|
||||
} else {
|
||||
|
||||
shrink_by = Math.sqrt( v_trans_lensq / 2 );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// handle special case of collinear edges
|
||||
|
||||
let direction_eq = false; // assumes: opposite
|
||||
|
||||
if ( v_prev_x > Number.EPSILON ) {
|
||||
|
||||
if ( v_next_x > Number.EPSILON ) {
|
||||
|
||||
direction_eq = true;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( v_prev_x < - Number.EPSILON ) {
|
||||
|
||||
if ( v_next_x < - Number.EPSILON ) {
|
||||
|
||||
direction_eq = true;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
|
||||
|
||||
direction_eq = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( direction_eq ) {
|
||||
|
||||
// console.log("Warning: lines are a straight sequence");
|
||||
v_trans_x = - v_prev_y;
|
||||
v_trans_y = v_prev_x;
|
||||
shrink_by = Math.sqrt( v_prev_lensq );
|
||||
|
||||
} else {
|
||||
|
||||
// console.log("Warning: lines are a straight spike");
|
||||
v_trans_x = v_prev_x;
|
||||
v_trans_y = v_prev_y;
|
||||
shrink_by = Math.sqrt( v_prev_lensq / 2 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
|
||||
|
||||
}
|
||||
|
||||
|
||||
const contourMovements = [];
|
||||
|
||||
for ( let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
|
||||
|
||||
if ( j === il ) j = 0;
|
||||
if ( k === il ) k = 0;
|
||||
|
||||
// (j)---(i)---(k)
|
||||
// console.log('i,j,k', i, j , k)
|
||||
|
||||
contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
|
||||
|
||||
}
|
||||
|
||||
const holesMovements = [];
|
||||
let oneHoleMovements, verticesMovements = contourMovements.concat();
|
||||
|
||||
for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
|
||||
|
||||
const ahole = holes[ h ];
|
||||
|
||||
oneHoleMovements = [];
|
||||
|
||||
for ( let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
|
||||
|
||||
if ( j === il ) j = 0;
|
||||
if ( k === il ) k = 0;
|
||||
|
||||
// (j)---(i)---(k)
|
||||
oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
|
||||
|
||||
}
|
||||
|
||||
holesMovements.push( oneHoleMovements );
|
||||
verticesMovements = verticesMovements.concat( oneHoleMovements );
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Loop bevelSegments, 1 for the front, 1 for the back
|
||||
|
||||
for ( let b = 0; b < bevelSegments; b ++ ) {
|
||||
|
||||
//for ( b = bevelSegments; b > 0; b -- ) {
|
||||
|
||||
const t = b / bevelSegments;
|
||||
const z = bevelThickness * Math.cos( t * Math.PI / 2 );
|
||||
const bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;
|
||||
|
||||
// contract shape
|
||||
|
||||
for ( let i = 0, il = contour.length; i < il; i ++ ) {
|
||||
|
||||
const vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
|
||||
|
||||
v( vert.x, vert.y, - z );
|
||||
|
||||
}
|
||||
|
||||
// expand holes
|
||||
|
||||
for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
|
||||
|
||||
const ahole = holes[ h ];
|
||||
oneHoleMovements = holesMovements[ h ];
|
||||
|
||||
for ( let i = 0, il = ahole.length; i < il; i ++ ) {
|
||||
|
||||
const vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
|
||||
|
||||
v( vert.x, vert.y, - z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const bs = bevelSize + bevelOffset;
|
||||
|
||||
// Back facing vertices
|
||||
|
||||
for ( let i = 0; i < vlen; i ++ ) {
|
||||
|
||||
const vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
|
||||
|
||||
if ( ! extrudeByPath ) {
|
||||
|
||||
v( vert.x, vert.y, 0 );
|
||||
|
||||
} else {
|
||||
|
||||
// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
|
||||
|
||||
normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
|
||||
binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
|
||||
|
||||
position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
|
||||
|
||||
v( position2.x, position2.y, position2.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Add stepped vertices...
|
||||
// Including front facing vertices
|
||||
|
||||
for ( let s = 1; s <= steps; s ++ ) {
|
||||
|
||||
for ( let i = 0; i < vlen; i ++ ) {
|
||||
|
||||
const vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
|
||||
|
||||
if ( ! extrudeByPath ) {
|
||||
|
||||
v( vert.x, vert.y, depth / steps * s );
|
||||
|
||||
} else {
|
||||
|
||||
// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
|
||||
|
||||
normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
|
||||
binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
|
||||
|
||||
position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
|
||||
|
||||
v( position2.x, position2.y, position2.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Add bevel segments planes
|
||||
|
||||
//for ( b = 1; b <= bevelSegments; b ++ ) {
|
||||
for ( let b = bevelSegments - 1; b >= 0; b -- ) {
|
||||
|
||||
const t = b / bevelSegments;
|
||||
const z = bevelThickness * Math.cos( t * Math.PI / 2 );
|
||||
const bs = bevelSize * Math.sin( t * Math.PI / 2 ) + bevelOffset;
|
||||
|
||||
// contract shape
|
||||
|
||||
for ( let i = 0, il = contour.length; i < il; i ++ ) {
|
||||
|
||||
const vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
|
||||
v( vert.x, vert.y, depth + z );
|
||||
|
||||
}
|
||||
|
||||
// expand holes
|
||||
|
||||
for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
|
||||
|
||||
const ahole = holes[ h ];
|
||||
oneHoleMovements = holesMovements[ h ];
|
||||
|
||||
for ( let i = 0, il = ahole.length; i < il; i ++ ) {
|
||||
|
||||
const vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
|
||||
|
||||
if ( ! extrudeByPath ) {
|
||||
|
||||
v( vert.x, vert.y, depth + z );
|
||||
|
||||
} else {
|
||||
|
||||
v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Faces */
|
||||
|
||||
// Top and bottom faces
|
||||
|
||||
buildLidFaces();
|
||||
|
||||
// Sides faces
|
||||
|
||||
buildSideFaces();
|
||||
|
||||
|
||||
///// Internal functions
|
||||
|
||||
function buildLidFaces() {
|
||||
|
||||
const start = verticesArray.length / 3;
|
||||
|
||||
if ( bevelEnabled ) {
|
||||
|
||||
let layer = 0; // steps + 1
|
||||
let offset = vlen * layer;
|
||||
|
||||
// Bottom faces
|
||||
|
||||
for ( let i = 0; i < flen; i ++ ) {
|
||||
|
||||
const face = faces[ i ];
|
||||
f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
|
||||
|
||||
}
|
||||
|
||||
layer = steps + bevelSegments * 2;
|
||||
offset = vlen * layer;
|
||||
|
||||
// Top faces
|
||||
|
||||
for ( let i = 0; i < flen; i ++ ) {
|
||||
|
||||
const face = faces[ i ];
|
||||
f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Bottom faces
|
||||
|
||||
for ( let i = 0; i < flen; i ++ ) {
|
||||
|
||||
const face = faces[ i ];
|
||||
f3( face[ 2 ], face[ 1 ], face[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
// Top faces
|
||||
|
||||
for ( let i = 0; i < flen; i ++ ) {
|
||||
|
||||
const face = faces[ i ];
|
||||
f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
scope.addGroup( start, verticesArray.length / 3 - start, 0 );
|
||||
|
||||
}
|
||||
|
||||
// Create faces for the z-sides of the shape
|
||||
|
||||
function buildSideFaces() {
|
||||
|
||||
const start = verticesArray.length / 3;
|
||||
let layeroffset = 0;
|
||||
sidewalls( contour, layeroffset );
|
||||
layeroffset += contour.length;
|
||||
|
||||
for ( let h = 0, hl = holes.length; h < hl; h ++ ) {
|
||||
|
||||
const ahole = holes[ h ];
|
||||
sidewalls( ahole, layeroffset );
|
||||
|
||||
//, true
|
||||
layeroffset += ahole.length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
scope.addGroup( start, verticesArray.length / 3 - start, 1 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
function sidewalls( contour, layeroffset ) {
|
||||
|
||||
let i = contour.length;
|
||||
|
||||
while ( -- i >= 0 ) {
|
||||
|
||||
const j = i;
|
||||
let k = i - 1;
|
||||
if ( k < 0 ) k = contour.length - 1;
|
||||
|
||||
//console.log('b', i,j, i-1, k,vertices.length);
|
||||
|
||||
for ( let s = 0, sl = ( steps + bevelSegments * 2 ); s < sl; s ++ ) {
|
||||
|
||||
const slen1 = vlen * s;
|
||||
const slen2 = vlen * ( s + 1 );
|
||||
|
||||
const a = layeroffset + j + slen1,
|
||||
b = layeroffset + k + slen1,
|
||||
c = layeroffset + k + slen2,
|
||||
d = layeroffset + j + slen2;
|
||||
|
||||
f4( a, b, c, d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function v( x, y, z ) {
|
||||
|
||||
placeholder.push( x );
|
||||
placeholder.push( y );
|
||||
placeholder.push( z );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function f3( a, b, c ) {
|
||||
|
||||
addVertex( a );
|
||||
addVertex( b );
|
||||
addVertex( c );
|
||||
|
||||
const nextIndex = verticesArray.length / 3;
|
||||
const uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
|
||||
|
||||
addUV( uvs[ 0 ] );
|
||||
addUV( uvs[ 1 ] );
|
||||
addUV( uvs[ 2 ] );
|
||||
|
||||
}
|
||||
|
||||
function f4( a, b, c, d ) {
|
||||
|
||||
addVertex( a );
|
||||
addVertex( b );
|
||||
addVertex( d );
|
||||
|
||||
addVertex( b );
|
||||
addVertex( c );
|
||||
addVertex( d );
|
||||
|
||||
|
||||
const nextIndex = verticesArray.length / 3;
|
||||
const uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
|
||||
|
||||
addUV( uvs[ 0 ] );
|
||||
addUV( uvs[ 1 ] );
|
||||
addUV( uvs[ 3 ] );
|
||||
|
||||
addUV( uvs[ 1 ] );
|
||||
addUV( uvs[ 2 ] );
|
||||
addUV( uvs[ 3 ] );
|
||||
|
||||
}
|
||||
|
||||
function addVertex( index ) {
|
||||
|
||||
verticesArray.push( placeholder[ index * 3 + 0 ] );
|
||||
verticesArray.push( placeholder[ index * 3 + 1 ] );
|
||||
verticesArray.push( placeholder[ index * 3 + 2 ] );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function addUV( vector2 ) {
|
||||
|
||||
uvArray.push( vector2.x );
|
||||
uvArray.push( vector2.y );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
const shapes = this.parameters.shapes;
|
||||
const options = this.parameters.options;
|
||||
|
||||
return toJSON( shapes, options, data );
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data, shapes ) {
|
||||
|
||||
const geometryShapes = [];
|
||||
|
||||
for ( let j = 0, jl = data.shapes.length; j < jl; j ++ ) {
|
||||
|
||||
const shape = shapes[ data.shapes[ j ] ];
|
||||
|
||||
geometryShapes.push( shape );
|
||||
|
||||
}
|
||||
|
||||
const extrudePath = data.options.extrudePath;
|
||||
|
||||
if ( extrudePath !== undefined ) {
|
||||
|
||||
data.options.extrudePath = new Curves[ extrudePath.type ]().fromJSON( extrudePath );
|
||||
|
||||
}
|
||||
|
||||
return new ExtrudeGeometry( geometryShapes, data.options );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const WorldUVGenerator = {
|
||||
|
||||
generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
|
||||
|
||||
const a_x = vertices[ indexA * 3 ];
|
||||
const a_y = vertices[ indexA * 3 + 1 ];
|
||||
const b_x = vertices[ indexB * 3 ];
|
||||
const b_y = vertices[ indexB * 3 + 1 ];
|
||||
const c_x = vertices[ indexC * 3 ];
|
||||
const c_y = vertices[ indexC * 3 + 1 ];
|
||||
|
||||
return [
|
||||
new Vector2( a_x, a_y ),
|
||||
new Vector2( b_x, b_y ),
|
||||
new Vector2( c_x, c_y )
|
||||
];
|
||||
|
||||
},
|
||||
|
||||
generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {
|
||||
|
||||
const a_x = vertices[ indexA * 3 ];
|
||||
const a_y = vertices[ indexA * 3 + 1 ];
|
||||
const a_z = vertices[ indexA * 3 + 2 ];
|
||||
const b_x = vertices[ indexB * 3 ];
|
||||
const b_y = vertices[ indexB * 3 + 1 ];
|
||||
const b_z = vertices[ indexB * 3 + 2 ];
|
||||
const c_x = vertices[ indexC * 3 ];
|
||||
const c_y = vertices[ indexC * 3 + 1 ];
|
||||
const c_z = vertices[ indexC * 3 + 2 ];
|
||||
const d_x = vertices[ indexD * 3 ];
|
||||
const d_y = vertices[ indexD * 3 + 1 ];
|
||||
const d_z = vertices[ indexD * 3 + 2 ];
|
||||
|
||||
if ( Math.abs( a_y - b_y ) < Math.abs( a_x - b_x ) ) {
|
||||
|
||||
return [
|
||||
new Vector2( a_x, 1 - a_z ),
|
||||
new Vector2( b_x, 1 - b_z ),
|
||||
new Vector2( c_x, 1 - c_z ),
|
||||
new Vector2( d_x, 1 - d_z )
|
||||
];
|
||||
|
||||
} else {
|
||||
|
||||
return [
|
||||
new Vector2( a_y, 1 - a_z ),
|
||||
new Vector2( b_y, 1 - b_z ),
|
||||
new Vector2( c_y, 1 - c_z ),
|
||||
new Vector2( d_y, 1 - d_z )
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function toJSON( shapes, options, data ) {
|
||||
|
||||
data.shapes = [];
|
||||
|
||||
if ( Array.isArray( shapes ) ) {
|
||||
|
||||
for ( let i = 0, l = shapes.length; i < l; i ++ ) {
|
||||
|
||||
const shape = shapes[ i ];
|
||||
|
||||
data.shapes.push( shape.uuid );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
data.shapes.push( shapes.uuid );
|
||||
|
||||
}
|
||||
|
||||
data.options = Object.assign( {}, options );
|
||||
|
||||
if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { ExtrudeGeometry };
|
||||
21
network-visualization/node_modules/three/src/geometries/Geometries.js
generated
vendored
Normal file
21
network-visualization/node_modules/three/src/geometries/Geometries.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
export * from './BoxGeometry.js';
|
||||
export * from './CapsuleGeometry.js';
|
||||
export * from './CircleGeometry.js';
|
||||
export * from './ConeGeometry.js';
|
||||
export * from './CylinderGeometry.js';
|
||||
export * from './DodecahedronGeometry.js';
|
||||
export * from './EdgesGeometry.js';
|
||||
export * from './ExtrudeGeometry.js';
|
||||
export * from './IcosahedronGeometry.js';
|
||||
export * from './LatheGeometry.js';
|
||||
export * from './OctahedronGeometry.js';
|
||||
export * from './PlaneGeometry.js';
|
||||
export * from './PolyhedronGeometry.js';
|
||||
export * from './RingGeometry.js';
|
||||
export * from './ShapeGeometry.js';
|
||||
export * from './SphereGeometry.js';
|
||||
export * from './TetrahedronGeometry.js';
|
||||
export * from './TorusGeometry.js';
|
||||
export * from './TorusKnotGeometry.js';
|
||||
export * from './TubeGeometry.js';
|
||||
export * from './WireframeGeometry.js';
|
||||
42
network-visualization/node_modules/three/src/geometries/IcosahedronGeometry.js
generated
vendored
Normal file
42
network-visualization/node_modules/three/src/geometries/IcosahedronGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import { PolyhedronGeometry } from './PolyhedronGeometry.js';
|
||||
|
||||
class IcosahedronGeometry extends PolyhedronGeometry {
|
||||
|
||||
constructor( radius = 1, detail = 0 ) {
|
||||
|
||||
const t = ( 1 + Math.sqrt( 5 ) ) / 2;
|
||||
|
||||
const vertices = [
|
||||
- 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t, 0,
|
||||
0, - 1, t, 0, 1, t, 0, - 1, - t, 0, 1, - t,
|
||||
t, 0, - 1, t, 0, 1, - t, 0, - 1, - t, 0, 1
|
||||
];
|
||||
|
||||
const indices = [
|
||||
0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11,
|
||||
1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8,
|
||||
3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9,
|
||||
4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1
|
||||
];
|
||||
|
||||
super( vertices, indices, radius, detail );
|
||||
|
||||
this.type = 'IcosahedronGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
detail: detail
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new IcosahedronGeometry( data.radius, data.detail );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { IcosahedronGeometry };
|
||||
189
network-visualization/node_modules/three/src/geometries/LatheGeometry.js
generated
vendored
Normal file
189
network-visualization/node_modules/three/src/geometries/LatheGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
import * as MathUtils from '../math/MathUtils.js';
|
||||
|
||||
class LatheGeometry extends BufferGeometry {
|
||||
|
||||
constructor( points = [ new Vector2( 0, - 0.5 ), new Vector2( 0.5, 0 ), new Vector2( 0, 0.5 ) ], segments = 12, phiStart = 0, phiLength = Math.PI * 2 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'LatheGeometry';
|
||||
|
||||
this.parameters = {
|
||||
points: points,
|
||||
segments: segments,
|
||||
phiStart: phiStart,
|
||||
phiLength: phiLength
|
||||
};
|
||||
|
||||
segments = Math.floor( segments );
|
||||
|
||||
// clamp phiLength so it's in range of [ 0, 2PI ]
|
||||
|
||||
phiLength = MathUtils.clamp( phiLength, 0, Math.PI * 2 );
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const uvs = [];
|
||||
const initNormals = [];
|
||||
const normals = [];
|
||||
|
||||
// helper variables
|
||||
|
||||
const inverseSegments = 1.0 / segments;
|
||||
const vertex = new Vector3();
|
||||
const uv = new Vector2();
|
||||
const normal = new Vector3();
|
||||
const curNormal = new Vector3();
|
||||
const prevNormal = new Vector3();
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
|
||||
// pre-compute normals for initial "meridian"
|
||||
|
||||
for ( let j = 0; j <= ( points.length - 1 ); j ++ ) {
|
||||
|
||||
switch ( j ) {
|
||||
|
||||
case 0: // special handling for 1st vertex on path
|
||||
|
||||
dx = points[ j + 1 ].x - points[ j ].x;
|
||||
dy = points[ j + 1 ].y - points[ j ].y;
|
||||
|
||||
normal.x = dy * 1.0;
|
||||
normal.y = - dx;
|
||||
normal.z = dy * 0.0;
|
||||
|
||||
prevNormal.copy( normal );
|
||||
|
||||
normal.normalize();
|
||||
|
||||
initNormals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
break;
|
||||
|
||||
case ( points.length - 1 ): // special handling for last Vertex on path
|
||||
|
||||
initNormals.push( prevNormal.x, prevNormal.y, prevNormal.z );
|
||||
|
||||
break;
|
||||
|
||||
default: // default handling for all vertices in between
|
||||
|
||||
dx = points[ j + 1 ].x - points[ j ].x;
|
||||
dy = points[ j + 1 ].y - points[ j ].y;
|
||||
|
||||
normal.x = dy * 1.0;
|
||||
normal.y = - dx;
|
||||
normal.z = dy * 0.0;
|
||||
|
||||
curNormal.copy( normal );
|
||||
|
||||
normal.x += prevNormal.x;
|
||||
normal.y += prevNormal.y;
|
||||
normal.z += prevNormal.z;
|
||||
|
||||
normal.normalize();
|
||||
|
||||
initNormals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
prevNormal.copy( curNormal );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// generate vertices, uvs and normals
|
||||
|
||||
for ( let i = 0; i <= segments; i ++ ) {
|
||||
|
||||
const phi = phiStart + i * inverseSegments * phiLength;
|
||||
|
||||
const sin = Math.sin( phi );
|
||||
const cos = Math.cos( phi );
|
||||
|
||||
for ( let j = 0; j <= ( points.length - 1 ); j ++ ) {
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = points[ j ].x * sin;
|
||||
vertex.y = points[ j ].y;
|
||||
vertex.z = points[ j ].x * cos;
|
||||
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// uv
|
||||
|
||||
uv.x = i / segments;
|
||||
uv.y = j / ( points.length - 1 );
|
||||
|
||||
uvs.push( uv.x, uv.y );
|
||||
|
||||
// normal
|
||||
|
||||
const x = initNormals[ 3 * j + 0 ] * sin;
|
||||
const y = initNormals[ 3 * j + 1 ];
|
||||
const z = initNormals[ 3 * j + 0 ] * cos;
|
||||
|
||||
normals.push( x, y, z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// indices
|
||||
|
||||
for ( let i = 0; i < segments; i ++ ) {
|
||||
|
||||
for ( let j = 0; j < ( points.length - 1 ); j ++ ) {
|
||||
|
||||
const base = j + i * points.length;
|
||||
|
||||
const a = base;
|
||||
const b = base + points.length;
|
||||
const c = base + points.length + 1;
|
||||
const d = base + 1;
|
||||
|
||||
// faces
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( c, d, b );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new LatheGeometry( data.points, data.segments, data.phiStart, data.phiLength );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { LatheGeometry };
|
||||
37
network-visualization/node_modules/three/src/geometries/OctahedronGeometry.js
generated
vendored
Normal file
37
network-visualization/node_modules/three/src/geometries/OctahedronGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PolyhedronGeometry } from './PolyhedronGeometry.js';
|
||||
|
||||
class OctahedronGeometry extends PolyhedronGeometry {
|
||||
|
||||
constructor( radius = 1, detail = 0 ) {
|
||||
|
||||
const vertices = [
|
||||
1, 0, 0, - 1, 0, 0, 0, 1, 0,
|
||||
0, - 1, 0, 0, 0, 1, 0, 0, - 1
|
||||
];
|
||||
|
||||
const indices = [
|
||||
0, 2, 4, 0, 4, 3, 0, 3, 5,
|
||||
0, 5, 2, 1, 2, 5, 1, 5, 3,
|
||||
1, 3, 4, 1, 4, 2
|
||||
];
|
||||
|
||||
super( vertices, indices, radius, detail );
|
||||
|
||||
this.type = 'OctahedronGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
detail: detail
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new OctahedronGeometry( data.radius, data.detail );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { OctahedronGeometry };
|
||||
98
network-visualization/node_modules/three/src/geometries/PlaneGeometry.js
generated
vendored
Normal file
98
network-visualization/node_modules/three/src/geometries/PlaneGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
|
||||
class PlaneGeometry extends BufferGeometry {
|
||||
|
||||
constructor( width = 1, height = 1, widthSegments = 1, heightSegments = 1 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'PlaneGeometry';
|
||||
|
||||
this.parameters = {
|
||||
width: width,
|
||||
height: height,
|
||||
widthSegments: widthSegments,
|
||||
heightSegments: heightSegments
|
||||
};
|
||||
|
||||
const width_half = width / 2;
|
||||
const height_half = height / 2;
|
||||
|
||||
const gridX = Math.floor( widthSegments );
|
||||
const gridY = Math.floor( heightSegments );
|
||||
|
||||
const gridX1 = gridX + 1;
|
||||
const gridY1 = gridY + 1;
|
||||
|
||||
const segment_width = width / gridX;
|
||||
const segment_height = height / gridY;
|
||||
|
||||
//
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
for ( let iy = 0; iy < gridY1; iy ++ ) {
|
||||
|
||||
const y = iy * segment_height - height_half;
|
||||
|
||||
for ( let ix = 0; ix < gridX1; ix ++ ) {
|
||||
|
||||
const x = ix * segment_width - width_half;
|
||||
|
||||
vertices.push( x, - y, 0 );
|
||||
|
||||
normals.push( 0, 0, 1 );
|
||||
|
||||
uvs.push( ix / gridX );
|
||||
uvs.push( 1 - ( iy / gridY ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( let iy = 0; iy < gridY; iy ++ ) {
|
||||
|
||||
for ( let ix = 0; ix < gridX; ix ++ ) {
|
||||
|
||||
const a = ix + gridX1 * iy;
|
||||
const b = ix + gridX1 * ( iy + 1 );
|
||||
const c = ( ix + 1 ) + gridX1 * ( iy + 1 );
|
||||
const d = ( ix + 1 ) + gridX1 * iy;
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( b, c, d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new PlaneGeometry( data.width, data.height, data.widthSegments, data.heightSegments );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { PlaneGeometry };
|
||||
319
network-visualization/node_modules/three/src/geometries/PolyhedronGeometry.js
generated
vendored
Normal file
319
network-visualization/node_modules/three/src/geometries/PolyhedronGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
|
||||
class PolyhedronGeometry extends BufferGeometry {
|
||||
|
||||
constructor( vertices = [], indices = [], radius = 1, detail = 0 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'PolyhedronGeometry';
|
||||
|
||||
this.parameters = {
|
||||
vertices: vertices,
|
||||
indices: indices,
|
||||
radius: radius,
|
||||
detail: detail
|
||||
};
|
||||
|
||||
// default buffer data
|
||||
|
||||
const vertexBuffer = [];
|
||||
const uvBuffer = [];
|
||||
|
||||
// the subdivision creates the vertex buffer data
|
||||
|
||||
subdivide( detail );
|
||||
|
||||
// all vertices should lie on a conceptual sphere with a given radius
|
||||
|
||||
applyRadius( radius );
|
||||
|
||||
// finally, create the uv data
|
||||
|
||||
generateUVs();
|
||||
|
||||
// build non-indexed geometry
|
||||
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertexBuffer, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( vertexBuffer.slice(), 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvBuffer, 2 ) );
|
||||
|
||||
if ( detail === 0 ) {
|
||||
|
||||
this.computeVertexNormals(); // flat normals
|
||||
|
||||
} else {
|
||||
|
||||
this.normalizeNormals(); // smooth normals
|
||||
|
||||
}
|
||||
|
||||
// helper functions
|
||||
|
||||
function subdivide( detail ) {
|
||||
|
||||
const a = new Vector3();
|
||||
const b = new Vector3();
|
||||
const c = new Vector3();
|
||||
|
||||
// iterate over all faces and apply a subdivision with the given detail value
|
||||
|
||||
for ( let i = 0; i < indices.length; i += 3 ) {
|
||||
|
||||
// get the vertices of the face
|
||||
|
||||
getVertexByIndex( indices[ i + 0 ], a );
|
||||
getVertexByIndex( indices[ i + 1 ], b );
|
||||
getVertexByIndex( indices[ i + 2 ], c );
|
||||
|
||||
// perform subdivision
|
||||
|
||||
subdivideFace( a, b, c, detail );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function subdivideFace( a, b, c, detail ) {
|
||||
|
||||
const cols = detail + 1;
|
||||
|
||||
// we use this multidimensional array as a data structure for creating the subdivision
|
||||
|
||||
const v = [];
|
||||
|
||||
// construct all of the vertices for this subdivision
|
||||
|
||||
for ( let i = 0; i <= cols; i ++ ) {
|
||||
|
||||
v[ i ] = [];
|
||||
|
||||
const aj = a.clone().lerp( c, i / cols );
|
||||
const bj = b.clone().lerp( c, i / cols );
|
||||
|
||||
const rows = cols - i;
|
||||
|
||||
for ( let j = 0; j <= rows; j ++ ) {
|
||||
|
||||
if ( j === 0 && i === cols ) {
|
||||
|
||||
v[ i ][ j ] = aj;
|
||||
|
||||
} else {
|
||||
|
||||
v[ i ][ j ] = aj.clone().lerp( bj, j / rows );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// construct all of the faces
|
||||
|
||||
for ( let i = 0; i < cols; i ++ ) {
|
||||
|
||||
for ( let j = 0; j < 2 * ( cols - i ) - 1; j ++ ) {
|
||||
|
||||
const k = Math.floor( j / 2 );
|
||||
|
||||
if ( j % 2 === 0 ) {
|
||||
|
||||
pushVertex( v[ i ][ k + 1 ] );
|
||||
pushVertex( v[ i + 1 ][ k ] );
|
||||
pushVertex( v[ i ][ k ] );
|
||||
|
||||
} else {
|
||||
|
||||
pushVertex( v[ i ][ k + 1 ] );
|
||||
pushVertex( v[ i + 1 ][ k + 1 ] );
|
||||
pushVertex( v[ i + 1 ][ k ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function applyRadius( radius ) {
|
||||
|
||||
const vertex = new Vector3();
|
||||
|
||||
// iterate over the entire buffer and apply the radius to each vertex
|
||||
|
||||
for ( let i = 0; i < vertexBuffer.length; i += 3 ) {
|
||||
|
||||
vertex.x = vertexBuffer[ i + 0 ];
|
||||
vertex.y = vertexBuffer[ i + 1 ];
|
||||
vertex.z = vertexBuffer[ i + 2 ];
|
||||
|
||||
vertex.normalize().multiplyScalar( radius );
|
||||
|
||||
vertexBuffer[ i + 0 ] = vertex.x;
|
||||
vertexBuffer[ i + 1 ] = vertex.y;
|
||||
vertexBuffer[ i + 2 ] = vertex.z;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function generateUVs() {
|
||||
|
||||
const vertex = new Vector3();
|
||||
|
||||
for ( let i = 0; i < vertexBuffer.length; i += 3 ) {
|
||||
|
||||
vertex.x = vertexBuffer[ i + 0 ];
|
||||
vertex.y = vertexBuffer[ i + 1 ];
|
||||
vertex.z = vertexBuffer[ i + 2 ];
|
||||
|
||||
const u = azimuth( vertex ) / 2 / Math.PI + 0.5;
|
||||
const v = inclination( vertex ) / Math.PI + 0.5;
|
||||
uvBuffer.push( u, 1 - v );
|
||||
|
||||
}
|
||||
|
||||
correctUVs();
|
||||
|
||||
correctSeam();
|
||||
|
||||
}
|
||||
|
||||
function correctSeam() {
|
||||
|
||||
// handle case when face straddles the seam, see #3269
|
||||
|
||||
for ( let i = 0; i < uvBuffer.length; i += 6 ) {
|
||||
|
||||
// uv data of a single face
|
||||
|
||||
const x0 = uvBuffer[ i + 0 ];
|
||||
const x1 = uvBuffer[ i + 2 ];
|
||||
const x2 = uvBuffer[ i + 4 ];
|
||||
|
||||
const max = Math.max( x0, x1, x2 );
|
||||
const min = Math.min( x0, x1, x2 );
|
||||
|
||||
// 0.9 is somewhat arbitrary
|
||||
|
||||
if ( max > 0.9 && min < 0.1 ) {
|
||||
|
||||
if ( x0 < 0.2 ) uvBuffer[ i + 0 ] += 1;
|
||||
if ( x1 < 0.2 ) uvBuffer[ i + 2 ] += 1;
|
||||
if ( x2 < 0.2 ) uvBuffer[ i + 4 ] += 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function pushVertex( vertex ) {
|
||||
|
||||
vertexBuffer.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
}
|
||||
|
||||
function getVertexByIndex( index, vertex ) {
|
||||
|
||||
const stride = index * 3;
|
||||
|
||||
vertex.x = vertices[ stride + 0 ];
|
||||
vertex.y = vertices[ stride + 1 ];
|
||||
vertex.z = vertices[ stride + 2 ];
|
||||
|
||||
}
|
||||
|
||||
function correctUVs() {
|
||||
|
||||
const a = new Vector3();
|
||||
const b = new Vector3();
|
||||
const c = new Vector3();
|
||||
|
||||
const centroid = new Vector3();
|
||||
|
||||
const uvA = new Vector2();
|
||||
const uvB = new Vector2();
|
||||
const uvC = new Vector2();
|
||||
|
||||
for ( let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6 ) {
|
||||
|
||||
a.set( vertexBuffer[ i + 0 ], vertexBuffer[ i + 1 ], vertexBuffer[ i + 2 ] );
|
||||
b.set( vertexBuffer[ i + 3 ], vertexBuffer[ i + 4 ], vertexBuffer[ i + 5 ] );
|
||||
c.set( vertexBuffer[ i + 6 ], vertexBuffer[ i + 7 ], vertexBuffer[ i + 8 ] );
|
||||
|
||||
uvA.set( uvBuffer[ j + 0 ], uvBuffer[ j + 1 ] );
|
||||
uvB.set( uvBuffer[ j + 2 ], uvBuffer[ j + 3 ] );
|
||||
uvC.set( uvBuffer[ j + 4 ], uvBuffer[ j + 5 ] );
|
||||
|
||||
centroid.copy( a ).add( b ).add( c ).divideScalar( 3 );
|
||||
|
||||
const azi = azimuth( centroid );
|
||||
|
||||
correctUV( uvA, j + 0, a, azi );
|
||||
correctUV( uvB, j + 2, b, azi );
|
||||
correctUV( uvC, j + 4, c, azi );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function correctUV( uv, stride, vector, azimuth ) {
|
||||
|
||||
if ( ( azimuth < 0 ) && ( uv.x === 1 ) ) {
|
||||
|
||||
uvBuffer[ stride ] = uv.x - 1;
|
||||
|
||||
}
|
||||
|
||||
if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) {
|
||||
|
||||
uvBuffer[ stride ] = azimuth / 2 / Math.PI + 0.5;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Angle around the Y axis, counter-clockwise when looking from above.
|
||||
|
||||
function azimuth( vector ) {
|
||||
|
||||
return Math.atan2( vector.z, - vector.x );
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Angle above the XZ plane.
|
||||
|
||||
function inclination( vector ) {
|
||||
|
||||
return Math.atan2( - vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new PolyhedronGeometry( data.vertices, data.indices, data.radius, data.details );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { PolyhedronGeometry };
|
||||
128
network-visualization/node_modules/three/src/geometries/RingGeometry.js
generated
vendored
Normal file
128
network-visualization/node_modules/three/src/geometries/RingGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
class RingGeometry extends BufferGeometry {
|
||||
|
||||
constructor( innerRadius = 0.5, outerRadius = 1, thetaSegments = 32, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'RingGeometry';
|
||||
|
||||
this.parameters = {
|
||||
innerRadius: innerRadius,
|
||||
outerRadius: outerRadius,
|
||||
thetaSegments: thetaSegments,
|
||||
phiSegments: phiSegments,
|
||||
thetaStart: thetaStart,
|
||||
thetaLength: thetaLength
|
||||
};
|
||||
|
||||
thetaSegments = Math.max( 3, thetaSegments );
|
||||
phiSegments = Math.max( 1, phiSegments );
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// some helper variables
|
||||
|
||||
let radius = innerRadius;
|
||||
const radiusStep = ( ( outerRadius - innerRadius ) / phiSegments );
|
||||
const vertex = new Vector3();
|
||||
const uv = new Vector2();
|
||||
|
||||
// generate vertices, normals and uvs
|
||||
|
||||
for ( let j = 0; j <= phiSegments; j ++ ) {
|
||||
|
||||
for ( let i = 0; i <= thetaSegments; i ++ ) {
|
||||
|
||||
// values are generate from the inside of the ring to the outside
|
||||
|
||||
const segment = thetaStart + i / thetaSegments * thetaLength;
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = radius * Math.cos( segment );
|
||||
vertex.y = radius * Math.sin( segment );
|
||||
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// normal
|
||||
|
||||
normals.push( 0, 0, 1 );
|
||||
|
||||
// uv
|
||||
|
||||
uv.x = ( vertex.x / outerRadius + 1 ) / 2;
|
||||
uv.y = ( vertex.y / outerRadius + 1 ) / 2;
|
||||
|
||||
uvs.push( uv.x, uv.y );
|
||||
|
||||
}
|
||||
|
||||
// increase the radius for next row of vertices
|
||||
|
||||
radius += radiusStep;
|
||||
|
||||
}
|
||||
|
||||
// indices
|
||||
|
||||
for ( let j = 0; j < phiSegments; j ++ ) {
|
||||
|
||||
const thetaSegmentLevel = j * ( thetaSegments + 1 );
|
||||
|
||||
for ( let i = 0; i < thetaSegments; i ++ ) {
|
||||
|
||||
const segment = i + thetaSegmentLevel;
|
||||
|
||||
const a = segment;
|
||||
const b = segment + thetaSegments + 1;
|
||||
const c = segment + thetaSegments + 2;
|
||||
const d = segment + 1;
|
||||
|
||||
// faces
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( b, c, d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new RingGeometry( data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { RingGeometry };
|
||||
195
network-visualization/node_modules/three/src/geometries/ShapeGeometry.js
generated
vendored
Normal file
195
network-visualization/node_modules/three/src/geometries/ShapeGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Shape } from '../extras/core/Shape.js';
|
||||
import { ShapeUtils } from '../extras/ShapeUtils.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
|
||||
class ShapeGeometry extends BufferGeometry {
|
||||
|
||||
constructor( shapes = new Shape( [ new Vector2( 0, 0.5 ), new Vector2( - 0.5, - 0.5 ), new Vector2( 0.5, - 0.5 ) ] ), curveSegments = 12 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'ShapeGeometry';
|
||||
|
||||
this.parameters = {
|
||||
shapes: shapes,
|
||||
curveSegments: curveSegments
|
||||
};
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// helper variables
|
||||
|
||||
let groupStart = 0;
|
||||
let groupCount = 0;
|
||||
|
||||
// allow single and array values for "shapes" parameter
|
||||
|
||||
if ( Array.isArray( shapes ) === false ) {
|
||||
|
||||
addShape( shapes );
|
||||
|
||||
} else {
|
||||
|
||||
for ( let i = 0; i < shapes.length; i ++ ) {
|
||||
|
||||
addShape( shapes[ i ] );
|
||||
|
||||
this.addGroup( groupStart, groupCount, i ); // enables MultiMaterial support
|
||||
|
||||
groupStart += groupCount;
|
||||
groupCount = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
|
||||
// helper functions
|
||||
|
||||
function addShape( shape ) {
|
||||
|
||||
const indexOffset = vertices.length / 3;
|
||||
const points = shape.extractPoints( curveSegments );
|
||||
|
||||
let shapeVertices = points.shape;
|
||||
const shapeHoles = points.holes;
|
||||
|
||||
// check direction of vertices
|
||||
|
||||
if ( ShapeUtils.isClockWise( shapeVertices ) === false ) {
|
||||
|
||||
shapeVertices = shapeVertices.reverse();
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0, l = shapeHoles.length; i < l; i ++ ) {
|
||||
|
||||
const shapeHole = shapeHoles[ i ];
|
||||
|
||||
if ( ShapeUtils.isClockWise( shapeHole ) === true ) {
|
||||
|
||||
shapeHoles[ i ] = shapeHole.reverse();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const faces = ShapeUtils.triangulateShape( shapeVertices, shapeHoles );
|
||||
|
||||
// join vertices of inner and outer paths to a single array
|
||||
|
||||
for ( let i = 0, l = shapeHoles.length; i < l; i ++ ) {
|
||||
|
||||
const shapeHole = shapeHoles[ i ];
|
||||
shapeVertices = shapeVertices.concat( shapeHole );
|
||||
|
||||
}
|
||||
|
||||
// vertices, normals, uvs
|
||||
|
||||
for ( let i = 0, l = shapeVertices.length; i < l; i ++ ) {
|
||||
|
||||
const vertex = shapeVertices[ i ];
|
||||
|
||||
vertices.push( vertex.x, vertex.y, 0 );
|
||||
normals.push( 0, 0, 1 );
|
||||
uvs.push( vertex.x, vertex.y ); // world uvs
|
||||
|
||||
}
|
||||
|
||||
// indices
|
||||
|
||||
for ( let i = 0, l = faces.length; i < l; i ++ ) {
|
||||
|
||||
const face = faces[ i ];
|
||||
|
||||
const a = face[ 0 ] + indexOffset;
|
||||
const b = face[ 1 ] + indexOffset;
|
||||
const c = face[ 2 ] + indexOffset;
|
||||
|
||||
indices.push( a, b, c );
|
||||
groupCount += 3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
const shapes = this.parameters.shapes;
|
||||
|
||||
return toJSON( shapes, data );
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data, shapes ) {
|
||||
|
||||
const geometryShapes = [];
|
||||
|
||||
for ( let j = 0, jl = data.shapes.length; j < jl; j ++ ) {
|
||||
|
||||
const shape = shapes[ data.shapes[ j ] ];
|
||||
|
||||
geometryShapes.push( shape );
|
||||
|
||||
}
|
||||
|
||||
return new ShapeGeometry( geometryShapes, data.curveSegments );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function toJSON( shapes, data ) {
|
||||
|
||||
data.shapes = [];
|
||||
|
||||
if ( Array.isArray( shapes ) ) {
|
||||
|
||||
for ( let i = 0, l = shapes.length; i < l; i ++ ) {
|
||||
|
||||
const shape = shapes[ i ];
|
||||
|
||||
data.shapes.push( shape.uuid );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
data.shapes.push( shapes.uuid );
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
export { ShapeGeometry };
|
||||
137
network-visualization/node_modules/three/src/geometries/SphereGeometry.js
generated
vendored
Normal file
137
network-visualization/node_modules/three/src/geometries/SphereGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
class SphereGeometry extends BufferGeometry {
|
||||
|
||||
constructor( radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'SphereGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
widthSegments: widthSegments,
|
||||
heightSegments: heightSegments,
|
||||
phiStart: phiStart,
|
||||
phiLength: phiLength,
|
||||
thetaStart: thetaStart,
|
||||
thetaLength: thetaLength
|
||||
};
|
||||
|
||||
widthSegments = Math.max( 3, Math.floor( widthSegments ) );
|
||||
heightSegments = Math.max( 2, Math.floor( heightSegments ) );
|
||||
|
||||
const thetaEnd = Math.min( thetaStart + thetaLength, Math.PI );
|
||||
|
||||
let index = 0;
|
||||
const grid = [];
|
||||
|
||||
const vertex = new Vector3();
|
||||
const normal = new Vector3();
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// generate vertices, normals and uvs
|
||||
|
||||
for ( let iy = 0; iy <= heightSegments; iy ++ ) {
|
||||
|
||||
const verticesRow = [];
|
||||
|
||||
const v = iy / heightSegments;
|
||||
|
||||
// special case for the poles
|
||||
|
||||
let uOffset = 0;
|
||||
|
||||
if ( iy === 0 && thetaStart === 0 ) {
|
||||
|
||||
uOffset = 0.5 / widthSegments;
|
||||
|
||||
} else if ( iy === heightSegments && thetaEnd === Math.PI ) {
|
||||
|
||||
uOffset = - 0.5 / widthSegments;
|
||||
|
||||
}
|
||||
|
||||
for ( let ix = 0; ix <= widthSegments; ix ++ ) {
|
||||
|
||||
const u = ix / widthSegments;
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
|
||||
vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
|
||||
vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
|
||||
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// normal
|
||||
|
||||
normal.copy( vertex ).normalize();
|
||||
normals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
// uv
|
||||
|
||||
uvs.push( u + uOffset, 1 - v );
|
||||
|
||||
verticesRow.push( index ++ );
|
||||
|
||||
}
|
||||
|
||||
grid.push( verticesRow );
|
||||
|
||||
}
|
||||
|
||||
// indices
|
||||
|
||||
for ( let iy = 0; iy < heightSegments; iy ++ ) {
|
||||
|
||||
for ( let ix = 0; ix < widthSegments; ix ++ ) {
|
||||
|
||||
const a = grid[ iy ][ ix + 1 ];
|
||||
const b = grid[ iy ][ ix ];
|
||||
const c = grid[ iy + 1 ][ ix ];
|
||||
const d = grid[ iy + 1 ][ ix + 1 ];
|
||||
|
||||
if ( iy !== 0 || thetaStart > 0 ) indices.push( a, b, d );
|
||||
if ( iy !== heightSegments - 1 || thetaEnd < Math.PI ) indices.push( b, c, d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new SphereGeometry( data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { SphereGeometry };
|
||||
34
network-visualization/node_modules/three/src/geometries/TetrahedronGeometry.js
generated
vendored
Normal file
34
network-visualization/node_modules/three/src/geometries/TetrahedronGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { PolyhedronGeometry } from './PolyhedronGeometry.js';
|
||||
|
||||
class TetrahedronGeometry extends PolyhedronGeometry {
|
||||
|
||||
constructor( radius = 1, detail = 0 ) {
|
||||
|
||||
const vertices = [
|
||||
1, 1, 1, - 1, - 1, 1, - 1, 1, - 1, 1, - 1, - 1
|
||||
];
|
||||
|
||||
const indices = [
|
||||
2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1
|
||||
];
|
||||
|
||||
super( vertices, indices, radius, detail );
|
||||
|
||||
this.type = 'TetrahedronGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
detail: detail
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new TetrahedronGeometry( data.radius, data.detail );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { TetrahedronGeometry };
|
||||
120
network-visualization/node_modules/three/src/geometries/TorusGeometry.js
generated
vendored
Normal file
120
network-visualization/node_modules/three/src/geometries/TorusGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
class TorusGeometry extends BufferGeometry {
|
||||
|
||||
constructor( radius = 1, tube = 0.4, radialSegments = 12, tubularSegments = 48, arc = Math.PI * 2 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'TorusGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
tube: tube,
|
||||
radialSegments: radialSegments,
|
||||
tubularSegments: tubularSegments,
|
||||
arc: arc
|
||||
};
|
||||
|
||||
radialSegments = Math.floor( radialSegments );
|
||||
tubularSegments = Math.floor( tubularSegments );
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// helper variables
|
||||
|
||||
const center = new Vector3();
|
||||
const vertex = new Vector3();
|
||||
const normal = new Vector3();
|
||||
|
||||
// generate vertices, normals and uvs
|
||||
|
||||
for ( let j = 0; j <= radialSegments; j ++ ) {
|
||||
|
||||
for ( let i = 0; i <= tubularSegments; i ++ ) {
|
||||
|
||||
const u = i / tubularSegments * arc;
|
||||
const v = j / radialSegments * Math.PI * 2;
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = ( radius + tube * Math.cos( v ) ) * Math.cos( u );
|
||||
vertex.y = ( radius + tube * Math.cos( v ) ) * Math.sin( u );
|
||||
vertex.z = tube * Math.sin( v );
|
||||
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// normal
|
||||
|
||||
center.x = radius * Math.cos( u );
|
||||
center.y = radius * Math.sin( u );
|
||||
normal.subVectors( vertex, center ).normalize();
|
||||
|
||||
normals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
// uv
|
||||
|
||||
uvs.push( i / tubularSegments );
|
||||
uvs.push( j / radialSegments );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// generate indices
|
||||
|
||||
for ( let j = 1; j <= radialSegments; j ++ ) {
|
||||
|
||||
for ( let i = 1; i <= tubularSegments; i ++ ) {
|
||||
|
||||
// indices
|
||||
|
||||
const a = ( tubularSegments + 1 ) * j + i - 1;
|
||||
const b = ( tubularSegments + 1 ) * ( j - 1 ) + i - 1;
|
||||
const c = ( tubularSegments + 1 ) * ( j - 1 ) + i;
|
||||
const d = ( tubularSegments + 1 ) * j + i;
|
||||
|
||||
// faces
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( b, c, d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new TorusGeometry( data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { TorusGeometry };
|
||||
167
network-visualization/node_modules/three/src/geometries/TorusKnotGeometry.js
generated
vendored
Normal file
167
network-visualization/node_modules/three/src/geometries/TorusKnotGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
class TorusKnotGeometry extends BufferGeometry {
|
||||
|
||||
constructor( radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'TorusKnotGeometry';
|
||||
|
||||
this.parameters = {
|
||||
radius: radius,
|
||||
tube: tube,
|
||||
tubularSegments: tubularSegments,
|
||||
radialSegments: radialSegments,
|
||||
p: p,
|
||||
q: q
|
||||
};
|
||||
|
||||
tubularSegments = Math.floor( tubularSegments );
|
||||
radialSegments = Math.floor( radialSegments );
|
||||
|
||||
// buffers
|
||||
|
||||
const indices = [];
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
|
||||
// helper variables
|
||||
|
||||
const vertex = new Vector3();
|
||||
const normal = new Vector3();
|
||||
|
||||
const P1 = new Vector3();
|
||||
const P2 = new Vector3();
|
||||
|
||||
const B = new Vector3();
|
||||
const T = new Vector3();
|
||||
const N = new Vector3();
|
||||
|
||||
// generate vertices, normals and uvs
|
||||
|
||||
for ( let i = 0; i <= tubularSegments; ++ i ) {
|
||||
|
||||
// the radian "u" is used to calculate the position on the torus curve of the current tubular segment
|
||||
|
||||
const u = i / tubularSegments * p * Math.PI * 2;
|
||||
|
||||
// now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.
|
||||
// these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions
|
||||
|
||||
calculatePositionOnCurve( u, p, q, radius, P1 );
|
||||
calculatePositionOnCurve( u + 0.01, p, q, radius, P2 );
|
||||
|
||||
// calculate orthonormal basis
|
||||
|
||||
T.subVectors( P2, P1 );
|
||||
N.addVectors( P2, P1 );
|
||||
B.crossVectors( T, N );
|
||||
N.crossVectors( B, T );
|
||||
|
||||
// normalize B, N. T can be ignored, we don't use it
|
||||
|
||||
B.normalize();
|
||||
N.normalize();
|
||||
|
||||
for ( let j = 0; j <= radialSegments; ++ j ) {
|
||||
|
||||
// now calculate the vertices. they are nothing more than an extrusion of the torus curve.
|
||||
// because we extrude a shape in the xy-plane, there is no need to calculate a z-value.
|
||||
|
||||
const v = j / radialSegments * Math.PI * 2;
|
||||
const cx = - tube * Math.cos( v );
|
||||
const cy = tube * Math.sin( v );
|
||||
|
||||
// now calculate the final vertex position.
|
||||
// first we orient the extrusion with our basis vectors, then we add it to the current position on the curve
|
||||
|
||||
vertex.x = P1.x + ( cx * N.x + cy * B.x );
|
||||
vertex.y = P1.y + ( cx * N.y + cy * B.y );
|
||||
vertex.z = P1.z + ( cx * N.z + cy * B.z );
|
||||
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
// normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)
|
||||
|
||||
normal.subVectors( vertex, P1 ).normalize();
|
||||
|
||||
normals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
// uv
|
||||
|
||||
uvs.push( i / tubularSegments );
|
||||
uvs.push( j / radialSegments );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// generate indices
|
||||
|
||||
for ( let j = 1; j <= tubularSegments; j ++ ) {
|
||||
|
||||
for ( let i = 1; i <= radialSegments; i ++ ) {
|
||||
|
||||
// indices
|
||||
|
||||
const a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
|
||||
const b = ( radialSegments + 1 ) * j + ( i - 1 );
|
||||
const c = ( radialSegments + 1 ) * j + i;
|
||||
const d = ( radialSegments + 1 ) * ( j - 1 ) + i;
|
||||
|
||||
// faces
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( b, c, d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
// this function calculates the current position on the torus curve
|
||||
|
||||
function calculatePositionOnCurve( u, p, q, radius, position ) {
|
||||
|
||||
const cu = Math.cos( u );
|
||||
const su = Math.sin( u );
|
||||
const quOverP = q / p * u;
|
||||
const cs = Math.cos( quOverP );
|
||||
|
||||
position.x = radius * ( 2 + cs ) * 0.5 * cu;
|
||||
position.y = radius * ( 2 + cs ) * su * 0.5;
|
||||
position.z = radius * Math.sin( quOverP ) * 0.5;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
return new TorusKnotGeometry( data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { TorusKnotGeometry };
|
||||
203
network-visualization/node_modules/three/src/geometries/TubeGeometry.js
generated
vendored
Normal file
203
network-visualization/node_modules/three/src/geometries/TubeGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import * as Curves from '../extras/curves/Curves.js';
|
||||
import { Vector2 } from '../math/Vector2.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
class TubeGeometry extends BufferGeometry {
|
||||
|
||||
constructor( path = new Curves[ 'QuadraticBezierCurve3' ]( new Vector3( - 1, - 1, 0 ), new Vector3( - 1, 1, 0 ), new Vector3( 1, 1, 0 ) ), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'TubeGeometry';
|
||||
|
||||
this.parameters = {
|
||||
path: path,
|
||||
tubularSegments: tubularSegments,
|
||||
radius: radius,
|
||||
radialSegments: radialSegments,
|
||||
closed: closed
|
||||
};
|
||||
|
||||
const frames = path.computeFrenetFrames( tubularSegments, closed );
|
||||
|
||||
// expose internals
|
||||
|
||||
this.tangents = frames.tangents;
|
||||
this.normals = frames.normals;
|
||||
this.binormals = frames.binormals;
|
||||
|
||||
// helper variables
|
||||
|
||||
const vertex = new Vector3();
|
||||
const normal = new Vector3();
|
||||
const uv = new Vector2();
|
||||
let P = new Vector3();
|
||||
|
||||
// buffer
|
||||
|
||||
const vertices = [];
|
||||
const normals = [];
|
||||
const uvs = [];
|
||||
const indices = [];
|
||||
|
||||
// create buffer data
|
||||
|
||||
generateBufferData();
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setIndex( indices );
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) );
|
||||
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
|
||||
|
||||
// functions
|
||||
|
||||
function generateBufferData() {
|
||||
|
||||
for ( let i = 0; i < tubularSegments; i ++ ) {
|
||||
|
||||
generateSegment( i );
|
||||
|
||||
}
|
||||
|
||||
// if the geometry is not closed, generate the last row of vertices and normals
|
||||
// at the regular position on the given path
|
||||
//
|
||||
// if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
|
||||
|
||||
generateSegment( ( closed === false ) ? tubularSegments : 0 );
|
||||
|
||||
// uvs are generated in a separate function.
|
||||
// this makes it easy compute correct values for closed geometries
|
||||
|
||||
generateUVs();
|
||||
|
||||
// finally create faces
|
||||
|
||||
generateIndices();
|
||||
|
||||
}
|
||||
|
||||
function generateSegment( i ) {
|
||||
|
||||
// we use getPointAt to sample evenly distributed points from the given path
|
||||
|
||||
P = path.getPointAt( i / tubularSegments, P );
|
||||
|
||||
// retrieve corresponding normal and binormal
|
||||
|
||||
const N = frames.normals[ i ];
|
||||
const B = frames.binormals[ i ];
|
||||
|
||||
// generate normals and vertices for the current segment
|
||||
|
||||
for ( let j = 0; j <= radialSegments; j ++ ) {
|
||||
|
||||
const v = j / radialSegments * Math.PI * 2;
|
||||
|
||||
const sin = Math.sin( v );
|
||||
const cos = - Math.cos( v );
|
||||
|
||||
// normal
|
||||
|
||||
normal.x = ( cos * N.x + sin * B.x );
|
||||
normal.y = ( cos * N.y + sin * B.y );
|
||||
normal.z = ( cos * N.z + sin * B.z );
|
||||
normal.normalize();
|
||||
|
||||
normals.push( normal.x, normal.y, normal.z );
|
||||
|
||||
// vertex
|
||||
|
||||
vertex.x = P.x + radius * normal.x;
|
||||
vertex.y = P.y + radius * normal.y;
|
||||
vertex.z = P.z + radius * normal.z;
|
||||
|
||||
vertices.push( vertex.x, vertex.y, vertex.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function generateIndices() {
|
||||
|
||||
for ( let j = 1; j <= tubularSegments; j ++ ) {
|
||||
|
||||
for ( let i = 1; i <= radialSegments; i ++ ) {
|
||||
|
||||
const a = ( radialSegments + 1 ) * ( j - 1 ) + ( i - 1 );
|
||||
const b = ( radialSegments + 1 ) * j + ( i - 1 );
|
||||
const c = ( radialSegments + 1 ) * j + i;
|
||||
const d = ( radialSegments + 1 ) * ( j - 1 ) + i;
|
||||
|
||||
// faces
|
||||
|
||||
indices.push( a, b, d );
|
||||
indices.push( b, c, d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function generateUVs() {
|
||||
|
||||
for ( let i = 0; i <= tubularSegments; i ++ ) {
|
||||
|
||||
for ( let j = 0; j <= radialSegments; j ++ ) {
|
||||
|
||||
uv.x = i / tubularSegments;
|
||||
uv.y = j / radialSegments;
|
||||
|
||||
uvs.push( uv.x, uv.y );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
||||
const data = super.toJSON();
|
||||
|
||||
data.path = this.parameters.path.toJSON();
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
static fromJSON( data ) {
|
||||
|
||||
// This only works for built-in curves (e.g. CatmullRomCurve3).
|
||||
// User defined curves or instances of CurvePath will not be deserialized.
|
||||
return new TubeGeometry(
|
||||
new Curves[ data.path.type ]().fromJSON( data.path ),
|
||||
data.tubularSegments,
|
||||
data.radius,
|
||||
data.radialSegments,
|
||||
data.closed
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { TubeGeometry };
|
||||
147
network-visualization/node_modules/three/src/geometries/WireframeGeometry.js
generated
vendored
Normal file
147
network-visualization/node_modules/three/src/geometries/WireframeGeometry.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
class WireframeGeometry extends BufferGeometry {
|
||||
|
||||
constructor( geometry = null ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'WireframeGeometry';
|
||||
|
||||
this.parameters = {
|
||||
geometry: geometry
|
||||
};
|
||||
|
||||
if ( geometry !== null ) {
|
||||
|
||||
// buffer
|
||||
|
||||
const vertices = [];
|
||||
const edges = new Set();
|
||||
|
||||
// helper variables
|
||||
|
||||
const start = new Vector3();
|
||||
const end = new Vector3();
|
||||
|
||||
if ( geometry.index !== null ) {
|
||||
|
||||
// indexed BufferGeometry
|
||||
|
||||
const position = geometry.attributes.position;
|
||||
const indices = geometry.index;
|
||||
let groups = geometry.groups;
|
||||
|
||||
if ( groups.length === 0 ) {
|
||||
|
||||
groups = [ { start: 0, count: indices.count, materialIndex: 0 } ];
|
||||
|
||||
}
|
||||
|
||||
// create a data structure that contains all edges without duplicates
|
||||
|
||||
for ( let o = 0, ol = groups.length; o < ol; ++ o ) {
|
||||
|
||||
const group = groups[ o ];
|
||||
|
||||
const groupStart = group.start;
|
||||
const groupCount = group.count;
|
||||
|
||||
for ( let i = groupStart, l = ( groupStart + groupCount ); i < l; i += 3 ) {
|
||||
|
||||
for ( let j = 0; j < 3; j ++ ) {
|
||||
|
||||
const index1 = indices.getX( i + j );
|
||||
const index2 = indices.getX( i + ( j + 1 ) % 3 );
|
||||
|
||||
start.fromBufferAttribute( position, index1 );
|
||||
end.fromBufferAttribute( position, index2 );
|
||||
|
||||
if ( isUniqueEdge( start, end, edges ) === true ) {
|
||||
|
||||
vertices.push( start.x, start.y, start.z );
|
||||
vertices.push( end.x, end.y, end.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// non-indexed BufferGeometry
|
||||
|
||||
const position = geometry.attributes.position;
|
||||
|
||||
for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) {
|
||||
|
||||
for ( let j = 0; j < 3; j ++ ) {
|
||||
|
||||
// three edges per triangle, an edge is represented as (index1, index2)
|
||||
// e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
|
||||
|
||||
const index1 = 3 * i + j;
|
||||
const index2 = 3 * i + ( ( j + 1 ) % 3 );
|
||||
|
||||
start.fromBufferAttribute( position, index1 );
|
||||
end.fromBufferAttribute( position, index2 );
|
||||
|
||||
if ( isUniqueEdge( start, end, edges ) === true ) {
|
||||
|
||||
vertices.push( start.x, start.y, start.z );
|
||||
vertices.push( end.x, end.y, end.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// build geometry
|
||||
|
||||
this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source );
|
||||
|
||||
this.parameters = Object.assign( {}, source.parameters );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function isUniqueEdge( start, end, edges ) {
|
||||
|
||||
const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`;
|
||||
const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge
|
||||
|
||||
if ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) {
|
||||
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
edges.add( hash1 );
|
||||
edges.add( hash2 );
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WireframeGeometry };
|
||||
114
network-visualization/node_modules/three/src/helpers/ArrowHelper.js
generated
vendored
Normal file
114
network-visualization/node_modules/three/src/helpers/ArrowHelper.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { CylinderGeometry } from '../geometries/CylinderGeometry.js';
|
||||
import { MeshBasicMaterial } from '../materials/MeshBasicMaterial.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { Mesh } from '../objects/Mesh.js';
|
||||
import { Line } from '../objects/Line.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
|
||||
const _axis = /*@__PURE__*/ new Vector3();
|
||||
let _lineGeometry, _coneGeometry;
|
||||
|
||||
class ArrowHelper extends Object3D {
|
||||
|
||||
// dir is assumed to be normalized
|
||||
|
||||
constructor( dir = new Vector3( 0, 0, 1 ), origin = new Vector3( 0, 0, 0 ), length = 1, color = 0xffff00, headLength = length * 0.2, headWidth = headLength * 0.2 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.type = 'ArrowHelper';
|
||||
|
||||
if ( _lineGeometry === undefined ) {
|
||||
|
||||
_lineGeometry = new BufferGeometry();
|
||||
_lineGeometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 1, 0 ], 3 ) );
|
||||
|
||||
_coneGeometry = new CylinderGeometry( 0, 0.5, 1, 5, 1 );
|
||||
_coneGeometry.translate( 0, - 0.5, 0 );
|
||||
|
||||
}
|
||||
|
||||
this.position.copy( origin );
|
||||
|
||||
this.line = new Line( _lineGeometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
|
||||
this.line.matrixAutoUpdate = false;
|
||||
this.add( this.line );
|
||||
|
||||
this.cone = new Mesh( _coneGeometry, new MeshBasicMaterial( { color: color, toneMapped: false } ) );
|
||||
this.cone.matrixAutoUpdate = false;
|
||||
this.add( this.cone );
|
||||
|
||||
this.setDirection( dir );
|
||||
this.setLength( length, headLength, headWidth );
|
||||
|
||||
}
|
||||
|
||||
setDirection( dir ) {
|
||||
|
||||
// dir is assumed to be normalized
|
||||
|
||||
if ( dir.y > 0.99999 ) {
|
||||
|
||||
this.quaternion.set( 0, 0, 0, 1 );
|
||||
|
||||
} else if ( dir.y < - 0.99999 ) {
|
||||
|
||||
this.quaternion.set( 1, 0, 0, 0 );
|
||||
|
||||
} else {
|
||||
|
||||
_axis.set( dir.z, 0, - dir.x ).normalize();
|
||||
|
||||
const radians = Math.acos( dir.y );
|
||||
|
||||
this.quaternion.setFromAxisAngle( _axis, radians );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setLength( length, headLength = length * 0.2, headWidth = headLength * 0.2 ) {
|
||||
|
||||
this.line.scale.set( 1, Math.max( 0.0001, length - headLength ), 1 ); // see #17458
|
||||
this.line.updateMatrix();
|
||||
|
||||
this.cone.scale.set( headWidth, headLength, headWidth );
|
||||
this.cone.position.y = length;
|
||||
this.cone.updateMatrix();
|
||||
|
||||
}
|
||||
|
||||
setColor( color ) {
|
||||
|
||||
this.line.material.color.set( color );
|
||||
this.cone.material.color.set( color );
|
||||
|
||||
}
|
||||
|
||||
copy( source ) {
|
||||
|
||||
super.copy( source, false );
|
||||
|
||||
this.line.copy( source.line );
|
||||
this.cone.copy( source.cone );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.line.geometry.dispose();
|
||||
this.line.material.dispose();
|
||||
this.cone.geometry.dispose();
|
||||
this.cone.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { ArrowHelper };
|
||||
68
network-visualization/node_modules/three/src/helpers/AxesHelper.js
generated
vendored
Normal file
68
network-visualization/node_modules/three/src/helpers/AxesHelper.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
import { LineSegments } from '../objects/LineSegments.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
|
||||
class AxesHelper extends LineSegments {
|
||||
|
||||
constructor( size = 1 ) {
|
||||
|
||||
const vertices = [
|
||||
0, 0, 0, size, 0, 0,
|
||||
0, 0, 0, 0, size, 0,
|
||||
0, 0, 0, 0, 0, size
|
||||
];
|
||||
|
||||
const colors = [
|
||||
1, 0, 0, 1, 0.6, 0,
|
||||
0, 1, 0, 0.6, 1, 0,
|
||||
0, 0, 1, 0, 0.6, 1
|
||||
];
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
||||
|
||||
const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.type = 'AxesHelper';
|
||||
|
||||
}
|
||||
|
||||
setColors( xAxisColor, yAxisColor, zAxisColor ) {
|
||||
|
||||
const color = new Color();
|
||||
const array = this.geometry.attributes.color.array;
|
||||
|
||||
color.set( xAxisColor );
|
||||
color.toArray( array, 0 );
|
||||
color.toArray( array, 3 );
|
||||
|
||||
color.set( yAxisColor );
|
||||
color.toArray( array, 6 );
|
||||
color.toArray( array, 9 );
|
||||
|
||||
color.set( zAxisColor );
|
||||
color.toArray( array, 12 );
|
||||
color.toArray( array, 15 );
|
||||
|
||||
this.geometry.attributes.color.needsUpdate = true;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { AxesHelper };
|
||||
55
network-visualization/node_modules/three/src/helpers/Box3Helper.js
generated
vendored
Normal file
55
network-visualization/node_modules/three/src/helpers/Box3Helper.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
import { LineSegments } from '../objects/LineSegments.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { BufferAttribute, Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
|
||||
class Box3Helper extends LineSegments {
|
||||
|
||||
constructor( box, color = 0xffff00 ) {
|
||||
|
||||
const indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
|
||||
|
||||
const positions = [ 1, 1, 1, - 1, 1, 1, - 1, - 1, 1, 1, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 1, - 1, 1, - 1, - 1 ];
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
|
||||
geometry.setIndex( new BufferAttribute( indices, 1 ) );
|
||||
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
|
||||
|
||||
super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
|
||||
|
||||
this.box = box;
|
||||
|
||||
this.type = 'Box3Helper';
|
||||
|
||||
this.geometry.computeBoundingSphere();
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld( force ) {
|
||||
|
||||
const box = this.box;
|
||||
|
||||
if ( box.isEmpty() ) return;
|
||||
|
||||
box.getCenter( this.position );
|
||||
|
||||
box.getSize( this.scale );
|
||||
|
||||
this.scale.multiplyScalar( 0.5 );
|
||||
|
||||
super.updateMatrixWorld( force );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Box3Helper };
|
||||
113
network-visualization/node_modules/three/src/helpers/BoxHelper.js
generated
vendored
Normal file
113
network-visualization/node_modules/three/src/helpers/BoxHelper.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
import { Box3 } from '../math/Box3.js';
|
||||
import { LineSegments } from '../objects/LineSegments.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
|
||||
const _box = /*@__PURE__*/ new Box3();
|
||||
|
||||
class BoxHelper extends LineSegments {
|
||||
|
||||
constructor( object, color = 0xffff00 ) {
|
||||
|
||||
const indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );
|
||||
const positions = new Float32Array( 8 * 3 );
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setIndex( new BufferAttribute( indices, 1 ) );
|
||||
geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
|
||||
|
||||
super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
|
||||
|
||||
this.object = object;
|
||||
this.type = 'BoxHelper';
|
||||
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
update( object ) {
|
||||
|
||||
if ( object !== undefined ) {
|
||||
|
||||
console.warn( 'THREE.BoxHelper: .update() has no longer arguments.' );
|
||||
|
||||
}
|
||||
|
||||
if ( this.object !== undefined ) {
|
||||
|
||||
_box.setFromObject( this.object );
|
||||
|
||||
}
|
||||
|
||||
if ( _box.isEmpty() ) return;
|
||||
|
||||
const min = _box.min;
|
||||
const max = _box.max;
|
||||
|
||||
/*
|
||||
5____4
|
||||
1/___0/|
|
||||
| 6__|_7
|
||||
2/___3/
|
||||
|
||||
0: max.x, max.y, max.z
|
||||
1: min.x, max.y, max.z
|
||||
2: min.x, min.y, max.z
|
||||
3: max.x, min.y, max.z
|
||||
4: max.x, max.y, min.z
|
||||
5: min.x, max.y, min.z
|
||||
6: min.x, min.y, min.z
|
||||
7: max.x, min.y, min.z
|
||||
*/
|
||||
|
||||
const position = this.geometry.attributes.position;
|
||||
const array = position.array;
|
||||
|
||||
array[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;
|
||||
array[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;
|
||||
array[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;
|
||||
array[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;
|
||||
array[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;
|
||||
array[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;
|
||||
array[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;
|
||||
array[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;
|
||||
|
||||
position.needsUpdate = true;
|
||||
|
||||
this.geometry.computeBoundingSphere();
|
||||
|
||||
}
|
||||
|
||||
setFromObject( object ) {
|
||||
|
||||
this.object = object;
|
||||
this.update();
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
copy( source, recursive ) {
|
||||
|
||||
super.copy( source, recursive );
|
||||
|
||||
this.object = source.object;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { BoxHelper };
|
||||
269
network-visualization/node_modules/three/src/helpers/CameraHelper.js
generated
vendored
Normal file
269
network-visualization/node_modules/three/src/helpers/CameraHelper.js
generated
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
import { Camera } from '../cameras/Camera.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { LineSegments } from '../objects/LineSegments.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
|
||||
const _vector = /*@__PURE__*/ new Vector3();
|
||||
const _camera = /*@__PURE__*/ new Camera();
|
||||
|
||||
/**
|
||||
* - shows frustum, line of sight and up of the camera
|
||||
* - suitable for fast updates
|
||||
* - based on frustum visualization in lightgl.js shadowmap example
|
||||
* https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html
|
||||
*/
|
||||
|
||||
class CameraHelper extends LineSegments {
|
||||
|
||||
constructor( camera ) {
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
const material = new LineBasicMaterial( { color: 0xffffff, vertexColors: true, toneMapped: false } );
|
||||
|
||||
const vertices = [];
|
||||
const colors = [];
|
||||
|
||||
const pointMap = {};
|
||||
|
||||
// near
|
||||
|
||||
addLine( 'n1', 'n2' );
|
||||
addLine( 'n2', 'n4' );
|
||||
addLine( 'n4', 'n3' );
|
||||
addLine( 'n3', 'n1' );
|
||||
|
||||
// far
|
||||
|
||||
addLine( 'f1', 'f2' );
|
||||
addLine( 'f2', 'f4' );
|
||||
addLine( 'f4', 'f3' );
|
||||
addLine( 'f3', 'f1' );
|
||||
|
||||
// sides
|
||||
|
||||
addLine( 'n1', 'f1' );
|
||||
addLine( 'n2', 'f2' );
|
||||
addLine( 'n3', 'f3' );
|
||||
addLine( 'n4', 'f4' );
|
||||
|
||||
// cone
|
||||
|
||||
addLine( 'p', 'n1' );
|
||||
addLine( 'p', 'n2' );
|
||||
addLine( 'p', 'n3' );
|
||||
addLine( 'p', 'n4' );
|
||||
|
||||
// up
|
||||
|
||||
addLine( 'u1', 'u2' );
|
||||
addLine( 'u2', 'u3' );
|
||||
addLine( 'u3', 'u1' );
|
||||
|
||||
// target
|
||||
|
||||
addLine( 'c', 't' );
|
||||
addLine( 'p', 'c' );
|
||||
|
||||
// cross
|
||||
|
||||
addLine( 'cn1', 'cn2' );
|
||||
addLine( 'cn3', 'cn4' );
|
||||
|
||||
addLine( 'cf1', 'cf2' );
|
||||
addLine( 'cf3', 'cf4' );
|
||||
|
||||
function addLine( a, b ) {
|
||||
|
||||
addPoint( a );
|
||||
addPoint( b );
|
||||
|
||||
}
|
||||
|
||||
function addPoint( id ) {
|
||||
|
||||
vertices.push( 0, 0, 0 );
|
||||
colors.push( 0, 0, 0 );
|
||||
|
||||
if ( pointMap[ id ] === undefined ) {
|
||||
|
||||
pointMap[ id ] = [];
|
||||
|
||||
}
|
||||
|
||||
pointMap[ id ].push( ( vertices.length / 3 ) - 1 );
|
||||
|
||||
}
|
||||
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.type = 'CameraHelper';
|
||||
|
||||
this.camera = camera;
|
||||
if ( this.camera.updateProjectionMatrix ) this.camera.updateProjectionMatrix();
|
||||
|
||||
this.matrix = camera.matrixWorld;
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
this.pointMap = pointMap;
|
||||
|
||||
this.update();
|
||||
|
||||
// colors
|
||||
|
||||
const colorFrustum = new Color( 0xffaa00 );
|
||||
const colorCone = new Color( 0xff0000 );
|
||||
const colorUp = new Color( 0x00aaff );
|
||||
const colorTarget = new Color( 0xffffff );
|
||||
const colorCross = new Color( 0x333333 );
|
||||
|
||||
this.setColors( colorFrustum, colorCone, colorUp, colorTarget, colorCross );
|
||||
|
||||
}
|
||||
|
||||
setColors( frustum, cone, up, target, cross ) {
|
||||
|
||||
const geometry = this.geometry;
|
||||
|
||||
const colorAttribute = geometry.getAttribute( 'color' );
|
||||
|
||||
// near
|
||||
|
||||
colorAttribute.setXYZ( 0, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 1, frustum.r, frustum.g, frustum.b ); // n1, n2
|
||||
colorAttribute.setXYZ( 2, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 3, frustum.r, frustum.g, frustum.b ); // n2, n4
|
||||
colorAttribute.setXYZ( 4, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 5, frustum.r, frustum.g, frustum.b ); // n4, n3
|
||||
colorAttribute.setXYZ( 6, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 7, frustum.r, frustum.g, frustum.b ); // n3, n1
|
||||
|
||||
// far
|
||||
|
||||
colorAttribute.setXYZ( 8, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 9, frustum.r, frustum.g, frustum.b ); // f1, f2
|
||||
colorAttribute.setXYZ( 10, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 11, frustum.r, frustum.g, frustum.b ); // f2, f4
|
||||
colorAttribute.setXYZ( 12, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 13, frustum.r, frustum.g, frustum.b ); // f4, f3
|
||||
colorAttribute.setXYZ( 14, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 15, frustum.r, frustum.g, frustum.b ); // f3, f1
|
||||
|
||||
// sides
|
||||
|
||||
colorAttribute.setXYZ( 16, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 17, frustum.r, frustum.g, frustum.b ); // n1, f1
|
||||
colorAttribute.setXYZ( 18, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 19, frustum.r, frustum.g, frustum.b ); // n2, f2
|
||||
colorAttribute.setXYZ( 20, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 21, frustum.r, frustum.g, frustum.b ); // n3, f3
|
||||
colorAttribute.setXYZ( 22, frustum.r, frustum.g, frustum.b ); colorAttribute.setXYZ( 23, frustum.r, frustum.g, frustum.b ); // n4, f4
|
||||
|
||||
// cone
|
||||
|
||||
colorAttribute.setXYZ( 24, cone.r, cone.g, cone.b ); colorAttribute.setXYZ( 25, cone.r, cone.g, cone.b ); // p, n1
|
||||
colorAttribute.setXYZ( 26, cone.r, cone.g, cone.b ); colorAttribute.setXYZ( 27, cone.r, cone.g, cone.b ); // p, n2
|
||||
colorAttribute.setXYZ( 28, cone.r, cone.g, cone.b ); colorAttribute.setXYZ( 29, cone.r, cone.g, cone.b ); // p, n3
|
||||
colorAttribute.setXYZ( 30, cone.r, cone.g, cone.b ); colorAttribute.setXYZ( 31, cone.r, cone.g, cone.b ); // p, n4
|
||||
|
||||
// up
|
||||
|
||||
colorAttribute.setXYZ( 32, up.r, up.g, up.b ); colorAttribute.setXYZ( 33, up.r, up.g, up.b ); // u1, u2
|
||||
colorAttribute.setXYZ( 34, up.r, up.g, up.b ); colorAttribute.setXYZ( 35, up.r, up.g, up.b ); // u2, u3
|
||||
colorAttribute.setXYZ( 36, up.r, up.g, up.b ); colorAttribute.setXYZ( 37, up.r, up.g, up.b ); // u3, u1
|
||||
|
||||
// target
|
||||
|
||||
colorAttribute.setXYZ( 38, target.r, target.g, target.b ); colorAttribute.setXYZ( 39, target.r, target.g, target.b ); // c, t
|
||||
colorAttribute.setXYZ( 40, cross.r, cross.g, cross.b ); colorAttribute.setXYZ( 41, cross.r, cross.g, cross.b ); // p, c
|
||||
|
||||
// cross
|
||||
|
||||
colorAttribute.setXYZ( 42, cross.r, cross.g, cross.b ); colorAttribute.setXYZ( 43, cross.r, cross.g, cross.b ); // cn1, cn2
|
||||
colorAttribute.setXYZ( 44, cross.r, cross.g, cross.b ); colorAttribute.setXYZ( 45, cross.r, cross.g, cross.b ); // cn3, cn4
|
||||
|
||||
colorAttribute.setXYZ( 46, cross.r, cross.g, cross.b ); colorAttribute.setXYZ( 47, cross.r, cross.g, cross.b ); // cf1, cf2
|
||||
colorAttribute.setXYZ( 48, cross.r, cross.g, cross.b ); colorAttribute.setXYZ( 49, cross.r, cross.g, cross.b ); // cf3, cf4
|
||||
|
||||
colorAttribute.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const geometry = this.geometry;
|
||||
const pointMap = this.pointMap;
|
||||
|
||||
const w = 1, h = 1;
|
||||
|
||||
// we need just camera projection matrix inverse
|
||||
// world matrix must be identity
|
||||
|
||||
_camera.projectionMatrixInverse.copy( this.camera.projectionMatrixInverse );
|
||||
|
||||
// center / target
|
||||
|
||||
setPoint( 'c', pointMap, geometry, _camera, 0, 0, - 1 );
|
||||
setPoint( 't', pointMap, geometry, _camera, 0, 0, 1 );
|
||||
|
||||
// near
|
||||
|
||||
setPoint( 'n1', pointMap, geometry, _camera, - w, - h, - 1 );
|
||||
setPoint( 'n2', pointMap, geometry, _camera, w, - h, - 1 );
|
||||
setPoint( 'n3', pointMap, geometry, _camera, - w, h, - 1 );
|
||||
setPoint( 'n4', pointMap, geometry, _camera, w, h, - 1 );
|
||||
|
||||
// far
|
||||
|
||||
setPoint( 'f1', pointMap, geometry, _camera, - w, - h, 1 );
|
||||
setPoint( 'f2', pointMap, geometry, _camera, w, - h, 1 );
|
||||
setPoint( 'f3', pointMap, geometry, _camera, - w, h, 1 );
|
||||
setPoint( 'f4', pointMap, geometry, _camera, w, h, 1 );
|
||||
|
||||
// up
|
||||
|
||||
setPoint( 'u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, - 1 );
|
||||
setPoint( 'u2', pointMap, geometry, _camera, - w * 0.7, h * 1.1, - 1 );
|
||||
setPoint( 'u3', pointMap, geometry, _camera, 0, h * 2, - 1 );
|
||||
|
||||
// cross
|
||||
|
||||
setPoint( 'cf1', pointMap, geometry, _camera, - w, 0, 1 );
|
||||
setPoint( 'cf2', pointMap, geometry, _camera, w, 0, 1 );
|
||||
setPoint( 'cf3', pointMap, geometry, _camera, 0, - h, 1 );
|
||||
setPoint( 'cf4', pointMap, geometry, _camera, 0, h, 1 );
|
||||
|
||||
setPoint( 'cn1', pointMap, geometry, _camera, - w, 0, - 1 );
|
||||
setPoint( 'cn2', pointMap, geometry, _camera, w, 0, - 1 );
|
||||
setPoint( 'cn3', pointMap, geometry, _camera, 0, - h, - 1 );
|
||||
setPoint( 'cn4', pointMap, geometry, _camera, 0, h, - 1 );
|
||||
|
||||
geometry.getAttribute( 'position' ).needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function setPoint( point, pointMap, geometry, camera, x, y, z ) {
|
||||
|
||||
_vector.set( x, y, z ).unproject( camera );
|
||||
|
||||
const points = pointMap[ point ];
|
||||
|
||||
if ( points !== undefined ) {
|
||||
|
||||
const position = geometry.getAttribute( 'position' );
|
||||
|
||||
for ( let i = 0, l = points.length; i < l; i ++ ) {
|
||||
|
||||
position.setXYZ( points[ i ], _vector.x, _vector.y, _vector.z );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { CameraHelper };
|
||||
93
network-visualization/node_modules/three/src/helpers/DirectionalLightHelper.js
generated
vendored
Normal file
93
network-visualization/node_modules/three/src/helpers/DirectionalLightHelper.js
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { Line } from '../objects/Line.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
|
||||
const _v1 = /*@__PURE__*/ new Vector3();
|
||||
const _v2 = /*@__PURE__*/ new Vector3();
|
||||
const _v3 = /*@__PURE__*/ new Vector3();
|
||||
|
||||
class DirectionalLightHelper extends Object3D {
|
||||
|
||||
constructor( light, size, color ) {
|
||||
|
||||
super();
|
||||
|
||||
this.light = light;
|
||||
|
||||
this.matrix = light.matrixWorld;
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
this.color = color;
|
||||
|
||||
this.type = 'DirectionalLightHelper';
|
||||
|
||||
if ( size === undefined ) size = 1;
|
||||
|
||||
let geometry = new BufferGeometry();
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( [
|
||||
- size, size, 0,
|
||||
size, size, 0,
|
||||
size, - size, 0,
|
||||
- size, - size, 0,
|
||||
- size, size, 0
|
||||
], 3 ) );
|
||||
|
||||
const material = new LineBasicMaterial( { fog: false, toneMapped: false } );
|
||||
|
||||
this.lightPlane = new Line( geometry, material );
|
||||
this.add( this.lightPlane );
|
||||
|
||||
geometry = new BufferGeometry();
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( [ 0, 0, 0, 0, 0, 1 ], 3 ) );
|
||||
|
||||
this.targetLine = new Line( geometry, material );
|
||||
this.add( this.targetLine );
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.lightPlane.geometry.dispose();
|
||||
this.lightPlane.material.dispose();
|
||||
this.targetLine.geometry.dispose();
|
||||
this.targetLine.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
this.light.updateWorldMatrix( true, false );
|
||||
this.light.target.updateWorldMatrix( true, false );
|
||||
|
||||
_v1.setFromMatrixPosition( this.light.matrixWorld );
|
||||
_v2.setFromMatrixPosition( this.light.target.matrixWorld );
|
||||
_v3.subVectors( _v2, _v1 );
|
||||
|
||||
this.lightPlane.lookAt( _v2 );
|
||||
|
||||
if ( this.color !== undefined ) {
|
||||
|
||||
this.lightPlane.material.color.set( this.color );
|
||||
this.targetLine.material.color.set( this.color );
|
||||
|
||||
} else {
|
||||
|
||||
this.lightPlane.material.color.copy( this.light.color );
|
||||
this.targetLine.material.color.copy( this.light.color );
|
||||
|
||||
}
|
||||
|
||||
this.targetLine.lookAt( _v2 );
|
||||
this.targetLine.scale.z = _v3.length();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { DirectionalLightHelper };
|
||||
56
network-visualization/node_modules/three/src/helpers/GridHelper.js
generated
vendored
Normal file
56
network-visualization/node_modules/three/src/helpers/GridHelper.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
import { LineSegments } from '../objects/LineSegments.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
|
||||
class GridHelper extends LineSegments {
|
||||
|
||||
constructor( size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888 ) {
|
||||
|
||||
color1 = new Color( color1 );
|
||||
color2 = new Color( color2 );
|
||||
|
||||
const center = divisions / 2;
|
||||
const step = size / divisions;
|
||||
const halfSize = size / 2;
|
||||
|
||||
const vertices = [], colors = [];
|
||||
|
||||
for ( let i = 0, j = 0, k = - halfSize; i <= divisions; i ++, k += step ) {
|
||||
|
||||
vertices.push( - halfSize, 0, k, halfSize, 0, k );
|
||||
vertices.push( k, 0, - halfSize, k, 0, halfSize );
|
||||
|
||||
const color = i === center ? color1 : color2;
|
||||
|
||||
color.toArray( colors, j ); j += 3;
|
||||
color.toArray( colors, j ); j += 3;
|
||||
color.toArray( colors, j ); j += 3;
|
||||
color.toArray( colors, j ); j += 3;
|
||||
|
||||
}
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
||||
|
||||
const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.type = 'GridHelper';
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { GridHelper };
|
||||
88
network-visualization/node_modules/three/src/helpers/HemisphereLightHelper.js
generated
vendored
Normal file
88
network-visualization/node_modules/three/src/helpers/HemisphereLightHelper.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
import { Object3D } from '../core/Object3D.js';
|
||||
import { Mesh } from '../objects/Mesh.js';
|
||||
import { MeshBasicMaterial } from '../materials/MeshBasicMaterial.js';
|
||||
import { OctahedronGeometry } from '../geometries/OctahedronGeometry.js';
|
||||
import { BufferAttribute } from '../core/BufferAttribute.js';
|
||||
|
||||
const _vector = /*@__PURE__*/ new Vector3();
|
||||
const _color1 = /*@__PURE__*/ new Color();
|
||||
const _color2 = /*@__PURE__*/ new Color();
|
||||
|
||||
class HemisphereLightHelper extends Object3D {
|
||||
|
||||
constructor( light, size, color ) {
|
||||
|
||||
super();
|
||||
|
||||
this.light = light;
|
||||
|
||||
this.matrix = light.matrixWorld;
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
this.color = color;
|
||||
|
||||
this.type = 'HemisphereLightHelper';
|
||||
|
||||
const geometry = new OctahedronGeometry( size );
|
||||
geometry.rotateY( Math.PI * 0.5 );
|
||||
|
||||
this.material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
|
||||
if ( this.color === undefined ) this.material.vertexColors = true;
|
||||
|
||||
const position = geometry.getAttribute( 'position' );
|
||||
const colors = new Float32Array( position.count * 3 );
|
||||
|
||||
geometry.setAttribute( 'color', new BufferAttribute( colors, 3 ) );
|
||||
|
||||
this.add( new Mesh( geometry, this.material ) );
|
||||
|
||||
this.update();
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.children[ 0 ].geometry.dispose();
|
||||
this.children[ 0 ].material.dispose();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const mesh = this.children[ 0 ];
|
||||
|
||||
if ( this.color !== undefined ) {
|
||||
|
||||
this.material.color.set( this.color );
|
||||
|
||||
} else {
|
||||
|
||||
const colors = mesh.geometry.getAttribute( 'color' );
|
||||
|
||||
_color1.copy( this.light.color );
|
||||
_color2.copy( this.light.groundColor );
|
||||
|
||||
for ( let i = 0, l = colors.count; i < l; i ++ ) {
|
||||
|
||||
const color = ( i < ( l / 2 ) ) ? _color1 : _color2;
|
||||
|
||||
colors.setXYZ( i, color.r, color.g, color.b );
|
||||
|
||||
}
|
||||
|
||||
colors.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
this.light.updateWorldMatrix( true, false );
|
||||
|
||||
mesh.lookAt( _vector.setFromMatrixPosition( this.light.matrixWorld ).negate() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { HemisphereLightHelper };
|
||||
63
network-visualization/node_modules/three/src/helpers/PlaneHelper.js
generated
vendored
Normal file
63
network-visualization/node_modules/three/src/helpers/PlaneHelper.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Line } from '../objects/Line.js';
|
||||
import { Mesh } from '../objects/Mesh.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { MeshBasicMaterial } from '../materials/MeshBasicMaterial.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
|
||||
class PlaneHelper extends Line {
|
||||
|
||||
constructor( plane, size = 1, hex = 0xffff00 ) {
|
||||
|
||||
const color = hex;
|
||||
|
||||
const positions = [ 1, - 1, 0, - 1, 1, 0, - 1, - 1, 0, 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();
|
||||
|
||||
super( geometry, new LineBasicMaterial( { color: color, toneMapped: false } ) );
|
||||
|
||||
this.type = 'PlaneHelper';
|
||||
|
||||
this.plane = plane;
|
||||
|
||||
this.size = size;
|
||||
|
||||
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( { color: color, opacity: 0.2, transparent: true, depthWrite: false, toneMapped: false } ) ) );
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld( force ) {
|
||||
|
||||
this.position.set( 0, 0, 0 );
|
||||
|
||||
this.scale.set( 0.5 * this.size, 0.5 * this.size, 1 );
|
||||
|
||||
this.lookAt( this.plane.normal );
|
||||
|
||||
this.translateZ( - this.plane.constant );
|
||||
|
||||
super.updateMatrixWorld( force );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
this.children[ 0 ].geometry.dispose();
|
||||
this.children[ 0 ].material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { PlaneHelper };
|
||||
92
network-visualization/node_modules/three/src/helpers/PointLightHelper.js
generated
vendored
Normal file
92
network-visualization/node_modules/three/src/helpers/PointLightHelper.js
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
import { Mesh } from '../objects/Mesh.js';
|
||||
import { MeshBasicMaterial } from '../materials/MeshBasicMaterial.js';
|
||||
import { SphereGeometry } from '../geometries/SphereGeometry.js';
|
||||
|
||||
class PointLightHelper extends Mesh {
|
||||
|
||||
constructor( light, sphereSize, color ) {
|
||||
|
||||
const geometry = new SphereGeometry( sphereSize, 4, 2 );
|
||||
const material = new MeshBasicMaterial( { wireframe: true, fog: false, toneMapped: false } );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.light = light;
|
||||
|
||||
this.color = color;
|
||||
|
||||
this.type = 'PointLightHelper';
|
||||
|
||||
this.matrix = this.light.matrixWorld;
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
this.update();
|
||||
|
||||
|
||||
/*
|
||||
// TODO: delete this comment?
|
||||
const distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );
|
||||
const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );
|
||||
|
||||
this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
|
||||
this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );
|
||||
|
||||
const d = light.distance;
|
||||
|
||||
if ( d === 0.0 ) {
|
||||
|
||||
this.lightDistance.visible = false;
|
||||
|
||||
} else {
|
||||
|
||||
this.lightDistance.scale.set( d, d, d );
|
||||
|
||||
}
|
||||
|
||||
this.add( this.lightDistance );
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
this.light.updateWorldMatrix( true, false );
|
||||
|
||||
if ( this.color !== undefined ) {
|
||||
|
||||
this.material.color.set( this.color );
|
||||
|
||||
} else {
|
||||
|
||||
this.material.color.copy( this.light.color );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
const d = this.light.distance;
|
||||
|
||||
if ( d === 0.0 ) {
|
||||
|
||||
this.lightDistance.visible = false;
|
||||
|
||||
} else {
|
||||
|
||||
this.lightDistance.visible = true;
|
||||
this.lightDistance.scale.set( d, d, d );
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { PointLightHelper };
|
||||
96
network-visualization/node_modules/three/src/helpers/PolarGridHelper.js
generated
vendored
Normal file
96
network-visualization/node_modules/three/src/helpers/PolarGridHelper.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
import { LineSegments } from '../objects/LineSegments.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
|
||||
class PolarGridHelper extends LineSegments {
|
||||
|
||||
constructor( radius = 10, sectors = 16, rings = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888 ) {
|
||||
|
||||
color1 = new Color( color1 );
|
||||
color2 = new Color( color2 );
|
||||
|
||||
const vertices = [];
|
||||
const colors = [];
|
||||
|
||||
// create the sectors
|
||||
|
||||
if ( sectors > 1 ) {
|
||||
|
||||
for ( let i = 0; i < sectors; i ++ ) {
|
||||
|
||||
const v = ( i / sectors ) * ( Math.PI * 2 );
|
||||
|
||||
const x = Math.sin( v ) * radius;
|
||||
const z = Math.cos( v ) * radius;
|
||||
|
||||
vertices.push( 0, 0, 0 );
|
||||
vertices.push( x, 0, z );
|
||||
|
||||
const color = ( i & 1 ) ? color1 : color2;
|
||||
|
||||
colors.push( color.r, color.g, color.b );
|
||||
colors.push( color.r, color.g, color.b );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// create the rings
|
||||
|
||||
for ( let i = 0; i < rings; i ++ ) {
|
||||
|
||||
const color = ( i & 1 ) ? color1 : color2;
|
||||
|
||||
const r = radius - ( radius / rings * i );
|
||||
|
||||
for ( let j = 0; j < divisions; j ++ ) {
|
||||
|
||||
// first vertex
|
||||
|
||||
let v = ( j / divisions ) * ( Math.PI * 2 );
|
||||
|
||||
let x = Math.sin( v ) * r;
|
||||
let z = Math.cos( v ) * r;
|
||||
|
||||
vertices.push( x, 0, z );
|
||||
colors.push( color.r, color.g, color.b );
|
||||
|
||||
// second vertex
|
||||
|
||||
v = ( ( j + 1 ) / divisions ) * ( Math.PI * 2 );
|
||||
|
||||
x = Math.sin( v ) * r;
|
||||
z = Math.cos( v ) * r;
|
||||
|
||||
vertices.push( x, 0, z );
|
||||
colors.push( color.r, color.g, color.b );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
||||
|
||||
const material = new LineBasicMaterial( { vertexColors: true, toneMapped: false } );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.type = 'PolarGridHelper';
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { PolarGridHelper };
|
||||
128
network-visualization/node_modules/three/src/helpers/SkeletonHelper.js
generated
vendored
Normal file
128
network-visualization/node_modules/three/src/helpers/SkeletonHelper.js
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
import { LineSegments } from '../objects/LineSegments.js';
|
||||
import { Matrix4 } from '../math/Matrix4.js';
|
||||
import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
|
||||
import { Color } from '../math/Color.js';
|
||||
import { Vector3 } from '../math/Vector3.js';
|
||||
import { BufferGeometry } from '../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
|
||||
|
||||
const _vector = /*@__PURE__*/ new Vector3();
|
||||
const _boneMatrix = /*@__PURE__*/ new Matrix4();
|
||||
const _matrixWorldInv = /*@__PURE__*/ new Matrix4();
|
||||
|
||||
|
||||
class SkeletonHelper extends LineSegments {
|
||||
|
||||
constructor( object ) {
|
||||
|
||||
const bones = getBoneList( object );
|
||||
|
||||
const geometry = new BufferGeometry();
|
||||
|
||||
const vertices = [];
|
||||
const colors = [];
|
||||
|
||||
const color1 = new Color( 0, 0, 1 );
|
||||
const color2 = new Color( 0, 1, 0 );
|
||||
|
||||
for ( let i = 0; i < bones.length; i ++ ) {
|
||||
|
||||
const bone = bones[ i ];
|
||||
|
||||
if ( bone.parent && bone.parent.isBone ) {
|
||||
|
||||
vertices.push( 0, 0, 0 );
|
||||
vertices.push( 0, 0, 0 );
|
||||
colors.push( color1.r, color1.g, color1.b );
|
||||
colors.push( color2.r, color2.g, color2.b );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
|
||||
geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
|
||||
|
||||
const material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } );
|
||||
|
||||
super( geometry, material );
|
||||
|
||||
this.isSkeletonHelper = true;
|
||||
|
||||
this.type = 'SkeletonHelper';
|
||||
|
||||
this.root = object;
|
||||
this.bones = bones;
|
||||
|
||||
this.matrix = object.matrixWorld;
|
||||
this.matrixAutoUpdate = false;
|
||||
|
||||
}
|
||||
|
||||
updateMatrixWorld( force ) {
|
||||
|
||||
const bones = this.bones;
|
||||
|
||||
const geometry = this.geometry;
|
||||
const position = geometry.getAttribute( 'position' );
|
||||
|
||||
_matrixWorldInv.copy( this.root.matrixWorld ).invert();
|
||||
|
||||
for ( let i = 0, j = 0; i < bones.length; i ++ ) {
|
||||
|
||||
const bone = bones[ i ];
|
||||
|
||||
if ( bone.parent && bone.parent.isBone ) {
|
||||
|
||||
_boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld );
|
||||
_vector.setFromMatrixPosition( _boneMatrix );
|
||||
position.setXYZ( j, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
_boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld );
|
||||
_vector.setFromMatrixPosition( _boneMatrix );
|
||||
position.setXYZ( j + 1, _vector.x, _vector.y, _vector.z );
|
||||
|
||||
j += 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
geometry.getAttribute( 'position' ).needsUpdate = true;
|
||||
|
||||
super.updateMatrixWorld( force );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.geometry.dispose();
|
||||
this.material.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function getBoneList( object ) {
|
||||
|
||||
const boneList = [];
|
||||
|
||||
if ( object.isBone === true ) {
|
||||
|
||||
boneList.push( object );
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0; i < object.children.length; i ++ ) {
|
||||
|
||||
boneList.push.apply( boneList, getBoneList( object.children[ i ] ) );
|
||||
|
||||
}
|
||||
|
||||
return boneList;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { SkeletonHelper };
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user