super-three 0.147.1 → 0.154.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/build/three.cjs +37190 -21678
- package/build/three.js +37182 -21669
- package/build/three.min.js +4 -2
- package/build/three.module.js +7656 -6548
- package/build/three.module.min.js +7 -0
- package/examples/jsm/animation/AnimationClipCreator.js +5 -3
- package/examples/jsm/cameras/CinematicCamera.js +1 -2
- package/examples/jsm/capabilities/WebGPU.js +17 -5
- package/examples/jsm/controls/ArcballControls.js +1835 -1827
- package/examples/jsm/controls/FlyControls.js +25 -9
- package/examples/jsm/controls/MapControls.js +28 -0
- package/examples/jsm/controls/OrbitControls.js +25 -46
- package/examples/jsm/controls/PointerLockControls.js +70 -65
- package/examples/jsm/controls/TrackballControls.js +18 -4
- package/examples/jsm/controls/TransformControls.js +0 -1
- package/examples/jsm/csm/CSM.js +12 -6
- package/examples/jsm/csm/CSMShader.js +7 -6
- package/examples/jsm/effects/AnaglyphEffect.js +6 -20
- package/examples/jsm/effects/AsciiEffect.js +3 -6
- package/examples/jsm/effects/OutlineEffect.js +2 -16
- package/examples/jsm/effects/ParallaxBarrierEffect.js +3 -0
- package/examples/jsm/environments/RoomEnvironment.js +6 -2
- package/examples/jsm/exporters/DRACOExporter.js +53 -11
- package/examples/jsm/exporters/EXRExporter.js +3 -9
- package/examples/jsm/exporters/GLTFExporter.js +597 -112
- package/examples/jsm/exporters/KTX2Exporter.js +34 -23
- package/examples/jsm/exporters/MMDExporter.js +1 -1
- package/examples/jsm/exporters/PLYExporter.js +8 -1
- package/examples/jsm/exporters/STLExporter.js +8 -4
- package/examples/jsm/exporters/USDZExporter.js +184 -124
- package/examples/jsm/geometries/ConvexGeometry.js +0 -6
- package/examples/jsm/geometries/ParametricGeometry.js +10 -0
- package/examples/jsm/helpers/OctreeHelper.js +1 -0
- package/examples/jsm/helpers/ViewHelper.js +71 -57
- package/examples/jsm/interactive/HTMLMesh.js +16 -3
- package/examples/jsm/interactive/InteractiveGroup.js +1 -1
- package/examples/{js → jsm}/libs/basis/README.md +4 -4
- package/examples/jsm/libs/draco/draco_decoder.js +34 -0
- package/examples/jsm/libs/draco/draco_decoder.wasm +0 -0
- package/examples/jsm/libs/draco/draco_wasm_wrapper.js +117 -0
- package/examples/jsm/libs/draco/gltf/draco_decoder.js +33 -0
- package/examples/jsm/libs/draco/gltf/draco_decoder.wasm +0 -0
- package/examples/jsm/libs/draco/gltf/draco_wasm_wrapper.js +116 -0
- package/examples/jsm/libs/lil-gui.module.min.js +2 -2
- package/examples/jsm/libs/tween.module.js +803 -0
- package/examples/jsm/lights/IESSpotLight.js +25 -0
- package/examples/jsm/lights/LightProbeGenerator.js +11 -9
- package/examples/jsm/lines/LineMaterial.js +1 -1
- package/examples/jsm/lines/LineSegments2.js +12 -10
- package/examples/jsm/loaders/3DMLoader.js +9 -6
- package/examples/jsm/loaders/3MFLoader.js +17 -12
- package/examples/jsm/loaders/AMFLoader.js +7 -4
- package/examples/jsm/loaders/BVHLoader.js +2 -2
- package/examples/jsm/loaders/ColladaLoader.js +19 -17
- package/examples/jsm/loaders/DRACOLoader.js +69 -18
- package/examples/jsm/loaders/EXRLoader.js +23 -24
- package/examples/jsm/loaders/FBXLoader.js +41 -52
- package/examples/jsm/loaders/GCodeLoader.js +1 -2
- package/examples/jsm/loaders/GLTFLoader.js +452 -282
- package/examples/jsm/loaders/HDRCubeTextureLoader.js +4 -4
- package/examples/jsm/loaders/IESLoader.js +337 -0
- package/examples/jsm/loaders/KMZLoader.js +4 -4
- package/examples/jsm/loaders/KTX2Loader.js +145 -69
- package/examples/jsm/loaders/LDrawLoader.js +24 -25
- package/examples/jsm/loaders/LWOLoader.js +12 -29
- package/examples/jsm/loaders/LottieLoader.js +3 -1
- package/examples/jsm/loaders/MMDLoader.js +49 -18
- package/examples/jsm/loaders/MTLLoader.js +2 -2
- package/examples/jsm/loaders/MaterialXLoader.js +9 -3
- package/examples/jsm/loaders/NRRDLoader.js +33 -5
- package/examples/jsm/loaders/OBJLoader.js +1 -1
- package/examples/jsm/loaders/PCDLoader.js +26 -12
- package/examples/jsm/loaders/PDBLoader.js +7 -2
- package/examples/jsm/loaders/PLYLoader.js +261 -106
- package/examples/jsm/loaders/RGBELoader.js +3 -3
- package/examples/jsm/loaders/STLLoader.js +9 -5
- package/examples/jsm/loaders/SVGLoader.js +36 -27
- package/examples/jsm/loaders/TTFLoader.js +1 -8
- package/examples/jsm/loaders/TiltLoader.js +13 -7
- package/examples/jsm/loaders/USDZLoader.js +5 -5
- package/examples/jsm/loaders/VOXLoader.js +8 -2
- package/examples/jsm/loaders/VRMLLoader.js +60 -20
- package/examples/jsm/loaders/VTKLoader.js +19 -10
- package/examples/jsm/loaders/XYZLoader.js +9 -3
- package/examples/jsm/loaders/lwo/IFFParser.js +19 -19
- package/examples/jsm/materials/MeshGouraudMaterial.js +2 -5
- package/examples/jsm/math/Lut.js +5 -4
- package/examples/jsm/math/MeshSurfaceSampler.js +82 -43
- package/examples/jsm/misc/ConvexObjectBreaker.js +2 -8
- package/examples/jsm/misc/GPUComputationRenderer.js +6 -5
- package/examples/jsm/misc/MD2Character.js +2 -2
- package/examples/jsm/misc/MD2CharacterComplex.js +2 -2
- package/examples/jsm/misc/ProgressiveLightMap.js +12 -10
- package/examples/jsm/misc/RollerCoaster.js +7 -1
- package/examples/jsm/misc/Volume.js +20 -5
- package/examples/jsm/misc/VolumeSlice.js +3 -1
- package/examples/jsm/modifiers/CurveModifier.js +1 -0
- package/examples/jsm/modifiers/TessellateModifier.js +19 -19
- package/examples/jsm/nodes/Nodes.js +149 -335
- package/examples/jsm/nodes/accessors/BitangentNode.js +43 -16
- package/examples/jsm/nodes/accessors/BufferAttributeNode.js +99 -0
- package/examples/jsm/nodes/accessors/BufferNode.js +6 -0
- package/examples/jsm/nodes/accessors/CameraNode.js +36 -5
- package/examples/jsm/nodes/accessors/CubeTextureNode.js +27 -33
- package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +64 -0
- package/examples/jsm/nodes/accessors/InstanceNode.js +39 -26
- package/examples/jsm/nodes/accessors/MaterialNode.js +164 -39
- package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +16 -0
- package/examples/jsm/nodes/accessors/ModelNode.js +13 -0
- package/examples/jsm/nodes/accessors/ModelViewProjectionNode.js +13 -14
- package/examples/jsm/nodes/accessors/MorphNode.js +70 -0
- package/examples/jsm/nodes/accessors/NormalNode.js +36 -19
- package/examples/jsm/nodes/accessors/Object3DNode.js +40 -12
- package/examples/jsm/nodes/accessors/PointUVNode.js +6 -1
- package/examples/jsm/nodes/accessors/PositionNode.js +38 -23
- package/examples/jsm/nodes/accessors/ReferenceNode.js +21 -14
- package/examples/jsm/nodes/accessors/ReflectVectorNode.js +11 -7
- package/examples/jsm/nodes/accessors/SceneNode.js +46 -0
- package/examples/jsm/nodes/accessors/SkinningNode.js +55 -71
- package/examples/jsm/nodes/accessors/StorageBufferNode.js +6 -0
- package/examples/jsm/nodes/accessors/TangentNode.js +28 -20
- package/examples/jsm/nodes/accessors/TextureBicubicNode.js +94 -0
- package/examples/jsm/nodes/accessors/TextureNode.js +143 -13
- package/examples/jsm/nodes/accessors/TextureSizeNode.js +35 -0
- package/examples/jsm/nodes/accessors/UVNode.js +7 -1
- package/examples/jsm/nodes/accessors/UserDataNode.js +6 -0
- package/examples/jsm/nodes/code/CodeNode.js +78 -0
- package/examples/jsm/nodes/code/ExpressionNode.js +37 -0
- package/examples/jsm/nodes/{core → code}/FunctionCallNode.js +15 -1
- package/examples/jsm/nodes/{core → code}/FunctionNode.js +31 -9
- package/examples/jsm/nodes/code/ScriptableNode.js +488 -0
- package/examples/jsm/nodes/code/ScriptableValueNode.js +167 -0
- package/examples/jsm/nodes/core/ArrayUniformNode.js +3 -0
- package/examples/jsm/nodes/core/AttributeNode.js +17 -9
- package/examples/jsm/nodes/core/BypassNode.js +11 -4
- package/examples/jsm/nodes/core/CacheNode.js +46 -0
- package/examples/jsm/nodes/core/ConstNode.js +3 -0
- package/examples/jsm/nodes/core/ContextNode.js +10 -1
- package/examples/jsm/nodes/core/IndexNode.js +66 -0
- package/examples/jsm/nodes/core/InputNode.js +26 -5
- package/examples/jsm/nodes/core/LightingModel.js +17 -0
- package/examples/jsm/nodes/core/Node.js +128 -37
- package/examples/jsm/nodes/core/NodeAttribute.js +2 -1
- package/examples/jsm/nodes/core/NodeBuilder.js +287 -118
- package/examples/jsm/nodes/core/NodeCache.js +26 -0
- package/examples/jsm/nodes/core/NodeFrame.js +56 -5
- package/examples/jsm/nodes/core/NodeUtils.js +115 -28
- package/examples/jsm/nodes/core/PropertyNode.js +23 -2
- package/examples/jsm/nodes/core/StackNode.js +99 -0
- package/examples/jsm/nodes/core/TempNode.js +11 -3
- package/examples/jsm/nodes/core/UniformNode.js +16 -1
- package/examples/jsm/nodes/core/VarNode.js +19 -29
- package/examples/jsm/nodes/core/VaryingNode.js +15 -2
- package/examples/jsm/nodes/core/constants.js +6 -0
- package/examples/jsm/nodes/display/BlendModeNode.js +33 -19
- package/examples/jsm/nodes/display/ColorAdjustmentNode.js +36 -20
- package/examples/jsm/nodes/display/ColorSpaceNode.js +60 -47
- package/examples/jsm/nodes/display/FrontFacingNode.js +7 -1
- package/examples/jsm/nodes/display/NormalMapNode.js +33 -20
- package/examples/jsm/nodes/display/PosterizeNode.js +10 -3
- package/examples/jsm/nodes/display/ToneMappingNode.js +101 -11
- package/examples/jsm/nodes/display/ViewportDepthNode.js +69 -0
- package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +34 -0
- package/examples/jsm/nodes/display/ViewportNode.js +27 -18
- package/examples/jsm/nodes/display/ViewportSharedTextureNode.js +31 -0
- package/examples/jsm/nodes/display/ViewportTextureNode.js +75 -0
- package/examples/jsm/nodes/fog/FogExp2Node.js +35 -0
- package/examples/jsm/nodes/fog/FogNode.js +12 -6
- package/examples/jsm/nodes/fog/FogRangeNode.js +12 -5
- package/examples/jsm/nodes/functions/BSDF/BRDF_BlinnPhong.js +30 -0
- package/examples/jsm/nodes/functions/BSDF/BRDF_GGX.js +15 -16
- package/examples/jsm/nodes/functions/BSDF/BRDF_Lambert.js +3 -3
- package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +43 -0
- package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +9 -7
- package/examples/jsm/nodes/functions/BSDF/D_GGX.js +5 -5
- package/examples/jsm/nodes/functions/BSDF/EnvironmentBRDF.js +13 -0
- package/examples/jsm/nodes/functions/BSDF/F_Schlick.js +4 -6
- package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +8 -6
- package/examples/jsm/nodes/functions/PhongLightingModel.js +28 -0
- package/examples/jsm/nodes/functions/PhysicalLightingModel.js +155 -45
- package/examples/jsm/nodes/functions/material/getGeometryRoughness.js +5 -4
- package/examples/jsm/nodes/functions/material/getRoughness.js +6 -6
- package/examples/jsm/nodes/geometry/RangeNode.js +50 -55
- package/examples/jsm/nodes/gpgpu/ComputeNode.js +9 -2
- package/examples/jsm/nodes/lighting/AONode.js +5 -3
- package/examples/jsm/nodes/lighting/AmbientLightNode.js +27 -0
- package/examples/jsm/nodes/lighting/AnalyticLightNode.js +114 -5
- package/examples/jsm/nodes/lighting/DirectionalLightNode.js +43 -0
- package/examples/jsm/nodes/lighting/EnvironmentNode.js +153 -38
- package/examples/jsm/nodes/lighting/HemisphereLightNode.js +15 -10
- package/examples/jsm/nodes/lighting/IESSpotLightNode.js +39 -0
- package/examples/jsm/nodes/lighting/LightNode.js +57 -0
- package/examples/jsm/nodes/lighting/LightUtils.js +17 -0
- package/examples/jsm/nodes/lighting/LightingContextNode.js +41 -17
- package/examples/jsm/nodes/lighting/LightingNode.js +3 -1
- package/examples/jsm/nodes/lighting/LightsNode.js +18 -10
- package/examples/jsm/nodes/lighting/PointLightNode.js +71 -0
- package/examples/jsm/nodes/lighting/SpotLightNode.js +92 -0
- package/examples/jsm/nodes/loaders/NodeLoader.js +5 -4
- package/examples/jsm/nodes/loaders/NodeMaterialLoader.js +4 -20
- package/examples/jsm/nodes/materials/LineBasicNodeMaterial.js +6 -24
- package/examples/jsm/nodes/materials/Materials.js +11 -55
- package/examples/jsm/nodes/materials/MeshBasicNodeMaterial.js +5 -26
- package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +38 -0
- package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +65 -0
- package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +47 -6
- package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +22 -110
- package/examples/jsm/nodes/materials/NodeMaterial.js +340 -67
- package/examples/jsm/nodes/materials/PointsNodeMaterial.js +7 -10
- package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +29 -32
- package/examples/jsm/nodes/materialx/MaterialXNodes.js +31 -22
- package/examples/jsm/nodes/materialx/lib/mx_hsv.js +3 -3
- package/examples/jsm/nodes/materialx/lib/mx_noise.js +14 -13
- package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +4 -3
- package/examples/jsm/nodes/math/CondNode.js +43 -17
- package/examples/jsm/nodes/math/MathNode.js +184 -73
- package/examples/jsm/nodes/math/OperatorNode.js +53 -3
- package/examples/jsm/nodes/procedural/CheckerNode.js +16 -8
- package/examples/jsm/nodes/shadernode/ShaderNode.js +206 -63
- package/examples/jsm/nodes/utils/ArrayElementNode.js +4 -2
- package/examples/jsm/nodes/utils/ConvertNode.js +19 -1
- package/examples/jsm/nodes/utils/DiscardNode.js +26 -0
- package/examples/jsm/nodes/utils/EquirectUVNode.js +10 -4
- package/examples/jsm/nodes/utils/JoinNode.js +4 -1
- package/examples/jsm/nodes/utils/LoopNode.js +186 -0
- package/examples/jsm/nodes/utils/MatcapUVNode.js +11 -4
- package/examples/jsm/nodes/utils/MaxMipLevelNode.js +18 -5
- package/examples/jsm/nodes/utils/OscNode.js +21 -14
- package/examples/jsm/nodes/utils/PackingNode.js +55 -0
- package/examples/jsm/nodes/utils/RemapNode.js +13 -5
- package/examples/jsm/nodes/utils/RotateUVNode.js +18 -7
- package/examples/jsm/nodes/utils/SpecularMIPLevelNode.js +37 -0
- package/examples/jsm/nodes/utils/SplitNode.js +7 -5
- package/examples/jsm/nodes/utils/SpriteSheetUVNode.js +15 -30
- package/examples/jsm/nodes/utils/TimerNode.js +16 -6
- package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +21 -10
- package/examples/jsm/objects/GroundProjectedSkybox.js +172 -0
- package/examples/jsm/objects/Lensflare.js +3 -4
- package/examples/jsm/objects/MarchingCubes.js +5 -1
- package/examples/jsm/objects/Reflector.js +8 -5
- package/examples/jsm/objects/Refractor.js +5 -5
- package/examples/jsm/objects/ShadowMesh.js +3 -3
- package/examples/jsm/objects/Sky.js +1 -1
- package/examples/jsm/objects/Water.js +2 -1
- package/examples/jsm/objects/Water2.js +1 -1
- package/examples/jsm/offscreen/scene.js +1 -0
- package/examples/jsm/physics/AmmoPhysics.js +27 -28
- package/examples/jsm/physics/RapierPhysics.js +199 -0
- package/examples/jsm/postprocessing/AfterimagePass.js +3 -2
- package/examples/jsm/postprocessing/BloomPass.js +7 -4
- package/examples/jsm/postprocessing/BokehPass.js +3 -8
- package/examples/jsm/postprocessing/DotScreenPass.js +1 -2
- package/examples/jsm/postprocessing/EffectComposer.js +7 -95
- package/examples/jsm/postprocessing/FilmPass.js +1 -2
- package/examples/jsm/postprocessing/GlitchPass.js +0 -2
- package/examples/jsm/postprocessing/HalftonePass.js +0 -6
- package/examples/jsm/postprocessing/OutlinePass.js +8 -10
- package/examples/jsm/postprocessing/OutputPass.js +72 -0
- package/examples/jsm/postprocessing/Pass.js +2 -0
- package/examples/jsm/postprocessing/RenderPixelatedPass.js +4 -3
- package/examples/jsm/postprocessing/SAOPass.js +4 -26
- package/examples/jsm/postprocessing/SMAAPass.js +5 -8
- package/examples/jsm/postprocessing/SSAARenderPass.js +5 -5
- package/examples/jsm/postprocessing/SSAOPass.js +4 -14
- package/examples/jsm/postprocessing/SSRPass.js +3 -7
- package/examples/jsm/postprocessing/SavePass.js +5 -4
- package/examples/jsm/postprocessing/ShaderPass.js +1 -0
- package/examples/jsm/postprocessing/TAARenderPass.js +17 -4
- package/examples/jsm/postprocessing/TexturePass.js +2 -3
- package/examples/jsm/postprocessing/UnrealBloomPass.js +13 -21
- package/examples/jsm/renderers/CSS2DRenderer.js +6 -1
- package/examples/jsm/renderers/CSS3DRenderer.js +27 -5
- package/examples/jsm/renderers/{webgpu/WebGPUAnimation.js → common/Animation.js} +4 -4
- package/examples/jsm/renderers/common/Attributes.js +75 -0
- package/examples/jsm/renderers/common/Backend.js +162 -0
- package/examples/jsm/renderers/common/Background.js +134 -0
- package/examples/jsm/renderers/common/Binding.js +11 -0
- package/examples/jsm/renderers/common/Bindings.js +169 -0
- package/examples/jsm/renderers/common/Buffer.js +38 -0
- package/examples/jsm/renderers/{webgpu/WebGPUBufferUtils.js → common/BufferUtils.js} +2 -2
- package/examples/jsm/renderers/common/ChainMap.js +89 -0
- package/examples/jsm/renderers/common/ComputePipeline.js +17 -0
- package/examples/jsm/renderers/common/Constants.js +14 -0
- package/examples/jsm/renderers/common/CubeRenderTarget.js +65 -0
- package/examples/jsm/renderers/common/DataMap.js +54 -0
- package/examples/jsm/renderers/common/Geometries.js +215 -0
- package/examples/jsm/renderers/{webgpu/WebGPUInfo.js → common/Info.js} +2 -3
- package/examples/jsm/renderers/common/Pipeline.js +13 -0
- package/examples/jsm/renderers/common/Pipelines.js +321 -0
- package/examples/jsm/renderers/common/ProgrammableStage.js +18 -0
- package/examples/jsm/renderers/common/RenderContext.js +37 -0
- package/examples/jsm/renderers/common/RenderContexts.js +38 -0
- package/examples/jsm/renderers/{webgpu/WebGPURenderLists.js → common/RenderList.js} +26 -47
- package/examples/jsm/renderers/common/RenderLists.js +38 -0
- package/examples/jsm/renderers/common/RenderObject.js +113 -0
- package/examples/jsm/renderers/common/RenderObjects.js +92 -0
- package/examples/jsm/renderers/common/RenderPipeline.js +16 -0
- package/examples/jsm/renderers/common/RenderTarget.js +15 -0
- package/examples/jsm/renderers/common/Renderer.js +864 -0
- package/examples/jsm/renderers/common/SampledTexture.js +80 -0
- package/examples/jsm/renderers/common/Sampler.js +18 -0
- package/examples/jsm/renderers/common/StorageBuffer.js +17 -0
- package/examples/jsm/renderers/common/Textures.js +206 -0
- package/examples/jsm/renderers/{webgpu/WebGPUUniform.js → common/Uniform.js} +13 -9
- package/examples/jsm/renderers/common/UniformBuffer.js +15 -0
- package/examples/jsm/renderers/{webgpu/WebGPUUniformsGroup.js → common/UniformsGroup.js} +13 -13
- package/examples/jsm/renderers/common/nodes/NodeRender.js +302 -0
- package/examples/jsm/renderers/{webgpu/nodes/WebGPUNodeSampledTexture.js → common/nodes/NodeSampledTexture.js} +4 -4
- package/examples/jsm/renderers/{webgpu/nodes/WebGPUNodeSampler.js → common/nodes/NodeSampler.js} +3 -3
- package/examples/jsm/renderers/{webgpu/nodes/WebGPUNodeUniform.js → common/nodes/NodeUniform.js} +1 -1
- package/examples/jsm/renderers/common/nodes/Nodes.js +319 -0
- package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +340 -0
- package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +58 -50
- package/examples/jsm/renderers/webgpu/WebGPUBackend.js +847 -0
- package/examples/jsm/renderers/webgpu/WebGPURenderer.js +15 -987
- package/examples/jsm/renderers/webgpu/nodes/{WebGPUNodeBuilder.js → WGSLNodeBuilder.js} +139 -92
- package/examples/jsm/{nodes/parsers → renderers/webgpu/nodes}/WGSLNodeFunction.js +2 -2
- package/examples/jsm/{nodes/parsers → renderers/webgpu/nodes}/WGSLNodeParser.js +1 -1
- package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +255 -0
- package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +145 -0
- package/examples/jsm/renderers/webgpu/{constants.js → utils/WebGPUConstants.js} +73 -12
- package/examples/jsm/renderers/webgpu/{WebGPURenderPipeline.js → utils/WebGPUPipelineUtils.js} +141 -296
- package/examples/jsm/renderers/webgpu/{WebGPUTextureUtils.js → utils/WebGPUTextureMipmapUtils.js} +5 -25
- package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +937 -0
- package/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js +92 -0
- package/examples/jsm/shaders/BleachBypassShader.js +2 -0
- package/examples/jsm/shaders/BlendShader.js +1 -2
- package/examples/jsm/shaders/BokehShader2.js +3 -0
- package/examples/jsm/shaders/ColorifyShader.js +2 -0
- package/examples/jsm/shaders/ConvolutionShader.js +2 -0
- package/examples/jsm/shaders/CopyShader.js +4 -2
- package/examples/jsm/shaders/DotScreenShader.js +2 -0
- package/examples/jsm/shaders/ExposureShader.js +44 -0
- package/examples/jsm/shaders/FilmShader.js +2 -0
- package/examples/jsm/shaders/GammaCorrectionShader.js +2 -0
- package/examples/jsm/shaders/HorizontalBlurShader.js +2 -0
- package/examples/jsm/shaders/MMDToonShader.js +15 -4
- package/examples/jsm/shaders/OutputShader.js +61 -0
- package/examples/jsm/shaders/RGBShiftShader.js +4 -2
- package/examples/jsm/shaders/SepiaShader.js +2 -0
- package/examples/jsm/shaders/ToonShader.js +13 -5
- package/examples/jsm/shaders/VelocityShader.js +1 -1
- package/examples/jsm/shaders/VerticalBlurShader.js +2 -0
- package/examples/jsm/shaders/VignetteShader.js +2 -0
- package/examples/jsm/shaders/WaterRefractionShader.js +5 -2
- package/examples/jsm/utils/BufferGeometryUtils.js +54 -36
- package/examples/jsm/utils/LDrawUtils.js +4 -4
- package/examples/jsm/utils/PackedPhongMaterial.js +5 -78
- package/examples/jsm/utils/SceneUtils.js +8 -4
- package/examples/jsm/utils/SkeletonUtils.js +27 -210
- package/examples/jsm/utils/TextureUtils.js +86 -0
- package/examples/jsm/webxr/OculusHandPointerModel.js +34 -13
- package/examples/jsm/webxr/VRButton.js +1 -2
- package/examples/jsm/webxr/XRButton.js +198 -0
- package/examples/jsm/webxr/XRHandPrimitiveModel.js +1 -0
- package/examples/jsm/webxr/XRPlanes.js +100 -0
- package/package.json +35 -87
- package/src/Three.Legacy.js +0 -319
- package/src/Three.js +4 -3
- package/src/animation/AnimationUtils.js +13 -1
- package/src/animation/PropertyBinding.js +2 -2
- package/src/audio/Audio.js +7 -2
- package/src/audio/PositionalAudio.js +8 -0
- package/src/cameras/Camera.js +5 -0
- package/src/cameras/CubeCamera.js +76 -13
- package/src/cameras/OrthographicCamera.js +1 -1
- package/src/cameras/PerspectiveCamera.js +1 -1
- package/src/constants.js +22 -2
- package/src/core/BufferAttribute.js +146 -29
- package/src/core/BufferGeometry.js +2 -15
- package/src/core/GLBufferAttribute.js +2 -0
- package/src/core/InterleavedBufferAttribute.js +1 -1
- package/src/core/Object3D.js +37 -8
- package/src/extras/DataUtils.js +7 -1
- package/src/extras/ImageUtils.js +2 -2
- package/src/extras/PMREMGenerator.js +5 -5
- package/src/extras/core/Curve.js +1 -1
- package/src/extras/curves/LineCurve.js +6 -4
- package/src/extras/curves/LineCurve3.js +13 -0
- package/src/geometries/BoxGeometry.js +10 -0
- package/src/geometries/CircleGeometry.js +11 -1
- package/src/geometries/ConeGeometry.js +1 -1
- package/src/geometries/CylinderGeometry.js +11 -1
- package/src/geometries/EdgesGeometry.js +10 -0
- package/src/geometries/ExtrudeGeometry.js +11 -1
- package/src/geometries/LatheGeometry.js +10 -0
- package/src/geometries/PlaneGeometry.js +10 -0
- package/src/geometries/PolyhedronGeometry.js +10 -0
- package/src/geometries/RingGeometry.js +11 -1
- package/src/geometries/ShapeGeometry.js +10 -0
- package/src/geometries/SphereGeometry.js +12 -2
- package/src/geometries/TorusGeometry.js +11 -1
- package/src/geometries/TorusKnotGeometry.js +10 -0
- package/src/geometries/TubeGeometry.js +10 -0
- package/src/geometries/WireframeGeometry.js +10 -0
- package/src/helpers/Box3Helper.js +1 -2
- package/src/lights/DirectionalLight.js +1 -1
- package/src/lights/HemisphereLight.js +1 -1
- package/src/lights/SpotLight.js +1 -1
- package/src/loaders/AudioLoader.js +14 -8
- package/src/loaders/CubeTextureLoader.js +2 -0
- package/src/loaders/DataTextureLoader.js +5 -1
- package/src/loaders/Loader.js +2 -0
- package/src/loaders/MaterialLoader.js +9 -0
- package/src/loaders/ObjectLoader.js +10 -2
- package/src/materials/LineBasicMaterial.js +4 -0
- package/src/materials/Material.js +19 -4
- package/src/materials/MeshDistanceMaterial.js +0 -9
- package/src/materials/MeshPhysicalMaterial.js +32 -6
- package/src/materials/ShaderMaterial.js +6 -1
- package/src/math/Box2.js +3 -2
- package/src/math/Box3.js +49 -64
- package/src/math/Color.js +88 -66
- package/src/math/ColorManagement.js +75 -16
- package/src/math/Euler.js +2 -11
- package/src/math/Frustum.js +29 -5
- package/src/math/MathUtils.js +43 -1
- package/src/math/Matrix3.js +26 -6
- package/src/math/Matrix4.js +74 -19
- package/src/math/Plane.js +2 -2
- package/src/math/Quaternion.js +6 -0
- package/src/math/Ray.js +7 -7
- package/src/math/Triangle.js +37 -7
- package/src/math/Vector2.js +16 -0
- package/src/math/Vector3.js +10 -0
- package/src/math/interpolants/CubicInterpolant.js +1 -2
- package/src/objects/InstancedMesh.js +82 -1
- package/src/objects/Mesh.js +108 -76
- package/src/objects/Skeleton.js +1 -3
- package/src/objects/SkinnedMesh.js +123 -8
- package/src/objects/Sprite.js +1 -1
- package/src/renderers/WebGLCubeRenderTarget.js +12 -3
- package/src/renderers/WebGLMultipleRenderTargets.js +4 -2
- package/src/renderers/WebGLRenderTarget.js +14 -2
- package/src/renderers/WebGLRenderer.js +1439 -1252
- package/src/renderers/shaders/ShaderChunk/alphahash_fragment.glsl.js +7 -0
- package/src/renderers/shaders/ShaderChunk/alphahash_pars_fragment.glsl.js +68 -0
- package/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/begin_vertex.glsl.js +6 -0
- package/src/renderers/shaders/ShaderChunk/bsdfs.glsl.js +0 -271
- package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +5 -5
- package/src/renderers/shaders/ShaderChunk/clearcoat_normal_fragment_maps.glsl.js +2 -10
- package/src/renderers/shaders/ShaderChunk/clearcoat_pars_fragment.glsl.js +5 -5
- package/src/renderers/shaders/ShaderChunk/common.glsl.js +38 -0
- package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/displacementmap_vertex.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/envmap_physical_pars_fragment.glsl.js +26 -3
- package/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +3 -3
- package/src/renderers/shaders/ShaderChunk/lights_fragment_maps.glsl.js +10 -2
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +11 -11
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +39 -13
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +306 -10
- package/src/renderers/shaders/ShaderChunk/map_fragment.glsl.js +1 -11
- package/src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl.js +9 -1
- package/src/renderers/shaders/ShaderChunk/map_particle_pars_fragment.glsl.js +10 -2
- package/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/normal_fragment_begin.glsl.js +40 -10
- package/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js +5 -13
- package/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl.js +7 -7
- package/src/renderers/shaders/ShaderChunk/{output_fragment.glsl.js → opaque_fragment.glsl.js} +1 -2
- package/src/renderers/shaders/ShaderChunk/packing.glsl.js +11 -5
- package/src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js +4 -11
- package/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +39 -34
- package/src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +5 -5
- package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +101 -16
- package/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl.js +113 -1
- package/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl.js +135 -7
- package/src/renderers/shaders/ShaderChunk/uv_vertex.glsl.js +117 -2
- package/src/renderers/shaders/ShaderChunk.js +10 -12
- package/src/renderers/shaders/ShaderLib/background.glsl.js +1 -9
- package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/cube.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/depth.glsl.js +2 -0
- package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +2 -0
- package/src/renderers/shaders/ShaderLib/equirect.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/linedashed.glsl.js +7 -2
- package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +5 -6
- package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +4 -5
- package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +4 -2
- package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +3 -3
- package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +4 -5
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +20 -14
- package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +4 -5
- package/src/renderers/shaders/ShaderLib/points.glsl.js +17 -2
- package/src/renderers/shaders/ShaderLib/shadow.glsl.js +6 -1
- package/src/renderers/shaders/ShaderLib/sprite.glsl.js +4 -2
- package/src/renderers/shaders/ShaderLib.js +18 -4
- package/src/renderers/shaders/UniformsLib.js +27 -15
- package/src/renderers/shaders/UniformsUtils.js +12 -3
- package/src/renderers/webgl/WebGLBackground.js +23 -12
- package/src/renderers/webgl/WebGLBindingStates.js +13 -5
- package/src/renderers/webgl/WebGLCapabilities.js +1 -2
- package/src/renderers/webgl/WebGLClipping.js +7 -3
- package/src/renderers/webgl/WebGLGeometries.js +12 -0
- package/src/renderers/webgl/WebGLInfo.js +0 -1
- package/src/renderers/webgl/WebGLLights.js +2 -2
- package/src/renderers/webgl/WebGLMaterials.js +123 -234
- package/src/renderers/webgl/WebGLMorphtargets.js +1 -1
- package/src/renderers/webgl/WebGLObjects.js +23 -3
- package/src/renderers/webgl/WebGLProgram.js +154 -53
- package/src/renderers/webgl/WebGLPrograms.js +213 -130
- package/src/renderers/webgl/WebGLRenderStates.js +2 -2
- package/src/renderers/webgl/WebGLShadowMap.js +40 -27
- package/src/renderers/webgl/WebGLState.js +23 -9
- package/src/renderers/webgl/WebGLTextures.js +39 -19
- package/src/renderers/webgl/WebGLUniformsGroups.js +74 -33
- package/src/renderers/webgl/WebGLUtils.js +41 -29
- package/src/renderers/webvr/WebVRManager.js +12 -0
- package/src/renderers/webxr/WebXRController.js +3 -0
- package/src/renderers/webxr/WebXRManager.js +96 -134
- package/src/scenes/Scene.js +2 -18
- package/src/textures/CompressedTexture.js +2 -2
- package/src/textures/CubeTexture.js +2 -2
- package/src/textures/DataTexture.js +2 -2
- package/src/textures/DepthTexture.js +22 -0
- package/src/textures/FramebufferTexture.js +1 -3
- package/src/textures/Source.js +4 -0
- package/src/textures/Texture.js +42 -13
- package/src/utils.js +13 -1
- package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff +0 -0
- package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff2 +0 -0
- package/examples/fonts/open-sans/open-sans.css +0 -9
- package/examples/fonts/tabler-icons/fonts/tabler-icons.eot +0 -0
- package/examples/fonts/tabler-icons/fonts/tabler-icons.svg +0 -3966
- package/examples/fonts/tabler-icons/fonts/tabler-icons.ttf +0 -0
- package/examples/fonts/tabler-icons/fonts/tabler-icons.woff +0 -0
- package/examples/fonts/tabler-icons/fonts/tabler-icons.woff2 +0 -0
- package/examples/fonts/tabler-icons/tabler-icons.min.css +0 -4
- package/examples/js/animation/AnimationClipCreator.js +0 -89
- package/examples/js/animation/CCDIKSolver.js +0 -416
- package/examples/js/animation/MMDAnimationHelper.js +0 -1046
- package/examples/js/animation/MMDPhysics.js +0 -1174
- package/examples/js/cameras/CinematicCamera.js +0 -168
- package/examples/js/controls/ArcballControls.js +0 -2770
- package/examples/js/controls/DragControls.js +0 -205
- package/examples/js/controls/FirstPersonControls.js +0 -312
- package/examples/js/controls/FlyControls.js +0 -321
- package/examples/js/controls/OrbitControls.js +0 -1101
- package/examples/js/controls/PointerLockControls.js +0 -144
- package/examples/js/controls/TrackballControls.js +0 -729
- package/examples/js/controls/TransformControls.js +0 -1301
- package/examples/js/csm/CSM.js +0 -347
- package/examples/js/csm/CSMFrustum.js +0 -127
- package/examples/js/csm/CSMHelper.js +0 -165
- package/examples/js/csm/CSMShader.js +0 -253
- package/examples/js/curves/CurveExtras.js +0 -348
- package/examples/js/curves/NURBSCurve.js +0 -63
- package/examples/js/curves/NURBSSurface.js +0 -48
- package/examples/js/curves/NURBSUtils.js +0 -439
- package/examples/js/effects/AnaglyphEffect.js +0 -86
- package/examples/js/effects/AsciiEffect.js +0 -260
- package/examples/js/effects/OutlineEffect.js +0 -450
- package/examples/js/effects/ParallaxBarrierEffect.js +0 -62
- package/examples/js/effects/PeppersGhostEffect.js +0 -139
- package/examples/js/effects/StereoEffect.js +0 -46
- package/examples/js/environments/DebugEnvironment.js +0 -53
- package/examples/js/environments/RoomEnvironment.js +0 -124
- package/examples/js/exporters/ColladaExporter.js +0 -487
- package/examples/js/exporters/DRACOExporter.js +0 -212
- package/examples/js/exporters/EXRExporter.js +0 -455
- package/examples/js/exporters/GLTFExporter.js +0 -2367
- package/examples/js/exporters/MMDExporter.js +0 -187
- package/examples/js/exporters/OBJExporter.js +0 -260
- package/examples/js/exporters/PLYExporter.js +0 -427
- package/examples/js/exporters/STLExporter.js +0 -188
- package/examples/js/exporters/USDZExporter.js +0 -608
- package/examples/js/geometries/BoxLineGeometry.js +0 -59
- package/examples/js/geometries/ConvexGeometry.js +0 -53
- package/examples/js/geometries/DecalGeometry.js +0 -324
- package/examples/js/geometries/LightningStrike.js +0 -861
- package/examples/js/geometries/ParametricGeometries.js +0 -216
- package/examples/js/geometries/ParametricGeometry.js +0 -121
- package/examples/js/geometries/RoundedBoxGeometry.js +0 -142
- package/examples/js/geometries/TeapotGeometry.js +0 -335
- package/examples/js/geometries/TextGeometry.js +0 -53
- package/examples/js/helpers/LightProbeHelper.js +0 -48
- package/examples/js/helpers/OctreeHelper.js +0 -76
- package/examples/js/helpers/PositionalAudioHelper.js +0 -91
- package/examples/js/helpers/RectAreaLightHelper.js +0 -73
- package/examples/js/helpers/VertexNormalsHelper.js +0 -74
- package/examples/js/helpers/VertexTangentsHelper.js +0 -68
- package/examples/js/helpers/ViewHelper.js +0 -281
- package/examples/js/interactive/HTMLMesh.js +0 -497
- package/examples/js/interactive/InteractiveGroup.js +0 -95
- package/examples/js/interactive/SelectionBox.js +0 -195
- package/examples/js/interactive/SelectionHelper.js +0 -83
- package/examples/js/libs/chevrotain.min.js +0 -3
- package/examples/js/libs/draco/draco_decoder.js +0 -52
- package/examples/js/libs/draco/draco_decoder.wasm +0 -0
- package/examples/js/libs/draco/draco_wasm_wrapper.js +0 -104
- package/examples/js/libs/draco/gltf/draco_decoder.js +0 -48
- package/examples/js/libs/draco/gltf/draco_decoder.wasm +0 -0
- package/examples/js/libs/draco/gltf/draco_wasm_wrapper.js +0 -104
- package/examples/js/libs/fflate.min.js +0 -7
- package/examples/js/libs/ktx-parse.umd.js +0 -1
- package/examples/js/libs/meshopt_decoder.js +0 -188
- package/examples/js/libs/opentype.min.js +0 -1
- package/examples/js/libs/stats.min.js +0 -5
- package/examples/js/lights/LightProbeGenerator.js +0 -221
- package/examples/js/lights/RectAreaLightUniformsLib.js +0 -60
- package/examples/js/lines/Line2.js +0 -19
- package/examples/js/lines/LineGeometry.js +0 -69
- package/examples/js/lines/LineMaterial.js +0 -635
- package/examples/js/lines/LineSegments2.js +0 -313
- package/examples/js/lines/LineSegmentsGeometry.js +0 -198
- package/examples/js/lines/Wireframe.js +0 -47
- package/examples/js/lines/WireframeGeometry2.js +0 -20
- package/examples/js/loaders/3DMLoader.js +0 -1273
- package/examples/js/loaders/3MFLoader.js +0 -1306
- package/examples/js/loaders/AMFLoader.js +0 -504
- package/examples/js/loaders/BVHLoader.js +0 -395
- package/examples/js/loaders/BasisTextureLoader.js +0 -706
- package/examples/js/loaders/ColladaLoader.js +0 -3690
- package/examples/js/loaders/DDSLoader.js +0 -244
- package/examples/js/loaders/DRACOLoader.js +0 -511
- package/examples/js/loaders/EXRLoader.js +0 -2039
- package/examples/js/loaders/FBXLoader.js +0 -3681
- package/examples/js/loaders/FontLoader.js +0 -160
- package/examples/js/loaders/GCodeLoader.js +0 -255
- package/examples/js/loaders/GLTFLoader.js +0 -3862
- package/examples/js/loaders/HDRCubeTextureLoader.js +0 -87
- package/examples/js/loaders/KMZLoader.js +0 -121
- package/examples/js/loaders/KTXLoader.js +0 -159
- package/examples/js/loaders/LDrawLoader.js +0 -2263
- package/examples/js/loaders/LUT3dlLoader.js +0 -135
- package/examples/js/loaders/LUTCubeLoader.js +0 -132
- package/examples/js/loaders/LWOLoader.js +0 -901
- package/examples/js/loaders/LogLuvLoader.js +0 -715
- package/examples/js/loaders/LottieLoader.js +0 -62
- package/examples/js/loaders/MD2Loader.js +0 -248
- package/examples/js/loaders/MDDLoader.js +0 -91
- package/examples/js/loaders/MMDLoader.js +0 -1915
- package/examples/js/loaders/MTLLoader.js +0 -472
- package/examples/js/loaders/NRRDLoader.js +0 -609
- package/examples/js/loaders/OBJLoader.js +0 -789
- package/examples/js/loaders/PCDLoader.js +0 -413
- package/examples/js/loaders/PDBLoader.js +0 -317
- package/examples/js/loaders/PLYLoader.js +0 -576
- package/examples/js/loaders/PRWMLoader.js +0 -249
- package/examples/js/loaders/PVRLoader.js +0 -218
- package/examples/js/loaders/RGBELoader.js +0 -442
- package/examples/js/loaders/RGBMLoader.js +0 -1354
- package/examples/js/loaders/STLLoader.js +0 -364
- package/examples/js/loaders/SVGLoader.js +0 -2783
- package/examples/js/loaders/TDSLoader.js +0 -992
- package/examples/js/loaders/TGALoader.js +0 -484
- package/examples/js/loaders/TIFFLoader.js +0 -30
- package/examples/js/loaders/TTFLoader.js +0 -203
- package/examples/js/loaders/TiltLoader.js +0 -459
- package/examples/js/loaders/VOXLoader.js +0 -240
- package/examples/js/loaders/VRMLLoader.js +0 -3140
- package/examples/js/loaders/VTKLoader.js +0 -1078
- package/examples/js/loaders/XYZLoader.js +0 -89
- package/examples/js/loaders/lwo/IFFParser.js +0 -1067
- package/examples/js/loaders/lwo/LWO2Parser.js +0 -397
- package/examples/js/loaders/lwo/LWO3Parser.js +0 -360
- package/examples/js/materials/MeshGouraudMaterial.js +0 -387
- package/examples/js/math/Capsule.js +0 -103
- package/examples/js/math/ColorConverter.js +0 -33
- package/examples/js/math/ConvexHull.js +0 -1154
- package/examples/js/math/ImprovedNoise.js +0 -66
- package/examples/js/math/Lut.js +0 -164
- package/examples/js/math/MeshSurfaceSampler.js +0 -171
- package/examples/js/math/OBB.js +0 -382
- package/examples/js/math/Octree.js +0 -410
- package/examples/js/math/SimplexNoise.js +0 -445
- package/examples/js/misc/ConvexObjectBreaker.js +0 -474
- package/examples/js/misc/GPUComputationRenderer.js +0 -393
- package/examples/js/misc/Gyroscope.js +0 -56
- package/examples/js/misc/MD2Character.js +0 -235
- package/examples/js/misc/MD2CharacterComplex.js +0 -513
- package/examples/js/misc/MorphAnimMesh.js +0 -63
- package/examples/js/misc/MorphBlendMesh.js +0 -265
- package/examples/js/misc/ProgressiveLightMap.js +0 -335
- package/examples/js/misc/RollerCoaster.js +0 -430
- package/examples/js/misc/TubePainter.js +0 -167
- package/examples/js/misc/Volume.js +0 -437
- package/examples/js/misc/VolumeSlice.js +0 -214
- package/examples/js/modifiers/CurveModifier.js +0 -309
- package/examples/js/modifiers/EdgeSplitModifier.js +0 -228
- package/examples/js/modifiers/SimplifyModifier.js +0 -465
- package/examples/js/modifiers/TessellateModifier.js +0 -276
- package/examples/js/objects/GroundProjectedEnv.js +0 -181
- package/examples/js/objects/Lensflare.js +0 -356
- package/examples/js/objects/LightningStorm.js +0 -206
- package/examples/js/objects/MarchingCubes.js +0 -759
- package/examples/js/objects/Reflector.js +0 -216
- package/examples/js/objects/ReflectorForSSRPass.js +0 -315
- package/examples/js/objects/Refractor.js +0 -283
- package/examples/js/objects/ShadowMesh.js +0 -59
- package/examples/js/objects/Sky.js +0 -218
- package/examples/js/objects/Water.js +0 -292
- package/examples/js/objects/Water2.js +0 -307
- package/examples/js/physics/AmmoPhysics.js +0 -259
- package/examples/js/physics/OimoPhysics.js +0 -217
- package/examples/js/postprocessing/AdaptiveToneMappingPass.js +0 -335
- package/examples/js/postprocessing/AfterimagePass.js +0 -77
- package/examples/js/postprocessing/BloomPass.js +0 -135
- package/examples/js/postprocessing/BokehPass.js +0 -120
- package/examples/js/postprocessing/ClearPass.js +0 -39
- package/examples/js/postprocessing/CubeTexturePass.js +0 -60
- package/examples/js/postprocessing/DotScreenPass.js +0 -51
- package/examples/js/postprocessing/EffectComposer.js +0 -272
- package/examples/js/postprocessing/FilmPass.js +0 -52
- package/examples/js/postprocessing/GlitchPass.js +0 -104
- package/examples/js/postprocessing/HalftonePass.js +0 -75
- package/examples/js/postprocessing/LUTPass.js +0 -171
- package/examples/js/postprocessing/MaskPass.js +0 -95
- package/examples/js/postprocessing/OutlinePass.js +0 -598
- package/examples/js/postprocessing/Pass.js +0 -72
- package/examples/js/postprocessing/RenderPass.js +0 -70
- package/examples/js/postprocessing/RenderPixelatedPass.js +0 -215
- package/examples/js/postprocessing/SAOPass.js +0 -374
- package/examples/js/postprocessing/SMAAPass.js +0 -170
- package/examples/js/postprocessing/SSAARenderPass.js +0 -156
- package/examples/js/postprocessing/SSAOPass.js +0 -365
- package/examples/js/postprocessing/SSRPass.js +0 -567
- package/examples/js/postprocessing/SavePass.js +0 -59
- package/examples/js/postprocessing/ShaderPass.js +0 -64
- package/examples/js/postprocessing/TAARenderPass.js +0 -130
- package/examples/js/postprocessing/TexturePass.js +0 -49
- package/examples/js/postprocessing/UnrealBloomPass.js +0 -375
- package/examples/js/renderers/CSS2DRenderer.js +0 -178
- package/examples/js/renderers/CSS3DRenderer.js +0 -237
- package/examples/js/renderers/Projector.js +0 -818
- package/examples/js/renderers/SVGRenderer.js +0 -491
- package/examples/js/shaders/ACESFilmicToneMappingShader.js +0 -89
- package/examples/js/shaders/AfterimageShader.js +0 -60
- package/examples/js/shaders/BasicShader.js +0 -27
- package/examples/js/shaders/BleachBypassShader.js +0 -62
- package/examples/js/shaders/BlendShader.js +0 -54
- package/examples/js/shaders/BokehShader.js +0 -156
- package/examples/js/shaders/BokehShader2.js +0 -419
- package/examples/js/shaders/BrightnessContrastShader.js +0 -58
- package/examples/js/shaders/ColorCorrectionShader.js +0 -52
- package/examples/js/shaders/ColorifyShader.js +0 -47
- package/examples/js/shaders/ConvolutionShader.js +0 -92
- package/examples/js/shaders/CopyShader.js +0 -45
- package/examples/js/shaders/DOFMipMapShader.js +0 -60
- package/examples/js/shaders/DepthLimitedBlurShader.js +0 -173
- package/examples/js/shaders/DigitalGlitch.js +0 -127
- package/examples/js/shaders/DotScreenShader.js +0 -72
- package/examples/js/shaders/FXAAShader.js +0 -284
- package/examples/js/shaders/FilmShader.js +0 -110
- package/examples/js/shaders/FocusShader.js +0 -95
- package/examples/js/shaders/FreiChenShader.js +0 -93
- package/examples/js/shaders/GammaCorrectionShader.js +0 -41
- package/examples/js/shaders/GodRaysShader.js +0 -284
- package/examples/js/shaders/HalftoneShader.js +0 -336
- package/examples/js/shaders/HorizontalBlurShader.js +0 -59
- package/examples/js/shaders/HorizontalTiltShiftShader.js +0 -65
- package/examples/js/shaders/HueSaturationShader.js +0 -69
- package/examples/js/shaders/KaleidoShader.js +0 -60
- package/examples/js/shaders/LuminosityHighPassShader.js +0 -67
- package/examples/js/shaders/LuminosityShader.js +0 -46
- package/examples/js/shaders/MMDToonShader.js +0 -94
- package/examples/js/shaders/MirrorShader.js +0 -56
- package/examples/js/shaders/NormalMapShader.js +0 -55
- package/examples/js/shaders/RGBShiftShader.js +0 -56
- package/examples/js/shaders/SAOShader.js +0 -209
- package/examples/js/shaders/SMAAShader.js +0 -454
- package/examples/js/shaders/SSAOShader.js +0 -295
- package/examples/js/shaders/SSRShader.js +0 -381
- package/examples/js/shaders/SepiaShader.js +0 -52
- package/examples/js/shaders/SobelOperatorShader.js +0 -88
- package/examples/js/shaders/SubsurfaceScatteringShader.js +0 -49
- package/examples/js/shaders/TechnicolorShader.js +0 -43
- package/examples/js/shaders/ToneMapShader.js +0 -84
- package/examples/js/shaders/ToonShader.js +0 -335
- package/examples/js/shaders/TriangleBlurShader.js +0 -70
- package/examples/js/shaders/UnpackDepthRGBAShader.js +0 -47
- package/examples/js/shaders/VelocityShader.js +0 -126
- package/examples/js/shaders/VerticalBlurShader.js +0 -59
- package/examples/js/shaders/VerticalTiltShiftShader.js +0 -65
- package/examples/js/shaders/VignetteShader.js +0 -53
- package/examples/js/shaders/VolumeShader.js +0 -296
- package/examples/js/shaders/WaterRefractionShader.js +0 -84
- package/examples/js/textures/FlakesTexture.js +0 -40
- package/examples/js/utils/BufferGeometryUtils.js +0 -1160
- package/examples/js/utils/CameraUtils.js +0 -71
- package/examples/js/utils/GPUStatsPanel.js +0 -125
- package/examples/js/utils/GeometryCompressionUtils.js +0 -549
- package/examples/js/utils/GeometryUtils.js +0 -168
- package/examples/js/utils/LDrawUtils.js +0 -179
- package/examples/js/utils/PackedPhongMaterial.js +0 -109
- package/examples/js/utils/SceneUtils.js +0 -214
- package/examples/js/utils/ShadowMapViewer.js +0 -183
- package/examples/js/utils/SkeletonUtils.js +0 -493
- package/examples/js/utils/UVsDebug.js +0 -143
- package/examples/js/utils/WorkerPool.js +0 -105
- package/examples/jsm/exporters/ColladaExporter.js +0 -713
- package/examples/jsm/geometries/LightningStrike.js +0 -1017
- package/examples/jsm/libs/OimoPhysics/OimoPhysics.js +0 -37071
- package/examples/jsm/libs/OimoPhysics/index.js +0 -43
- package/examples/jsm/libs/flow.module.js +0 -4552
- package/examples/jsm/libs/tween.module.min.js +0 -3
- package/examples/jsm/loaders/BasisTextureLoader.js +0 -790
- package/examples/jsm/loaders/IFCLoader.js +0 -2431
- package/examples/jsm/loaders/PRWMLoader.js +0 -299
- package/examples/jsm/loaders/ifc/web-ifc-api.js +0 -47504
- package/examples/jsm/loaders/ifc/web-ifc.wasm +0 -0
- package/examples/jsm/node-editor/NodeEditor.js +0 -857
- package/examples/jsm/node-editor/accessors/MatcapUVEditor.js +0 -14
- package/examples/jsm/node-editor/accessors/NormalEditor.js +0 -30
- package/examples/jsm/node-editor/accessors/PositionEditor.js +0 -30
- package/examples/jsm/node-editor/accessors/UVEditor.js +0 -25
- package/examples/jsm/node-editor/core/BaseNode.js +0 -96
- package/examples/jsm/node-editor/core/DataFile.js +0 -59
- package/examples/jsm/node-editor/core/FileEditor.js +0 -20
- package/examples/jsm/node-editor/core/FileURLEditor.js +0 -29
- package/examples/jsm/node-editor/display/BlendEditor.js +0 -44
- package/examples/jsm/node-editor/display/NormalMapEditor.js +0 -49
- package/examples/jsm/node-editor/examples/animate-uv.json +0 -1
- package/examples/jsm/node-editor/examples/fake-top-light.json +0 -1
- package/examples/jsm/node-editor/examples/matcap.json +0 -1
- package/examples/jsm/node-editor/examples/oscillator-color.json +0 -1
- package/examples/jsm/node-editor/examples/rim.json +0 -1
- package/examples/jsm/node-editor/inputs/ColorEditor.js +0 -96
- package/examples/jsm/node-editor/inputs/FloatEditor.js +0 -23
- package/examples/jsm/node-editor/inputs/SliderEditor.js +0 -67
- package/examples/jsm/node-editor/inputs/TextureEditor.js +0 -155
- package/examples/jsm/node-editor/inputs/Vector2Editor.js +0 -28
- package/examples/jsm/node-editor/inputs/Vector3Editor.js +0 -30
- package/examples/jsm/node-editor/inputs/Vector4Editor.js +0 -37
- package/examples/jsm/node-editor/materials/BasicMaterialEditor.js +0 -84
- package/examples/jsm/node-editor/materials/PointsMaterialEditor.js +0 -102
- package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +0 -118
- package/examples/jsm/node-editor/math/AngleEditor.js +0 -40
- package/examples/jsm/node-editor/math/DotEditor.js +0 -35
- package/examples/jsm/node-editor/math/InvertEditor.js +0 -39
- package/examples/jsm/node-editor/math/LimiterEditor.js +0 -62
- package/examples/jsm/node-editor/math/NormalizeEditor.js +0 -28
- package/examples/jsm/node-editor/math/OperatorEditor.js +0 -63
- package/examples/jsm/node-editor/math/PowerEditor.js +0 -44
- package/examples/jsm/node-editor/math/TrigonometryEditor.js +0 -45
- package/examples/jsm/node-editor/procedural/CheckerEditor.js +0 -27
- package/examples/jsm/node-editor/scene/MeshEditor.js +0 -102
- package/examples/jsm/node-editor/scene/Object3DEditor.js +0 -160
- package/examples/jsm/node-editor/scene/PointsEditor.js +0 -99
- package/examples/jsm/node-editor/utils/JoinEditor.js +0 -58
- package/examples/jsm/node-editor/utils/OscillatorEditor.js +0 -43
- package/examples/jsm/node-editor/utils/PreviewEditor.js +0 -170
- package/examples/jsm/node-editor/utils/SplitEditor.js +0 -39
- package/examples/jsm/node-editor/utils/TimerEditor.js +0 -58
- package/examples/jsm/nodes/core/CodeNode.js +0 -50
- package/examples/jsm/nodes/core/ExpressionNode.js +0 -32
- package/examples/jsm/nodes/core/InstanceIndexNode.js +0 -21
- package/examples/jsm/nodes/functions/light/getDistanceAttenuation.js +0 -22
- package/examples/jsm/nodes/lighting/PunctualLightNode.js +0 -68
- package/examples/jsm/nodes/shadernode/ShaderNodeBaseElements.js +0 -301
- package/examples/jsm/nodes/shadernode/ShaderNodeElements.js +0 -149
- package/examples/jsm/objects/GroundProjectedEnv.js +0 -186
- package/examples/jsm/objects/LightningStorm.js +0 -245
- package/examples/jsm/physics/OimoPhysics.js +0 -231
- package/examples/jsm/postprocessing/AdaptiveToneMappingPass.js +0 -369
- package/examples/jsm/renderers/webgpu/WebGPUAttributes.js +0 -187
- package/examples/jsm/renderers/webgpu/WebGPUBackground.js +0 -173
- package/examples/jsm/renderers/webgpu/WebGPUBinding.js +0 -22
- package/examples/jsm/renderers/webgpu/WebGPUBindings.js +0 -255
- package/examples/jsm/renderers/webgpu/WebGPUBuffer.js +0 -43
- package/examples/jsm/renderers/webgpu/WebGPUComputePipelines.js +0 -78
- package/examples/jsm/renderers/webgpu/WebGPUGeometries.js +0 -82
- package/examples/jsm/renderers/webgpu/WebGPUObjects.js +0 -36
- package/examples/jsm/renderers/webgpu/WebGPUProgrammableStage.js +0 -22
- package/examples/jsm/renderers/webgpu/WebGPUProperties.js +0 -38
- package/examples/jsm/renderers/webgpu/WebGPURenderPipelines.js +0 -296
- package/examples/jsm/renderers/webgpu/WebGPURenderStates.js +0 -66
- package/examples/jsm/renderers/webgpu/WebGPUSampledTexture.js +0 -73
- package/examples/jsm/renderers/webgpu/WebGPUSampler.js +0 -29
- package/examples/jsm/renderers/webgpu/WebGPUStorageBuffer.js +0 -20
- package/examples/jsm/renderers/webgpu/WebGPUTextureRenderer.js +0 -40
- package/examples/jsm/renderers/webgpu/WebGPUTextures.js +0 -794
- package/examples/jsm/renderers/webgpu/WebGPUUniformBuffer.js +0 -18
- package/examples/jsm/renderers/webgpu/WebGPUUtils.js +0 -81
- package/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js +0 -83
- package/examples/jsm/shaders/ToneMapShader.js +0 -73
- package/src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl.js +0 -7
- package/src/renderers/shaders/ShaderChunk/uv2_pars_vertex.glsl.js +0 -10
- package/src/renderers/shaders/ShaderChunk/uv2_vertex.glsl.js +0 -7
- /package/examples/{js → jsm}/libs/ammo.wasm.js +0 -0
- /package/examples/{js → jsm}/libs/ammo.wasm.wasm +0 -0
- /package/examples/{js → jsm}/libs/basis/basis_transcoder.js +0 -0
- /package/examples/{js → jsm}/libs/basis/basis_transcoder.wasm +0 -0
- /package/examples/{js → jsm}/libs/draco/README.md +0 -0
- /package/examples/{js → jsm}/libs/draco/draco_encoder.js +0 -0
- /package/examples/{js → jsm}/libs/draco/gltf/draco_encoder.js +0 -0
- /package/src/renderers/shaders/ShaderChunk/{encodings_fragment.glsl.js → colorspace_fragment.glsl.js} +0 -0
- /package/src/renderers/shaders/ShaderChunk/{encodings_pars_fragment.glsl.js → colorspace_pars_fragment.glsl.js} +0 -0
|
@@ -199,6 +199,7 @@ class ArcballControls extends EventDispatcher {
|
|
|
199
199
|
this.cursorZoom = false; //if wheel zoom should be cursor centered
|
|
200
200
|
this.minFov = 5;
|
|
201
201
|
this.maxFov = 90;
|
|
202
|
+
this.rotateSpeed = 1;
|
|
202
203
|
|
|
203
204
|
this.enabled = true;
|
|
204
205
|
this.enablePan = true;
|
|
@@ -230,2986 +231,2993 @@ class ArcballControls extends EventDispatcher {
|
|
|
230
231
|
|
|
231
232
|
this.initializeMouseActions();
|
|
232
233
|
|
|
233
|
-
this.
|
|
234
|
-
this.
|
|
235
|
-
this.
|
|
236
|
-
this.
|
|
234
|
+
this._onContextMenu = onContextMenu.bind( this );
|
|
235
|
+
this._onWheel = onWheel.bind( this );
|
|
236
|
+
this._onPointerUp = onPointerUp.bind( this );
|
|
237
|
+
this._onPointerMove = onPointerMove.bind( this );
|
|
238
|
+
this._onPointerDown = onPointerDown.bind( this );
|
|
239
|
+
this._onPointerCancel = onPointerCancel.bind( this );
|
|
240
|
+
this._onWindowResize = onWindowResize.bind( this );
|
|
237
241
|
|
|
238
|
-
|
|
242
|
+
this.domElement.addEventListener( 'contextmenu', this._onContextMenu );
|
|
243
|
+
this.domElement.addEventListener( 'wheel', this._onWheel );
|
|
244
|
+
this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
|
|
245
|
+
this.domElement.addEventListener( 'pointercancel', this._onPointerCancel );
|
|
239
246
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
//listeners
|
|
243
|
-
|
|
244
|
-
onWindowResize = () => {
|
|
245
|
-
|
|
246
|
-
const scale = ( this._gizmos.scale.x + this._gizmos.scale.y + this._gizmos.scale.z ) / 3;
|
|
247
|
-
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
248
|
-
|
|
249
|
-
const newRadius = this._tbRadius / scale;
|
|
250
|
-
const curve = new EllipseCurve( 0, 0, newRadius, newRadius );
|
|
251
|
-
const points = curve.getPoints( this._curvePts );
|
|
252
|
-
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
247
|
+
window.addEventListener( 'resize', this._onWindowResize );
|
|
253
248
|
|
|
249
|
+
}
|
|
254
250
|
|
|
255
|
-
|
|
251
|
+
onSinglePanStart( event, operation ) {
|
|
256
252
|
|
|
257
|
-
|
|
253
|
+
if ( this.enabled ) {
|
|
258
254
|
|
|
259
|
-
|
|
255
|
+
this.dispatchEvent( _startEvent );
|
|
260
256
|
|
|
261
|
-
|
|
257
|
+
this.setCenter( event.clientX, event.clientY );
|
|
262
258
|
|
|
263
|
-
|
|
259
|
+
switch ( operation ) {
|
|
264
260
|
|
|
265
|
-
|
|
261
|
+
case 'PAN':
|
|
266
262
|
|
|
267
|
-
|
|
263
|
+
if ( ! this.enablePan ) {
|
|
268
264
|
|
|
269
|
-
|
|
265
|
+
return;
|
|
270
266
|
|
|
271
|
-
|
|
267
|
+
}
|
|
272
268
|
|
|
273
|
-
|
|
269
|
+
if ( this._animationId != - 1 ) {
|
|
274
270
|
|
|
275
|
-
|
|
271
|
+
cancelAnimationFrame( this._animationId );
|
|
272
|
+
this._animationId = - 1;
|
|
273
|
+
this._timeStart = - 1;
|
|
276
274
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
break;
|
|
275
|
+
this.activateGizmos( false );
|
|
276
|
+
this.dispatchEvent( _changeEvent );
|
|
280
277
|
|
|
281
|
-
|
|
278
|
+
}
|
|
282
279
|
|
|
283
|
-
|
|
280
|
+
this.updateTbState( STATE.PAN, true );
|
|
281
|
+
this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ) );
|
|
282
|
+
if ( this.enableGrid ) {
|
|
284
283
|
|
|
285
|
-
|
|
284
|
+
this.drawGrid();
|
|
285
|
+
this.dispatchEvent( _changeEvent );
|
|
286
286
|
|
|
287
|
-
|
|
287
|
+
}
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
this._touchCurrent.splice( 0, this._touchCurrent.length );
|
|
291
|
-
this._input = INPUT.NONE;
|
|
289
|
+
break;
|
|
292
290
|
|
|
293
|
-
|
|
291
|
+
case 'ROTATE':
|
|
294
292
|
|
|
295
|
-
|
|
293
|
+
if ( ! this.enableRotate ) {
|
|
296
294
|
|
|
297
|
-
|
|
295
|
+
return;
|
|
298
296
|
|
|
299
|
-
|
|
300
|
-
this._downEvents.push( event );
|
|
301
|
-
this._downStart = performance.now();
|
|
297
|
+
}
|
|
302
298
|
|
|
303
|
-
|
|
299
|
+
if ( this._animationId != - 1 ) {
|
|
304
300
|
|
|
305
|
-
|
|
301
|
+
cancelAnimationFrame( this._animationId );
|
|
302
|
+
this._animationId = - 1;
|
|
303
|
+
this._timeStart = - 1;
|
|
306
304
|
|
|
307
|
-
|
|
305
|
+
}
|
|
308
306
|
|
|
309
|
-
|
|
307
|
+
this.updateTbState( STATE.ROTATE, true );
|
|
308
|
+
this._startCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) );
|
|
309
|
+
this.activateGizmos( true );
|
|
310
|
+
if ( this.enableAnimations ) {
|
|
310
311
|
|
|
311
|
-
|
|
312
|
-
|
|
312
|
+
this._timePrev = this._timeCurrent = performance.now();
|
|
313
|
+
this._angleCurrent = this._anglePrev = 0;
|
|
314
|
+
this._cursorPosPrev.copy( this._startCursorPosition );
|
|
315
|
+
this._cursorPosCurr.copy( this._cursorPosPrev );
|
|
316
|
+
this._wCurr = 0;
|
|
317
|
+
this._wPrev = this._wCurr;
|
|
313
318
|
|
|
314
|
-
|
|
319
|
+
}
|
|
315
320
|
|
|
316
|
-
|
|
321
|
+
this.dispatchEvent( _changeEvent );
|
|
322
|
+
break;
|
|
317
323
|
|
|
318
|
-
|
|
319
|
-
this._input = INPUT.ONE_FINGER;
|
|
320
|
-
this.onSinglePanStart( event, 'ROTATE' );
|
|
324
|
+
case 'FOV':
|
|
321
325
|
|
|
322
|
-
|
|
323
|
-
window.addEventListener( 'pointerup', this.onPointerUp );
|
|
326
|
+
if ( ! this.camera.isPerspectiveCamera || ! this.enableZoom ) {
|
|
324
327
|
|
|
325
|
-
|
|
328
|
+
return;
|
|
326
329
|
|
|
327
|
-
|
|
328
|
-
case INPUT.ONE_FINGER_SWITCHED:
|
|
330
|
+
}
|
|
329
331
|
|
|
330
|
-
|
|
331
|
-
this._input = INPUT.TWO_FINGER;
|
|
332
|
+
if ( this._animationId != - 1 ) {
|
|
332
333
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
334
|
+
cancelAnimationFrame( this._animationId );
|
|
335
|
+
this._animationId = - 1;
|
|
336
|
+
this._timeStart = - 1;
|
|
336
337
|
|
|
337
|
-
|
|
338
|
+
this.activateGizmos( false );
|
|
339
|
+
this.dispatchEvent( _changeEvent );
|
|
338
340
|
|
|
339
|
-
|
|
341
|
+
}
|
|
340
342
|
|
|
341
|
-
|
|
342
|
-
this.
|
|
343
|
-
this.
|
|
343
|
+
this.updateTbState( STATE.FOV, true );
|
|
344
|
+
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
345
|
+
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
344
346
|
break;
|
|
345
347
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
} else if ( event.pointerType != 'touch' && this._input == INPUT.NONE ) {
|
|
349
|
-
|
|
350
|
-
let modifier = null;
|
|
348
|
+
case 'ZOOM':
|
|
351
349
|
|
|
352
|
-
|
|
350
|
+
if ( ! this.enableZoom ) {
|
|
353
351
|
|
|
354
|
-
|
|
352
|
+
return;
|
|
355
353
|
|
|
356
|
-
|
|
354
|
+
}
|
|
357
355
|
|
|
358
|
-
|
|
356
|
+
if ( this._animationId != - 1 ) {
|
|
359
357
|
|
|
360
|
-
|
|
358
|
+
cancelAnimationFrame( this._animationId );
|
|
359
|
+
this._animationId = - 1;
|
|
360
|
+
this._timeStart = - 1;
|
|
361
361
|
|
|
362
|
-
|
|
363
|
-
|
|
362
|
+
this.activateGizmos( false );
|
|
363
|
+
this.dispatchEvent( _changeEvent );
|
|
364
364
|
|
|
365
|
-
|
|
366
|
-
window.addEventListener( 'pointerup', this.onPointerUp );
|
|
365
|
+
}
|
|
367
366
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
367
|
+
this.updateTbState( STATE.SCALE, true );
|
|
368
|
+
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
369
|
+
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
370
|
+
break;
|
|
372
371
|
|
|
373
372
|
}
|
|
374
373
|
|
|
375
374
|
}
|
|
376
375
|
|
|
377
|
-
}
|
|
376
|
+
}
|
|
378
377
|
|
|
379
|
-
|
|
378
|
+
onSinglePanMove( event, opState ) {
|
|
380
379
|
|
|
381
|
-
if (
|
|
380
|
+
if ( this.enabled ) {
|
|
382
381
|
|
|
383
|
-
|
|
382
|
+
const restart = opState != this._state;
|
|
383
|
+
this.setCenter( event.clientX, event.clientY );
|
|
384
384
|
|
|
385
|
-
|
|
385
|
+
switch ( opState ) {
|
|
386
386
|
|
|
387
|
-
|
|
388
|
-
this.updateTouchEvent( event );
|
|
387
|
+
case STATE.PAN:
|
|
389
388
|
|
|
390
|
-
|
|
391
|
-
break;
|
|
389
|
+
if ( this.enablePan ) {
|
|
392
390
|
|
|
393
|
-
|
|
391
|
+
if ( restart ) {
|
|
394
392
|
|
|
395
|
-
|
|
393
|
+
//switch to pan operation
|
|
396
394
|
|
|
397
|
-
|
|
395
|
+
this.dispatchEvent( _endEvent );
|
|
396
|
+
this.dispatchEvent( _startEvent );
|
|
398
397
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
398
|
+
this.updateTbState( opState, true );
|
|
399
|
+
this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ) );
|
|
400
|
+
if ( this.enableGrid ) {
|
|
402
401
|
|
|
403
|
-
|
|
404
|
-
break;
|
|
402
|
+
this.drawGrid();
|
|
405
403
|
|
|
406
|
-
|
|
404
|
+
}
|
|
407
405
|
|
|
408
|
-
|
|
406
|
+
this.activateGizmos( false );
|
|
409
407
|
|
|
410
|
-
|
|
408
|
+
} else {
|
|
411
409
|
|
|
412
|
-
|
|
413
|
-
|
|
410
|
+
//continue with pan operation
|
|
411
|
+
this._currentCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ) );
|
|
412
|
+
this.applyTransformMatrix( this.pan( this._startCursorPosition, this._currentCursorPosition ) );
|
|
413
|
+
|
|
414
|
+
}
|
|
414
415
|
|
|
415
|
-
|
|
416
|
-
this.onPinchMove();
|
|
417
|
-
this.onDoublePanMove();
|
|
416
|
+
}
|
|
418
417
|
|
|
419
418
|
break;
|
|
420
419
|
|
|
421
|
-
case
|
|
422
|
-
|
|
423
|
-
//multMove
|
|
424
|
-
this.updateTouchEvent( event );
|
|
420
|
+
case STATE.ROTATE:
|
|
425
421
|
|
|
426
|
-
this.
|
|
427
|
-
break;
|
|
422
|
+
if ( this.enableRotate ) {
|
|
428
423
|
|
|
429
|
-
|
|
424
|
+
if ( restart ) {
|
|
430
425
|
|
|
431
|
-
|
|
426
|
+
//switch to rotate operation
|
|
432
427
|
|
|
433
|
-
|
|
428
|
+
this.dispatchEvent( _endEvent );
|
|
429
|
+
this.dispatchEvent( _startEvent );
|
|
434
430
|
|
|
435
|
-
|
|
431
|
+
this.updateTbState( opState, true );
|
|
432
|
+
this._startCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) );
|
|
436
433
|
|
|
437
|
-
|
|
434
|
+
if ( this.enableGrid ) {
|
|
438
435
|
|
|
439
|
-
|
|
436
|
+
this.disposeGrid();
|
|
440
437
|
|
|
441
|
-
|
|
438
|
+
}
|
|
442
439
|
|
|
443
|
-
|
|
440
|
+
this.activateGizmos( true );
|
|
444
441
|
|
|
445
|
-
|
|
442
|
+
} else {
|
|
446
443
|
|
|
447
|
-
|
|
444
|
+
//continue with rotate operation
|
|
445
|
+
this._currentCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) );
|
|
448
446
|
|
|
449
|
-
|
|
447
|
+
const distance = this._startCursorPosition.distanceTo( this._currentCursorPosition );
|
|
448
|
+
const angle = this._startCursorPosition.angleTo( this._currentCursorPosition );
|
|
449
|
+
const amount = Math.max( distance / this._tbRadius, angle ) * this.rotateSpeed; //effective rotation angle
|
|
450
450
|
|
|
451
|
-
|
|
451
|
+
this.applyTransformMatrix( this.rotate( this.calculateRotationAxis( this._startCursorPosition, this._currentCursorPosition ), amount ) );
|
|
452
452
|
|
|
453
|
-
|
|
453
|
+
if ( this.enableAnimations ) {
|
|
454
454
|
|
|
455
|
-
|
|
456
|
-
|
|
455
|
+
this._timePrev = this._timeCurrent;
|
|
456
|
+
this._timeCurrent = performance.now();
|
|
457
|
+
this._anglePrev = this._angleCurrent;
|
|
458
|
+
this._angleCurrent = amount;
|
|
459
|
+
this._cursorPosPrev.copy( this._cursorPosCurr );
|
|
460
|
+
this._cursorPosCurr.copy( this._currentCursorPosition );
|
|
461
|
+
this._wPrev = this._wCurr;
|
|
462
|
+
this._wCurr = this.calculateAngularSpeed( this._anglePrev, this._angleCurrent, this._timePrev, this._timeCurrent );
|
|
457
463
|
|
|
458
|
-
|
|
459
|
-
if ( movement > this._movementThreshold ) {
|
|
464
|
+
}
|
|
460
465
|
|
|
461
|
-
|
|
466
|
+
}
|
|
462
467
|
|
|
463
|
-
|
|
468
|
+
}
|
|
464
469
|
|
|
465
|
-
|
|
470
|
+
break;
|
|
466
471
|
|
|
467
|
-
|
|
472
|
+
case STATE.SCALE:
|
|
468
473
|
|
|
469
|
-
|
|
474
|
+
if ( this.enableZoom ) {
|
|
470
475
|
|
|
471
|
-
|
|
476
|
+
if ( restart ) {
|
|
472
477
|
|
|
473
|
-
|
|
478
|
+
//switch to zoom operation
|
|
474
479
|
|
|
475
|
-
|
|
480
|
+
this.dispatchEvent( _endEvent );
|
|
481
|
+
this.dispatchEvent( _startEvent );
|
|
476
482
|
|
|
477
|
-
|
|
483
|
+
this.updateTbState( opState, true );
|
|
484
|
+
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
485
|
+
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
478
486
|
|
|
479
|
-
|
|
480
|
-
this._touchStart.splice( i, 1 );
|
|
481
|
-
break;
|
|
487
|
+
if ( this.enableGrid ) {
|
|
482
488
|
|
|
483
|
-
|
|
489
|
+
this.disposeGrid();
|
|
484
490
|
|
|
485
|
-
|
|
491
|
+
}
|
|
486
492
|
|
|
487
|
-
|
|
493
|
+
this.activateGizmos( false );
|
|
488
494
|
|
|
489
|
-
|
|
490
|
-
case INPUT.ONE_FINGER_SWITCHED:
|
|
495
|
+
} else {
|
|
491
496
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
497
|
+
//continue with zoom operation
|
|
498
|
+
const screenNotches = 8; //how many wheel notches corresponds to a full screen pan
|
|
499
|
+
this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
495
500
|
|
|
496
|
-
|
|
497
|
-
this.onSinglePanEnd();
|
|
501
|
+
const movement = this._currentCursorPosition.y - this._startCursorPosition.y;
|
|
498
502
|
|
|
499
|
-
|
|
503
|
+
let size = 1;
|
|
500
504
|
|
|
501
|
-
|
|
505
|
+
if ( movement < 0 ) {
|
|
502
506
|
|
|
503
|
-
|
|
504
|
-
this.onDoublePanEnd( event );
|
|
505
|
-
this.onPinchEnd( event );
|
|
506
|
-
this.onRotateEnd( event );
|
|
507
|
+
size = 1 / ( Math.pow( this.scaleFactor, - movement * screenNotches ) );
|
|
507
508
|
|
|
508
|
-
|
|
509
|
-
this._input = INPUT.ONE_FINGER_SWITCHED;
|
|
509
|
+
} else if ( movement > 0 ) {
|
|
510
510
|
|
|
511
|
-
|
|
511
|
+
size = Math.pow( this.scaleFactor, movement * screenNotches );
|
|
512
512
|
|
|
513
|
-
|
|
513
|
+
}
|
|
514
514
|
|
|
515
|
-
|
|
515
|
+
this._v3_1.setFromMatrixPosition( this._gizmoMatrixState );
|
|
516
516
|
|
|
517
|
-
|
|
518
|
-
window.removeEventListener( 'pointerup', this.onPointerUp );
|
|
517
|
+
this.applyTransformMatrix( this.scale( size, this._v3_1 ) );
|
|
519
518
|
|
|
520
|
-
|
|
521
|
-
this._input = INPUT.NONE;
|
|
522
|
-
this.onTriplePanEnd();
|
|
519
|
+
}
|
|
523
520
|
|
|
524
521
|
}
|
|
525
522
|
|
|
526
523
|
break;
|
|
527
524
|
|
|
528
|
-
|
|
525
|
+
case STATE.FOV:
|
|
529
526
|
|
|
530
|
-
|
|
527
|
+
if ( this.enableZoom && this.camera.isPerspectiveCamera ) {
|
|
531
528
|
|
|
532
|
-
|
|
533
|
-
window.removeEventListener( 'pointerup', this.onPointerUp );
|
|
529
|
+
if ( restart ) {
|
|
534
530
|
|
|
535
|
-
|
|
536
|
-
this.onSinglePanEnd();
|
|
537
|
-
this._button = - 1;
|
|
531
|
+
//switch to fov operation
|
|
538
532
|
|
|
539
|
-
|
|
533
|
+
this.dispatchEvent( _endEvent );
|
|
534
|
+
this.dispatchEvent( _startEvent );
|
|
540
535
|
|
|
541
|
-
|
|
536
|
+
this.updateTbState( opState, true );
|
|
537
|
+
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
538
|
+
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
542
539
|
|
|
543
|
-
|
|
540
|
+
if ( this.enableGrid ) {
|
|
544
541
|
|
|
545
|
-
|
|
542
|
+
this.disposeGrid();
|
|
546
543
|
|
|
547
|
-
|
|
544
|
+
}
|
|
548
545
|
|
|
549
|
-
|
|
546
|
+
this.activateGizmos( false );
|
|
550
547
|
|
|
551
|
-
|
|
552
|
-
this._nclicks = 1;
|
|
553
|
-
this._clickStart = performance.now();
|
|
548
|
+
} else {
|
|
554
549
|
|
|
555
|
-
|
|
550
|
+
//continue with fov operation
|
|
551
|
+
const screenNotches = 8; //how many wheel notches corresponds to a full screen pan
|
|
552
|
+
this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
556
553
|
|
|
557
|
-
|
|
558
|
-
const movement = this.calculatePointersDistance( this._downEvents[ 1 ], this._downEvents[ 0 ] ) * this._devPxRatio;
|
|
554
|
+
const movement = this._currentCursorPosition.y - this._startCursorPosition.y;
|
|
559
555
|
|
|
560
|
-
|
|
556
|
+
let size = 1;
|
|
561
557
|
|
|
562
|
-
|
|
563
|
-
//fire double tap and reset values
|
|
564
|
-
this._nclicks = 0;
|
|
565
|
-
this._downEvents.splice( 0, this._downEvents.length );
|
|
566
|
-
this.onDoubleTap( event );
|
|
558
|
+
if ( movement < 0 ) {
|
|
567
559
|
|
|
568
|
-
|
|
560
|
+
size = 1 / ( Math.pow( this.scaleFactor, - movement * screenNotches ) );
|
|
569
561
|
|
|
570
|
-
|
|
571
|
-
this._nclicks = 1;
|
|
572
|
-
this._downEvents.shift();
|
|
573
|
-
this._clickStart = performance.now();
|
|
562
|
+
} else if ( movement > 0 ) {
|
|
574
563
|
|
|
575
|
-
|
|
564
|
+
size = Math.pow( this.scaleFactor, movement * screenNotches );
|
|
576
565
|
|
|
577
|
-
|
|
566
|
+
}
|
|
578
567
|
|
|
579
|
-
|
|
568
|
+
this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
|
|
569
|
+
const x = this._v3_1.distanceTo( this._gizmos.position );
|
|
570
|
+
let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
|
|
580
571
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
this._downEvents.splice( 0, this._downEvents.length );
|
|
572
|
+
//check min and max distance
|
|
573
|
+
xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
|
|
584
574
|
|
|
585
|
-
|
|
575
|
+
const y = x * Math.tan( MathUtils.DEG2RAD * this._fovState * 0.5 );
|
|
586
576
|
|
|
587
|
-
|
|
577
|
+
//calculate new fov
|
|
578
|
+
let newFov = MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 );
|
|
588
579
|
|
|
589
|
-
|
|
590
|
-
|
|
580
|
+
//check min and max fov
|
|
581
|
+
newFov = MathUtils.clamp( newFov, this.minFov, this.maxFov );
|
|
591
582
|
|
|
592
|
-
|
|
583
|
+
const newDistance = y / Math.tan( MathUtils.DEG2RAD * ( newFov / 2 ) );
|
|
584
|
+
size = x / newDistance;
|
|
585
|
+
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
|
|
593
586
|
|
|
594
|
-
|
|
587
|
+
this.setFov( newFov );
|
|
588
|
+
this.applyTransformMatrix( this.scale( size, this._v3_2, false ) );
|
|
589
|
+
|
|
590
|
+
//adjusting distance
|
|
591
|
+
_offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x );
|
|
592
|
+
this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
|
|
593
|
+
|
|
594
|
+
}
|
|
595
595
|
|
|
596
|
-
|
|
596
|
+
}
|
|
597
597
|
|
|
598
|
-
|
|
598
|
+
break;
|
|
599
599
|
|
|
600
|
-
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
this.dispatchEvent( _changeEvent );
|
|
603
|
+
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
}
|
|
601
607
|
|
|
602
|
-
|
|
608
|
+
onSinglePanEnd() {
|
|
603
609
|
|
|
604
|
-
|
|
610
|
+
if ( this._state == STATE.ROTATE ) {
|
|
605
611
|
|
|
606
|
-
modifier = 'CTRL';
|
|
607
612
|
|
|
608
|
-
|
|
613
|
+
if ( ! this.enableRotate ) {
|
|
609
614
|
|
|
610
|
-
|
|
615
|
+
return;
|
|
611
616
|
|
|
612
617
|
}
|
|
613
618
|
|
|
614
|
-
|
|
619
|
+
if ( this.enableAnimations ) {
|
|
615
620
|
|
|
616
|
-
|
|
621
|
+
//perform rotation animation
|
|
622
|
+
const deltaTime = ( performance.now() - this._timeCurrent );
|
|
623
|
+
if ( deltaTime < 120 ) {
|
|
617
624
|
|
|
618
|
-
|
|
619
|
-
this.dispatchEvent( _startEvent );
|
|
625
|
+
const w = Math.abs( ( this._wPrev + this._wCurr ) / 2 );
|
|
620
626
|
|
|
621
|
-
|
|
622
|
-
|
|
627
|
+
const self = this;
|
|
628
|
+
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
623
629
|
|
|
624
|
-
|
|
630
|
+
self.updateTbState( STATE.ANIMATION_ROTATE, true );
|
|
631
|
+
const rotationAxis = self.calculateRotationAxis( self._cursorPosPrev, self._cursorPosCurr );
|
|
625
632
|
|
|
626
|
-
|
|
633
|
+
self.onRotationAnim( t, rotationAxis, Math.min( w, self.wMax ) );
|
|
627
634
|
|
|
628
|
-
|
|
635
|
+
} );
|
|
629
636
|
|
|
630
|
-
} else
|
|
637
|
+
} else {
|
|
631
638
|
|
|
632
|
-
|
|
639
|
+
//cursor has been standing still for over 120 ms since last movement
|
|
640
|
+
this.updateTbState( STATE.IDLE, false );
|
|
641
|
+
this.activateGizmos( false );
|
|
642
|
+
this.dispatchEvent( _changeEvent );
|
|
633
643
|
|
|
634
644
|
}
|
|
635
645
|
|
|
636
|
-
|
|
646
|
+
} else {
|
|
637
647
|
|
|
638
|
-
|
|
648
|
+
this.updateTbState( STATE.IDLE, false );
|
|
649
|
+
this.activateGizmos( false );
|
|
650
|
+
this.dispatchEvent( _changeEvent );
|
|
639
651
|
|
|
640
|
-
|
|
652
|
+
}
|
|
641
653
|
|
|
642
|
-
|
|
654
|
+
} else if ( this._state == STATE.PAN || this._state == STATE.IDLE ) {
|
|
643
655
|
|
|
644
|
-
|
|
656
|
+
this.updateTbState( STATE.IDLE, false );
|
|
645
657
|
|
|
646
|
-
|
|
658
|
+
if ( this.enableGrid ) {
|
|
647
659
|
|
|
648
|
-
|
|
660
|
+
this.disposeGrid();
|
|
649
661
|
|
|
650
|
-
|
|
662
|
+
}
|
|
651
663
|
|
|
652
|
-
|
|
664
|
+
this.activateGizmos( false );
|
|
665
|
+
this.dispatchEvent( _changeEvent );
|
|
653
666
|
|
|
654
|
-
let scalePoint;
|
|
655
667
|
|
|
656
|
-
|
|
668
|
+
}
|
|
657
669
|
|
|
658
|
-
|
|
670
|
+
this.dispatchEvent( _endEvent );
|
|
659
671
|
|
|
660
|
-
|
|
672
|
+
}
|
|
661
673
|
|
|
662
|
-
|
|
674
|
+
onDoubleTap( event ) {
|
|
663
675
|
|
|
664
|
-
|
|
676
|
+
if ( this.enabled && this.enablePan && this.scene != null ) {
|
|
665
677
|
|
|
666
|
-
|
|
678
|
+
this.dispatchEvent( _startEvent );
|
|
667
679
|
|
|
668
|
-
|
|
680
|
+
this.setCenter( event.clientX, event.clientY );
|
|
681
|
+
const hitP = this.unprojectOnObj( this.getCursorNDC( _center.x, _center.y, this.domElement ), this.camera );
|
|
669
682
|
|
|
670
|
-
|
|
683
|
+
if ( hitP != null && this.enableAnimations ) {
|
|
671
684
|
|
|
672
|
-
|
|
685
|
+
const self = this;
|
|
686
|
+
if ( this._animationId != - 1 ) {
|
|
673
687
|
|
|
674
|
-
|
|
688
|
+
window.cancelAnimationFrame( this._animationId );
|
|
675
689
|
|
|
676
|
-
|
|
677
|
-
this.drawGrid();
|
|
690
|
+
}
|
|
678
691
|
|
|
679
|
-
|
|
692
|
+
this._timeStart = - 1;
|
|
693
|
+
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
680
694
|
|
|
681
|
-
|
|
695
|
+
self.updateTbState( STATE.ANIMATION_FOCUS, true );
|
|
696
|
+
self.onFocusAnim( t, hitP, self._cameraMatrixState, self._gizmoMatrixState );
|
|
682
697
|
|
|
683
|
-
|
|
684
|
-
this.dispatchEvent( _endEvent );
|
|
698
|
+
} );
|
|
685
699
|
|
|
686
|
-
|
|
700
|
+
} else if ( hitP != null && ! this.enableAnimations ) {
|
|
687
701
|
|
|
688
|
-
|
|
702
|
+
this.updateTbState( STATE.FOCUS, true );
|
|
703
|
+
this.focus( hitP, this.scaleFactor );
|
|
704
|
+
this.updateTbState( STATE.IDLE, false );
|
|
705
|
+
this.dispatchEvent( _changeEvent );
|
|
689
706
|
|
|
690
|
-
|
|
707
|
+
}
|
|
691
708
|
|
|
692
|
-
|
|
709
|
+
}
|
|
693
710
|
|
|
711
|
+
this.dispatchEvent( _endEvent );
|
|
694
712
|
|
|
695
|
-
|
|
713
|
+
}
|
|
696
714
|
|
|
697
|
-
|
|
698
|
-
// |\
|
|
699
|
-
// | \
|
|
700
|
-
// | \
|
|
701
|
-
// x | \
|
|
702
|
-
// | \
|
|
703
|
-
// | \
|
|
704
|
-
// | _ _ _\
|
|
705
|
-
// y
|
|
715
|
+
onDoublePanStart() {
|
|
706
716
|
|
|
707
|
-
|
|
708
|
-
if ( event.deltaX != 0 ) {
|
|
717
|
+
if ( this.enabled && this.enablePan ) {
|
|
709
718
|
|
|
710
|
-
|
|
719
|
+
this.dispatchEvent( _startEvent );
|
|
711
720
|
|
|
712
|
-
|
|
721
|
+
this.updateTbState( STATE.PAN, true );
|
|
713
722
|
|
|
714
|
-
|
|
723
|
+
this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
|
|
724
|
+
this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement, true ) );
|
|
725
|
+
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
715
726
|
|
|
716
|
-
|
|
727
|
+
this.activateGizmos( false );
|
|
717
728
|
|
|
718
|
-
|
|
729
|
+
}
|
|
719
730
|
|
|
720
|
-
|
|
731
|
+
}
|
|
721
732
|
|
|
722
|
-
|
|
733
|
+
onDoublePanMove() {
|
|
723
734
|
|
|
724
|
-
|
|
735
|
+
if ( this.enabled && this.enablePan ) {
|
|
725
736
|
|
|
726
|
-
|
|
727
|
-
const x = this._v3_1.distanceTo( this._gizmos.position );
|
|
728
|
-
let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
|
|
737
|
+
this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
|
|
729
738
|
|
|
730
|
-
|
|
731
|
-
xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
|
|
739
|
+
if ( this._state != STATE.PAN ) {
|
|
732
740
|
|
|
733
|
-
|
|
741
|
+
this.updateTbState( STATE.PAN, true );
|
|
742
|
+
this._startCursorPosition.copy( this._currentCursorPosition );
|
|
734
743
|
|
|
735
|
-
|
|
736
|
-
let newFov = MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 );
|
|
744
|
+
}
|
|
737
745
|
|
|
738
|
-
|
|
739
|
-
|
|
746
|
+
this._currentCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement, true ) );
|
|
747
|
+
this.applyTransformMatrix( this.pan( this._startCursorPosition, this._currentCursorPosition, true ) );
|
|
748
|
+
this.dispatchEvent( _changeEvent );
|
|
740
749
|
|
|
741
|
-
|
|
750
|
+
}
|
|
742
751
|
|
|
743
|
-
|
|
752
|
+
}
|
|
744
753
|
|
|
745
|
-
|
|
754
|
+
onDoublePanEnd() {
|
|
746
755
|
|
|
747
|
-
|
|
756
|
+
this.updateTbState( STATE.IDLE, false );
|
|
757
|
+
this.dispatchEvent( _endEvent );
|
|
748
758
|
|
|
749
|
-
|
|
750
|
-
size = x / newDistance;
|
|
759
|
+
}
|
|
751
760
|
|
|
752
|
-
|
|
753
|
-
this.applyTransformMatrix( this.scale( size, this._gizmos.position, false ) );
|
|
761
|
+
onRotateStart() {
|
|
754
762
|
|
|
755
|
-
|
|
763
|
+
if ( this.enabled && this.enableRotate ) {
|
|
756
764
|
|
|
757
|
-
|
|
765
|
+
this.dispatchEvent( _startEvent );
|
|
758
766
|
|
|
759
|
-
|
|
760
|
-
this.drawGrid();
|
|
767
|
+
this.updateTbState( STATE.ZROTATE, true );
|
|
761
768
|
|
|
762
|
-
|
|
769
|
+
//this._startFingerRotation = event.rotation;
|
|
763
770
|
|
|
764
|
-
|
|
771
|
+
this._startFingerRotation = this.getAngle( this._touchCurrent[ 1 ], this._touchCurrent[ 0 ] ) + this.getAngle( this._touchStart[ 1 ], this._touchStart[ 0 ] );
|
|
772
|
+
this._currentFingerRotation = this._startFingerRotation;
|
|
765
773
|
|
|
766
|
-
|
|
767
|
-
this.dispatchEvent( _endEvent );
|
|
774
|
+
this.camera.getWorldDirection( this._rotationAxis ); //rotation axis
|
|
768
775
|
|
|
769
|
-
|
|
776
|
+
if ( ! this.enablePan && ! this.enableZoom ) {
|
|
770
777
|
|
|
771
|
-
|
|
778
|
+
this.activateGizmos( true );
|
|
772
779
|
|
|
773
780
|
}
|
|
774
781
|
|
|
775
782
|
}
|
|
776
783
|
|
|
777
|
-
}
|
|
784
|
+
}
|
|
778
785
|
|
|
779
|
-
|
|
786
|
+
onRotateMove() {
|
|
780
787
|
|
|
781
|
-
if ( this.enabled ) {
|
|
788
|
+
if ( this.enabled && this.enableRotate ) {
|
|
782
789
|
|
|
783
|
-
this.
|
|
790
|
+
this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
|
|
791
|
+
let rotationPoint;
|
|
784
792
|
|
|
785
|
-
|
|
793
|
+
if ( this._state != STATE.ZROTATE ) {
|
|
786
794
|
|
|
787
|
-
|
|
795
|
+
this.updateTbState( STATE.ZROTATE, true );
|
|
796
|
+
this._startFingerRotation = this._currentFingerRotation;
|
|
788
797
|
|
|
789
|
-
|
|
798
|
+
}
|
|
790
799
|
|
|
791
|
-
|
|
800
|
+
//this._currentFingerRotation = event.rotation;
|
|
801
|
+
this._currentFingerRotation = this.getAngle( this._touchCurrent[ 1 ], this._touchCurrent[ 0 ] ) + this.getAngle( this._touchStart[ 1 ], this._touchStart[ 0 ] );
|
|
792
802
|
|
|
793
|
-
|
|
803
|
+
if ( ! this.enablePan ) {
|
|
794
804
|
|
|
795
|
-
|
|
805
|
+
rotationPoint = new Vector3().setFromMatrixPosition( this._gizmoMatrixState );
|
|
796
806
|
|
|
797
|
-
|
|
807
|
+
} else {
|
|
798
808
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
this._timeStart = - 1;
|
|
809
|
+
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
|
|
810
|
+
rotationPoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement ).applyQuaternion( this.camera.quaternion ).multiplyScalar( 1 / this.camera.zoom ).add( this._v3_2 );
|
|
802
811
|
|
|
803
|
-
|
|
804
|
-
this.dispatchEvent( _changeEvent );
|
|
812
|
+
}
|
|
805
813
|
|
|
806
|
-
|
|
814
|
+
const amount = MathUtils.DEG2RAD * ( this._startFingerRotation - this._currentFingerRotation );
|
|
807
815
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
if ( this.enableGrid ) {
|
|
816
|
+
this.applyTransformMatrix( this.zRotate( rotationPoint, amount ) );
|
|
817
|
+
this.dispatchEvent( _changeEvent );
|
|
811
818
|
|
|
812
|
-
|
|
813
|
-
this.dispatchEvent( _changeEvent );
|
|
819
|
+
}
|
|
814
820
|
|
|
815
|
-
|
|
821
|
+
}
|
|
816
822
|
|
|
817
|
-
|
|
823
|
+
onRotateEnd() {
|
|
818
824
|
|
|
819
|
-
|
|
825
|
+
this.updateTbState( STATE.IDLE, false );
|
|
826
|
+
this.activateGizmos( false );
|
|
827
|
+
this.dispatchEvent( _endEvent );
|
|
820
828
|
|
|
821
|
-
|
|
829
|
+
}
|
|
822
830
|
|
|
823
|
-
|
|
831
|
+
onPinchStart() {
|
|
824
832
|
|
|
825
|
-
|
|
833
|
+
if ( this.enabled && this.enableZoom ) {
|
|
826
834
|
|
|
827
|
-
|
|
835
|
+
this.dispatchEvent( _startEvent );
|
|
836
|
+
this.updateTbState( STATE.SCALE, true );
|
|
828
837
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
this._timeStart = - 1;
|
|
838
|
+
this._startFingerDistance = this.calculatePointersDistance( this._touchCurrent[ 0 ], this._touchCurrent[ 1 ] );
|
|
839
|
+
this._currentFingerDistance = this._startFingerDistance;
|
|
832
840
|
|
|
833
|
-
|
|
841
|
+
this.activateGizmos( false );
|
|
834
842
|
|
|
835
|
-
|
|
836
|
-
this._startCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) );
|
|
837
|
-
this.activateGizmos( true );
|
|
838
|
-
if ( this.enableAnimations ) {
|
|
843
|
+
}
|
|
839
844
|
|
|
840
|
-
|
|
841
|
-
this._angleCurrent = this._anglePrev = 0;
|
|
842
|
-
this._cursorPosPrev.copy( this._startCursorPosition );
|
|
843
|
-
this._cursorPosCurr.copy( this._cursorPosPrev );
|
|
844
|
-
this._wCurr = 0;
|
|
845
|
-
this._wPrev = this._wCurr;
|
|
845
|
+
}
|
|
846
846
|
|
|
847
|
-
|
|
847
|
+
onPinchMove() {
|
|
848
848
|
|
|
849
|
-
|
|
850
|
-
break;
|
|
849
|
+
if ( this.enabled && this.enableZoom ) {
|
|
851
850
|
|
|
852
|
-
|
|
851
|
+
this.setCenter( ( this._touchCurrent[ 0 ].clientX + this._touchCurrent[ 1 ].clientX ) / 2, ( this._touchCurrent[ 0 ].clientY + this._touchCurrent[ 1 ].clientY ) / 2 );
|
|
852
|
+
const minDistance = 12; //minimum distance between fingers (in css pixels)
|
|
853
853
|
|
|
854
|
-
|
|
854
|
+
if ( this._state != STATE.SCALE ) {
|
|
855
855
|
|
|
856
|
-
|
|
856
|
+
this._startFingerDistance = this._currentFingerDistance;
|
|
857
|
+
this.updateTbState( STATE.SCALE, true );
|
|
857
858
|
|
|
858
|
-
|
|
859
|
+
}
|
|
859
860
|
|
|
860
|
-
|
|
861
|
+
this._currentFingerDistance = Math.max( this.calculatePointersDistance( this._touchCurrent[ 0 ], this._touchCurrent[ 1 ] ), minDistance * this._devPxRatio );
|
|
862
|
+
const amount = this._currentFingerDistance / this._startFingerDistance;
|
|
861
863
|
|
|
862
|
-
|
|
863
|
-
this._animationId = - 1;
|
|
864
|
-
this._timeStart = - 1;
|
|
864
|
+
let scalePoint;
|
|
865
865
|
|
|
866
|
-
|
|
867
|
-
this.dispatchEvent( _changeEvent );
|
|
866
|
+
if ( ! this.enablePan ) {
|
|
868
867
|
|
|
869
|
-
|
|
868
|
+
scalePoint = this._gizmos.position;
|
|
870
869
|
|
|
871
|
-
|
|
872
|
-
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
873
|
-
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
874
|
-
break;
|
|
870
|
+
} else {
|
|
875
871
|
|
|
876
|
-
|
|
872
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
877
873
|
|
|
878
|
-
|
|
874
|
+
scalePoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement )
|
|
875
|
+
.applyQuaternion( this.camera.quaternion )
|
|
876
|
+
.multiplyScalar( 1 / this.camera.zoom )
|
|
877
|
+
.add( this._gizmos.position );
|
|
879
878
|
|
|
880
|
-
|
|
879
|
+
} else if ( this.camera.isPerspectiveCamera ) {
|
|
881
880
|
|
|
882
|
-
|
|
881
|
+
scalePoint = this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement )
|
|
882
|
+
.applyQuaternion( this.camera.quaternion )
|
|
883
|
+
.add( this._gizmos.position );
|
|
883
884
|
|
|
884
|
-
|
|
885
|
+
}
|
|
885
886
|
|
|
886
|
-
|
|
887
|
-
this._animationId = - 1;
|
|
888
|
-
this._timeStart = - 1;
|
|
887
|
+
}
|
|
889
888
|
|
|
890
|
-
|
|
891
|
-
|
|
889
|
+
this.applyTransformMatrix( this.scale( amount, scalePoint ) );
|
|
890
|
+
this.dispatchEvent( _changeEvent );
|
|
892
891
|
|
|
893
|
-
|
|
892
|
+
}
|
|
894
893
|
|
|
895
|
-
|
|
896
|
-
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
897
|
-
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
898
|
-
break;
|
|
894
|
+
}
|
|
899
895
|
|
|
900
|
-
|
|
896
|
+
onPinchEnd() {
|
|
901
897
|
|
|
902
|
-
|
|
898
|
+
this.updateTbState( STATE.IDLE, false );
|
|
899
|
+
this.dispatchEvent( _endEvent );
|
|
903
900
|
|
|
904
|
-
}
|
|
901
|
+
}
|
|
905
902
|
|
|
906
|
-
|
|
903
|
+
onTriplePanStart() {
|
|
907
904
|
|
|
908
|
-
if ( this.enabled ) {
|
|
905
|
+
if ( this.enabled && this.enableZoom ) {
|
|
909
906
|
|
|
910
|
-
|
|
911
|
-
this.setCenter( event.clientX, event.clientY );
|
|
907
|
+
this.dispatchEvent( _startEvent );
|
|
912
908
|
|
|
913
|
-
|
|
909
|
+
this.updateTbState( STATE.SCALE, true );
|
|
914
910
|
|
|
915
|
-
|
|
911
|
+
//const center = event.center;
|
|
912
|
+
let clientX = 0;
|
|
913
|
+
let clientY = 0;
|
|
914
|
+
const nFingers = this._touchCurrent.length;
|
|
916
915
|
|
|
917
|
-
|
|
916
|
+
for ( let i = 0; i < nFingers; i ++ ) {
|
|
918
917
|
|
|
919
|
-
|
|
918
|
+
clientX += this._touchCurrent[ i ].clientX;
|
|
919
|
+
clientY += this._touchCurrent[ i ].clientY;
|
|
920
920
|
|
|
921
|
-
|
|
921
|
+
}
|
|
922
922
|
|
|
923
|
-
|
|
924
|
-
this.dispatchEvent( _startEvent );
|
|
923
|
+
this.setCenter( clientX / nFingers, clientY / nFingers );
|
|
925
924
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
if ( this.enableGrid ) {
|
|
925
|
+
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
926
|
+
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
929
927
|
|
|
930
|
-
|
|
928
|
+
}
|
|
931
929
|
|
|
932
|
-
|
|
930
|
+
}
|
|
933
931
|
|
|
934
|
-
|
|
932
|
+
onTriplePanMove() {
|
|
935
933
|
|
|
936
|
-
|
|
934
|
+
if ( this.enabled && this.enableZoom ) {
|
|
937
935
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
936
|
+
// fov / 2
|
|
937
|
+
// |\
|
|
938
|
+
// | \
|
|
939
|
+
// | \
|
|
940
|
+
// x | \
|
|
941
|
+
// | \
|
|
942
|
+
// | \
|
|
943
|
+
// | _ _ _\
|
|
944
|
+
// y
|
|
941
945
|
|
|
942
|
-
|
|
946
|
+
//const center = event.center;
|
|
947
|
+
let clientX = 0;
|
|
948
|
+
let clientY = 0;
|
|
949
|
+
const nFingers = this._touchCurrent.length;
|
|
943
950
|
|
|
944
|
-
|
|
951
|
+
for ( let i = 0; i < nFingers; i ++ ) {
|
|
945
952
|
|
|
946
|
-
|
|
953
|
+
clientX += this._touchCurrent[ i ].clientX;
|
|
954
|
+
clientY += this._touchCurrent[ i ].clientY;
|
|
947
955
|
|
|
948
|
-
|
|
956
|
+
}
|
|
949
957
|
|
|
950
|
-
|
|
958
|
+
this.setCenter( clientX / nFingers, clientY / nFingers );
|
|
951
959
|
|
|
952
|
-
|
|
960
|
+
const screenNotches = 8; //how many wheel notches corresponds to a full screen pan
|
|
961
|
+
this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
953
962
|
|
|
954
|
-
|
|
963
|
+
const movement = this._currentCursorPosition.y - this._startCursorPosition.y;
|
|
955
964
|
|
|
956
|
-
|
|
957
|
-
this.dispatchEvent( _startEvent );
|
|
965
|
+
let size = 1;
|
|
958
966
|
|
|
959
|
-
|
|
960
|
-
this._startCursorPosition.copy( this.unprojectOnTbSurface( this.camera, _center.x, _center.y, this.domElement, this._tbRadius ) );
|
|
967
|
+
if ( movement < 0 ) {
|
|
961
968
|
|
|
962
|
-
|
|
969
|
+
size = 1 / ( Math.pow( this.scaleFactor, - movement * screenNotches ) );
|
|
963
970
|
|
|
964
|
-
|
|
971
|
+
} else if ( movement > 0 ) {
|
|
965
972
|
|
|
966
|
-
|
|
973
|
+
size = Math.pow( this.scaleFactor, movement * screenNotches );
|
|
967
974
|
|
|
968
|
-
|
|
975
|
+
}
|
|
969
976
|
|
|
970
|
-
|
|
977
|
+
this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
|
|
978
|
+
const x = this._v3_1.distanceTo( this._gizmos.position );
|
|
979
|
+
let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
|
|
971
980
|
|
|
972
|
-
|
|
973
|
-
|
|
981
|
+
//check min and max distance
|
|
982
|
+
xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
|
|
974
983
|
|
|
975
|
-
|
|
976
|
-
const angle = this._startCursorPosition.angleTo( this._currentCursorPosition );
|
|
977
|
-
const amount = Math.max( distance / this._tbRadius, angle ); //effective rotation angle
|
|
984
|
+
const y = x * Math.tan( MathUtils.DEG2RAD * this._fovState * 0.5 );
|
|
978
985
|
|
|
979
|
-
|
|
986
|
+
//calculate new fov
|
|
987
|
+
let newFov = MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 );
|
|
980
988
|
|
|
981
|
-
|
|
989
|
+
//check min and max fov
|
|
990
|
+
newFov = MathUtils.clamp( newFov, this.minFov, this.maxFov );
|
|
982
991
|
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
this._angleCurrent = amount;
|
|
987
|
-
this._cursorPosPrev.copy( this._cursorPosCurr );
|
|
988
|
-
this._cursorPosCurr.copy( this._currentCursorPosition );
|
|
989
|
-
this._wPrev = this._wCurr;
|
|
990
|
-
this._wCurr = this.calculateAngularSpeed( this._anglePrev, this._angleCurrent, this._timePrev, this._timeCurrent );
|
|
992
|
+
const newDistance = y / Math.tan( MathUtils.DEG2RAD * ( newFov / 2 ) );
|
|
993
|
+
size = x / newDistance;
|
|
994
|
+
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
|
|
991
995
|
|
|
992
|
-
|
|
996
|
+
this.setFov( newFov );
|
|
997
|
+
this.applyTransformMatrix( this.scale( size, this._v3_2, false ) );
|
|
993
998
|
|
|
994
|
-
|
|
999
|
+
//adjusting distance
|
|
1000
|
+
_offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x );
|
|
1001
|
+
this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
|
|
995
1002
|
|
|
996
|
-
|
|
1003
|
+
this.dispatchEvent( _changeEvent );
|
|
997
1004
|
|
|
998
|
-
|
|
1005
|
+
}
|
|
999
1006
|
|
|
1000
|
-
|
|
1007
|
+
}
|
|
1001
1008
|
|
|
1002
|
-
|
|
1009
|
+
onTriplePanEnd() {
|
|
1003
1010
|
|
|
1004
|
-
|
|
1011
|
+
this.updateTbState( STATE.IDLE, false );
|
|
1012
|
+
this.dispatchEvent( _endEvent );
|
|
1013
|
+
//this.dispatchEvent( _changeEvent );
|
|
1005
1014
|
|
|
1006
|
-
|
|
1015
|
+
}
|
|
1007
1016
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1017
|
+
/**
|
|
1018
|
+
* Set _center's x/y coordinates
|
|
1019
|
+
* @param {Number} clientX
|
|
1020
|
+
* @param {Number} clientY
|
|
1021
|
+
*/
|
|
1022
|
+
setCenter( clientX, clientY ) {
|
|
1010
1023
|
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
1024
|
+
_center.x = clientX;
|
|
1025
|
+
_center.y = clientY;
|
|
1014
1026
|
|
|
1015
|
-
|
|
1027
|
+
}
|
|
1016
1028
|
|
|
1017
|
-
|
|
1029
|
+
/**
|
|
1030
|
+
* Set default mouse actions
|
|
1031
|
+
*/
|
|
1032
|
+
initializeMouseActions() {
|
|
1018
1033
|
|
|
1019
|
-
|
|
1034
|
+
this.setMouseAction( 'PAN', 0, 'CTRL' );
|
|
1035
|
+
this.setMouseAction( 'PAN', 2 );
|
|
1020
1036
|
|
|
1021
|
-
|
|
1037
|
+
this.setMouseAction( 'ROTATE', 0 );
|
|
1022
1038
|
|
|
1023
|
-
|
|
1039
|
+
this.setMouseAction( 'ZOOM', 'WHEEL' );
|
|
1040
|
+
this.setMouseAction( 'ZOOM', 1 );
|
|
1024
1041
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
1042
|
+
this.setMouseAction( 'FOV', 'WHEEL', 'SHIFT' );
|
|
1043
|
+
this.setMouseAction( 'FOV', 1, 'SHIFT' );
|
|
1028
1044
|
|
|
1029
|
-
const movement = this._currentCursorPosition.y - this._startCursorPosition.y;
|
|
1030
1045
|
|
|
1031
|
-
|
|
1046
|
+
}
|
|
1032
1047
|
|
|
1033
|
-
|
|
1048
|
+
/**
|
|
1049
|
+
* Compare two mouse actions
|
|
1050
|
+
* @param {Object} action1
|
|
1051
|
+
* @param {Object} action2
|
|
1052
|
+
* @returns {Boolean} True if action1 and action 2 are the same mouse action, false otherwise
|
|
1053
|
+
*/
|
|
1054
|
+
compareMouseAction( action1, action2 ) {
|
|
1034
1055
|
|
|
1035
|
-
|
|
1056
|
+
if ( action1.operation == action2.operation ) {
|
|
1036
1057
|
|
|
1037
|
-
|
|
1058
|
+
if ( action1.mouse == action2.mouse && action1.key == action2.key ) {
|
|
1038
1059
|
|
|
1039
|
-
|
|
1060
|
+
return true;
|
|
1040
1061
|
|
|
1041
|
-
|
|
1062
|
+
} else {
|
|
1042
1063
|
|
|
1043
|
-
|
|
1064
|
+
return false;
|
|
1044
1065
|
|
|
1045
|
-
|
|
1066
|
+
}
|
|
1046
1067
|
|
|
1047
|
-
|
|
1068
|
+
} else {
|
|
1048
1069
|
|
|
1049
|
-
|
|
1070
|
+
return false;
|
|
1050
1071
|
|
|
1051
|
-
|
|
1072
|
+
}
|
|
1052
1073
|
|
|
1053
|
-
|
|
1074
|
+
}
|
|
1054
1075
|
|
|
1055
|
-
|
|
1076
|
+
/**
|
|
1077
|
+
* Set a new mouse action by specifying the operation to be performed and a mouse/key combination. In case of conflict, replaces the existing one
|
|
1078
|
+
* @param {String} operation The operation to be performed ('PAN', 'ROTATE', 'ZOOM', 'FOV)
|
|
1079
|
+
* @param {*} mouse A mouse button (0, 1, 2) or 'WHEEL' for wheel notches
|
|
1080
|
+
* @param {*} key The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed
|
|
1081
|
+
* @returns {Boolean} True if the mouse action has been successfully added, false otherwise
|
|
1082
|
+
*/
|
|
1083
|
+
setMouseAction( operation, mouse, key = null ) {
|
|
1056
1084
|
|
|
1057
|
-
|
|
1085
|
+
const operationInput = [ 'PAN', 'ROTATE', 'ZOOM', 'FOV' ];
|
|
1086
|
+
const mouseInput = [ 0, 1, 2, 'WHEEL' ];
|
|
1087
|
+
const keyInput = [ 'CTRL', 'SHIFT', null ];
|
|
1088
|
+
let state;
|
|
1058
1089
|
|
|
1059
|
-
|
|
1090
|
+
if ( ! operationInput.includes( operation ) || ! mouseInput.includes( mouse ) || ! keyInput.includes( key ) ) {
|
|
1060
1091
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1092
|
+
//invalid parameters
|
|
1093
|
+
return false;
|
|
1063
1094
|
|
|
1064
|
-
|
|
1065
|
-
this._startCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
1066
|
-
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
1095
|
+
}
|
|
1067
1096
|
|
|
1068
|
-
|
|
1097
|
+
if ( mouse == 'WHEEL' ) {
|
|
1069
1098
|
|
|
1070
|
-
|
|
1099
|
+
if ( operation != 'ZOOM' && operation != 'FOV' ) {
|
|
1071
1100
|
|
|
1072
|
-
|
|
1101
|
+
//cannot associate 2D operation to 1D input
|
|
1102
|
+
return false;
|
|
1073
1103
|
|
|
1074
|
-
|
|
1104
|
+
}
|
|
1075
1105
|
|
|
1076
|
-
|
|
1106
|
+
}
|
|
1077
1107
|
|
|
1078
|
-
|
|
1079
|
-
const screenNotches = 8; //how many wheel notches corresponds to a full screen pan
|
|
1080
|
-
this._currentCursorPosition.setY( this.getCursorNDC( _center.x, _center.y, this.domElement ).y * 0.5 );
|
|
1108
|
+
switch ( operation ) {
|
|
1081
1109
|
|
|
1082
|
-
|
|
1110
|
+
case 'PAN':
|
|
1083
1111
|
|
|
1084
|
-
|
|
1112
|
+
state = STATE.PAN;
|
|
1113
|
+
break;
|
|
1085
1114
|
|
|
1086
|
-
|
|
1115
|
+
case 'ROTATE':
|
|
1087
1116
|
|
|
1088
|
-
|
|
1117
|
+
state = STATE.ROTATE;
|
|
1118
|
+
break;
|
|
1089
1119
|
|
|
1090
|
-
|
|
1120
|
+
case 'ZOOM':
|
|
1091
1121
|
|
|
1092
|
-
|
|
1122
|
+
state = STATE.SCALE;
|
|
1123
|
+
break;
|
|
1093
1124
|
|
|
1094
|
-
|
|
1125
|
+
case 'FOV':
|
|
1095
1126
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
|
|
1127
|
+
state = STATE.FOV;
|
|
1128
|
+
break;
|
|
1099
1129
|
|
|
1100
|
-
|
|
1101
|
-
xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
|
|
1130
|
+
}
|
|
1102
1131
|
|
|
1103
|
-
|
|
1132
|
+
const action = {
|
|
1104
1133
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1134
|
+
operation: operation,
|
|
1135
|
+
mouse: mouse,
|
|
1136
|
+
key: key,
|
|
1137
|
+
state: state
|
|
1107
1138
|
|
|
1108
|
-
|
|
1109
|
-
newFov = MathUtils.clamp( newFov, this.minFov, this.maxFov );
|
|
1139
|
+
};
|
|
1110
1140
|
|
|
1111
|
-
|
|
1112
|
-
size = x / newDistance;
|
|
1113
|
-
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
|
|
1141
|
+
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
1114
1142
|
|
|
1115
|
-
|
|
1116
|
-
this.applyTransformMatrix( this.scale( size, this._v3_2, false ) );
|
|
1143
|
+
if ( this.mouseActions[ i ].mouse == action.mouse && this.mouseActions[ i ].key == action.key ) {
|
|
1117
1144
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
|
|
1145
|
+
this.mouseActions.splice( i, 1, action );
|
|
1146
|
+
return true;
|
|
1121
1147
|
|
|
1122
|
-
|
|
1148
|
+
}
|
|
1123
1149
|
|
|
1124
|
-
|
|
1150
|
+
}
|
|
1125
1151
|
|
|
1126
|
-
|
|
1152
|
+
this.mouseActions.push( action );
|
|
1153
|
+
return true;
|
|
1127
1154
|
|
|
1128
|
-
|
|
1155
|
+
}
|
|
1129
1156
|
|
|
1130
|
-
|
|
1157
|
+
/**
|
|
1158
|
+
* Remove a mouse action by specifying its mouse/key combination
|
|
1159
|
+
* @param {*} mouse A mouse button (0, 1, 2) or 'WHEEL' for wheel notches
|
|
1160
|
+
* @param {*} key The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed
|
|
1161
|
+
* @returns {Boolean} True if the operation has been succesfully removed, false otherwise
|
|
1162
|
+
*/
|
|
1163
|
+
unsetMouseAction( mouse, key = null ) {
|
|
1131
1164
|
|
|
1132
|
-
|
|
1165
|
+
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
1133
1166
|
|
|
1134
|
-
|
|
1167
|
+
if ( this.mouseActions[ i ].mouse == mouse && this.mouseActions[ i ].key == key ) {
|
|
1135
1168
|
|
|
1136
|
-
|
|
1169
|
+
this.mouseActions.splice( i, 1 );
|
|
1170
|
+
return true;
|
|
1137
1171
|
|
|
1138
|
-
|
|
1172
|
+
}
|
|
1139
1173
|
|
|
1174
|
+
}
|
|
1140
1175
|
|
|
1141
|
-
|
|
1176
|
+
return false;
|
|
1142
1177
|
|
|
1143
|
-
|
|
1178
|
+
}
|
|
1144
1179
|
|
|
1145
|
-
|
|
1180
|
+
/**
|
|
1181
|
+
* Return the operation associated to a mouse/keyboard combination
|
|
1182
|
+
* @param {*} mouse A mouse button (0, 1, 2) or 'WHEEL' for wheel notches
|
|
1183
|
+
* @param {*} key The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed
|
|
1184
|
+
* @returns The operation if it has been found, null otherwise
|
|
1185
|
+
*/
|
|
1186
|
+
getOpFromAction( mouse, key ) {
|
|
1146
1187
|
|
|
1147
|
-
|
|
1188
|
+
let action;
|
|
1148
1189
|
|
|
1149
|
-
|
|
1150
|
-
const deltaTime = ( performance.now() - this._timeCurrent );
|
|
1151
|
-
if ( deltaTime < 120 ) {
|
|
1190
|
+
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
1152
1191
|
|
|
1153
|
-
|
|
1192
|
+
action = this.mouseActions[ i ];
|
|
1193
|
+
if ( action.mouse == mouse && action.key == key ) {
|
|
1154
1194
|
|
|
1155
|
-
|
|
1156
|
-
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
1195
|
+
return action.operation;
|
|
1157
1196
|
|
|
1158
|
-
|
|
1159
|
-
const rotationAxis = self.calculateRotationAxis( self._cursorPosPrev, self._cursorPosCurr );
|
|
1197
|
+
}
|
|
1160
1198
|
|
|
1161
|
-
|
|
1199
|
+
}
|
|
1162
1200
|
|
|
1163
|
-
|
|
1201
|
+
if ( key != null ) {
|
|
1164
1202
|
|
|
1165
|
-
|
|
1203
|
+
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
1166
1204
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1205
|
+
action = this.mouseActions[ i ];
|
|
1206
|
+
if ( action.mouse == mouse && action.key == null ) {
|
|
1207
|
+
|
|
1208
|
+
return action.operation;
|
|
1171
1209
|
|
|
1172
1210
|
}
|
|
1173
1211
|
|
|
1174
|
-
}
|
|
1212
|
+
}
|
|
1175
1213
|
|
|
1176
|
-
|
|
1177
|
-
this.activateGizmos( false );
|
|
1178
|
-
this.dispatchEvent( _changeEvent );
|
|
1214
|
+
}
|
|
1179
1215
|
|
|
1180
|
-
|
|
1216
|
+
return null;
|
|
1181
1217
|
|
|
1182
|
-
|
|
1218
|
+
}
|
|
1183
1219
|
|
|
1184
|
-
|
|
1220
|
+
/**
|
|
1221
|
+
* Get the operation associated to mouse and key combination and returns the corresponding FSA state
|
|
1222
|
+
* @param {Number} mouse Mouse button
|
|
1223
|
+
* @param {String} key Keyboard modifier
|
|
1224
|
+
* @returns The FSA state obtained from the operation associated to mouse/keyboard combination
|
|
1225
|
+
*/
|
|
1226
|
+
getOpStateFromAction( mouse, key ) {
|
|
1185
1227
|
|
|
1186
|
-
|
|
1228
|
+
let action;
|
|
1187
1229
|
|
|
1188
|
-
|
|
1230
|
+
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
1189
1231
|
|
|
1190
|
-
|
|
1232
|
+
action = this.mouseActions[ i ];
|
|
1233
|
+
if ( action.mouse == mouse && action.key == key ) {
|
|
1191
1234
|
|
|
1192
|
-
|
|
1193
|
-
this.dispatchEvent( _changeEvent );
|
|
1235
|
+
return action.state;
|
|
1194
1236
|
|
|
1237
|
+
}
|
|
1195
1238
|
|
|
1196
1239
|
}
|
|
1197
1240
|
|
|
1198
|
-
|
|
1241
|
+
if ( key != null ) {
|
|
1199
1242
|
|
|
1200
|
-
|
|
1243
|
+
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
1201
1244
|
|
|
1202
|
-
|
|
1245
|
+
action = this.mouseActions[ i ];
|
|
1246
|
+
if ( action.mouse == mouse && action.key == null ) {
|
|
1203
1247
|
|
|
1204
|
-
|
|
1248
|
+
return action.state;
|
|
1205
1249
|
|
|
1206
|
-
|
|
1250
|
+
}
|
|
1207
1251
|
|
|
1208
|
-
|
|
1209
|
-
const hitP = this.unprojectOnObj( this.getCursorNDC( _center.x, _center.y, this.domElement ), this.camera );
|
|
1252
|
+
}
|
|
1210
1253
|
|
|
1211
|
-
|
|
1254
|
+
}
|
|
1212
1255
|
|
|
1213
|
-
|
|
1214
|
-
if ( this._animationId != - 1 ) {
|
|
1256
|
+
return null;
|
|
1215
1257
|
|
|
1216
|
-
|
|
1258
|
+
}
|
|
1217
1259
|
|
|
1218
|
-
|
|
1260
|
+
/**
|
|
1261
|
+
* Calculate the angle between two pointers
|
|
1262
|
+
* @param {PointerEvent} p1
|
|
1263
|
+
* @param {PointerEvent} p2
|
|
1264
|
+
* @returns {Number} The angle between two pointers in degrees
|
|
1265
|
+
*/
|
|
1266
|
+
getAngle( p1, p2 ) {
|
|
1219
1267
|
|
|
1220
|
-
|
|
1221
|
-
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
1268
|
+
return Math.atan2( p2.clientY - p1.clientY, p2.clientX - p1.clientX ) * 180 / Math.PI;
|
|
1222
1269
|
|
|
1223
|
-
|
|
1224
|
-
self.onFocusAnim( t, hitP, self._cameraMatrixState, self._gizmoMatrixState );
|
|
1270
|
+
}
|
|
1225
1271
|
|
|
1226
|
-
|
|
1272
|
+
/**
|
|
1273
|
+
* Update a PointerEvent inside current pointerevents array
|
|
1274
|
+
* @param {PointerEvent} event
|
|
1275
|
+
*/
|
|
1276
|
+
updateTouchEvent( event ) {
|
|
1227
1277
|
|
|
1228
|
-
|
|
1278
|
+
for ( let i = 0; i < this._touchCurrent.length; i ++ ) {
|
|
1229
1279
|
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
this.
|
|
1233
|
-
|
|
1280
|
+
if ( this._touchCurrent[ i ].pointerId == event.pointerId ) {
|
|
1281
|
+
|
|
1282
|
+
this._touchCurrent.splice( i, 1, event );
|
|
1283
|
+
break;
|
|
1234
1284
|
|
|
1235
1285
|
}
|
|
1236
1286
|
|
|
1237
1287
|
}
|
|
1238
1288
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
};
|
|
1289
|
+
}
|
|
1242
1290
|
|
|
1243
|
-
|
|
1291
|
+
/**
|
|
1292
|
+
* Apply a transformation matrix, to the camera and gizmos
|
|
1293
|
+
* @param {Object} transformation Object containing matrices to apply to camera and gizmos
|
|
1294
|
+
*/
|
|
1295
|
+
applyTransformMatrix( transformation ) {
|
|
1244
1296
|
|
|
1245
|
-
if (
|
|
1297
|
+
if ( transformation.camera != null ) {
|
|
1246
1298
|
|
|
1247
|
-
this.
|
|
1299
|
+
this._m4_1.copy( this._cameraMatrixState ).premultiply( transformation.camera );
|
|
1300
|
+
this._m4_1.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
1301
|
+
this.camera.updateMatrix();
|
|
1248
1302
|
|
|
1249
|
-
|
|
1303
|
+
//update camera up vector
|
|
1304
|
+
if ( this._state == STATE.ROTATE || this._state == STATE.ZROTATE || this._state == STATE.ANIMATION_ROTATE ) {
|
|
1250
1305
|
|
|
1251
|
-
|
|
1252
|
-
this._startCursorPosition.copy( this.unprojectOnTbPlane( this.camera, _center.x, _center.y, this.domElement, true ) );
|
|
1253
|
-
this._currentCursorPosition.copy( this._startCursorPosition );
|
|
1306
|
+
this.camera.up.copy( this._upState ).applyQuaternion( this.camera.quaternion );
|
|
1254
1307
|
|
|
1255
|
-
|
|
1308
|
+
}
|
|
1256
1309
|
|
|
1257
1310
|
}
|
|
1258
1311
|
|
|
1259
|
-
|
|
1312
|
+
if ( transformation.gizmos != null ) {
|
|
1260
1313
|
|
|
1261
|
-
|
|
1314
|
+
this._m4_1.copy( this._gizmoMatrixState ).premultiply( transformation.gizmos );
|
|
1315
|
+
this._m4_1.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
1316
|
+
this._gizmos.updateMatrix();
|
|
1262
1317
|
|
|
1263
|
-
|
|
1318
|
+
}
|
|
1264
1319
|
|
|
1265
|
-
|
|
1320
|
+
if ( this._state == STATE.SCALE || this._state == STATE.FOCUS || this._state == STATE.ANIMATION_FOCUS ) {
|
|
1266
1321
|
|
|
1267
|
-
|
|
1322
|
+
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
1268
1323
|
|
|
1269
|
-
|
|
1270
|
-
this._startCursorPosition.copy( this._currentCursorPosition );
|
|
1324
|
+
if ( this.adjustNearFar ) {
|
|
1271
1325
|
|
|
1272
|
-
|
|
1326
|
+
const cameraDistance = this.camera.position.distanceTo( this._gizmos.position );
|
|
1273
1327
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1328
|
+
const bb = new Box3();
|
|
1329
|
+
bb.setFromObject( this._gizmos );
|
|
1330
|
+
const sphere = new Sphere();
|
|
1331
|
+
bb.getBoundingSphere( sphere );
|
|
1277
1332
|
|
|
1278
|
-
|
|
1333
|
+
const adjustedNearPosition = Math.max( this._nearPos0, sphere.radius + sphere.center.length() );
|
|
1334
|
+
const regularNearPosition = cameraDistance - this._initialNear;
|
|
1335
|
+
|
|
1336
|
+
const minNearPos = Math.min( adjustedNearPosition, regularNearPosition );
|
|
1337
|
+
this.camera.near = cameraDistance - minNearPos;
|
|
1279
1338
|
|
|
1280
|
-
};
|
|
1281
1339
|
|
|
1282
|
-
|
|
1340
|
+
const adjustedFarPosition = Math.min( this._farPos0, - sphere.radius + sphere.center.length() );
|
|
1341
|
+
const regularFarPosition = cameraDistance - this._initialFar;
|
|
1283
1342
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1343
|
+
const minFarPos = Math.min( adjustedFarPosition, regularFarPosition );
|
|
1344
|
+
this.camera.far = cameraDistance - minFarPos;
|
|
1286
1345
|
|
|
1287
|
-
|
|
1346
|
+
this.camera.updateProjectionMatrix();
|
|
1288
1347
|
|
|
1348
|
+
} else {
|
|
1289
1349
|
|
|
1290
|
-
|
|
1350
|
+
let update = false;
|
|
1291
1351
|
|
|
1292
|
-
|
|
1352
|
+
if ( this.camera.near != this._initialNear ) {
|
|
1293
1353
|
|
|
1294
|
-
|
|
1354
|
+
this.camera.near = this._initialNear;
|
|
1355
|
+
update = true;
|
|
1295
1356
|
|
|
1296
|
-
|
|
1357
|
+
}
|
|
1297
1358
|
|
|
1298
|
-
|
|
1359
|
+
if ( this.camera.far != this._initialFar ) {
|
|
1299
1360
|
|
|
1300
|
-
|
|
1301
|
-
|
|
1361
|
+
this.camera.far = this._initialFar;
|
|
1362
|
+
update = true;
|
|
1302
1363
|
|
|
1303
|
-
|
|
1364
|
+
}
|
|
1304
1365
|
|
|
1305
|
-
|
|
1366
|
+
if ( update ) {
|
|
1306
1367
|
|
|
1307
|
-
|
|
1368
|
+
this.camera.updateProjectionMatrix();
|
|
1369
|
+
|
|
1370
|
+
}
|
|
1308
1371
|
|
|
1309
1372
|
}
|
|
1310
1373
|
|
|
1311
1374
|
}
|
|
1312
1375
|
|
|
1313
|
-
}
|
|
1314
|
-
|
|
1315
|
-
onRotateMove = () => {
|
|
1376
|
+
}
|
|
1316
1377
|
|
|
1317
|
-
|
|
1378
|
+
/**
|
|
1379
|
+
* Calculate the angular speed
|
|
1380
|
+
* @param {Number} p0 Position at t0
|
|
1381
|
+
* @param {Number} p1 Position at t1
|
|
1382
|
+
* @param {Number} t0 Initial time in milliseconds
|
|
1383
|
+
* @param {Number} t1 Ending time in milliseconds
|
|
1384
|
+
*/
|
|
1385
|
+
calculateAngularSpeed( p0, p1, t0, t1 ) {
|
|
1318
1386
|
|
|
1319
|
-
|
|
1320
|
-
|
|
1387
|
+
const s = p1 - p0;
|
|
1388
|
+
const t = ( t1 - t0 ) / 1000;
|
|
1389
|
+
if ( t == 0 ) {
|
|
1321
1390
|
|
|
1322
|
-
|
|
1391
|
+
return 0;
|
|
1323
1392
|
|
|
1324
|
-
|
|
1325
|
-
this._startFingerRotation = this._currentFingerRotation;
|
|
1393
|
+
}
|
|
1326
1394
|
|
|
1327
|
-
|
|
1395
|
+
return s / t;
|
|
1328
1396
|
|
|
1329
|
-
|
|
1330
|
-
this._currentFingerRotation = this.getAngle( this._touchCurrent[ 1 ], this._touchCurrent[ 0 ] ) + this.getAngle( this._touchStart[ 1 ], this._touchStart[ 0 ] );
|
|
1397
|
+
}
|
|
1331
1398
|
|
|
1332
|
-
|
|
1399
|
+
/**
|
|
1400
|
+
* Calculate the distance between two pointers
|
|
1401
|
+
* @param {PointerEvent} p0 The first pointer
|
|
1402
|
+
* @param {PointerEvent} p1 The second pointer
|
|
1403
|
+
* @returns {number} The distance between the two pointers
|
|
1404
|
+
*/
|
|
1405
|
+
calculatePointersDistance( p0, p1 ) {
|
|
1333
1406
|
|
|
1334
|
-
|
|
1407
|
+
return Math.sqrt( Math.pow( p1.clientX - p0.clientX, 2 ) + Math.pow( p1.clientY - p0.clientY, 2 ) );
|
|
1335
1408
|
|
|
1336
|
-
|
|
1409
|
+
}
|
|
1337
1410
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1411
|
+
/**
|
|
1412
|
+
* Calculate the rotation axis as the vector perpendicular between two vectors
|
|
1413
|
+
* @param {Vector3} vec1 The first vector
|
|
1414
|
+
* @param {Vector3} vec2 The second vector
|
|
1415
|
+
* @returns {Vector3} The normalized rotation axis
|
|
1416
|
+
*/
|
|
1417
|
+
calculateRotationAxis( vec1, vec2 ) {
|
|
1340
1418
|
|
|
1341
|
-
|
|
1419
|
+
this._rotationMatrix.extractRotation( this._cameraMatrixState );
|
|
1420
|
+
this._quat.setFromRotationMatrix( this._rotationMatrix );
|
|
1342
1421
|
|
|
1343
|
-
|
|
1422
|
+
this._rotationAxis.crossVectors( vec1, vec2 ).applyQuaternion( this._quat );
|
|
1423
|
+
return this._rotationAxis.normalize().clone();
|
|
1344
1424
|
|
|
1345
|
-
|
|
1346
|
-
this.dispatchEvent( _changeEvent );
|
|
1425
|
+
}
|
|
1347
1426
|
|
|
1348
|
-
|
|
1427
|
+
/**
|
|
1428
|
+
* Calculate the trackball radius so that gizmo's diamater will be 2/3 of the minimum side of the camera frustum
|
|
1429
|
+
* @param {Camera} camera
|
|
1430
|
+
* @returns {Number} The trackball radius
|
|
1431
|
+
*/
|
|
1432
|
+
calculateTbRadius( camera ) {
|
|
1349
1433
|
|
|
1350
|
-
|
|
1434
|
+
const distance = camera.position.distanceTo( this._gizmos.position );
|
|
1351
1435
|
|
|
1352
|
-
|
|
1436
|
+
if ( camera.type == 'PerspectiveCamera' ) {
|
|
1353
1437
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1438
|
+
const halfFovV = MathUtils.DEG2RAD * camera.fov * 0.5; //vertical fov/2 in radians
|
|
1439
|
+
const halfFovH = Math.atan( ( camera.aspect ) * Math.tan( halfFovV ) ); //horizontal fov/2 in radians
|
|
1440
|
+
return Math.tan( Math.min( halfFovV, halfFovH ) ) * distance * this.radiusFactor;
|
|
1357
1441
|
|
|
1358
|
-
|
|
1442
|
+
} else if ( camera.type == 'OrthographicCamera' ) {
|
|
1359
1443
|
|
|
1360
|
-
|
|
1444
|
+
return Math.min( camera.top, camera.right ) * this.radiusFactor;
|
|
1361
1445
|
|
|
1362
|
-
|
|
1446
|
+
}
|
|
1363
1447
|
|
|
1364
|
-
|
|
1365
|
-
this.updateTbState( STATE.SCALE, true );
|
|
1448
|
+
}
|
|
1366
1449
|
|
|
1367
|
-
|
|
1368
|
-
|
|
1450
|
+
/**
|
|
1451
|
+
* Focus operation consist of positioning the point of interest in front of the camera and a slightly zoom in
|
|
1452
|
+
* @param {Vector3} point The point of interest
|
|
1453
|
+
* @param {Number} size Scale factor
|
|
1454
|
+
* @param {Number} amount Amount of operation to be completed (used for focus animations, default is complete full operation)
|
|
1455
|
+
*/
|
|
1456
|
+
focus( point, size, amount = 1 ) {
|
|
1369
1457
|
|
|
1370
|
-
|
|
1458
|
+
//move center of camera (along with gizmos) towards point of interest
|
|
1459
|
+
_offset.copy( point ).sub( this._gizmos.position ).multiplyScalar( amount );
|
|
1460
|
+
this._translationMatrix.makeTranslation( _offset.x, _offset.y, _offset.z );
|
|
1371
1461
|
|
|
1372
|
-
|
|
1462
|
+
_gizmoMatrixStateTemp.copy( this._gizmoMatrixState );
|
|
1463
|
+
this._gizmoMatrixState.premultiply( this._translationMatrix );
|
|
1464
|
+
this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
1373
1465
|
|
|
1374
|
-
|
|
1466
|
+
_cameraMatrixStateTemp.copy( this._cameraMatrixState );
|
|
1467
|
+
this._cameraMatrixState.premultiply( this._translationMatrix );
|
|
1468
|
+
this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
1375
1469
|
|
|
1376
|
-
|
|
1470
|
+
//apply zoom
|
|
1471
|
+
if ( this.enableZoom ) {
|
|
1377
1472
|
|
|
1378
|
-
|
|
1473
|
+
this.applyTransformMatrix( this.scale( size, this._gizmos.position ) );
|
|
1379
1474
|
|
|
1380
|
-
|
|
1381
|
-
const minDistance = 12; //minimum distance between fingers (in css pixels)
|
|
1475
|
+
}
|
|
1382
1476
|
|
|
1383
|
-
|
|
1477
|
+
this._gizmoMatrixState.copy( _gizmoMatrixStateTemp );
|
|
1478
|
+
this._cameraMatrixState.copy( _cameraMatrixStateTemp );
|
|
1384
1479
|
|
|
1385
|
-
|
|
1386
|
-
this.updateTbState( STATE.SCALE, true );
|
|
1480
|
+
}
|
|
1387
1481
|
|
|
1388
|
-
|
|
1482
|
+
/**
|
|
1483
|
+
* Draw a grid and add it to the scene
|
|
1484
|
+
*/
|
|
1485
|
+
drawGrid() {
|
|
1389
1486
|
|
|
1390
|
-
|
|
1391
|
-
const amount = this._currentFingerDistance / this._startFingerDistance;
|
|
1487
|
+
if ( this.scene != null ) {
|
|
1392
1488
|
|
|
1393
|
-
|
|
1489
|
+
const color = 0x888888;
|
|
1490
|
+
const multiplier = 3;
|
|
1491
|
+
let size, divisions, maxLength, tick;
|
|
1394
1492
|
|
|
1395
|
-
if (
|
|
1493
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
1396
1494
|
|
|
1397
|
-
|
|
1495
|
+
const width = this.camera.right - this.camera.left;
|
|
1496
|
+
const height = this.camera.bottom - this.camera.top;
|
|
1398
1497
|
|
|
1399
|
-
|
|
1498
|
+
maxLength = Math.max( width, height );
|
|
1499
|
+
tick = maxLength / 20;
|
|
1400
1500
|
|
|
1401
|
-
|
|
1501
|
+
size = maxLength / this.camera.zoom * multiplier;
|
|
1502
|
+
divisions = size / tick * this.camera.zoom;
|
|
1402
1503
|
|
|
1403
|
-
|
|
1404
|
-
.applyQuaternion( this.camera.quaternion )
|
|
1405
|
-
.multiplyScalar( 1 / this.camera.zoom )
|
|
1406
|
-
.add( this._gizmos.position );
|
|
1504
|
+
} else if ( this.camera.isPerspectiveCamera ) {
|
|
1407
1505
|
|
|
1408
|
-
|
|
1506
|
+
const distance = this.camera.position.distanceTo( this._gizmos.position );
|
|
1507
|
+
const halfFovV = MathUtils.DEG2RAD * this.camera.fov * 0.5;
|
|
1508
|
+
const halfFovH = Math.atan( ( this.camera.aspect ) * Math.tan( halfFovV ) );
|
|
1409
1509
|
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
.add( this._gizmos.position );
|
|
1510
|
+
maxLength = Math.tan( Math.max( halfFovV, halfFovH ) ) * distance * 2;
|
|
1511
|
+
tick = maxLength / 20;
|
|
1413
1512
|
|
|
1414
|
-
|
|
1513
|
+
size = maxLength * multiplier;
|
|
1514
|
+
divisions = size / tick;
|
|
1415
1515
|
|
|
1416
1516
|
}
|
|
1417
1517
|
|
|
1418
|
-
|
|
1419
|
-
this.dispatchEvent( _changeEvent );
|
|
1518
|
+
if ( this._grid == null ) {
|
|
1420
1519
|
|
|
1421
|
-
|
|
1520
|
+
this._grid = new GridHelper( size, divisions, color, color );
|
|
1521
|
+
this._grid.position.copy( this._gizmos.position );
|
|
1522
|
+
this._gridPosition.copy( this._grid.position );
|
|
1523
|
+
this._grid.quaternion.copy( this.camera.quaternion );
|
|
1524
|
+
this._grid.rotateX( Math.PI * 0.5 );
|
|
1422
1525
|
|
|
1423
|
-
|
|
1526
|
+
this.scene.add( this._grid );
|
|
1424
1527
|
|
|
1425
|
-
|
|
1528
|
+
}
|
|
1426
1529
|
|
|
1427
|
-
|
|
1428
|
-
this.dispatchEvent( _endEvent );
|
|
1530
|
+
}
|
|
1429
1531
|
|
|
1430
|
-
}
|
|
1532
|
+
}
|
|
1431
1533
|
|
|
1432
|
-
|
|
1534
|
+
/**
|
|
1535
|
+
* Remove all listeners, stop animations and clean scene
|
|
1536
|
+
*/
|
|
1537
|
+
dispose() {
|
|
1433
1538
|
|
|
1434
|
-
if ( this.
|
|
1539
|
+
if ( this._animationId != - 1 ) {
|
|
1435
1540
|
|
|
1436
|
-
|
|
1541
|
+
window.cancelAnimationFrame( this._animationId );
|
|
1437
1542
|
|
|
1438
|
-
|
|
1543
|
+
}
|
|
1439
1544
|
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1545
|
+
this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
|
|
1546
|
+
this.domElement.removeEventListener( 'pointercancel', this._onPointerCancel );
|
|
1547
|
+
this.domElement.removeEventListener( 'wheel', this._onWheel );
|
|
1548
|
+
this.domElement.removeEventListener( 'contextmenu', this._onContextMenu );
|
|
1444
1549
|
|
|
1445
|
-
|
|
1550
|
+
window.removeEventListener( 'pointermove', this._onPointerMove );
|
|
1551
|
+
window.removeEventListener( 'pointerup', this._onPointerUp );
|
|
1446
1552
|
|
|
1447
|
-
|
|
1448
|
-
clientY += this._touchCurrent[ i ].clientY;
|
|
1553
|
+
window.removeEventListener( 'resize', this._onWindowResize );
|
|
1449
1554
|
|
|
1450
|
-
|
|
1555
|
+
if ( this.scene !== null ) this.scene.remove( this._gizmos );
|
|
1556
|
+
this.disposeGrid();
|
|
1451
1557
|
|
|
1452
|
-
|
|
1558
|
+
}
|
|
1453
1559
|
|
|
1454
|
-
|
|
1455
|
-
|
|
1560
|
+
/**
|
|
1561
|
+
* remove the grid from the scene
|
|
1562
|
+
*/
|
|
1563
|
+
disposeGrid() {
|
|
1456
1564
|
|
|
1457
|
-
|
|
1565
|
+
if ( this._grid != null && this.scene != null ) {
|
|
1458
1566
|
|
|
1459
|
-
|
|
1567
|
+
this.scene.remove( this._grid );
|
|
1568
|
+
this._grid = null;
|
|
1460
1569
|
|
|
1461
|
-
|
|
1570
|
+
}
|
|
1462
1571
|
|
|
1463
|
-
|
|
1572
|
+
}
|
|
1464
1573
|
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
// | \
|
|
1472
|
-
// | _ _ _\
|
|
1473
|
-
// y
|
|
1574
|
+
/**
|
|
1575
|
+
* Compute the easing out cubic function for ease out effect in animation
|
|
1576
|
+
* @param {Number} t The absolute progress of the animation in the bound of 0 (beginning of the) and 1 (ending of animation)
|
|
1577
|
+
* @returns {Number} Result of easing out cubic at time t
|
|
1578
|
+
*/
|
|
1579
|
+
easeOutCubic( t ) {
|
|
1474
1580
|
|
|
1475
|
-
|
|
1476
|
-
let clientX = 0;
|
|
1477
|
-
let clientY = 0;
|
|
1478
|
-
const nFingers = this._touchCurrent.length;
|
|
1581
|
+
return 1 - Math.pow( 1 - t, 3 );
|
|
1479
1582
|
|
|
1480
|
-
|
|
1583
|
+
}
|
|
1481
1584
|
|
|
1482
|
-
|
|
1483
|
-
|
|
1585
|
+
/**
|
|
1586
|
+
* Make rotation gizmos more or less visible
|
|
1587
|
+
* @param {Boolean} isActive If true, make gizmos more visible
|
|
1588
|
+
*/
|
|
1589
|
+
activateGizmos( isActive ) {
|
|
1484
1590
|
|
|
1485
|
-
|
|
1591
|
+
const gizmoX = this._gizmos.children[ 0 ];
|
|
1592
|
+
const gizmoY = this._gizmos.children[ 1 ];
|
|
1593
|
+
const gizmoZ = this._gizmos.children[ 2 ];
|
|
1486
1594
|
|
|
1487
|
-
|
|
1595
|
+
if ( isActive ) {
|
|
1488
1596
|
|
|
1489
|
-
|
|
1490
|
-
|
|
1597
|
+
gizmoX.material.setValues( { opacity: 1 } );
|
|
1598
|
+
gizmoY.material.setValues( { opacity: 1 } );
|
|
1599
|
+
gizmoZ.material.setValues( { opacity: 1 } );
|
|
1491
1600
|
|
|
1492
|
-
|
|
1601
|
+
} else {
|
|
1493
1602
|
|
|
1494
|
-
|
|
1603
|
+
gizmoX.material.setValues( { opacity: 0.6 } );
|
|
1604
|
+
gizmoY.material.setValues( { opacity: 0.6 } );
|
|
1605
|
+
gizmoZ.material.setValues( { opacity: 0.6 } );
|
|
1495
1606
|
|
|
1496
|
-
|
|
1607
|
+
}
|
|
1497
1608
|
|
|
1498
|
-
|
|
1609
|
+
}
|
|
1499
1610
|
|
|
1500
|
-
|
|
1611
|
+
/**
|
|
1612
|
+
* Calculate the cursor position in NDC
|
|
1613
|
+
* @param {number} x Cursor horizontal coordinate within the canvas
|
|
1614
|
+
* @param {number} y Cursor vertical coordinate within the canvas
|
|
1615
|
+
* @param {HTMLElement} canvas The canvas where the renderer draws its output
|
|
1616
|
+
* @returns {Vector2} Cursor normalized position inside the canvas
|
|
1617
|
+
*/
|
|
1618
|
+
getCursorNDC( cursorX, cursorY, canvas ) {
|
|
1501
1619
|
|
|
1502
|
-
|
|
1620
|
+
const canvasRect = canvas.getBoundingClientRect();
|
|
1621
|
+
this._v2_1.setX( ( ( cursorX - canvasRect.left ) / canvasRect.width ) * 2 - 1 );
|
|
1622
|
+
this._v2_1.setY( ( ( canvasRect.bottom - cursorY ) / canvasRect.height ) * 2 - 1 );
|
|
1623
|
+
return this._v2_1.clone();
|
|
1503
1624
|
|
|
1504
|
-
|
|
1625
|
+
}
|
|
1505
1626
|
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1627
|
+
/**
|
|
1628
|
+
* Calculate the cursor position inside the canvas x/y coordinates with the origin being in the center of the canvas
|
|
1629
|
+
* @param {Number} x Cursor horizontal coordinate within the canvas
|
|
1630
|
+
* @param {Number} y Cursor vertical coordinate within the canvas
|
|
1631
|
+
* @param {HTMLElement} canvas The canvas where the renderer draws its output
|
|
1632
|
+
* @returns {Vector2} Cursor position inside the canvas
|
|
1633
|
+
*/
|
|
1634
|
+
getCursorPosition( cursorX, cursorY, canvas ) {
|
|
1509
1635
|
|
|
1510
|
-
|
|
1511
|
-
|
|
1636
|
+
this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
|
|
1637
|
+
this._v2_1.x *= ( this.camera.right - this.camera.left ) * 0.5;
|
|
1638
|
+
this._v2_1.y *= ( this.camera.top - this.camera.bottom ) * 0.5;
|
|
1639
|
+
return this._v2_1.clone();
|
|
1512
1640
|
|
|
1513
|
-
|
|
1641
|
+
}
|
|
1514
1642
|
|
|
1515
|
-
|
|
1516
|
-
|
|
1643
|
+
/**
|
|
1644
|
+
* Set the camera to be controlled
|
|
1645
|
+
* @param {Camera} camera The virtual camera to be controlled
|
|
1646
|
+
*/
|
|
1647
|
+
setCamera( camera ) {
|
|
1517
1648
|
|
|
1518
|
-
|
|
1519
|
-
|
|
1649
|
+
camera.lookAt( this.target );
|
|
1650
|
+
camera.updateMatrix();
|
|
1520
1651
|
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
|
|
1652
|
+
//setting state
|
|
1653
|
+
if ( camera.type == 'PerspectiveCamera' ) {
|
|
1524
1654
|
|
|
1525
|
-
this.
|
|
1526
|
-
this.
|
|
1655
|
+
this._fov0 = camera.fov;
|
|
1656
|
+
this._fovState = camera.fov;
|
|
1527
1657
|
|
|
1528
|
-
|
|
1529
|
-
_offset.copy( this._gizmos.position ).sub( this.camera.position ).normalize().multiplyScalar( newDistance / x );
|
|
1530
|
-
this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
|
|
1658
|
+
}
|
|
1531
1659
|
|
|
1532
|
-
|
|
1660
|
+
this._cameraMatrixState0.copy( camera.matrix );
|
|
1661
|
+
this._cameraMatrixState.copy( this._cameraMatrixState0 );
|
|
1662
|
+
this._cameraProjectionState.copy( camera.projectionMatrix );
|
|
1663
|
+
this._zoom0 = camera.zoom;
|
|
1664
|
+
this._zoomState = this._zoom0;
|
|
1533
1665
|
|
|
1534
|
-
|
|
1666
|
+
this._initialNear = camera.near;
|
|
1667
|
+
this._nearPos0 = camera.position.distanceTo( this.target ) - camera.near;
|
|
1668
|
+
this._nearPos = this._initialNear;
|
|
1669
|
+
|
|
1670
|
+
this._initialFar = camera.far;
|
|
1671
|
+
this._farPos0 = camera.position.distanceTo( this.target ) - camera.far;
|
|
1672
|
+
this._farPos = this._initialFar;
|
|
1535
1673
|
|
|
1536
|
-
|
|
1674
|
+
this._up0.copy( camera.up );
|
|
1675
|
+
this._upState.copy( camera.up );
|
|
1537
1676
|
|
|
1538
|
-
|
|
1677
|
+
this.camera = camera;
|
|
1678
|
+
this.camera.updateProjectionMatrix();
|
|
1539
1679
|
|
|
1540
|
-
|
|
1541
|
-
this.
|
|
1542
|
-
|
|
1680
|
+
//making gizmos
|
|
1681
|
+
this._tbRadius = this.calculateTbRadius( camera );
|
|
1682
|
+
this.makeGizmos( this.target, this._tbRadius );
|
|
1543
1683
|
|
|
1544
|
-
}
|
|
1684
|
+
}
|
|
1545
1685
|
|
|
1546
1686
|
/**
|
|
1547
|
-
* Set
|
|
1548
|
-
* @param {
|
|
1549
|
-
* @param {Number} clientY
|
|
1687
|
+
* Set gizmos visibility
|
|
1688
|
+
* @param {Boolean} value Value of gizmos visibility
|
|
1550
1689
|
*/
|
|
1551
|
-
|
|
1690
|
+
setGizmosVisible( value ) {
|
|
1552
1691
|
|
|
1553
|
-
|
|
1554
|
-
|
|
1692
|
+
this._gizmos.visible = value;
|
|
1693
|
+
this.dispatchEvent( _changeEvent );
|
|
1555
1694
|
|
|
1556
|
-
}
|
|
1695
|
+
}
|
|
1557
1696
|
|
|
1558
1697
|
/**
|
|
1559
|
-
* Set
|
|
1698
|
+
* Set gizmos radius factor and redraws gizmos
|
|
1699
|
+
* @param {Float} value Value of radius factor
|
|
1560
1700
|
*/
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
this.setMouseAction( 'PAN', 0, 'CTRL' );
|
|
1564
|
-
this.setMouseAction( 'PAN', 2 );
|
|
1565
|
-
|
|
1566
|
-
this.setMouseAction( 'ROTATE', 0 );
|
|
1701
|
+
setTbRadius( value ) {
|
|
1567
1702
|
|
|
1568
|
-
this.
|
|
1569
|
-
this.
|
|
1703
|
+
this.radiusFactor = value;
|
|
1704
|
+
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
1570
1705
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1706
|
+
const curve = new EllipseCurve( 0, 0, this._tbRadius, this._tbRadius );
|
|
1707
|
+
const points = curve.getPoints( this._curvePts );
|
|
1708
|
+
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
1573
1709
|
|
|
1574
1710
|
|
|
1575
|
-
|
|
1711
|
+
for ( const gizmo in this._gizmos.children ) {
|
|
1576
1712
|
|
|
1577
|
-
|
|
1578
|
-
* Compare two mouse actions
|
|
1579
|
-
* @param {Object} action1
|
|
1580
|
-
* @param {Object} action2
|
|
1581
|
-
* @returns {Boolean} True if action1 and action 2 are the same mouse action, false otherwise
|
|
1582
|
-
*/
|
|
1583
|
-
compareMouseAction = ( action1, action2 ) => {
|
|
1713
|
+
this._gizmos.children[ gizmo ].geometry = curveGeometry;
|
|
1584
1714
|
|
|
1585
|
-
|
|
1715
|
+
}
|
|
1586
1716
|
|
|
1587
|
-
|
|
1717
|
+
this.dispatchEvent( _changeEvent );
|
|
1588
1718
|
|
|
1589
|
-
|
|
1719
|
+
}
|
|
1590
1720
|
|
|
1591
|
-
|
|
1721
|
+
/**
|
|
1722
|
+
* Creates the rotation gizmos matching trackball center and radius
|
|
1723
|
+
* @param {Vector3} tbCenter The trackball center
|
|
1724
|
+
* @param {number} tbRadius The trackball radius
|
|
1725
|
+
*/
|
|
1726
|
+
makeGizmos( tbCenter, tbRadius ) {
|
|
1592
1727
|
|
|
1593
|
-
|
|
1728
|
+
const curve = new EllipseCurve( 0, 0, tbRadius, tbRadius );
|
|
1729
|
+
const points = curve.getPoints( this._curvePts );
|
|
1594
1730
|
|
|
1595
|
-
|
|
1731
|
+
//geometry
|
|
1732
|
+
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
1596
1733
|
|
|
1597
|
-
|
|
1734
|
+
//material
|
|
1735
|
+
const curveMaterialX = new LineBasicMaterial( { color: 0xff8080, fog: false, transparent: true, opacity: 0.6 } );
|
|
1736
|
+
const curveMaterialY = new LineBasicMaterial( { color: 0x80ff80, fog: false, transparent: true, opacity: 0.6 } );
|
|
1737
|
+
const curveMaterialZ = new LineBasicMaterial( { color: 0x8080ff, fog: false, transparent: true, opacity: 0.6 } );
|
|
1598
1738
|
|
|
1599
|
-
|
|
1739
|
+
//line
|
|
1740
|
+
const gizmoX = new Line( curveGeometry, curveMaterialX );
|
|
1741
|
+
const gizmoY = new Line( curveGeometry, curveMaterialY );
|
|
1742
|
+
const gizmoZ = new Line( curveGeometry, curveMaterialZ );
|
|
1600
1743
|
|
|
1601
|
-
|
|
1744
|
+
const rotation = Math.PI * 0.5;
|
|
1745
|
+
gizmoX.rotation.x = rotation;
|
|
1746
|
+
gizmoY.rotation.y = rotation;
|
|
1602
1747
|
|
|
1603
|
-
};
|
|
1604
1748
|
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
* @param {*} mouse A mouse button (0, 1, 2) or 'WHEEL' for wheel notches
|
|
1609
|
-
* @param {*} key The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed
|
|
1610
|
-
* @returns {Boolean} True if the mouse action has been successfully added, false otherwise
|
|
1611
|
-
*/
|
|
1612
|
-
setMouseAction = ( operation, mouse, key = null ) => {
|
|
1749
|
+
//setting state
|
|
1750
|
+
this._gizmoMatrixState0.identity().setPosition( tbCenter );
|
|
1751
|
+
this._gizmoMatrixState.copy( this._gizmoMatrixState0 );
|
|
1613
1752
|
|
|
1614
|
-
|
|
1615
|
-
const mouseInput = [ 0, 1, 2, 'WHEEL' ];
|
|
1616
|
-
const keyInput = [ 'CTRL', 'SHIFT', null ];
|
|
1617
|
-
let state;
|
|
1753
|
+
if ( this.camera.zoom !== 1 ) {
|
|
1618
1754
|
|
|
1619
|
-
|
|
1755
|
+
//adapt gizmos size to camera zoom
|
|
1756
|
+
const size = 1 / this.camera.zoom;
|
|
1757
|
+
this._scaleMatrix.makeScale( size, size, size );
|
|
1758
|
+
this._translationMatrix.makeTranslation( - tbCenter.x, - tbCenter.y, - tbCenter.z );
|
|
1620
1759
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1760
|
+
this._gizmoMatrixState.premultiply( this._translationMatrix ).premultiply( this._scaleMatrix );
|
|
1761
|
+
this._translationMatrix.makeTranslation( tbCenter.x, tbCenter.y, tbCenter.z );
|
|
1762
|
+
this._gizmoMatrixState.premultiply( this._translationMatrix );
|
|
1623
1763
|
|
|
1624
1764
|
}
|
|
1625
1765
|
|
|
1626
|
-
|
|
1766
|
+
this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
1627
1767
|
|
|
1628
|
-
|
|
1768
|
+
//
|
|
1629
1769
|
|
|
1630
|
-
|
|
1631
|
-
return false;
|
|
1770
|
+
this._gizmos.traverse( function ( object ) {
|
|
1632
1771
|
|
|
1633
|
-
|
|
1772
|
+
if ( object.isLine ) {
|
|
1634
1773
|
|
|
1635
|
-
|
|
1774
|
+
object.geometry.dispose();
|
|
1775
|
+
object.material.dispose();
|
|
1636
1776
|
|
|
1637
|
-
|
|
1777
|
+
}
|
|
1638
1778
|
|
|
1639
|
-
|
|
1779
|
+
} );
|
|
1640
1780
|
|
|
1641
|
-
|
|
1642
|
-
break;
|
|
1781
|
+
this._gizmos.clear();
|
|
1643
1782
|
|
|
1644
|
-
|
|
1783
|
+
//
|
|
1645
1784
|
|
|
1646
|
-
|
|
1647
|
-
|
|
1785
|
+
this._gizmos.add( gizmoX );
|
|
1786
|
+
this._gizmos.add( gizmoY );
|
|
1787
|
+
this._gizmos.add( gizmoZ );
|
|
1648
1788
|
|
|
1649
|
-
|
|
1789
|
+
}
|
|
1650
1790
|
|
|
1651
|
-
|
|
1652
|
-
|
|
1791
|
+
/**
|
|
1792
|
+
* Perform animation for focus operation
|
|
1793
|
+
* @param {Number} time Instant in which this function is called as performance.now()
|
|
1794
|
+
* @param {Vector3} point Point of interest for focus operation
|
|
1795
|
+
* @param {Matrix4} cameraMatrix Camera matrix
|
|
1796
|
+
* @param {Matrix4} gizmoMatrix Gizmos matrix
|
|
1797
|
+
*/
|
|
1798
|
+
onFocusAnim( time, point, cameraMatrix, gizmoMatrix ) {
|
|
1653
1799
|
|
|
1654
|
-
|
|
1800
|
+
if ( this._timeStart == - 1 ) {
|
|
1655
1801
|
|
|
1656
|
-
|
|
1657
|
-
|
|
1802
|
+
//animation start
|
|
1803
|
+
this._timeStart = time;
|
|
1658
1804
|
|
|
1659
1805
|
}
|
|
1660
1806
|
|
|
1661
|
-
|
|
1807
|
+
if ( this._state == STATE.ANIMATION_FOCUS ) {
|
|
1662
1808
|
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
key: key,
|
|
1666
|
-
state: state
|
|
1809
|
+
const deltaTime = time - this._timeStart;
|
|
1810
|
+
const animTime = deltaTime / this.focusAnimationTime;
|
|
1667
1811
|
|
|
1668
|
-
|
|
1812
|
+
this._gizmoMatrixState.copy( gizmoMatrix );
|
|
1669
1813
|
|
|
1670
|
-
|
|
1814
|
+
if ( animTime >= 1 ) {
|
|
1671
1815
|
|
|
1672
|
-
|
|
1816
|
+
//animation end
|
|
1673
1817
|
|
|
1674
|
-
this.
|
|
1675
|
-
return true;
|
|
1818
|
+
this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
1676
1819
|
|
|
1677
|
-
|
|
1820
|
+
this.focus( point, this.scaleFactor );
|
|
1678
1821
|
|
|
1679
|
-
|
|
1822
|
+
this._timeStart = - 1;
|
|
1823
|
+
this.updateTbState( STATE.IDLE, false );
|
|
1824
|
+
this.activateGizmos( false );
|
|
1680
1825
|
|
|
1681
|
-
|
|
1682
|
-
return true;
|
|
1826
|
+
this.dispatchEvent( _changeEvent );
|
|
1683
1827
|
|
|
1684
|
-
|
|
1828
|
+
} else {
|
|
1685
1829
|
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
* @param {*} mouse A mouse button (0, 1, 2) or 'WHEEL' for wheel notches
|
|
1689
|
-
* @param {*} key The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed
|
|
1690
|
-
* @returns {Boolean} True if the operation has been succesfully removed, false otherwise
|
|
1691
|
-
*/
|
|
1692
|
-
unsetMouseAction = ( mouse, key = null ) => {
|
|
1830
|
+
const amount = this.easeOutCubic( animTime );
|
|
1831
|
+
const size = ( ( 1 - amount ) + ( this.scaleFactor * amount ) );
|
|
1693
1832
|
|
|
1694
|
-
|
|
1833
|
+
this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
1834
|
+
this.focus( point, size, amount );
|
|
1695
1835
|
|
|
1696
|
-
|
|
1836
|
+
this.dispatchEvent( _changeEvent );
|
|
1837
|
+
const self = this;
|
|
1838
|
+
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
1697
1839
|
|
|
1698
|
-
|
|
1699
|
-
|
|
1840
|
+
self.onFocusAnim( t, point, cameraMatrix, gizmoMatrix.clone() );
|
|
1841
|
+
|
|
1842
|
+
} );
|
|
1700
1843
|
|
|
1701
1844
|
}
|
|
1702
1845
|
|
|
1703
|
-
}
|
|
1846
|
+
} else {
|
|
1704
1847
|
|
|
1705
|
-
|
|
1848
|
+
//interrupt animation
|
|
1706
1849
|
|
|
1707
|
-
|
|
1850
|
+
this._animationId = - 1;
|
|
1851
|
+
this._timeStart = - 1;
|
|
1708
1852
|
|
|
1709
|
-
|
|
1710
|
-
* Return the operation associated to a mouse/keyboard combination
|
|
1711
|
-
* @param {*} mouse A mouse button (0, 1, 2) or 'WHEEL' for wheel notches
|
|
1712
|
-
* @param {*} key The keyboard modifier ('CTRL', 'SHIFT') or null if key is not needed
|
|
1713
|
-
* @returns The operation if it has been found, null otherwise
|
|
1714
|
-
*/
|
|
1715
|
-
getOpFromAction = ( mouse, key ) => {
|
|
1716
|
-
|
|
1717
|
-
let action;
|
|
1853
|
+
}
|
|
1718
1854
|
|
|
1719
|
-
|
|
1855
|
+
}
|
|
1720
1856
|
|
|
1721
|
-
|
|
1722
|
-
|
|
1857
|
+
/**
|
|
1858
|
+
* Perform animation for rotation operation
|
|
1859
|
+
* @param {Number} time Instant in which this function is called as performance.now()
|
|
1860
|
+
* @param {Vector3} rotationAxis Rotation axis
|
|
1861
|
+
* @param {number} w0 Initial angular velocity
|
|
1862
|
+
*/
|
|
1863
|
+
onRotationAnim( time, rotationAxis, w0 ) {
|
|
1723
1864
|
|
|
1724
|
-
|
|
1865
|
+
if ( this._timeStart == - 1 ) {
|
|
1725
1866
|
|
|
1726
|
-
|
|
1867
|
+
//animation start
|
|
1868
|
+
this._anglePrev = 0;
|
|
1869
|
+
this._angleCurrent = 0;
|
|
1870
|
+
this._timeStart = time;
|
|
1727
1871
|
|
|
1728
1872
|
}
|
|
1729
1873
|
|
|
1730
|
-
if (
|
|
1731
|
-
|
|
1732
|
-
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
1733
|
-
|
|
1734
|
-
action = this.mouseActions[ i ];
|
|
1735
|
-
if ( action.mouse == mouse && action.key == null ) {
|
|
1736
|
-
|
|
1737
|
-
return action.operation;
|
|
1738
|
-
|
|
1739
|
-
}
|
|
1874
|
+
if ( this._state == STATE.ANIMATION_ROTATE ) {
|
|
1740
1875
|
|
|
1741
|
-
|
|
1876
|
+
//w = w0 + alpha * t
|
|
1877
|
+
const deltaTime = ( time - this._timeStart ) / 1000;
|
|
1878
|
+
const w = w0 + ( ( - this.dampingFactor ) * deltaTime );
|
|
1742
1879
|
|
|
1743
|
-
|
|
1880
|
+
if ( w > 0 ) {
|
|
1744
1881
|
|
|
1745
|
-
|
|
1882
|
+
//tetha = 0.5 * alpha * t^2 + w0 * t + tetha0
|
|
1883
|
+
this._angleCurrent = 0.5 * ( - this.dampingFactor ) * Math.pow( deltaTime, 2 ) + w0 * deltaTime + 0;
|
|
1884
|
+
this.applyTransformMatrix( this.rotate( rotationAxis, this._angleCurrent ) );
|
|
1885
|
+
this.dispatchEvent( _changeEvent );
|
|
1886
|
+
const self = this;
|
|
1887
|
+
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
1746
1888
|
|
|
1747
|
-
|
|
1889
|
+
self.onRotationAnim( t, rotationAxis, w0 );
|
|
1748
1890
|
|
|
1749
|
-
|
|
1750
|
-
* Get the operation associated to mouse and key combination and returns the corresponding FSA state
|
|
1751
|
-
* @param {Number} mouse Mouse button
|
|
1752
|
-
* @param {String} key Keyboard modifier
|
|
1753
|
-
* @returns The FSA state obtained from the operation associated to mouse/keyboard combination
|
|
1754
|
-
*/
|
|
1755
|
-
getOpStateFromAction = ( mouse, key ) => {
|
|
1891
|
+
} );
|
|
1756
1892
|
|
|
1757
|
-
|
|
1893
|
+
} else {
|
|
1758
1894
|
|
|
1759
|
-
|
|
1895
|
+
this._animationId = - 1;
|
|
1896
|
+
this._timeStart = - 1;
|
|
1760
1897
|
|
|
1761
|
-
|
|
1762
|
-
|
|
1898
|
+
this.updateTbState( STATE.IDLE, false );
|
|
1899
|
+
this.activateGizmos( false );
|
|
1763
1900
|
|
|
1764
|
-
|
|
1901
|
+
this.dispatchEvent( _changeEvent );
|
|
1765
1902
|
|
|
1766
1903
|
}
|
|
1767
1904
|
|
|
1768
|
-
}
|
|
1769
|
-
|
|
1770
|
-
if ( key != null ) {
|
|
1905
|
+
} else {
|
|
1771
1906
|
|
|
1772
|
-
|
|
1907
|
+
//interrupt animation
|
|
1773
1908
|
|
|
1774
|
-
|
|
1775
|
-
|
|
1909
|
+
this._animationId = - 1;
|
|
1910
|
+
this._timeStart = - 1;
|
|
1776
1911
|
|
|
1777
|
-
|
|
1912
|
+
if ( this._state != STATE.ROTATE ) {
|
|
1778
1913
|
|
|
1779
|
-
|
|
1914
|
+
this.activateGizmos( false );
|
|
1915
|
+
this.dispatchEvent( _changeEvent );
|
|
1780
1916
|
|
|
1781
1917
|
}
|
|
1782
1918
|
|
|
1783
1919
|
}
|
|
1784
1920
|
|
|
1785
|
-
|
|
1921
|
+
}
|
|
1786
1922
|
|
|
1787
|
-
};
|
|
1788
1923
|
|
|
1789
1924
|
/**
|
|
1790
|
-
*
|
|
1791
|
-
* @param {
|
|
1792
|
-
* @param {
|
|
1793
|
-
* @
|
|
1925
|
+
* Perform pan operation moving camera between two points
|
|
1926
|
+
* @param {Vector3} p0 Initial point
|
|
1927
|
+
* @param {Vector3} p1 Ending point
|
|
1928
|
+
* @param {Boolean} adjust If movement should be adjusted considering camera distance (Perspective only)
|
|
1794
1929
|
*/
|
|
1795
|
-
|
|
1930
|
+
pan( p0, p1, adjust = false ) {
|
|
1796
1931
|
|
|
1797
|
-
|
|
1932
|
+
const movement = p0.clone().sub( p1 );
|
|
1798
1933
|
|
|
1799
|
-
|
|
1934
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
1800
1935
|
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
* @param {PointerEvent} event
|
|
1804
|
-
*/
|
|
1805
|
-
updateTouchEvent = ( event ) => {
|
|
1936
|
+
//adjust movement amount
|
|
1937
|
+
movement.multiplyScalar( 1 / this.camera.zoom );
|
|
1806
1938
|
|
|
1807
|
-
|
|
1939
|
+
} else if ( this.camera.isPerspectiveCamera && adjust ) {
|
|
1808
1940
|
|
|
1809
|
-
|
|
1941
|
+
//adjust movement amount
|
|
1942
|
+
this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 ); //camera's initial position
|
|
1943
|
+
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ); //gizmo's initial position
|
|
1944
|
+
const distanceFactor = this._v3_1.distanceTo( this._v3_2 ) / this.camera.position.distanceTo( this._gizmos.position );
|
|
1945
|
+
movement.multiplyScalar( 1 / distanceFactor );
|
|
1810
1946
|
|
|
1811
|
-
|
|
1812
|
-
break;
|
|
1947
|
+
}
|
|
1813
1948
|
|
|
1814
|
-
|
|
1949
|
+
this._v3_1.set( movement.x, movement.y, 0 ).applyQuaternion( this.camera.quaternion );
|
|
1815
1950
|
|
|
1816
|
-
|
|
1951
|
+
this._m4_1.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z );
|
|
1952
|
+
|
|
1953
|
+
this.setTransformationMatrices( this._m4_1, this._m4_1 );
|
|
1954
|
+
return _transformation;
|
|
1817
1955
|
|
|
1818
|
-
}
|
|
1956
|
+
}
|
|
1819
1957
|
|
|
1820
1958
|
/**
|
|
1821
|
-
*
|
|
1822
|
-
* @param {Object} transformation Object containing matrices to apply to camera and gizmos
|
|
1959
|
+
* Reset trackball
|
|
1823
1960
|
*/
|
|
1824
|
-
|
|
1961
|
+
reset() {
|
|
1825
1962
|
|
|
1826
|
-
|
|
1963
|
+
this.camera.zoom = this._zoom0;
|
|
1827
1964
|
|
|
1828
|
-
|
|
1829
|
-
this._m4_1.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
1830
|
-
this.camera.updateMatrix();
|
|
1965
|
+
if ( this.camera.isPerspectiveCamera ) {
|
|
1831
1966
|
|
|
1832
|
-
|
|
1833
|
-
if ( this._state == STATE.ROTATE || this._state == STATE.ZROTATE || this._state == STATE.ANIMATION_ROTATE ) {
|
|
1967
|
+
this.camera.fov = this._fov0;
|
|
1834
1968
|
|
|
1835
|
-
|
|
1969
|
+
}
|
|
1836
1970
|
|
|
1837
|
-
|
|
1971
|
+
this.camera.near = this._nearPos;
|
|
1972
|
+
this.camera.far = this._farPos;
|
|
1973
|
+
this._cameraMatrixState.copy( this._cameraMatrixState0 );
|
|
1974
|
+
this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
1975
|
+
this.camera.up.copy( this._up0 );
|
|
1838
1976
|
|
|
1839
|
-
|
|
1977
|
+
this.camera.updateMatrix();
|
|
1978
|
+
this.camera.updateProjectionMatrix();
|
|
1840
1979
|
|
|
1841
|
-
|
|
1980
|
+
this._gizmoMatrixState.copy( this._gizmoMatrixState0 );
|
|
1981
|
+
this._gizmoMatrixState0.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
1982
|
+
this._gizmos.updateMatrix();
|
|
1842
1983
|
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
this._gizmos.updateMatrix();
|
|
1984
|
+
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
1985
|
+
this.makeGizmos( this._gizmos.position, this._tbRadius );
|
|
1846
1986
|
|
|
1847
|
-
|
|
1987
|
+
this.camera.lookAt( this._gizmos.position );
|
|
1848
1988
|
|
|
1849
|
-
|
|
1989
|
+
this.updateTbState( STATE.IDLE, false );
|
|
1850
1990
|
|
|
1851
|
-
|
|
1991
|
+
this.dispatchEvent( _changeEvent );
|
|
1852
1992
|
|
|
1853
|
-
|
|
1993
|
+
}
|
|
1854
1994
|
|
|
1855
|
-
|
|
1995
|
+
/**
|
|
1996
|
+
* Rotate the camera around an axis passing by trackball's center
|
|
1997
|
+
* @param {Vector3} axis Rotation axis
|
|
1998
|
+
* @param {number} angle Angle in radians
|
|
1999
|
+
* @returns {Object} Object with 'camera' field containing transformation matrix resulting from the operation to be applied to the camera
|
|
2000
|
+
*/
|
|
2001
|
+
rotate( axis, angle ) {
|
|
1856
2002
|
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
bb.getBoundingSphere( sphere );
|
|
2003
|
+
const point = this._gizmos.position; //rotation center
|
|
2004
|
+
this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z );
|
|
2005
|
+
this._rotationMatrix.makeRotationAxis( axis, - angle );
|
|
1861
2006
|
|
|
1862
|
-
|
|
1863
|
-
|
|
2007
|
+
//rotate camera
|
|
2008
|
+
this._m4_1.makeTranslation( point.x, point.y, point.z );
|
|
2009
|
+
this._m4_1.multiply( this._rotationMatrix );
|
|
2010
|
+
this._m4_1.multiply( this._translationMatrix );
|
|
1864
2011
|
|
|
1865
|
-
|
|
1866
|
-
this.camera.near = cameraDistance - minNearPos;
|
|
2012
|
+
this.setTransformationMatrices( this._m4_1 );
|
|
1867
2013
|
|
|
2014
|
+
return _transformation;
|
|
1868
2015
|
|
|
1869
|
-
|
|
1870
|
-
const regularFarPosition = cameraDistance - this._initialFar;
|
|
2016
|
+
}
|
|
1871
2017
|
|
|
1872
|
-
|
|
1873
|
-
this.camera.far = cameraDistance - minFarPos;
|
|
2018
|
+
copyState() {
|
|
1874
2019
|
|
|
1875
|
-
|
|
2020
|
+
let state;
|
|
2021
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
1876
2022
|
|
|
1877
|
-
|
|
2023
|
+
state = JSON.stringify( { arcballState: {
|
|
1878
2024
|
|
|
1879
|
-
|
|
2025
|
+
cameraFar: this.camera.far,
|
|
2026
|
+
cameraMatrix: this.camera.matrix,
|
|
2027
|
+
cameraNear: this.camera.near,
|
|
2028
|
+
cameraUp: this.camera.up,
|
|
2029
|
+
cameraZoom: this.camera.zoom,
|
|
2030
|
+
gizmoMatrix: this._gizmos.matrix
|
|
1880
2031
|
|
|
1881
|
-
|
|
2032
|
+
} } );
|
|
1882
2033
|
|
|
1883
|
-
|
|
1884
|
-
update = true;
|
|
2034
|
+
} else if ( this.camera.isPerspectiveCamera ) {
|
|
1885
2035
|
|
|
1886
|
-
|
|
2036
|
+
state = JSON.stringify( { arcballState: {
|
|
2037
|
+
cameraFar: this.camera.far,
|
|
2038
|
+
cameraFov: this.camera.fov,
|
|
2039
|
+
cameraMatrix: this.camera.matrix,
|
|
2040
|
+
cameraNear: this.camera.near,
|
|
2041
|
+
cameraUp: this.camera.up,
|
|
2042
|
+
cameraZoom: this.camera.zoom,
|
|
2043
|
+
gizmoMatrix: this._gizmos.matrix
|
|
1887
2044
|
|
|
1888
|
-
|
|
2045
|
+
} } );
|
|
1889
2046
|
|
|
1890
|
-
|
|
1891
|
-
update = true;
|
|
2047
|
+
}
|
|
1892
2048
|
|
|
1893
|
-
|
|
2049
|
+
navigator.clipboard.writeText( state );
|
|
1894
2050
|
|
|
1895
|
-
|
|
2051
|
+
}
|
|
1896
2052
|
|
|
1897
|
-
|
|
2053
|
+
pasteState() {
|
|
1898
2054
|
|
|
1899
|
-
|
|
2055
|
+
const self = this;
|
|
2056
|
+
navigator.clipboard.readText().then( function resolved( value ) {
|
|
1900
2057
|
|
|
1901
|
-
|
|
2058
|
+
self.setStateFromJSON( value );
|
|
1902
2059
|
|
|
1903
|
-
}
|
|
2060
|
+
} );
|
|
1904
2061
|
|
|
1905
2062
|
}
|
|
1906
2063
|
|
|
1907
2064
|
/**
|
|
1908
|
-
*
|
|
1909
|
-
* @param {Number} p0 Position at t0
|
|
1910
|
-
* @param {Number} p1 Position at t1
|
|
1911
|
-
* @param {Number} t0 Initial time in milliseconds
|
|
1912
|
-
* @param {Number} t1 Ending time in milliseconds
|
|
2065
|
+
* Save the current state of the control. This can later be recover with .reset
|
|
1913
2066
|
*/
|
|
1914
|
-
|
|
2067
|
+
saveState() {
|
|
1915
2068
|
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
2069
|
+
this._cameraMatrixState0.copy( this.camera.matrix );
|
|
2070
|
+
this._gizmoMatrixState0.copy( this._gizmos.matrix );
|
|
2071
|
+
this._nearPos = this.camera.near;
|
|
2072
|
+
this._farPos = this.camera.far;
|
|
2073
|
+
this._zoom0 = this.camera.zoom;
|
|
2074
|
+
this._up0.copy( this.camera.up );
|
|
1919
2075
|
|
|
1920
|
-
|
|
2076
|
+
if ( this.camera.isPerspectiveCamera ) {
|
|
2077
|
+
|
|
2078
|
+
this._fov0 = this.camera.fov;
|
|
1921
2079
|
|
|
1922
2080
|
}
|
|
1923
2081
|
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
};
|
|
2082
|
+
}
|
|
1927
2083
|
|
|
1928
2084
|
/**
|
|
1929
|
-
*
|
|
1930
|
-
* @param {
|
|
1931
|
-
* @param {
|
|
1932
|
-
* @
|
|
2085
|
+
* Perform uniform scale operation around a given point
|
|
2086
|
+
* @param {Number} size Scale factor
|
|
2087
|
+
* @param {Vector3} point Point around which scale
|
|
2088
|
+
* @param {Boolean} scaleGizmos If gizmos should be scaled (Perspective only)
|
|
2089
|
+
* @returns {Object} Object with 'camera' and 'gizmo' fields containing transformation matrices resulting from the operation to be applied to the camera and gizmos
|
|
1933
2090
|
*/
|
|
1934
|
-
|
|
2091
|
+
scale( size, point, scaleGizmos = true ) {
|
|
1935
2092
|
|
|
1936
|
-
|
|
2093
|
+
_scalePointTemp.copy( point );
|
|
2094
|
+
let sizeInverse = 1 / size;
|
|
1937
2095
|
|
|
1938
|
-
|
|
2096
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
1939
2097
|
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
* @param {Vector3} vec2 The second vector
|
|
1944
|
-
* @returns {Vector3} The normalized rotation axis
|
|
1945
|
-
*/
|
|
1946
|
-
calculateRotationAxis = ( vec1, vec2 ) => {
|
|
2098
|
+
//camera zoom
|
|
2099
|
+
this.camera.zoom = this._zoomState;
|
|
2100
|
+
this.camera.zoom *= size;
|
|
1947
2101
|
|
|
1948
|
-
|
|
1949
|
-
|
|
2102
|
+
//check min and max zoom
|
|
2103
|
+
if ( this.camera.zoom > this.maxZoom ) {
|
|
1950
2104
|
|
|
1951
|
-
|
|
1952
|
-
|
|
2105
|
+
this.camera.zoom = this.maxZoom;
|
|
2106
|
+
sizeInverse = this._zoomState / this.maxZoom;
|
|
1953
2107
|
|
|
1954
|
-
|
|
2108
|
+
} else if ( this.camera.zoom < this.minZoom ) {
|
|
1955
2109
|
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
* @param {Camera} camera
|
|
1959
|
-
* @returns {Number} The trackball radius
|
|
1960
|
-
*/
|
|
1961
|
-
calculateTbRadius = ( camera ) => {
|
|
2110
|
+
this.camera.zoom = this.minZoom;
|
|
2111
|
+
sizeInverse = this._zoomState / this.minZoom;
|
|
1962
2112
|
|
|
1963
|
-
|
|
2113
|
+
}
|
|
1964
2114
|
|
|
1965
|
-
|
|
2115
|
+
this.camera.updateProjectionMatrix();
|
|
1966
2116
|
|
|
1967
|
-
|
|
1968
|
-
const halfFovH = Math.atan( ( camera.aspect ) * Math.tan( halfFovV ) ); //horizontal fov/2 in radians
|
|
1969
|
-
return Math.tan( Math.min( halfFovV, halfFovH ) ) * distance * this.radiusFactor;
|
|
2117
|
+
this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ); //gizmos position
|
|
1970
2118
|
|
|
1971
|
-
|
|
2119
|
+
//scale gizmos so they appear in the same spot having the same dimension
|
|
2120
|
+
this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse );
|
|
2121
|
+
this._translationMatrix.makeTranslation( - this._v3_1.x, - this._v3_1.y, - this._v3_1.z );
|
|
1972
2122
|
|
|
1973
|
-
|
|
2123
|
+
this._m4_2.makeTranslation( this._v3_1.x, this._v3_1.y, this._v3_1.z ).multiply( this._scaleMatrix );
|
|
2124
|
+
this._m4_2.multiply( this._translationMatrix );
|
|
1974
2125
|
|
|
1975
|
-
}
|
|
1976
2126
|
|
|
1977
|
-
|
|
2127
|
+
//move camera and gizmos to obtain pinch effect
|
|
2128
|
+
_scalePointTemp.sub( this._v3_1 );
|
|
1978
2129
|
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
* @param {Vector3} point The point of interest
|
|
1982
|
-
* @param {Number} size Scale factor
|
|
1983
|
-
* @param {Number} amount Amount of operation to be completed (used for focus animations, default is complete full operation)
|
|
1984
|
-
*/
|
|
1985
|
-
focus = ( point, size, amount = 1 ) => {
|
|
2130
|
+
const amount = _scalePointTemp.clone().multiplyScalar( sizeInverse );
|
|
2131
|
+
_scalePointTemp.sub( amount );
|
|
1986
2132
|
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
this._translationMatrix.makeTranslation( _offset.x, _offset.y, _offset.z );
|
|
2133
|
+
this._m4_1.makeTranslation( _scalePointTemp.x, _scalePointTemp.y, _scalePointTemp.z );
|
|
2134
|
+
this._m4_2.premultiply( this._m4_1 );
|
|
1990
2135
|
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
2136
|
+
this.setTransformationMatrices( this._m4_1, this._m4_2 );
|
|
2137
|
+
return _transformation;
|
|
1994
2138
|
|
|
1995
|
-
|
|
1996
|
-
this._cameraMatrixState.premultiply( this._translationMatrix );
|
|
1997
|
-
this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
2139
|
+
} else if ( this.camera.isPerspectiveCamera ) {
|
|
1998
2140
|
|
|
1999
|
-
|
|
2000
|
-
|
|
2141
|
+
this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
|
|
2142
|
+
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState );
|
|
2001
2143
|
|
|
2002
|
-
|
|
2144
|
+
//move camera
|
|
2145
|
+
let distance = this._v3_1.distanceTo( _scalePointTemp );
|
|
2146
|
+
let amount = distance - ( distance * sizeInverse );
|
|
2003
2147
|
|
|
2004
|
-
|
|
2148
|
+
//check min and max distance
|
|
2149
|
+
const newDistance = distance - amount;
|
|
2150
|
+
if ( newDistance < this.minDistance ) {
|
|
2005
2151
|
|
|
2006
|
-
|
|
2007
|
-
|
|
2152
|
+
sizeInverse = this.minDistance / distance;
|
|
2153
|
+
amount = distance - ( distance * sizeInverse );
|
|
2008
2154
|
|
|
2009
|
-
|
|
2155
|
+
} else if ( newDistance > this.maxDistance ) {
|
|
2010
2156
|
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
*/
|
|
2014
|
-
drawGrid = () => {
|
|
2157
|
+
sizeInverse = this.maxDistance / distance;
|
|
2158
|
+
amount = distance - ( distance * sizeInverse );
|
|
2015
2159
|
|
|
2016
|
-
|
|
2160
|
+
}
|
|
2017
2161
|
|
|
2018
|
-
|
|
2019
|
-
const multiplier = 3;
|
|
2020
|
-
let size, divisions, maxLength, tick;
|
|
2162
|
+
_offset.copy( _scalePointTemp ).sub( this._v3_1 ).normalize().multiplyScalar( amount );
|
|
2021
2163
|
|
|
2022
|
-
|
|
2164
|
+
this._m4_1.makeTranslation( _offset.x, _offset.y, _offset.z );
|
|
2023
2165
|
|
|
2024
|
-
const width = this.camera.right - this.camera.left;
|
|
2025
|
-
const height = this.camera.bottom - this.camera.top;
|
|
2026
2166
|
|
|
2027
|
-
|
|
2028
|
-
tick = maxLength / 20;
|
|
2167
|
+
if ( scaleGizmos ) {
|
|
2029
2168
|
|
|
2030
|
-
|
|
2031
|
-
|
|
2169
|
+
//scale gizmos so they appear in the same spot having the same dimension
|
|
2170
|
+
const pos = this._v3_2;
|
|
2032
2171
|
|
|
2033
|
-
|
|
2172
|
+
distance = pos.distanceTo( _scalePointTemp );
|
|
2173
|
+
amount = distance - ( distance * sizeInverse );
|
|
2174
|
+
_offset.copy( _scalePointTemp ).sub( this._v3_2 ).normalize().multiplyScalar( amount );
|
|
2034
2175
|
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
const halfFovH = Math.atan( ( this.camera.aspect ) * Math.tan( halfFovV ) );
|
|
2176
|
+
this._translationMatrix.makeTranslation( pos.x, pos.y, pos.z );
|
|
2177
|
+
this._scaleMatrix.makeScale( sizeInverse, sizeInverse, sizeInverse );
|
|
2038
2178
|
|
|
2039
|
-
|
|
2040
|
-
|
|
2179
|
+
this._m4_2.makeTranslation( _offset.x, _offset.y, _offset.z ).multiply( this._translationMatrix );
|
|
2180
|
+
this._m4_2.multiply( this._scaleMatrix );
|
|
2041
2181
|
|
|
2042
|
-
|
|
2043
|
-
divisions = size / tick;
|
|
2182
|
+
this._translationMatrix.makeTranslation( - pos.x, - pos.y, - pos.z );
|
|
2044
2183
|
|
|
2045
|
-
|
|
2184
|
+
this._m4_2.multiply( this._translationMatrix );
|
|
2185
|
+
this.setTransformationMatrices( this._m4_1, this._m4_2 );
|
|
2046
2186
|
|
|
2047
|
-
if ( this._grid == null ) {
|
|
2048
2187
|
|
|
2049
|
-
|
|
2050
|
-
this._grid.position.copy( this._gizmos.position );
|
|
2051
|
-
this._gridPosition.copy( this._grid.position );
|
|
2052
|
-
this._grid.quaternion.copy( this.camera.quaternion );
|
|
2053
|
-
this._grid.rotateX( Math.PI * 0.5 );
|
|
2188
|
+
} else {
|
|
2054
2189
|
|
|
2055
|
-
this.
|
|
2190
|
+
this.setTransformationMatrices( this._m4_1 );
|
|
2056
2191
|
|
|
2057
2192
|
}
|
|
2058
2193
|
|
|
2194
|
+
return _transformation;
|
|
2195
|
+
|
|
2059
2196
|
}
|
|
2060
2197
|
|
|
2061
|
-
}
|
|
2198
|
+
}
|
|
2062
2199
|
|
|
2063
2200
|
/**
|
|
2064
|
-
*
|
|
2201
|
+
* Set camera fov
|
|
2202
|
+
* @param {Number} value fov to be setted
|
|
2065
2203
|
*/
|
|
2066
|
-
|
|
2204
|
+
setFov( value ) {
|
|
2067
2205
|
|
|
2068
|
-
if ( this.
|
|
2206
|
+
if ( this.camera.isPerspectiveCamera ) {
|
|
2069
2207
|
|
|
2070
|
-
|
|
2208
|
+
this.camera.fov = MathUtils.clamp( value, this.minFov, this.maxFov );
|
|
2209
|
+
this.camera.updateProjectionMatrix();
|
|
2071
2210
|
|
|
2072
2211
|
}
|
|
2073
2212
|
|
|
2074
|
-
|
|
2075
|
-
this.domElement.removeEventListener( 'pointercancel', this.onPointerCancel );
|
|
2076
|
-
this.domElement.removeEventListener( 'wheel', this.onWheel );
|
|
2077
|
-
this.domElement.removeEventListener( 'contextmenu', this.onContextMenu );
|
|
2213
|
+
}
|
|
2078
2214
|
|
|
2079
|
-
|
|
2080
|
-
|
|
2215
|
+
/**
|
|
2216
|
+
* Set values in transformation object
|
|
2217
|
+
* @param {Matrix4} camera Transformation to be applied to the camera
|
|
2218
|
+
* @param {Matrix4} gizmos Transformation to be applied to gizmos
|
|
2219
|
+
*/
|
|
2220
|
+
setTransformationMatrices( camera = null, gizmos = null ) {
|
|
2081
2221
|
|
|
2082
|
-
|
|
2222
|
+
if ( camera != null ) {
|
|
2083
2223
|
|
|
2084
|
-
|
|
2085
|
-
this.disposeGrid();
|
|
2224
|
+
if ( _transformation.camera != null ) {
|
|
2086
2225
|
|
|
2087
|
-
|
|
2226
|
+
_transformation.camera.copy( camera );
|
|
2088
2227
|
|
|
2089
|
-
|
|
2090
|
-
* remove the grid from the scene
|
|
2091
|
-
*/
|
|
2092
|
-
disposeGrid = () => {
|
|
2228
|
+
} else {
|
|
2093
2229
|
|
|
2094
|
-
|
|
2230
|
+
_transformation.camera = camera.clone();
|
|
2095
2231
|
|
|
2096
|
-
|
|
2097
|
-
this._grid = null;
|
|
2232
|
+
}
|
|
2098
2233
|
|
|
2099
|
-
}
|
|
2234
|
+
} else {
|
|
2100
2235
|
|
|
2101
|
-
|
|
2236
|
+
_transformation.camera = null;
|
|
2102
2237
|
|
|
2103
|
-
|
|
2104
|
-
* Compute the easing out cubic function for ease out effect in animation
|
|
2105
|
-
* @param {Number} t The absolute progress of the animation in the bound of 0 (beginning of the) and 1 (ending of animation)
|
|
2106
|
-
* @returns {Number} Result of easing out cubic at time t
|
|
2107
|
-
*/
|
|
2108
|
-
easeOutCubic = ( t ) => {
|
|
2238
|
+
}
|
|
2109
2239
|
|
|
2110
|
-
|
|
2240
|
+
if ( gizmos != null ) {
|
|
2111
2241
|
|
|
2112
|
-
|
|
2242
|
+
if ( _transformation.gizmos != null ) {
|
|
2113
2243
|
|
|
2114
|
-
|
|
2115
|
-
* Make rotation gizmos more or less visible
|
|
2116
|
-
* @param {Boolean} isActive If true, make gizmos more visible
|
|
2117
|
-
*/
|
|
2118
|
-
activateGizmos = ( isActive ) => {
|
|
2244
|
+
_transformation.gizmos.copy( gizmos );
|
|
2119
2245
|
|
|
2120
|
-
|
|
2121
|
-
const gizmoY = this._gizmos.children[ 1 ];
|
|
2122
|
-
const gizmoZ = this._gizmos.children[ 2 ];
|
|
2246
|
+
} else {
|
|
2123
2247
|
|
|
2124
|
-
|
|
2248
|
+
_transformation.gizmos = gizmos.clone();
|
|
2125
2249
|
|
|
2126
|
-
|
|
2127
|
-
gizmoY.material.setValues( { opacity: 1 } );
|
|
2128
|
-
gizmoZ.material.setValues( { opacity: 1 } );
|
|
2250
|
+
}
|
|
2129
2251
|
|
|
2130
2252
|
} else {
|
|
2131
2253
|
|
|
2132
|
-
|
|
2133
|
-
gizmoY.material.setValues( { opacity: 0.6 } );
|
|
2134
|
-
gizmoZ.material.setValues( { opacity: 0.6 } );
|
|
2254
|
+
_transformation.gizmos = null;
|
|
2135
2255
|
|
|
2136
2256
|
}
|
|
2137
2257
|
|
|
2138
|
-
}
|
|
2258
|
+
}
|
|
2139
2259
|
|
|
2140
2260
|
/**
|
|
2141
|
-
*
|
|
2142
|
-
* @param {
|
|
2143
|
-
* @param {
|
|
2144
|
-
* @
|
|
2145
|
-
* @returns {Vector2} Cursor normalized position inside the canvas
|
|
2261
|
+
* Rotate camera around its direction axis passing by a given point by a given angle
|
|
2262
|
+
* @param {Vector3} point The point where the rotation axis is passing trough
|
|
2263
|
+
* @param {Number} angle Angle in radians
|
|
2264
|
+
* @returns The computed transormation matix
|
|
2146
2265
|
*/
|
|
2147
|
-
|
|
2266
|
+
zRotate( point, angle ) {
|
|
2148
2267
|
|
|
2149
|
-
|
|
2150
|
-
this.
|
|
2151
|
-
this._v2_1.setY( ( ( canvasRect.bottom - cursorY ) / canvasRect.height ) * 2 - 1 );
|
|
2152
|
-
return this._v2_1.clone();
|
|
2268
|
+
this._rotationMatrix.makeRotationAxis( this._rotationAxis, angle );
|
|
2269
|
+
this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z );
|
|
2153
2270
|
|
|
2154
|
-
|
|
2271
|
+
this._m4_1.makeTranslation( point.x, point.y, point.z );
|
|
2272
|
+
this._m4_1.multiply( this._rotationMatrix );
|
|
2273
|
+
this._m4_1.multiply( this._translationMatrix );
|
|
2155
2274
|
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
* @param {Number} y Cursor vertical coordinate within the canvas
|
|
2160
|
-
* @param {HTMLElement} canvas The canvas where the renderer draws its output
|
|
2161
|
-
* @returns {Vector2} Cursor position inside the canvas
|
|
2162
|
-
*/
|
|
2163
|
-
getCursorPosition = ( cursorX, cursorY, canvas ) => {
|
|
2275
|
+
this._v3_1.setFromMatrixPosition( this._gizmoMatrixState ).sub( point ); //vector from rotation center to gizmos position
|
|
2276
|
+
this._v3_2.copy( this._v3_1 ).applyAxisAngle( this._rotationAxis, angle ); //apply rotation
|
|
2277
|
+
this._v3_2.sub( this._v3_1 );
|
|
2164
2278
|
|
|
2165
|
-
this.
|
|
2166
|
-
this._v2_1.x *= ( this.camera.right - this.camera.left ) * 0.5;
|
|
2167
|
-
this._v2_1.y *= ( this.camera.top - this.camera.bottom ) * 0.5;
|
|
2168
|
-
return this._v2_1.clone();
|
|
2279
|
+
this._m4_2.makeTranslation( this._v3_2.x, this._v3_2.y, this._v3_2.z );
|
|
2169
2280
|
|
|
2170
|
-
|
|
2281
|
+
this.setTransformationMatrices( this._m4_1, this._m4_2 );
|
|
2282
|
+
return _transformation;
|
|
2171
2283
|
|
|
2172
|
-
|
|
2173
|
-
* Set the camera to be controlled
|
|
2174
|
-
* @param {Camera} camera The virtual camera to be controlled
|
|
2175
|
-
*/
|
|
2176
|
-
setCamera = ( camera ) => {
|
|
2284
|
+
}
|
|
2177
2285
|
|
|
2178
|
-
camera.lookAt( this.target );
|
|
2179
|
-
camera.updateMatrix();
|
|
2180
2286
|
|
|
2181
|
-
|
|
2182
|
-
if ( camera.type == 'PerspectiveCamera' ) {
|
|
2287
|
+
getRaycaster() {
|
|
2183
2288
|
|
|
2184
|
-
|
|
2185
|
-
this._fovState = camera.fov;
|
|
2289
|
+
return _raycaster;
|
|
2186
2290
|
|
|
2187
|
-
|
|
2291
|
+
}
|
|
2188
2292
|
|
|
2189
|
-
this._cameraMatrixState0.copy( camera.matrix );
|
|
2190
|
-
this._cameraMatrixState.copy( this._cameraMatrixState0 );
|
|
2191
|
-
this._cameraProjectionState.copy( camera.projectionMatrix );
|
|
2192
|
-
this._zoom0 = camera.zoom;
|
|
2193
|
-
this._zoomState = this._zoom0;
|
|
2194
2293
|
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2294
|
+
/**
|
|
2295
|
+
* Unproject the cursor on the 3D object surface
|
|
2296
|
+
* @param {Vector2} cursor Cursor coordinates in NDC
|
|
2297
|
+
* @param {Camera} camera Virtual camera
|
|
2298
|
+
* @returns {Vector3} The point of intersection with the model, if exist, null otherwise
|
|
2299
|
+
*/
|
|
2300
|
+
unprojectOnObj( cursor, camera ) {
|
|
2198
2301
|
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2302
|
+
const raycaster = this.getRaycaster();
|
|
2303
|
+
raycaster.near = camera.near;
|
|
2304
|
+
raycaster.far = camera.far;
|
|
2305
|
+
raycaster.setFromCamera( cursor, camera );
|
|
2202
2306
|
|
|
2203
|
-
|
|
2204
|
-
this._upState.copy( camera.up );
|
|
2307
|
+
const intersect = raycaster.intersectObjects( this.scene.children, true );
|
|
2205
2308
|
|
|
2206
|
-
|
|
2207
|
-
this.camera.updateProjectionMatrix();
|
|
2309
|
+
for ( let i = 0; i < intersect.length; i ++ ) {
|
|
2208
2310
|
|
|
2209
|
-
|
|
2210
|
-
this._tbRadius = this.calculateTbRadius( camera );
|
|
2211
|
-
this.makeGizmos( this.target, this._tbRadius );
|
|
2311
|
+
if ( intersect[ i ].object.uuid != this._gizmos.uuid && intersect[ i ].face != null ) {
|
|
2212
2312
|
|
|
2213
|
-
|
|
2313
|
+
return intersect[ i ].point.clone();
|
|
2214
2314
|
|
|
2215
|
-
|
|
2216
|
-
* Set gizmos visibility
|
|
2217
|
-
* @param {Boolean} value Value of gizmos visibility
|
|
2218
|
-
*/
|
|
2219
|
-
setGizmosVisible( value ) {
|
|
2315
|
+
}
|
|
2220
2316
|
|
|
2221
|
-
|
|
2222
|
-
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
return null;
|
|
2223
2320
|
|
|
2224
2321
|
}
|
|
2225
2322
|
|
|
2226
2323
|
/**
|
|
2227
|
-
*
|
|
2228
|
-
* @param {
|
|
2324
|
+
* Unproject the cursor on the trackball surface
|
|
2325
|
+
* @param {Camera} camera The virtual camera
|
|
2326
|
+
* @param {Number} cursorX Cursor horizontal coordinate on screen
|
|
2327
|
+
* @param {Number} cursorY Cursor vertical coordinate on screen
|
|
2328
|
+
* @param {HTMLElement} canvas The canvas where the renderer draws its output
|
|
2329
|
+
* @param {number} tbRadius The trackball radius
|
|
2330
|
+
* @returns {Vector3} The unprojected point on the trackball surface
|
|
2229
2331
|
*/
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
this.radiusFactor = value;
|
|
2233
|
-
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
2234
|
-
|
|
2235
|
-
const curve = new EllipseCurve( 0, 0, this._tbRadius, this._tbRadius );
|
|
2236
|
-
const points = curve.getPoints( this._curvePts );
|
|
2237
|
-
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
2332
|
+
unprojectOnTbSurface( camera, cursorX, cursorY, canvas, tbRadius ) {
|
|
2238
2333
|
|
|
2334
|
+
if ( camera.type == 'OrthographicCamera' ) {
|
|
2239
2335
|
|
|
2240
|
-
|
|
2336
|
+
this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
|
|
2337
|
+
this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
|
|
2241
2338
|
|
|
2242
|
-
this.
|
|
2339
|
+
const x2 = Math.pow( this._v2_1.x, 2 );
|
|
2340
|
+
const y2 = Math.pow( this._v2_1.y, 2 );
|
|
2341
|
+
const r2 = Math.pow( this._tbRadius, 2 );
|
|
2243
2342
|
|
|
2244
|
-
|
|
2343
|
+
if ( x2 + y2 <= r2 * 0.5 ) {
|
|
2245
2344
|
|
|
2246
|
-
|
|
2345
|
+
//intersection with sphere
|
|
2346
|
+
this._v3_1.setZ( Math.sqrt( r2 - ( x2 + y2 ) ) );
|
|
2247
2347
|
|
|
2248
|
-
|
|
2348
|
+
} else {
|
|
2249
2349
|
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
* @param {Vector3} tbCenter The trackball center
|
|
2253
|
-
* @param {number} tbRadius The trackball radius
|
|
2254
|
-
*/
|
|
2255
|
-
makeGizmos = ( tbCenter, tbRadius ) => {
|
|
2350
|
+
//intersection with hyperboloid
|
|
2351
|
+
this._v3_1.setZ( ( r2 * 0.5 ) / ( Math.sqrt( x2 + y2 ) ) );
|
|
2256
2352
|
|
|
2257
|
-
|
|
2258
|
-
const points = curve.getPoints( this._curvePts );
|
|
2353
|
+
}
|
|
2259
2354
|
|
|
2260
|
-
|
|
2261
|
-
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
2355
|
+
return this._v3_1;
|
|
2262
2356
|
|
|
2263
|
-
|
|
2264
|
-
const curveMaterialX = new LineBasicMaterial( { color: 0xff8080, fog: false, transparent: true, opacity: 0.6 } );
|
|
2265
|
-
const curveMaterialY = new LineBasicMaterial( { color: 0x80ff80, fog: false, transparent: true, opacity: 0.6 } );
|
|
2266
|
-
const curveMaterialZ = new LineBasicMaterial( { color: 0x8080ff, fog: false, transparent: true, opacity: 0.6 } );
|
|
2357
|
+
} else if ( camera.type == 'PerspectiveCamera' ) {
|
|
2267
2358
|
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
const gizmoY = new Line( curveGeometry, curveMaterialY );
|
|
2271
|
-
const gizmoZ = new Line( curveGeometry, curveMaterialZ );
|
|
2359
|
+
//unproject cursor on the near plane
|
|
2360
|
+
this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
|
|
2272
2361
|
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
gizmoY.rotation.y = rotation;
|
|
2362
|
+
this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 );
|
|
2363
|
+
this._v3_1.applyMatrix4( camera.projectionMatrixInverse );
|
|
2276
2364
|
|
|
2365
|
+
const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction
|
|
2366
|
+
const cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position );
|
|
2367
|
+
const radius2 = Math.pow( tbRadius, 2 );
|
|
2277
2368
|
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2369
|
+
// camera
|
|
2370
|
+
// |\
|
|
2371
|
+
// | \
|
|
2372
|
+
// | \
|
|
2373
|
+
// h | \
|
|
2374
|
+
// | \
|
|
2375
|
+
// | \
|
|
2376
|
+
// _ _ | _ _ _\ _ _ near plane
|
|
2377
|
+
// l
|
|
2281
2378
|
|
|
2282
|
-
|
|
2379
|
+
const h = this._v3_1.z;
|
|
2380
|
+
const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
|
|
2283
2381
|
|
|
2284
|
-
|
|
2285
|
-
const size = 1 / this.camera.zoom;
|
|
2286
|
-
this._scaleMatrix.makeScale( size, size, size );
|
|
2287
|
-
this._translationMatrix.makeTranslation( - tbCenter.x, - tbCenter.y, - tbCenter.z );
|
|
2382
|
+
if ( l == 0 ) {
|
|
2288
2383
|
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2384
|
+
//ray aligned with camera
|
|
2385
|
+
rayDir.set( this._v3_1.x, this._v3_1.y, tbRadius );
|
|
2386
|
+
return rayDir;
|
|
2292
2387
|
|
|
2293
|
-
|
|
2388
|
+
}
|
|
2294
2389
|
|
|
2295
|
-
|
|
2390
|
+
const m = h / l;
|
|
2391
|
+
const q = cameraGizmoDistance;
|
|
2296
2392
|
|
|
2297
|
-
|
|
2393
|
+
/*
|
|
2394
|
+
* calculate intersection point between unprojected ray and trackball surface
|
|
2395
|
+
*|y = m * x + q
|
|
2396
|
+
*|x^2 + y^2 = r^2
|
|
2397
|
+
*
|
|
2398
|
+
* (m^2 + 1) * x^2 + (2 * m * q) * x + q^2 - r^2 = 0
|
|
2399
|
+
*/
|
|
2400
|
+
let a = Math.pow( m, 2 ) + 1;
|
|
2401
|
+
let b = 2 * m * q;
|
|
2402
|
+
let c = Math.pow( q, 2 ) - radius2;
|
|
2403
|
+
let delta = Math.pow( b, 2 ) - ( 4 * a * c );
|
|
2298
2404
|
|
|
2299
|
-
|
|
2405
|
+
if ( delta >= 0 ) {
|
|
2300
2406
|
|
|
2301
|
-
|
|
2407
|
+
//intersection with sphere
|
|
2408
|
+
this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
|
|
2409
|
+
this._v2_1.setY( m * this._v2_1.x + q );
|
|
2302
2410
|
|
|
2303
|
-
|
|
2304
|
-
object.material.dispose();
|
|
2411
|
+
const angle = MathUtils.RAD2DEG * this._v2_1.angle();
|
|
2305
2412
|
|
|
2306
|
-
|
|
2413
|
+
if ( angle >= 45 ) {
|
|
2307
2414
|
|
|
2308
|
-
|
|
2415
|
+
//if angle between intersection point and X' axis is >= 45°, return that point
|
|
2416
|
+
//otherwise, calculate intersection point with hyperboloid
|
|
2309
2417
|
|
|
2310
|
-
|
|
2418
|
+
const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( ( cameraGizmoDistance - this._v2_1.y ), 2 ) );
|
|
2419
|
+
rayDir.multiplyScalar( rayLength );
|
|
2420
|
+
rayDir.z += cameraGizmoDistance;
|
|
2421
|
+
return rayDir;
|
|
2311
2422
|
|
|
2312
|
-
|
|
2423
|
+
}
|
|
2313
2424
|
|
|
2314
|
-
|
|
2315
|
-
this._gizmos.add( gizmoY );
|
|
2316
|
-
this._gizmos.add( gizmoZ );
|
|
2425
|
+
}
|
|
2317
2426
|
|
|
2318
|
-
|
|
2427
|
+
//intersection with hyperboloid
|
|
2428
|
+
/*
|
|
2429
|
+
*|y = m * x + q
|
|
2430
|
+
*|y = (1 / x) * (r^2 / 2)
|
|
2431
|
+
*
|
|
2432
|
+
* m * x^2 + q * x - r^2 / 2 = 0
|
|
2433
|
+
*/
|
|
2319
2434
|
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
*/
|
|
2327
|
-
onFocusAnim = ( time, point, cameraMatrix, gizmoMatrix ) => {
|
|
2435
|
+
a = m;
|
|
2436
|
+
b = q;
|
|
2437
|
+
c = - radius2 * 0.5;
|
|
2438
|
+
delta = Math.pow( b, 2 ) - ( 4 * a * c );
|
|
2439
|
+
this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
|
|
2440
|
+
this._v2_1.setY( m * this._v2_1.x + q );
|
|
2328
2441
|
|
|
2329
|
-
|
|
2442
|
+
const rayLength = Math.sqrt( Math.pow( this._v2_1.x, 2 ) + Math.pow( ( cameraGizmoDistance - this._v2_1.y ), 2 ) );
|
|
2330
2443
|
|
|
2331
|
-
|
|
2332
|
-
|
|
2444
|
+
rayDir.multiplyScalar( rayLength );
|
|
2445
|
+
rayDir.z += cameraGizmoDistance;
|
|
2446
|
+
return rayDir;
|
|
2333
2447
|
|
|
2334
2448
|
}
|
|
2335
2449
|
|
|
2336
|
-
|
|
2450
|
+
}
|
|
2337
2451
|
|
|
2338
|
-
const deltaTime = time - this._timeStart;
|
|
2339
|
-
const animTime = deltaTime / this.focusAnimationTime;
|
|
2340
2452
|
|
|
2341
|
-
|
|
2453
|
+
/**
|
|
2454
|
+
* Unproject the cursor on the plane passing through the center of the trackball orthogonal to the camera
|
|
2455
|
+
* @param {Camera} camera The virtual camera
|
|
2456
|
+
* @param {Number} cursorX Cursor horizontal coordinate on screen
|
|
2457
|
+
* @param {Number} cursorY Cursor vertical coordinate on screen
|
|
2458
|
+
* @param {HTMLElement} canvas The canvas where the renderer draws its output
|
|
2459
|
+
* @param {Boolean} initialDistance If initial distance between camera and gizmos should be used for calculations instead of current (Perspective only)
|
|
2460
|
+
* @returns {Vector3} The unprojected point on the trackball plane
|
|
2461
|
+
*/
|
|
2462
|
+
unprojectOnTbPlane( camera, cursorX, cursorY, canvas, initialDistance = false ) {
|
|
2342
2463
|
|
|
2343
|
-
|
|
2464
|
+
if ( camera.type == 'OrthographicCamera' ) {
|
|
2344
2465
|
|
|
2345
|
-
|
|
2466
|
+
this._v2_1.copy( this.getCursorPosition( cursorX, cursorY, canvas ) );
|
|
2467
|
+
this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
|
|
2346
2468
|
|
|
2347
|
-
|
|
2469
|
+
return this._v3_1.clone();
|
|
2348
2470
|
|
|
2349
|
-
|
|
2471
|
+
} else if ( camera.type == 'PerspectiveCamera' ) {
|
|
2350
2472
|
|
|
2351
|
-
|
|
2352
|
-
this.updateTbState( STATE.IDLE, false );
|
|
2353
|
-
this.activateGizmos( false );
|
|
2473
|
+
this._v2_1.copy( this.getCursorNDC( cursorX, cursorY, canvas ) );
|
|
2354
2474
|
|
|
2355
|
-
|
|
2475
|
+
//unproject cursor on the near plane
|
|
2476
|
+
this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 );
|
|
2477
|
+
this._v3_1.applyMatrix4( camera.projectionMatrixInverse );
|
|
2356
2478
|
|
|
2357
|
-
|
|
2479
|
+
const rayDir = this._v3_1.clone().normalize(); //unprojected ray direction
|
|
2358
2480
|
|
|
2359
|
-
|
|
2360
|
-
|
|
2481
|
+
// camera
|
|
2482
|
+
// |\
|
|
2483
|
+
// | \
|
|
2484
|
+
// | \
|
|
2485
|
+
// h | \
|
|
2486
|
+
// | \
|
|
2487
|
+
// | \
|
|
2488
|
+
// _ _ | _ _ _\ _ _ near plane
|
|
2489
|
+
// l
|
|
2361
2490
|
|
|
2362
|
-
|
|
2363
|
-
|
|
2491
|
+
const h = this._v3_1.z;
|
|
2492
|
+
const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
|
|
2493
|
+
let cameraGizmoDistance;
|
|
2364
2494
|
|
|
2365
|
-
|
|
2366
|
-
const self = this;
|
|
2367
|
-
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
2495
|
+
if ( initialDistance ) {
|
|
2368
2496
|
|
|
2369
|
-
|
|
2497
|
+
cameraGizmoDistance = this._v3_1.setFromMatrixPosition( this._cameraMatrixState0 ).distanceTo( this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ) );
|
|
2370
2498
|
|
|
2371
|
-
|
|
2499
|
+
} else {
|
|
2500
|
+
|
|
2501
|
+
cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position );
|
|
2372
2502
|
|
|
2373
2503
|
}
|
|
2374
2504
|
|
|
2375
|
-
|
|
2505
|
+
/*
|
|
2506
|
+
* calculate intersection point between unprojected ray and the plane
|
|
2507
|
+
*|y = mx + q
|
|
2508
|
+
*|y = 0
|
|
2509
|
+
*
|
|
2510
|
+
* x = -q/m
|
|
2511
|
+
*/
|
|
2512
|
+
if ( l == 0 ) {
|
|
2376
2513
|
|
|
2377
|
-
|
|
2514
|
+
//ray aligned with camera
|
|
2515
|
+
rayDir.set( 0, 0, 0 );
|
|
2516
|
+
return rayDir;
|
|
2378
2517
|
|
|
2379
|
-
|
|
2380
|
-
|
|
2518
|
+
}
|
|
2519
|
+
|
|
2520
|
+
const m = h / l;
|
|
2521
|
+
const q = cameraGizmoDistance;
|
|
2522
|
+
const x = - q / m;
|
|
2523
|
+
|
|
2524
|
+
const rayLength = Math.sqrt( Math.pow( q, 2 ) + Math.pow( x, 2 ) );
|
|
2525
|
+
rayDir.multiplyScalar( rayLength );
|
|
2526
|
+
rayDir.z = 0;
|
|
2527
|
+
return rayDir;
|
|
2381
2528
|
|
|
2382
2529
|
}
|
|
2383
2530
|
|
|
2384
|
-
}
|
|
2531
|
+
}
|
|
2385
2532
|
|
|
2386
2533
|
/**
|
|
2387
|
-
*
|
|
2388
|
-
* @param {Number} time Instant in which this function is called as performance.now()
|
|
2389
|
-
* @param {Vector3} rotationAxis Rotation axis
|
|
2390
|
-
* @param {number} w0 Initial angular velocity
|
|
2534
|
+
* Update camera and gizmos state
|
|
2391
2535
|
*/
|
|
2392
|
-
|
|
2536
|
+
updateMatrixState() {
|
|
2393
2537
|
|
|
2394
|
-
|
|
2538
|
+
//update camera and gizmos state
|
|
2539
|
+
this._cameraMatrixState.copy( this.camera.matrix );
|
|
2540
|
+
this._gizmoMatrixState.copy( this._gizmos.matrix );
|
|
2395
2541
|
|
|
2396
|
-
|
|
2397
|
-
this._anglePrev = 0;
|
|
2398
|
-
this._angleCurrent = 0;
|
|
2399
|
-
this._timeStart = time;
|
|
2542
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
2400
2543
|
|
|
2401
|
-
|
|
2544
|
+
this._cameraProjectionState.copy( this.camera.projectionMatrix );
|
|
2545
|
+
this.camera.updateProjectionMatrix();
|
|
2546
|
+
this._zoomState = this.camera.zoom;
|
|
2402
2547
|
|
|
2403
|
-
if ( this.
|
|
2548
|
+
} else if ( this.camera.isPerspectiveCamera ) {
|
|
2404
2549
|
|
|
2405
|
-
|
|
2406
|
-
const deltaTime = ( time - this._timeStart ) / 1000;
|
|
2407
|
-
const w = w0 + ( ( - this.dampingFactor ) * deltaTime );
|
|
2550
|
+
this._fovState = this.camera.fov;
|
|
2408
2551
|
|
|
2409
|
-
|
|
2552
|
+
}
|
|
2410
2553
|
|
|
2411
|
-
|
|
2412
|
-
this._angleCurrent = 0.5 * ( - this.dampingFactor ) * Math.pow( deltaTime, 2 ) + w0 * deltaTime + 0;
|
|
2413
|
-
this.applyTransformMatrix( this.rotate( rotationAxis, this._angleCurrent ) );
|
|
2414
|
-
this.dispatchEvent( _changeEvent );
|
|
2415
|
-
const self = this;
|
|
2416
|
-
this._animationId = window.requestAnimationFrame( function ( t ) {
|
|
2554
|
+
}
|
|
2417
2555
|
|
|
2418
|
-
|
|
2556
|
+
/**
|
|
2557
|
+
* Update the trackball FSA
|
|
2558
|
+
* @param {STATE} newState New state of the FSA
|
|
2559
|
+
* @param {Boolean} updateMatrices If matriices state should be updated
|
|
2560
|
+
*/
|
|
2561
|
+
updateTbState( newState, updateMatrices ) {
|
|
2419
2562
|
|
|
2420
|
-
|
|
2563
|
+
this._state = newState;
|
|
2564
|
+
if ( updateMatrices ) {
|
|
2421
2565
|
|
|
2422
|
-
|
|
2566
|
+
this.updateMatrixState();
|
|
2423
2567
|
|
|
2424
|
-
|
|
2425
|
-
this._timeStart = - 1;
|
|
2568
|
+
}
|
|
2426
2569
|
|
|
2427
|
-
|
|
2428
|
-
this.activateGizmos( false );
|
|
2570
|
+
}
|
|
2429
2571
|
|
|
2430
|
-
|
|
2572
|
+
update() {
|
|
2431
2573
|
|
|
2432
|
-
|
|
2574
|
+
const EPS = 0.000001;
|
|
2433
2575
|
|
|
2434
|
-
|
|
2576
|
+
if ( this.target.equals( this._currentTarget ) === false ) {
|
|
2435
2577
|
|
|
2436
|
-
//
|
|
2578
|
+
this._gizmos.position.copy( this.target ); //for correct radius calculation
|
|
2579
|
+
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
2580
|
+
this.makeGizmos( this.target, this._tbRadius );
|
|
2581
|
+
this._currentTarget.copy( this.target );
|
|
2437
2582
|
|
|
2438
|
-
|
|
2439
|
-
this._timeStart = - 1;
|
|
2583
|
+
}
|
|
2440
2584
|
|
|
2441
|
-
|
|
2585
|
+
//check min/max parameters
|
|
2586
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
2442
2587
|
|
|
2443
|
-
|
|
2444
|
-
|
|
2588
|
+
//check zoom
|
|
2589
|
+
if ( this.camera.zoom > this.maxZoom || this.camera.zoom < this.minZoom ) {
|
|
2590
|
+
|
|
2591
|
+
const newZoom = MathUtils.clamp( this.camera.zoom, this.minZoom, this.maxZoom );
|
|
2592
|
+
this.applyTransformMatrix( this.scale( newZoom / this.camera.zoom, this._gizmos.position, true ) );
|
|
2445
2593
|
|
|
2446
2594
|
}
|
|
2447
2595
|
|
|
2448
|
-
}
|
|
2596
|
+
} else if ( this.camera.isPerspectiveCamera ) {
|
|
2449
2597
|
|
|
2450
|
-
|
|
2598
|
+
//check distance
|
|
2599
|
+
const distance = this.camera.position.distanceTo( this._gizmos.position );
|
|
2451
2600
|
|
|
2601
|
+
if ( distance > this.maxDistance + EPS || distance < this.minDistance - EPS ) {
|
|
2452
2602
|
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
* @param {Vector3} p1 Ending point
|
|
2457
|
-
* @param {Boolean} adjust If movement should be adjusted considering camera distance (Perspective only)
|
|
2458
|
-
*/
|
|
2459
|
-
pan = ( p0, p1, adjust = false ) => {
|
|
2603
|
+
const newDistance = MathUtils.clamp( distance, this.minDistance, this.maxDistance );
|
|
2604
|
+
this.applyTransformMatrix( this.scale( newDistance / distance, this._gizmos.position ) );
|
|
2605
|
+
this.updateMatrixState();
|
|
2460
2606
|
|
|
2461
|
-
|
|
2607
|
+
}
|
|
2462
2608
|
|
|
2463
|
-
|
|
2609
|
+
//check fov
|
|
2610
|
+
if ( this.camera.fov < this.minFov || this.camera.fov > this.maxFov ) {
|
|
2464
2611
|
|
|
2465
|
-
|
|
2466
|
-
|
|
2612
|
+
this.camera.fov = MathUtils.clamp( this.camera.fov, this.minFov, this.maxFov );
|
|
2613
|
+
this.camera.updateProjectionMatrix();
|
|
2467
2614
|
|
|
2468
|
-
|
|
2615
|
+
}
|
|
2469
2616
|
|
|
2470
|
-
|
|
2471
|
-
this.
|
|
2472
|
-
this._v3_2.setFromMatrixPosition( this._gizmoMatrixState0 ); //gizmo's initial position
|
|
2473
|
-
const distanceFactor = this._v3_1.distanceTo( this._v3_2 ) / this.camera.position.distanceTo( this._gizmos.position );
|
|
2474
|
-
movement.multiplyScalar( 1 / distanceFactor );
|
|
2617
|
+
const oldRadius = this._tbRadius;
|
|
2618
|
+
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
2475
2619
|
|
|
2476
|
-
|
|
2620
|
+
if ( oldRadius < this._tbRadius - EPS || oldRadius > this._tbRadius + EPS ) {
|
|
2477
2621
|
|
|
2478
|
-
|
|
2622
|
+
const scale = ( this._gizmos.scale.x + this._gizmos.scale.y + this._gizmos.scale.z ) / 3;
|
|
2623
|
+
const newRadius = this._tbRadius / scale;
|
|
2624
|
+
const curve = new EllipseCurve( 0, 0, newRadius, newRadius );
|
|
2625
|
+
const points = curve.getPoints( this._curvePts );
|
|
2626
|
+
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
2479
2627
|
|
|
2480
|
-
|
|
2628
|
+
for ( const gizmo in this._gizmos.children ) {
|
|
2481
2629
|
|
|
2482
|
-
|
|
2483
|
-
return _transformation;
|
|
2630
|
+
this._gizmos.children[ gizmo ].geometry = curveGeometry;
|
|
2484
2631
|
|
|
2485
|
-
|
|
2632
|
+
}
|
|
2486
2633
|
|
|
2487
|
-
|
|
2488
|
-
* Reset trackball
|
|
2489
|
-
*/
|
|
2490
|
-
reset = () => {
|
|
2634
|
+
}
|
|
2491
2635
|
|
|
2492
|
-
|
|
2636
|
+
}
|
|
2493
2637
|
|
|
2494
|
-
|
|
2638
|
+
this.camera.lookAt( this._gizmos.position );
|
|
2495
2639
|
|
|
2496
|
-
|
|
2640
|
+
}
|
|
2497
2641
|
|
|
2498
|
-
|
|
2642
|
+
setStateFromJSON( json ) {
|
|
2499
2643
|
|
|
2500
|
-
|
|
2501
|
-
this.camera.far = this._farPos;
|
|
2502
|
-
this._cameraMatrixState.copy( this._cameraMatrixState0 );
|
|
2503
|
-
this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
2504
|
-
this.camera.up.copy( this._up0 );
|
|
2644
|
+
const state = JSON.parse( json );
|
|
2505
2645
|
|
|
2506
|
-
|
|
2507
|
-
this.camera.updateProjectionMatrix();
|
|
2646
|
+
if ( state.arcballState != undefined ) {
|
|
2508
2647
|
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
this._gizmos.updateMatrix();
|
|
2648
|
+
this._cameraMatrixState.fromArray( state.arcballState.cameraMatrix.elements );
|
|
2649
|
+
this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
2512
2650
|
|
|
2513
|
-
|
|
2514
|
-
|
|
2651
|
+
this.camera.up.copy( state.arcballState.cameraUp );
|
|
2652
|
+
this.camera.near = state.arcballState.cameraNear;
|
|
2653
|
+
this.camera.far = state.arcballState.cameraFar;
|
|
2515
2654
|
|
|
2516
|
-
|
|
2655
|
+
this.camera.zoom = state.arcballState.cameraZoom;
|
|
2517
2656
|
|
|
2518
|
-
|
|
2657
|
+
if ( this.camera.isPerspectiveCamera ) {
|
|
2519
2658
|
|
|
2520
|
-
|
|
2659
|
+
this.camera.fov = state.arcballState.cameraFov;
|
|
2521
2660
|
|
|
2522
|
-
|
|
2661
|
+
}
|
|
2523
2662
|
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
* @param {Vector3} axis Rotation axis
|
|
2527
|
-
* @param {number} angle Angle in radians
|
|
2528
|
-
* @returns {Object} Object with 'camera' field containing transformation matrix resulting from the operation to be applied to the camera
|
|
2529
|
-
*/
|
|
2530
|
-
rotate = ( axis, angle ) => {
|
|
2663
|
+
this._gizmoMatrixState.fromArray( state.arcballState.gizmoMatrix.elements );
|
|
2664
|
+
this._gizmoMatrixState.decompose( this._gizmos.position, this._gizmos.quaternion, this._gizmos.scale );
|
|
2531
2665
|
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
this._rotationMatrix.makeRotationAxis( axis, - angle );
|
|
2666
|
+
this.camera.updateMatrix();
|
|
2667
|
+
this.camera.updateProjectionMatrix();
|
|
2535
2668
|
|
|
2536
|
-
|
|
2537
|
-
this._m4_1.makeTranslation( point.x, point.y, point.z );
|
|
2538
|
-
this._m4_1.multiply( this._rotationMatrix );
|
|
2539
|
-
this._m4_1.multiply( this._translationMatrix );
|
|
2669
|
+
this._gizmos.updateMatrix();
|
|
2540
2670
|
|
|
2541
|
-
|
|
2671
|
+
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
2672
|
+
const gizmoTmp = new Matrix4().copy( this._gizmoMatrixState0 );
|
|
2673
|
+
this.makeGizmos( this._gizmos.position, this._tbRadius );
|
|
2674
|
+
this._gizmoMatrixState0.copy( gizmoTmp );
|
|
2542
2675
|
|
|
2543
|
-
|
|
2676
|
+
this.camera.lookAt( this._gizmos.position );
|
|
2677
|
+
this.updateTbState( STATE.IDLE, false );
|
|
2544
2678
|
|
|
2545
|
-
|
|
2679
|
+
this.dispatchEvent( _changeEvent );
|
|
2546
2680
|
|
|
2547
|
-
|
|
2681
|
+
}
|
|
2548
2682
|
|
|
2549
|
-
|
|
2550
|
-
if ( this.camera.isOrthographicCamera ) {
|
|
2683
|
+
}
|
|
2551
2684
|
|
|
2552
|
-
|
|
2685
|
+
}
|
|
2553
2686
|
|
|
2554
|
-
|
|
2555
|
-
cameraMatrix: this.camera.matrix,
|
|
2556
|
-
cameraNear: this.camera.near,
|
|
2557
|
-
cameraUp: this.camera.up,
|
|
2558
|
-
cameraZoom: this.camera.zoom,
|
|
2559
|
-
gizmoMatrix: this._gizmos.matrix
|
|
2687
|
+
//listeners
|
|
2560
2688
|
|
|
2561
|
-
|
|
2689
|
+
function onWindowResize() {
|
|
2562
2690
|
|
|
2563
|
-
|
|
2691
|
+
const scale = ( this._gizmos.scale.x + this._gizmos.scale.y + this._gizmos.scale.z ) / 3;
|
|
2692
|
+
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
2564
2693
|
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
cameraNear: this.camera.near,
|
|
2570
|
-
cameraUp: this.camera.up,
|
|
2571
|
-
cameraZoom: this.camera.zoom,
|
|
2572
|
-
gizmoMatrix: this._gizmos.matrix
|
|
2694
|
+
const newRadius = this._tbRadius / scale;
|
|
2695
|
+
const curve = new EllipseCurve( 0, 0, newRadius, newRadius );
|
|
2696
|
+
const points = curve.getPoints( this._curvePts );
|
|
2697
|
+
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
2573
2698
|
|
|
2574
|
-
} } );
|
|
2575
2699
|
|
|
2576
|
-
|
|
2700
|
+
for ( const gizmo in this._gizmos.children ) {
|
|
2577
2701
|
|
|
2578
|
-
|
|
2702
|
+
this._gizmos.children[ gizmo ].geometry = curveGeometry;
|
|
2579
2703
|
|
|
2580
|
-
}
|
|
2704
|
+
}
|
|
2581
2705
|
|
|
2582
|
-
|
|
2706
|
+
this.dispatchEvent( _changeEvent );
|
|
2583
2707
|
|
|
2584
|
-
|
|
2585
|
-
navigator.clipboard.readText().then( function resolved( value ) {
|
|
2708
|
+
}
|
|
2586
2709
|
|
|
2587
|
-
|
|
2710
|
+
function onContextMenu( event ) {
|
|
2588
2711
|
|
|
2589
|
-
|
|
2712
|
+
if ( ! this.enabled ) {
|
|
2590
2713
|
|
|
2591
|
-
|
|
2714
|
+
return;
|
|
2592
2715
|
|
|
2593
|
-
|
|
2594
|
-
* Save the current state of the control. This can later be recover with .reset
|
|
2595
|
-
*/
|
|
2596
|
-
saveState = () => {
|
|
2716
|
+
}
|
|
2597
2717
|
|
|
2598
|
-
|
|
2599
|
-
this._gizmoMatrixState0.copy( this._gizmos.matrix );
|
|
2600
|
-
this._nearPos = this.camera.near;
|
|
2601
|
-
this._farPos = this.camera.far;
|
|
2602
|
-
this._zoom0 = this.camera.zoom;
|
|
2603
|
-
this._up0.copy( this.camera.up );
|
|
2718
|
+
for ( let i = 0; i < this.mouseActions.length; i ++ ) {
|
|
2604
2719
|
|
|
2605
|
-
if ( this.
|
|
2720
|
+
if ( this.mouseActions[ i ].mouse == 2 ) {
|
|
2606
2721
|
|
|
2607
|
-
|
|
2722
|
+
//prevent only if button 2 is actually used
|
|
2723
|
+
event.preventDefault();
|
|
2724
|
+
break;
|
|
2608
2725
|
|
|
2609
2726
|
}
|
|
2610
2727
|
|
|
2611
|
-
}
|
|
2728
|
+
}
|
|
2612
2729
|
|
|
2613
|
-
|
|
2614
|
-
* Perform uniform scale operation around a given point
|
|
2615
|
-
* @param {Number} size Scale factor
|
|
2616
|
-
* @param {Vector3} point Point around which scale
|
|
2617
|
-
* @param {Boolean} scaleGizmos If gizmos should be scaled (Perspective only)
|
|
2618
|
-
* @returns {Object} Object with 'camera' and 'gizmo' fields containing transformation matrices resulting from the operation to be applied to the camera and gizmos
|
|
2619
|
-
*/
|
|
2620
|
-
scale = ( size, point, scaleGizmos = true ) => {
|
|
2730
|
+
}
|
|
2621
2731
|
|
|
2622
|
-
|
|
2623
|
-
let sizeInverse = 1 / size;
|
|
2732
|
+
function onPointerCancel() {
|
|
2624
2733
|
|
|
2625
|
-
|
|
2734
|
+
this._touchStart.splice( 0, this._touchStart.length );
|
|
2735
|
+
this._touchCurrent.splice( 0, this._touchCurrent.length );
|
|
2736
|
+
this._input = INPUT.NONE;
|
|
2626
2737
|
|
|
2627
|
-
|
|
2628
|
-
this.camera.zoom = this._zoomState;
|
|
2629
|
-
this.camera.zoom *= size;
|
|
2738
|
+
}
|
|
2630
2739
|
|
|
2631
|
-
|
|
2632
|
-
if ( this.camera.zoom > this.maxZoom ) {
|
|
2740
|
+
function onPointerDown( event ) {
|
|
2633
2741
|
|
|
2634
|
-
|
|
2635
|
-
sizeInverse = this._zoomState / this.maxZoom;
|
|
2742
|
+
if ( event.button == 0 && event.isPrimary ) {
|
|
2636
2743
|
|
|
2637
|
-
|
|
2744
|
+
this._downValid = true;
|
|
2745
|
+
this._downEvents.push( event );
|
|
2746
|
+
this._downStart = performance.now();
|
|
2638
2747
|
|
|
2639
|
-
|
|
2640
|
-
sizeInverse = this._zoomState / this.minZoom;
|
|
2748
|
+
} else {
|
|
2641
2749
|
|
|
2642
|
-
|
|
2750
|
+
this._downValid = false;
|
|
2643
2751
|
|
|
2644
|
-
|
|
2752
|
+
}
|
|
2645
2753
|
|
|
2646
|
-
|
|
2754
|
+
if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) {
|
|
2647
2755
|
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
this._translationMatrix.makeTranslation( - this._v3_1.x, - this._v3_1.y, - this._v3_1.z );
|
|
2756
|
+
this._touchStart.push( event );
|
|
2757
|
+
this._touchCurrent.push( event );
|
|
2651
2758
|
|
|
2652
|
-
|
|
2653
|
-
this._m4_2.multiply( this._translationMatrix );
|
|
2759
|
+
switch ( this._input ) {
|
|
2654
2760
|
|
|
2761
|
+
case INPUT.NONE:
|
|
2655
2762
|
|
|
2656
|
-
|
|
2657
|
-
|
|
2763
|
+
//singleStart
|
|
2764
|
+
this._input = INPUT.ONE_FINGER;
|
|
2765
|
+
this.onSinglePanStart( event, 'ROTATE' );
|
|
2658
2766
|
|
|
2659
|
-
|
|
2660
|
-
|
|
2767
|
+
window.addEventListener( 'pointermove', this._onPointerMove );
|
|
2768
|
+
window.addEventListener( 'pointerup', this._onPointerUp );
|
|
2661
2769
|
|
|
2662
|
-
|
|
2663
|
-
this._m4_2.premultiply( this._m4_1 );
|
|
2770
|
+
break;
|
|
2664
2771
|
|
|
2665
|
-
|
|
2666
|
-
|
|
2772
|
+
case INPUT.ONE_FINGER:
|
|
2773
|
+
case INPUT.ONE_FINGER_SWITCHED:
|
|
2667
2774
|
|
|
2668
|
-
|
|
2775
|
+
//doubleStart
|
|
2776
|
+
this._input = INPUT.TWO_FINGER;
|
|
2669
2777
|
|
|
2670
|
-
|
|
2671
|
-
|
|
2778
|
+
this.onRotateStart();
|
|
2779
|
+
this.onPinchStart();
|
|
2780
|
+
this.onDoublePanStart();
|
|
2672
2781
|
|
|
2673
|
-
|
|
2674
|
-
let distance = this._v3_1.distanceTo( _scalePointTemp );
|
|
2675
|
-
let amount = distance - ( distance * sizeInverse );
|
|
2782
|
+
break;
|
|
2676
2783
|
|
|
2677
|
-
|
|
2678
|
-
const newDistance = distance - amount;
|
|
2679
|
-
if ( newDistance < this.minDistance ) {
|
|
2784
|
+
case INPUT.TWO_FINGER:
|
|
2680
2785
|
|
|
2681
|
-
|
|
2682
|
-
|
|
2786
|
+
//multipleStart
|
|
2787
|
+
this._input = INPUT.MULT_FINGER;
|
|
2788
|
+
this.onTriplePanStart( event );
|
|
2789
|
+
break;
|
|
2683
2790
|
|
|
2684
|
-
|
|
2791
|
+
}
|
|
2685
2792
|
|
|
2686
|
-
|
|
2687
|
-
amount = distance - ( distance * sizeInverse );
|
|
2793
|
+
} else if ( event.pointerType != 'touch' && this._input == INPUT.NONE ) {
|
|
2688
2794
|
|
|
2689
|
-
|
|
2795
|
+
let modifier = null;
|
|
2690
2796
|
|
|
2691
|
-
|
|
2797
|
+
if ( event.ctrlKey || event.metaKey ) {
|
|
2692
2798
|
|
|
2693
|
-
|
|
2799
|
+
modifier = 'CTRL';
|
|
2694
2800
|
|
|
2801
|
+
} else if ( event.shiftKey ) {
|
|
2695
2802
|
|
|
2696
|
-
|
|
2803
|
+
modifier = 'SHIFT';
|
|
2697
2804
|
|
|
2698
|
-
|
|
2699
|
-
const pos = this._v3_2;
|
|
2805
|
+
}
|
|
2700
2806
|
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
_offset.copy( _scalePointTemp ).sub( this._v3_2 ).normalize().multiplyScalar( amount );
|
|
2807
|
+
this._mouseOp = this.getOpFromAction( event.button, modifier );
|
|
2808
|
+
if ( this._mouseOp != null ) {
|
|
2704
2809
|
|
|
2705
|
-
|
|
2706
|
-
|
|
2810
|
+
window.addEventListener( 'pointermove', this._onPointerMove );
|
|
2811
|
+
window.addEventListener( 'pointerup', this._onPointerUp );
|
|
2707
2812
|
|
|
2708
|
-
|
|
2709
|
-
|
|
2813
|
+
//singleStart
|
|
2814
|
+
this._input = INPUT.CURSOR;
|
|
2815
|
+
this._button = event.button;
|
|
2816
|
+
this.onSinglePanStart( event, this._mouseOp );
|
|
2710
2817
|
|
|
2711
|
-
|
|
2818
|
+
}
|
|
2712
2819
|
|
|
2713
|
-
|
|
2714
|
-
this.setTransformationMatrices( this._m4_1, this._m4_2 );
|
|
2820
|
+
}
|
|
2715
2821
|
|
|
2822
|
+
}
|
|
2716
2823
|
|
|
2717
|
-
|
|
2824
|
+
function onPointerMove( event ) {
|
|
2718
2825
|
|
|
2719
|
-
|
|
2826
|
+
if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) {
|
|
2720
2827
|
|
|
2721
|
-
|
|
2828
|
+
switch ( this._input ) {
|
|
2722
2829
|
|
|
2723
|
-
|
|
2830
|
+
case INPUT.ONE_FINGER:
|
|
2724
2831
|
|
|
2725
|
-
|
|
2832
|
+
//singleMove
|
|
2833
|
+
this.updateTouchEvent( event );
|
|
2726
2834
|
|
|
2727
|
-
|
|
2835
|
+
this.onSinglePanMove( event, STATE.ROTATE );
|
|
2836
|
+
break;
|
|
2728
2837
|
|
|
2729
|
-
|
|
2730
|
-
* Set camera fov
|
|
2731
|
-
* @param {Number} value fov to be setted
|
|
2732
|
-
*/
|
|
2733
|
-
setFov = ( value ) => {
|
|
2838
|
+
case INPUT.ONE_FINGER_SWITCHED:
|
|
2734
2839
|
|
|
2735
|
-
|
|
2840
|
+
const movement = this.calculatePointersDistance( this._touchCurrent[ 0 ], event ) * this._devPxRatio;
|
|
2736
2841
|
|
|
2737
|
-
|
|
2738
|
-
this.camera.updateProjectionMatrix();
|
|
2842
|
+
if ( movement >= this._switchSensibility ) {
|
|
2739
2843
|
|
|
2740
|
-
|
|
2844
|
+
//singleMove
|
|
2845
|
+
this._input = INPUT.ONE_FINGER;
|
|
2846
|
+
this.updateTouchEvent( event );
|
|
2741
2847
|
|
|
2742
|
-
|
|
2848
|
+
this.onSinglePanStart( event, 'ROTATE' );
|
|
2849
|
+
break;
|
|
2743
2850
|
|
|
2744
|
-
|
|
2745
|
-
* Set values in transformation object
|
|
2746
|
-
* @param {Matrix4} camera Transformation to be applied to the camera
|
|
2747
|
-
* @param {Matrix4} gizmos Transformation to be applied to gizmos
|
|
2748
|
-
*/
|
|
2749
|
-
setTransformationMatrices( camera = null, gizmos = null ) {
|
|
2851
|
+
}
|
|
2750
2852
|
|
|
2751
|
-
|
|
2853
|
+
break;
|
|
2752
2854
|
|
|
2753
|
-
|
|
2855
|
+
case INPUT.TWO_FINGER:
|
|
2754
2856
|
|
|
2755
|
-
|
|
2857
|
+
//rotate/pan/pinchMove
|
|
2858
|
+
this.updateTouchEvent( event );
|
|
2756
2859
|
|
|
2757
|
-
|
|
2860
|
+
this.onRotateMove();
|
|
2861
|
+
this.onPinchMove();
|
|
2862
|
+
this.onDoublePanMove();
|
|
2758
2863
|
|
|
2759
|
-
|
|
2864
|
+
break;
|
|
2760
2865
|
|
|
2761
|
-
|
|
2866
|
+
case INPUT.MULT_FINGER:
|
|
2762
2867
|
|
|
2763
|
-
|
|
2868
|
+
//multMove
|
|
2869
|
+
this.updateTouchEvent( event );
|
|
2764
2870
|
|
|
2765
|
-
|
|
2871
|
+
this.onTriplePanMove( event );
|
|
2872
|
+
break;
|
|
2766
2873
|
|
|
2767
2874
|
}
|
|
2768
2875
|
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
if ( _transformation.gizmos != null ) {
|
|
2772
|
-
|
|
2773
|
-
_transformation.gizmos.copy( gizmos );
|
|
2876
|
+
} else if ( event.pointerType != 'touch' && this._input == INPUT.CURSOR ) {
|
|
2774
2877
|
|
|
2775
|
-
|
|
2878
|
+
let modifier = null;
|
|
2776
2879
|
|
|
2777
|
-
|
|
2880
|
+
if ( event.ctrlKey || event.metaKey ) {
|
|
2778
2881
|
|
|
2779
|
-
|
|
2882
|
+
modifier = 'CTRL';
|
|
2780
2883
|
|
|
2781
|
-
} else {
|
|
2884
|
+
} else if ( event.shiftKey ) {
|
|
2782
2885
|
|
|
2783
|
-
|
|
2886
|
+
modifier = 'SHIFT';
|
|
2784
2887
|
|
|
2785
2888
|
}
|
|
2786
2889
|
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
/**
|
|
2790
|
-
* Rotate camera around its direction axis passing by a given point by a given angle
|
|
2791
|
-
* @param {Vector3} point The point where the rotation axis is passing trough
|
|
2792
|
-
* @param {Number} angle Angle in radians
|
|
2793
|
-
* @returns The computed transormation matix
|
|
2794
|
-
*/
|
|
2795
|
-
zRotate = ( point, angle ) => {
|
|
2796
|
-
|
|
2797
|
-
this._rotationMatrix.makeRotationAxis( this._rotationAxis, angle );
|
|
2798
|
-
this._translationMatrix.makeTranslation( - point.x, - point.y, - point.z );
|
|
2890
|
+
const mouseOpState = this.getOpStateFromAction( this._button, modifier );
|
|
2799
2891
|
|
|
2800
|
-
|
|
2801
|
-
this._m4_1.multiply( this._rotationMatrix );
|
|
2802
|
-
this._m4_1.multiply( this._translationMatrix );
|
|
2892
|
+
if ( mouseOpState != null ) {
|
|
2803
2893
|
|
|
2804
|
-
|
|
2805
|
-
this._v3_2.copy( this._v3_1 ).applyAxisAngle( this._rotationAxis, angle ); //apply rotation
|
|
2806
|
-
this._v3_2.sub( this._v3_1 );
|
|
2894
|
+
this.onSinglePanMove( event, mouseOpState );
|
|
2807
2895
|
|
|
2808
|
-
|
|
2896
|
+
}
|
|
2809
2897
|
|
|
2810
|
-
|
|
2811
|
-
return _transformation;
|
|
2898
|
+
}
|
|
2812
2899
|
|
|
2813
|
-
|
|
2900
|
+
//checkDistance
|
|
2901
|
+
if ( this._downValid ) {
|
|
2814
2902
|
|
|
2903
|
+
const movement = this.calculatePointersDistance( this._downEvents[ this._downEvents.length - 1 ], event ) * this._devPxRatio;
|
|
2904
|
+
if ( movement > this._movementThreshold ) {
|
|
2815
2905
|
|
|
2816
|
-
|
|
2906
|
+
this._downValid = false;
|
|
2817
2907
|
|
|
2818
|
-
|
|
2908
|
+
}
|
|
2819
2909
|
|
|
2820
2910
|
}
|
|
2821
2911
|
|
|
2912
|
+
}
|
|
2822
2913
|
|
|
2823
|
-
|
|
2824
|
-
* Unproject the cursor on the 3D object surface
|
|
2825
|
-
* @param {Vector2} cursor Cursor coordinates in NDC
|
|
2826
|
-
* @param {Camera} camera Virtual camera
|
|
2827
|
-
* @returns {Vector3} The point of intersection with the model, if exist, null otherwise
|
|
2828
|
-
*/
|
|
2829
|
-
unprojectOnObj = ( cursor, camera ) => {
|
|
2914
|
+
function onPointerUp( event ) {
|
|
2830
2915
|
|
|
2831
|
-
|
|
2832
|
-
raycaster.near = camera.near;
|
|
2833
|
-
raycaster.far = camera.far;
|
|
2834
|
-
raycaster.setFromCamera( cursor, camera );
|
|
2916
|
+
if ( event.pointerType == 'touch' && this._input != INPUT.CURSOR ) {
|
|
2835
2917
|
|
|
2836
|
-
const
|
|
2918
|
+
const nTouch = this._touchCurrent.length;
|
|
2837
2919
|
|
|
2838
|
-
for ( let i = 0; i <
|
|
2920
|
+
for ( let i = 0; i < nTouch; i ++ ) {
|
|
2839
2921
|
|
|
2840
|
-
if (
|
|
2922
|
+
if ( this._touchCurrent[ i ].pointerId == event.pointerId ) {
|
|
2841
2923
|
|
|
2842
|
-
|
|
2924
|
+
this._touchCurrent.splice( i, 1 );
|
|
2925
|
+
this._touchStart.splice( i, 1 );
|
|
2926
|
+
break;
|
|
2843
2927
|
|
|
2844
2928
|
}
|
|
2845
2929
|
|
|
2846
2930
|
}
|
|
2847
2931
|
|
|
2848
|
-
|
|
2932
|
+
switch ( this._input ) {
|
|
2849
2933
|
|
|
2850
|
-
|
|
2934
|
+
case INPUT.ONE_FINGER:
|
|
2935
|
+
case INPUT.ONE_FINGER_SWITCHED:
|
|
2851
2936
|
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
* @param {Number} cursorX Cursor horizontal coordinate on screen
|
|
2856
|
-
* @param {Number} cursorY Cursor vertical coordinate on screen
|
|
2857
|
-
* @param {HTMLElement} canvas The canvas where the renderer draws its output
|
|
2858
|
-
* @param {number} tbRadius The trackball radius
|
|
2859
|
-
* @returns {Vector3} The unprojected point on the trackball surface
|
|
2860
|
-
*/
|
|
2861
|
-
unprojectOnTbSurface = ( camera, cursorX, cursorY, canvas, tbRadius ) => {
|
|
2937
|
+
//singleEnd
|
|
2938
|
+
window.removeEventListener( 'pointermove', this._onPointerMove );
|
|
2939
|
+
window.removeEventListener( 'pointerup', this._onPointerUp );
|
|
2862
2940
|
|
|
2863
|
-
|
|
2941
|
+
this._input = INPUT.NONE;
|
|
2942
|
+
this.onSinglePanEnd();
|
|
2864
2943
|
|
|
2865
|
-
|
|
2866
|
-
this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
|
|
2944
|
+
break;
|
|
2867
2945
|
|
|
2868
|
-
|
|
2869
|
-
const y2 = Math.pow( this._v2_1.y, 2 );
|
|
2870
|
-
const r2 = Math.pow( this._tbRadius, 2 );
|
|
2946
|
+
case INPUT.TWO_FINGER:
|
|
2871
2947
|
|
|
2872
|
-
|
|
2948
|
+
//doubleEnd
|
|
2949
|
+
this.onDoublePanEnd( event );
|
|
2950
|
+
this.onPinchEnd( event );
|
|
2951
|
+
this.onRotateEnd( event );
|
|
2873
2952
|
|
|
2874
|
-
//
|
|
2875
|
-
this.
|
|
2953
|
+
//switching to singleStart
|
|
2954
|
+
this._input = INPUT.ONE_FINGER_SWITCHED;
|
|
2876
2955
|
|
|
2877
|
-
|
|
2956
|
+
break;
|
|
2878
2957
|
|
|
2879
|
-
|
|
2880
|
-
|
|
2958
|
+
case INPUT.MULT_FINGER:
|
|
2959
|
+
|
|
2960
|
+
if ( this._touchCurrent.length == 0 ) {
|
|
2961
|
+
|
|
2962
|
+
window.removeEventListener( 'pointermove', this._onPointerMove );
|
|
2963
|
+
window.removeEventListener( 'pointerup', this._onPointerUp );
|
|
2964
|
+
|
|
2965
|
+
//multCancel
|
|
2966
|
+
this._input = INPUT.NONE;
|
|
2967
|
+
this.onTriplePanEnd();
|
|
2968
|
+
|
|
2969
|
+
}
|
|
2881
2970
|
|
|
2882
|
-
|
|
2971
|
+
break;
|
|
2883
2972
|
|
|
2884
|
-
|
|
2973
|
+
}
|
|
2885
2974
|
|
|
2886
|
-
|
|
2975
|
+
} else if ( event.pointerType != 'touch' && this._input == INPUT.CURSOR ) {
|
|
2887
2976
|
|
|
2888
|
-
|
|
2889
|
-
|
|
2977
|
+
window.removeEventListener( 'pointermove', this._onPointerMove );
|
|
2978
|
+
window.removeEventListener( 'pointerup', this._onPointerUp );
|
|
2890
2979
|
|
|
2891
|
-
|
|
2892
|
-
|
|
2980
|
+
this._input = INPUT.NONE;
|
|
2981
|
+
this.onSinglePanEnd();
|
|
2982
|
+
this._button = - 1;
|
|
2893
2983
|
|
|
2894
|
-
|
|
2895
|
-
const cameraGizmoDistance = camera.position.distanceTo( this._gizmos.position );
|
|
2896
|
-
const radius2 = Math.pow( tbRadius, 2 );
|
|
2984
|
+
}
|
|
2897
2985
|
|
|
2898
|
-
|
|
2899
|
-
// |\
|
|
2900
|
-
// | \
|
|
2901
|
-
// | \
|
|
2902
|
-
// h | \
|
|
2903
|
-
// | \
|
|
2904
|
-
// | \
|
|
2905
|
-
// _ _ | _ _ _\ _ _ near plane
|
|
2906
|
-
// l
|
|
2986
|
+
if ( event.isPrimary ) {
|
|
2907
2987
|
|
|
2908
|
-
|
|
2909
|
-
const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
|
|
2988
|
+
if ( this._downValid ) {
|
|
2910
2989
|
|
|
2911
|
-
|
|
2990
|
+
const downTime = event.timeStamp - this._downEvents[ this._downEvents.length - 1 ].timeStamp;
|
|
2912
2991
|
|
|
2913
|
-
|
|
2914
|
-
rayDir.set( this._v3_1.x, this._v3_1.y, tbRadius );
|
|
2915
|
-
return rayDir;
|
|
2992
|
+
if ( downTime <= this._maxDownTime ) {
|
|
2916
2993
|
|
|
2917
|
-
|
|
2994
|
+
if ( this._nclicks == 0 ) {
|
|
2918
2995
|
|
|
2919
|
-
|
|
2920
|
-
|
|
2996
|
+
//first valid click detected
|
|
2997
|
+
this._nclicks = 1;
|
|
2998
|
+
this._clickStart = performance.now();
|
|
2921
2999
|
|
|
2922
|
-
|
|
2923
|
-
* calculate intersection point between unprojected ray and trackball surface
|
|
2924
|
-
*|y = m * x + q
|
|
2925
|
-
*|x^2 + y^2 = r^2
|
|
2926
|
-
*
|
|
2927
|
-
* (m^2 + 1) * x^2 + (2 * m * q) * x + q^2 - r^2 = 0
|
|
2928
|
-
*/
|
|
2929
|
-
let a = Math.pow( m, 2 ) + 1;
|
|
2930
|
-
let b = 2 * m * q;
|
|
2931
|
-
let c = Math.pow( q, 2 ) - radius2;
|
|
2932
|
-
let delta = Math.pow( b, 2 ) - ( 4 * a * c );
|
|
3000
|
+
} else {
|
|
2933
3001
|
|
|
2934
|
-
|
|
3002
|
+
const clickInterval = event.timeStamp - this._clickStart;
|
|
3003
|
+
const movement = this.calculatePointersDistance( this._downEvents[ 1 ], this._downEvents[ 0 ] ) * this._devPxRatio;
|
|
2935
3004
|
|
|
2936
|
-
|
|
2937
|
-
this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
|
|
2938
|
-
this._v2_1.setY( m * this._v2_1.x + q );
|
|
3005
|
+
if ( clickInterval <= this._maxInterval && movement <= this._posThreshold ) {
|
|
2939
3006
|
|
|
2940
|
-
|
|
3007
|
+
//second valid click detected
|
|
3008
|
+
//fire double tap and reset values
|
|
3009
|
+
this._nclicks = 0;
|
|
3010
|
+
this._downEvents.splice( 0, this._downEvents.length );
|
|
3011
|
+
this.onDoubleTap( event );
|
|
2941
3012
|
|
|
2942
|
-
|
|
3013
|
+
} else {
|
|
2943
3014
|
|
|
2944
|
-
|
|
2945
|
-
|
|
3015
|
+
//new 'first click'
|
|
3016
|
+
this._nclicks = 1;
|
|
3017
|
+
this._downEvents.shift();
|
|
3018
|
+
this._clickStart = performance.now();
|
|
2946
3019
|
|
|
2947
|
-
|
|
2948
|
-
rayDir.multiplyScalar( rayLength );
|
|
2949
|
-
rayDir.z += cameraGizmoDistance;
|
|
2950
|
-
return rayDir;
|
|
3020
|
+
}
|
|
2951
3021
|
|
|
2952
3022
|
}
|
|
2953
3023
|
|
|
2954
|
-
}
|
|
3024
|
+
} else {
|
|
2955
3025
|
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
*|y = (1 / x) * (r^2 / 2)
|
|
2960
|
-
*
|
|
2961
|
-
* m * x^2 + q * x - r^2 / 2 = 0
|
|
2962
|
-
*/
|
|
3026
|
+
this._downValid = false;
|
|
3027
|
+
this._nclicks = 0;
|
|
3028
|
+
this._downEvents.splice( 0, this._downEvents.length );
|
|
2963
3029
|
|
|
2964
|
-
|
|
2965
|
-
b = q;
|
|
2966
|
-
c = - radius2 * 0.5;
|
|
2967
|
-
delta = Math.pow( b, 2 ) - ( 4 * a * c );
|
|
2968
|
-
this._v2_1.setX( ( - b - Math.sqrt( delta ) ) / ( 2 * a ) );
|
|
2969
|
-
this._v2_1.setY( m * this._v2_1.x + q );
|
|
3030
|
+
}
|
|
2970
3031
|
|
|
2971
|
-
|
|
3032
|
+
} else {
|
|
2972
3033
|
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
return rayDir;
|
|
3034
|
+
this._nclicks = 0;
|
|
3035
|
+
this._downEvents.splice( 0, this._downEvents.length );
|
|
2976
3036
|
|
|
2977
3037
|
}
|
|
2978
3038
|
|
|
2979
|
-
}
|
|
3039
|
+
}
|
|
2980
3040
|
|
|
3041
|
+
}
|
|
2981
3042
|
|
|
2982
|
-
|
|
2983
|
-
* Unproject the cursor on the plane passing through the center of the trackball orthogonal to the camera
|
|
2984
|
-
* @param {Camera} camera The virtual camera
|
|
2985
|
-
* @param {Number} cursorX Cursor horizontal coordinate on screen
|
|
2986
|
-
* @param {Number} cursorY Cursor vertical coordinate on screen
|
|
2987
|
-
* @param {HTMLElement} canvas The canvas where the renderer draws its output
|
|
2988
|
-
* @param {Boolean} initialDistance If initial distance between camera and gizmos should be used for calculations instead of current (Perspective only)
|
|
2989
|
-
* @returns {Vector3} The unprojected point on the trackball plane
|
|
2990
|
-
*/
|
|
2991
|
-
unprojectOnTbPlane = ( camera, cursorX, cursorY, canvas, initialDistance = false ) => {
|
|
3043
|
+
function onWheel( event ) {
|
|
2992
3044
|
|
|
2993
|
-
|
|
3045
|
+
if ( this.enabled && this.enableZoom ) {
|
|
2994
3046
|
|
|
2995
|
-
|
|
2996
|
-
this._v3_1.set( this._v2_1.x, this._v2_1.y, 0 );
|
|
3047
|
+
let modifier = null;
|
|
2997
3048
|
|
|
2998
|
-
|
|
3049
|
+
if ( event.ctrlKey || event.metaKey ) {
|
|
2999
3050
|
|
|
3000
|
-
|
|
3051
|
+
modifier = 'CTRL';
|
|
3001
3052
|
|
|
3002
|
-
|
|
3053
|
+
} else if ( event.shiftKey ) {
|
|
3003
3054
|
|
|
3004
|
-
|
|
3005
|
-
this._v3_1.set( this._v2_1.x, this._v2_1.y, - 1 );
|
|
3006
|
-
this._v3_1.applyMatrix4( camera.projectionMatrixInverse );
|
|
3055
|
+
modifier = 'SHIFT';
|
|
3007
3056
|
|
|
3008
|
-
|
|
3057
|
+
}
|
|
3009
3058
|
|
|
3010
|
-
|
|
3011
|
-
// |\
|
|
3012
|
-
// | \
|
|
3013
|
-
// | \
|
|
3014
|
-
// h | \
|
|
3015
|
-
// | \
|
|
3016
|
-
// | \
|
|
3017
|
-
// _ _ | _ _ _\ _ _ near plane
|
|
3018
|
-
// l
|
|
3059
|
+
const mouseOp = this.getOpFromAction( 'WHEEL', modifier );
|
|
3019
3060
|
|
|
3020
|
-
|
|
3021
|
-
const l = Math.sqrt( Math.pow( this._v3_1.x, 2 ) + Math.pow( this._v3_1.y, 2 ) );
|
|
3022
|
-
let cameraGizmoDistance;
|
|
3061
|
+
if ( mouseOp != null ) {
|
|
3023
3062
|
|
|
3024
|
-
|
|
3063
|
+
event.preventDefault();
|
|
3064
|
+
this.dispatchEvent( _startEvent );
|
|
3025
3065
|
|
|
3026
|
-
|
|
3066
|
+
const notchDeltaY = 125; //distance of one notch of mouse wheel
|
|
3067
|
+
let sgn = event.deltaY / notchDeltaY;
|
|
3027
3068
|
|
|
3028
|
-
|
|
3069
|
+
let size = 1;
|
|
3029
3070
|
|
|
3030
|
-
|
|
3071
|
+
if ( sgn > 0 ) {
|
|
3031
3072
|
|
|
3032
|
-
|
|
3073
|
+
size = 1 / this.scaleFactor;
|
|
3033
3074
|
|
|
3034
|
-
|
|
3035
|
-
* calculate intersection point between unprojected ray and the plane
|
|
3036
|
-
*|y = mx + q
|
|
3037
|
-
*|y = 0
|
|
3038
|
-
*
|
|
3039
|
-
* x = -q/m
|
|
3040
|
-
*/
|
|
3041
|
-
if ( l == 0 ) {
|
|
3075
|
+
} else if ( sgn < 0 ) {
|
|
3042
3076
|
|
|
3043
|
-
|
|
3044
|
-
rayDir.set( 0, 0, 0 );
|
|
3045
|
-
return rayDir;
|
|
3077
|
+
size = this.scaleFactor;
|
|
3046
3078
|
|
|
3047
3079
|
}
|
|
3048
3080
|
|
|
3049
|
-
|
|
3050
|
-
const q = cameraGizmoDistance;
|
|
3051
|
-
const x = - q / m;
|
|
3081
|
+
switch ( mouseOp ) {
|
|
3052
3082
|
|
|
3053
|
-
|
|
3054
|
-
rayDir.multiplyScalar( rayLength );
|
|
3055
|
-
rayDir.z = 0;
|
|
3056
|
-
return rayDir;
|
|
3083
|
+
case 'ZOOM':
|
|
3057
3084
|
|
|
3058
|
-
|
|
3085
|
+
this.updateTbState( STATE.SCALE, true );
|
|
3059
3086
|
|
|
3060
|
-
|
|
3087
|
+
if ( sgn > 0 ) {
|
|
3061
3088
|
|
|
3062
|
-
|
|
3063
|
-
* Update camera and gizmos state
|
|
3064
|
-
*/
|
|
3065
|
-
updateMatrixState = () => {
|
|
3089
|
+
size = 1 / ( Math.pow( this.scaleFactor, sgn ) );
|
|
3066
3090
|
|
|
3067
|
-
|
|
3068
|
-
this._cameraMatrixState.copy( this.camera.matrix );
|
|
3069
|
-
this._gizmoMatrixState.copy( this._gizmos.matrix );
|
|
3091
|
+
} else if ( sgn < 0 ) {
|
|
3070
3092
|
|
|
3071
|
-
|
|
3093
|
+
size = Math.pow( this.scaleFactor, - sgn );
|
|
3072
3094
|
|
|
3073
|
-
|
|
3074
|
-
this.camera.updateProjectionMatrix();
|
|
3075
|
-
this._zoomState = this.camera.zoom;
|
|
3095
|
+
}
|
|
3076
3096
|
|
|
3077
|
-
|
|
3097
|
+
if ( this.cursorZoom && this.enablePan ) {
|
|
3078
3098
|
|
|
3079
|
-
|
|
3099
|
+
let scalePoint;
|
|
3080
3100
|
|
|
3081
|
-
|
|
3101
|
+
if ( this.camera.isOrthographicCamera ) {
|
|
3082
3102
|
|
|
3083
|
-
|
|
3103
|
+
scalePoint = this.unprojectOnTbPlane( this.camera, event.clientX, event.clientY, this.domElement ).applyQuaternion( this.camera.quaternion ).multiplyScalar( 1 / this.camera.zoom ).add( this._gizmos.position );
|
|
3084
3104
|
|
|
3085
|
-
|
|
3086
|
-
* Update the trackball FSA
|
|
3087
|
-
* @param {STATE} newState New state of the FSA
|
|
3088
|
-
* @param {Boolean} updateMatrices If matriices state should be updated
|
|
3089
|
-
*/
|
|
3090
|
-
updateTbState = ( newState, updateMatrices ) => {
|
|
3105
|
+
} else if ( this.camera.isPerspectiveCamera ) {
|
|
3091
3106
|
|
|
3092
|
-
|
|
3093
|
-
if ( updateMatrices ) {
|
|
3107
|
+
scalePoint = this.unprojectOnTbPlane( this.camera, event.clientX, event.clientY, this.domElement ).applyQuaternion( this.camera.quaternion ).add( this._gizmos.position );
|
|
3094
3108
|
|
|
3095
|
-
|
|
3109
|
+
}
|
|
3096
3110
|
|
|
3097
|
-
|
|
3111
|
+
this.applyTransformMatrix( this.scale( size, scalePoint ) );
|
|
3098
3112
|
|
|
3099
|
-
|
|
3113
|
+
} else {
|
|
3100
3114
|
|
|
3101
|
-
|
|
3115
|
+
this.applyTransformMatrix( this.scale( size, this._gizmos.position ) );
|
|
3102
3116
|
|
|
3103
|
-
|
|
3117
|
+
}
|
|
3104
3118
|
|
|
3105
|
-
|
|
3119
|
+
if ( this._grid != null ) {
|
|
3106
3120
|
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
this.makeGizmos( this.target, this._tbRadius );
|
|
3110
|
-
this._currentTarget.copy( this.target );
|
|
3121
|
+
this.disposeGrid();
|
|
3122
|
+
this.drawGrid();
|
|
3111
3123
|
|
|
3112
|
-
|
|
3124
|
+
}
|
|
3113
3125
|
|
|
3114
|
-
|
|
3115
|
-
if ( this.camera.isOrthographicCamera ) {
|
|
3126
|
+
this.updateTbState( STATE.IDLE, false );
|
|
3116
3127
|
|
|
3117
|
-
|
|
3118
|
-
|
|
3128
|
+
this.dispatchEvent( _changeEvent );
|
|
3129
|
+
this.dispatchEvent( _endEvent );
|
|
3119
3130
|
|
|
3120
|
-
|
|
3121
|
-
this.applyTransformMatrix( this.scale( newZoom / this.camera.zoom, this._gizmos.position, true ) );
|
|
3131
|
+
break;
|
|
3122
3132
|
|
|
3123
|
-
|
|
3133
|
+
case 'FOV':
|
|
3124
3134
|
|
|
3125
|
-
|
|
3135
|
+
if ( this.camera.isPerspectiveCamera ) {
|
|
3126
3136
|
|
|
3127
|
-
|
|
3128
|
-
const distance = this.camera.position.distanceTo( this._gizmos.position );
|
|
3137
|
+
this.updateTbState( STATE.FOV, true );
|
|
3129
3138
|
|
|
3130
|
-
if ( distance > this.maxDistance + EPS || distance < this.minDistance - EPS ) {
|
|
3131
3139
|
|
|
3132
|
-
|
|
3133
|
-
this.applyTransformMatrix( this.scale( newDistance / distance, this._gizmos.position ) );
|
|
3134
|
-
this.updateMatrixState();
|
|
3140
|
+
//Vertigo effect
|
|
3135
3141
|
|
|
3136
|
-
|
|
3142
|
+
// fov / 2
|
|
3143
|
+
// |\
|
|
3144
|
+
// | \
|
|
3145
|
+
// | \
|
|
3146
|
+
// x | \
|
|
3147
|
+
// | \
|
|
3148
|
+
// | \
|
|
3149
|
+
// | _ _ _\
|
|
3150
|
+
// y
|
|
3137
3151
|
|
|
3138
|
-
|
|
3139
|
-
|
|
3152
|
+
//check for iOs shift shortcut
|
|
3153
|
+
if ( event.deltaX != 0 ) {
|
|
3140
3154
|
|
|
3141
|
-
|
|
3142
|
-
this.camera.updateProjectionMatrix();
|
|
3155
|
+
sgn = event.deltaX / notchDeltaY;
|
|
3143
3156
|
|
|
3144
|
-
|
|
3157
|
+
size = 1;
|
|
3145
3158
|
|
|
3146
|
-
|
|
3147
|
-
this._tbRadius = this.calculateTbRadius( this.camera );
|
|
3159
|
+
if ( sgn > 0 ) {
|
|
3148
3160
|
|
|
3149
|
-
|
|
3161
|
+
size = 1 / ( Math.pow( this.scaleFactor, sgn ) );
|
|
3150
3162
|
|
|
3151
|
-
|
|
3152
|
-
const newRadius = this._tbRadius / scale;
|
|
3153
|
-
const curve = new EllipseCurve( 0, 0, newRadius, newRadius );
|
|
3154
|
-
const points = curve.getPoints( this._curvePts );
|
|
3155
|
-
const curveGeometry = new BufferGeometry().setFromPoints( points );
|
|
3163
|
+
} else if ( sgn < 0 ) {
|
|
3156
3164
|
|
|
3157
|
-
|
|
3165
|
+
size = Math.pow( this.scaleFactor, - sgn );
|
|
3158
3166
|
|
|
3159
|
-
|
|
3167
|
+
}
|
|
3160
3168
|
|
|
3161
|
-
|
|
3169
|
+
}
|
|
3162
3170
|
|
|
3163
|
-
|
|
3171
|
+
this._v3_1.setFromMatrixPosition( this._cameraMatrixState );
|
|
3172
|
+
const x = this._v3_1.distanceTo( this._gizmos.position );
|
|
3173
|
+
let xNew = x / size; //distance between camera and gizmos if scale(size, scalepoint) would be performed
|
|
3164
3174
|
|
|
3165
|
-
|
|
3175
|
+
//check min and max distance
|
|
3176
|
+
xNew = MathUtils.clamp( xNew, this.minDistance, this.maxDistance );
|
|
3166
3177
|
|
|
3167
|
-
|
|
3178
|
+
const y = x * Math.tan( MathUtils.DEG2RAD * this.camera.fov * 0.5 );
|
|
3168
3179
|
|
|
3169
|
-
|
|
3180
|
+
//calculate new fov
|
|
3181
|
+
let newFov = MathUtils.RAD2DEG * ( Math.atan( y / xNew ) * 2 );
|
|
3170
3182
|
|
|
3171
|
-
|
|
3183
|
+
//check min and max fov
|
|
3184
|
+
if ( newFov > this.maxFov ) {
|
|
3172
3185
|
|
|
3173
|
-
|
|
3186
|
+
newFov = this.maxFov;
|
|
3174
3187
|
|
|
3175
|
-
|
|
3188
|
+
} else if ( newFov < this.minFov ) {
|
|
3176
3189
|
|
|
3177
|
-
|
|
3178
|
-
this._cameraMatrixState.decompose( this.camera.position, this.camera.quaternion, this.camera.scale );
|
|
3190
|
+
newFov = this.minFov;
|
|
3179
3191
|
|
|
3180
|
-
|
|
3181
|
-
this.camera.near = state.arcballState.cameraNear;
|
|
3182
|
-
this.camera.far = state.arcballState.cameraFar;
|
|
3192
|
+
}
|
|
3183
3193
|
|
|
3184
|
-
|
|
3194
|
+
const newDistance = y / Math.tan( MathUtils.DEG2RAD * ( newFov / 2 ) );
|
|
3195
|
+
size = x / newDistance;
|
|
3185
3196
|
|
|
3186
|
-
|
|
3197
|
+
this.setFov( newFov );
|
|
3198
|
+
this.applyTransformMatrix( this.scale( size, this._gizmos.position, false ) );
|
|
3187
3199
|
|
|
3188
|
-
|
|
3200
|
+
}
|
|
3189
3201
|
|
|
3190
|
-
|
|
3202
|
+
if ( this._grid != null ) {
|
|
3191
3203
|
|
|
3192
|
-
|
|
3193
|
-
|
|
3204
|
+
this.disposeGrid();
|
|
3205
|
+
this.drawGrid();
|
|
3194
3206
|
|
|
3195
|
-
|
|
3196
|
-
this.camera.updateProjectionMatrix();
|
|
3207
|
+
}
|
|
3197
3208
|
|
|
3198
|
-
|
|
3209
|
+
this.updateTbState( STATE.IDLE, false );
|
|
3199
3210
|
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
this.makeGizmos( this._gizmos.position, this._tbRadius );
|
|
3203
|
-
this._gizmoMatrixState0.copy( gizmoTmp );
|
|
3211
|
+
this.dispatchEvent( _changeEvent );
|
|
3212
|
+
this.dispatchEvent( _endEvent );
|
|
3204
3213
|
|
|
3205
|
-
|
|
3206
|
-
this.updateTbState( STATE.IDLE, false );
|
|
3214
|
+
break;
|
|
3207
3215
|
|
|
3208
|
-
|
|
3216
|
+
}
|
|
3209
3217
|
|
|
3210
3218
|
}
|
|
3211
3219
|
|
|
3212
|
-
}
|
|
3220
|
+
}
|
|
3213
3221
|
|
|
3214
3222
|
}
|
|
3215
3223
|
|