simview 4.2.0__tar.gz → 4.2.1__tar.gz
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.
- {simview-4.2.0/simview.egg-info → simview-4.2.1}/PKG-INFO +1 -1
- {simview-4.2.0 → simview-4.2.1}/pyproject.toml +1 -1
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/SimView.js +18 -5
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/components/Scene.js +18 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/config.js +9 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/objects/Body.js +43 -3
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/BodyStateWindow.js +6 -1
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/Controls.js +46 -7
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/ScalarPlotter.js +35 -3
- simview-4.2.1/simview/static/js/utils/cameraRange.js +37 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/viewState.js +6 -0
- {simview-4.2.0 → simview-4.2.1/simview.egg-info}/PKG-INFO +1 -1
- {simview-4.2.0 → simview-4.2.1}/simview.egg-info/SOURCES.txt +1 -0
- {simview-4.2.0 → simview-4.2.1}/LICENSE +0 -0
- {simview-4.2.0 → simview-4.2.1}/MANIFEST.in +0 -0
- {simview-4.2.0 → simview-4.2.1}/README.md +0 -0
- {simview-4.2.0 → simview-4.2.1}/setup.cfg +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/__init__.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/__main__.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/columnar.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/diff.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/info.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/launcher.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/live.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/merge.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/model.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/py.typed +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/remote.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/render.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/scene.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/server.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/state.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/css/controls.css +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/components/AnimationController.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/components/BatchManager.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/components/InteractionController.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/components/InteractionControls.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/components/StateStore.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/components/WindowedField.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/main.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/objects/StaticObject.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/objects/Terrain.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/objects/colormap.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/objects/similarity.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/objects/utils.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/AnalysisPanel.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/BatchLegend.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/ErrorMetrics.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/Legend.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/PlaybackControls.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/ui/TerrainProfile.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/batchPresets.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/batchVisibility.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/blobCodec.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/blobWindow.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/bodyTransforms.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/csv.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/episodes.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/errorMath.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/injectStyles.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/interpolate.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/liveFollow.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/loadRecordingLibs.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/js/utils/terrainSample.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/index.min.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/Color.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/chroma.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/colors/colorbrewer.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/colors/w3cx11.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/generator/average.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/generator/bezier.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/generator/blend.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/generator/cubehelix.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/generator/mix.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/generator/random.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/generator/scale.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/_hsx.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hcg.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsi.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsl.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsv.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lab.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lch.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lrgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/num.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/oklab.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/oklch.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/interpolator/rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/cmyk2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/rgb2cmyk.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/css2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/hsl2css.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/lab2css.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/lch2css.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/oklab2css.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/oklch2css.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/css/rgb2css.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/gl/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/hcg2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/rgb2hcg.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hex/hex2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hex/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hex/rgb2hex.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/hsi2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/rgb2hsi.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/hsl2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/rgb2hsl.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/hsv2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/rgb2hsv.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/input.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lab/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lab/lab-constants.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lab/lab2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lab/rgb2lab.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lch/hcl2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lch/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lab2lch.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2lab.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/lch/rgb2lch.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/named/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/num/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/num/num2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/num/rgb2num.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/oklab2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/rgb2oklab.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/oklch2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/rgb2oklch.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/rgb/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/temp/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/temp/rgb2temperature.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/io/temp/temperature2rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/alpha.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/clipped.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/darken.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/get.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/luminance.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/mix.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/premultiply.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/saturate.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/set.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/ops/shade.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/analyze.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/clip_rgb.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/contrast.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/contrastAPCA.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/delta-e.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/distance.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/index.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/last.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/limit.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/multiply-matrices.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/scales.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/type.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/unpack.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/utils/valid.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/version.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/download.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/js-colormaps.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/tar.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/three-0.174.0/addons/controls/OrbitControls.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/three-0.174.0/addons/libs/lil-gui.module.min.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/three-0.174.0/three.core.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/three-0.174.0/three.module.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/uPlot.esm.js +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/lib/uPlot.min.css +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/textures/contacts/red-cross0.png +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/textures/points/ball0.png +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/static/textures/points/ball1.png +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/templates/index.html +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/terrain.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview/utils.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview.egg-info/dependency_links.txt +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview.egg-info/entry_points.txt +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview.egg-info/requires.txt +0 -0
- {simview-4.2.0 → simview-4.2.1}/simview.egg-info/top_level.txt +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_batch_selection.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_cli.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_columnar_ondisk.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_columnar_states.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_contacts.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_diff.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_episodes.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_info.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_launcher.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_live.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_merge.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_pointcloud_features.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_remote.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_roundtrip.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_scene.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_server.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_show.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_terrain.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_terrain_query.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_trajectory.py +0 -0
- {simview-4.2.0 → simview-4.2.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simview
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.1
|
|
4
4
|
Summary: THREE.js-based simulation visualization tool
|
|
5
5
|
Author-email: Jan Vlk <vlkjan6@fel.cvut.cz>, Ales Kucera <kuceral4@fel.cvut.cz>, David Korcak <david.korcak@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -383,6 +383,10 @@ export class SimView {
|
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
385
|
this.appendBodyHistories(0);
|
|
386
|
+
// Whether a point-cloud body is listed depends on whether it turned
|
|
387
|
+
// out to carry per-frame data, which is only knowable now that
|
|
388
|
+
// appendBodyHistories has run (see BodyStateWindow.updateBodyList).
|
|
389
|
+
if (this.bodyStateWindow) this.bodyStateWindow.updateBodyList();
|
|
386
390
|
if (this.errorMetrics) {
|
|
387
391
|
this.errorMetrics.onHistoryReady();
|
|
388
392
|
}
|
|
@@ -464,12 +468,18 @@ export class SimView {
|
|
|
464
468
|
this.batchManager = new BatchManager(this, model);
|
|
465
469
|
this.bodies = new Map();
|
|
466
470
|
|
|
467
|
-
// Auto-detect visualization mode
|
|
468
|
-
//
|
|
469
|
-
//
|
|
471
|
+
// Auto-detect visualization mode from the first body the mode
|
|
472
|
+
// actually governs: anything with a real surface
|
|
473
|
+
// (box/sphere/cylinder/mesh) defaults to mesh. Point clouds are
|
|
474
|
+
// skipped rather than inspected -- they're outside the mode
|
|
475
|
+
// entirely (see Body#pointsVisible), and model.bodies[0] being a
|
|
476
|
+
// cloud must not leave a scene full of meshes defaulting to a
|
|
477
|
+
// mode that renders none of them.
|
|
470
478
|
if (Array.isArray(model.bodies) && model.bodies.length > 0) {
|
|
471
|
-
const
|
|
472
|
-
|
|
479
|
+
const firstSolid = model.bodies.find(
|
|
480
|
+
(b) => b.shape && b.shape.type !== "pointcloud"
|
|
481
|
+
);
|
|
482
|
+
if (firstSolid) {
|
|
473
483
|
console.log("Auto-switching visualization mode to 'mesh' based on body type");
|
|
474
484
|
this.uiState.bodyVisualizationMode = "mesh";
|
|
475
485
|
}
|
|
@@ -498,6 +508,9 @@ export class SimView {
|
|
|
498
508
|
console.debug("Using terrain data");
|
|
499
509
|
this.terrain = new Terrain(model.terrain, this);
|
|
500
510
|
this.scene.addObject3D(this.terrain.getObject3D());
|
|
511
|
+
// Terrain extent is what tells us how far this scene reaches,
|
|
512
|
+
// so the camera's clipping/orbit range can stop being a guess.
|
|
513
|
+
this.scene.applySceneExtent(this.terrain.bounds);
|
|
501
514
|
} else {
|
|
502
515
|
throw new Error("Terrain data is missing in model");
|
|
503
516
|
}
|
|
@@ -4,8 +4,10 @@ import {
|
|
|
4
4
|
SCENE_CONFIG,
|
|
5
5
|
RENDERER_CONFIG,
|
|
6
6
|
CAMERA_CONFIG,
|
|
7
|
+
CONTROLS_CONFIG,
|
|
7
8
|
LIGHTING_CONFIG,
|
|
8
9
|
} from "../config.js";
|
|
10
|
+
import { cameraRangeForBounds } from "../utils/cameraRange.js";
|
|
9
11
|
|
|
10
12
|
export class Scene {
|
|
11
13
|
constructor(app) {
|
|
@@ -31,6 +33,22 @@ export class Scene {
|
|
|
31
33
|
this.setupWindowHandlers();
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
// Sizes the camera's far plane and the orbit distance limit to the scene
|
|
37
|
+
// actually being viewed. Called once the terrain is known (see
|
|
38
|
+
// SimView.initFromModel) -- the config defaults are floors chosen for
|
|
39
|
+
// small scenes, and a several-hundred-metre recording clips against them.
|
|
40
|
+
applySceneExtent(bounds) {
|
|
41
|
+
const { far, maxDistance } = cameraRangeForBounds(bounds, {
|
|
42
|
+
far: CAMERA_CONFIG.far,
|
|
43
|
+
maxDistance: CONTROLS_CONFIG.maxDistance,
|
|
44
|
+
});
|
|
45
|
+
if (this.camera && this.camera.far !== far) {
|
|
46
|
+
this.camera.far = far;
|
|
47
|
+
this.camera.updateProjectionMatrix();
|
|
48
|
+
}
|
|
49
|
+
if (this.controls) this.controls.maxDistance = maxDistance;
|
|
50
|
+
}
|
|
51
|
+
|
|
34
52
|
setupWindowHandlers() {
|
|
35
53
|
window.addEventListener("resize", () => this.#handleWindowResize());
|
|
36
54
|
window.addEventListener("error", (event) => this.#handleError(event));
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export const UI_DEFAULT_CONFIG = {
|
|
2
2
|
bodyVisualizationMode: "points",
|
|
3
|
+
// Point-cloud bodies sit outside Body Visualization Mode (a cloud isn't a
|
|
4
|
+
// way of drawing a body, it's the whole object), so they get their own
|
|
5
|
+
// visibility toggle -- see Body#pointsVisible.
|
|
6
|
+
pointCloudsVisible: true,
|
|
3
7
|
axesVisible: false,
|
|
4
8
|
trailsVisible: false,
|
|
5
9
|
smoothInterpolation: true,
|
|
@@ -31,6 +35,8 @@ export const FREQ_CONFIG = {
|
|
|
31
35
|
|
|
32
36
|
export const CONTROLS_CONFIG = {
|
|
33
37
|
minDistance: 1,
|
|
38
|
+
// Also a floor, widened alongside the far plane so the whole scene can
|
|
39
|
+
// actually be framed on a large map (see Scene.applySceneExtent).
|
|
34
40
|
maxDistance: 500,
|
|
35
41
|
enableDamping: false,
|
|
36
42
|
dampingFactor: 0.05,
|
|
@@ -58,6 +64,9 @@ export const RENDERER_CONFIG = {
|
|
|
58
64
|
export const CAMERA_CONFIG = {
|
|
59
65
|
fov: 40,
|
|
60
66
|
near: 0.1,
|
|
67
|
+
// A floor, not the final value: widened at load to span the terrain
|
|
68
|
+
// extent, so scenes hundreds of metres across don't clip their own
|
|
69
|
+
// terrain and bodies away (see Scene.applySceneExtent).
|
|
61
70
|
far: 500,
|
|
62
71
|
position: [-15, -15, 10],
|
|
63
72
|
up: [0, 0, 1],
|
|
@@ -86,6 +86,10 @@ export class Body {
|
|
|
86
86
|
this.bodyVectors = [];
|
|
87
87
|
this.contactPoints = [];
|
|
88
88
|
this.contactPointSizes = [];
|
|
89
|
+
// A point cloud is its own kind of object rather than a body drawn
|
|
90
|
+
// "as points", so it stays out of Body Visualization Mode entirely --
|
|
91
|
+
// "none" included -- and follows setPointCloudsVisible instead.
|
|
92
|
+
this.isPointCloud = bodyData.shape?.type === "pointcloud";
|
|
89
93
|
this.representations = { mesh: [], wireframe: [], points: [] };
|
|
90
94
|
this.createBatchGroups(bodyData);
|
|
91
95
|
|
|
@@ -356,8 +360,7 @@ export class Body {
|
|
|
356
360
|
if (this.batchGroups[i]) this.batchGroups[i].visible = visible;
|
|
357
361
|
const pointsRep = this.representations["points"];
|
|
358
362
|
if (Array.isArray(pointsRep) && pointsRep[i]) {
|
|
359
|
-
pointsRep[i].visible =
|
|
360
|
-
visible && this.app.uiState.bodyVisualizationMode === "points";
|
|
363
|
+
pointsRep[i].visible = visible && this.#pointsVisible();
|
|
361
364
|
}
|
|
362
365
|
if (this.contactPoints[i]) {
|
|
363
366
|
this.contactPoints[i].visible =
|
|
@@ -370,6 +373,26 @@ export class Body {
|
|
|
370
373
|
this.updateAllInstances();
|
|
371
374
|
}
|
|
372
375
|
|
|
376
|
+
// Should this body's points be on screen right now? A point-cloud body
|
|
377
|
+
// answers to its own "Show Point Clouds" toggle; every other body's
|
|
378
|
+
// points are one of its visualization modes, like mesh and wireframe.
|
|
379
|
+
#pointsVisible() {
|
|
380
|
+
return this.isPointCloud
|
|
381
|
+
? this.app.uiState.pointCloudsVisible !== false
|
|
382
|
+
: this.app.uiState.bodyVisualizationMode === "points";
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Applies the "Show Point Clouds" toggle. A no-op on bodies that aren't
|
|
386
|
+
// point clouds -- their points belong to the visualization mode instead.
|
|
387
|
+
setPointCloudsVisible(visible) {
|
|
388
|
+
if (!this.isPointCloud) return;
|
|
389
|
+
const pointsRep = this.representations["points"];
|
|
390
|
+
if (!Array.isArray(pointsRep)) return;
|
|
391
|
+
pointsRep.forEach((points, i) => {
|
|
392
|
+
if (points) points.visible = visible && this.#isBatchVisible(i);
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
373
396
|
#isBatchVisible(batchIndex) {
|
|
374
397
|
const batchManager = this.app.batchManager;
|
|
375
398
|
return batchManager?.isBatchVisible
|
|
@@ -415,7 +438,7 @@ export class Body {
|
|
|
415
438
|
this.pointColors
|
|
416
439
|
);
|
|
417
440
|
if (!points) return;
|
|
418
|
-
points.visible = this
|
|
441
|
+
points.visible = this.#pointsVisible();
|
|
419
442
|
// Lets InteractionController resolve a raycast hit back to this
|
|
420
443
|
// body/batch without a reverse lookup.
|
|
421
444
|
points.userData.bodyName = this.name;
|
|
@@ -463,6 +486,15 @@ export class Body {
|
|
|
463
486
|
|
|
464
487
|
const instancedMesh = new THREE.InstancedMesh(source, material, this.simBatches);
|
|
465
488
|
instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);
|
|
489
|
+
// Instances are placed by setMatrixAt (see updateInstanceMatrix),
|
|
490
|
+
// which leaves this object's own matrixWorld at identity. THREE
|
|
491
|
+
// computes an InstancedMesh's bounding sphere lazily on the first
|
|
492
|
+
// frustum test and then caches it forever -- instanceMatrix.needsUpdate
|
|
493
|
+
// does not invalidate it -- so bodies that travel away from wherever
|
|
494
|
+
// they started get culled wholesale once that stale sphere leaves the
|
|
495
|
+
// frustum. Skip the test rather than recomputing the sphere every
|
|
496
|
+
// frame across every batch; trails do the same for the same reason.
|
|
497
|
+
instancedMesh.frustumCulled = false;
|
|
466
498
|
instancedMesh.visible = this.app.uiState.bodyVisualizationMode === type;
|
|
467
499
|
instancedMesh.castShadow = (type === "mesh");
|
|
468
500
|
instancedMesh.receiveShadow = (type === "mesh");
|
|
@@ -696,6 +728,9 @@ export class Body {
|
|
|
696
728
|
|
|
697
729
|
updateVisualizationMode(mode) {
|
|
698
730
|
for (const [type, obj] of Object.entries(this.representations)) {
|
|
731
|
+
// A point cloud isn't one of the modes, so nothing the mode
|
|
732
|
+
// switch does -- including "none" -- should touch it.
|
|
733
|
+
if (type === "points" && this.isPointCloud) continue;
|
|
699
734
|
if (obj instanceof THREE.InstancedMesh) {
|
|
700
735
|
obj.visible = type === mode;
|
|
701
736
|
} else if (Array.isArray(obj)) {
|
|
@@ -804,7 +839,12 @@ export class Body {
|
|
|
804
839
|
|
|
805
840
|
// Which of the mesh/wireframe/points representations this body actually has,
|
|
806
841
|
// so the UI can only offer visualization modes that will show something.
|
|
842
|
+
// A point-cloud body reports none: its cloud is the object itself, not a
|
|
843
|
+
// way of drawing it, and it has its own toggle (see #pointsVisible). That
|
|
844
|
+
// keeps "points" out of the dropdown unless some body really does carry
|
|
845
|
+
// body-points, which is what made selecting it blank out every mesh body.
|
|
807
846
|
getAvailableVisualizationModes() {
|
|
847
|
+
if (this.isPointCloud) return [];
|
|
808
848
|
const modes = [];
|
|
809
849
|
for (const type of ["mesh", "wireframe", "points"]) {
|
|
810
850
|
const rep = this.representations[type];
|
|
@@ -310,7 +310,12 @@ export class BodyStateWindow {
|
|
|
310
310
|
const list = document.createElement("ul");
|
|
311
311
|
list.classList.add("body-list"); // Use CSS class
|
|
312
312
|
|
|
313
|
-
for (const name of this.app.bodies
|
|
313
|
+
for (const [name, body] of this.app.bodies) {
|
|
314
|
+
// A point cloud with no per-frame data is a static prop, not a
|
|
315
|
+
// body with a pose worth reading -- listing it only offers a
|
|
316
|
+
// permanently-zero Position/Rotation row. One that does move
|
|
317
|
+
// (validStates > 0) stays listed like any other body.
|
|
318
|
+
if (body.isPointCloud && !(body.validStates > 0)) continue;
|
|
314
319
|
const item = document.createElement("li");
|
|
315
320
|
item.classList.add("body-list-item"); // Use CSS class
|
|
316
321
|
item.textContent = name;
|
|
@@ -8,6 +8,7 @@ export class UIControls {
|
|
|
8
8
|
this.app = app;
|
|
9
9
|
this.attributeAvailability = this.determineAttributeAvailability();
|
|
10
10
|
this.visualizationModes = this.determineAvailableVisualizationModes();
|
|
11
|
+
this.hasPointClouds = this.determineHasPointClouds();
|
|
11
12
|
this.gui = this.createDatGUI();
|
|
12
13
|
this.keyboardControlsListener = null;
|
|
13
14
|
this.setupKeyboardControls(app);
|
|
@@ -44,15 +45,27 @@ export class UIControls {
|
|
|
44
45
|
|
|
45
46
|
// Union of visualization modes actually available across all bodies, plus a
|
|
46
47
|
// "none" option to hide bodies entirely (e.g. for terrain-only viewing).
|
|
48
|
+
// Point-cloud bodies contribute nothing and are unaffected by the mode --
|
|
49
|
+
// they have their own toggle -- so a scene of nothing but point clouds
|
|
50
|
+
// gets no mode control at all rather than a dropdown that only hides things.
|
|
47
51
|
determineAvailableVisualizationModes() {
|
|
48
52
|
const modes = new Set();
|
|
49
53
|
this.app.bodies.forEach((body) => {
|
|
50
54
|
body.getAvailableVisualizationModes().forEach((m) => modes.add(m));
|
|
51
55
|
});
|
|
56
|
+
if (modes.size === 0) return [];
|
|
52
57
|
modes.add("none");
|
|
53
58
|
return [...modes];
|
|
54
59
|
}
|
|
55
60
|
|
|
61
|
+
determineHasPointClouds() {
|
|
62
|
+
let found = false;
|
|
63
|
+
this.app.bodies.forEach((body) => {
|
|
64
|
+
if (body.isPointCloud) found = true;
|
|
65
|
+
});
|
|
66
|
+
return found;
|
|
67
|
+
}
|
|
68
|
+
|
|
56
69
|
changeTargetBatch(key) {
|
|
57
70
|
const { scene, batchManager } = this.app;
|
|
58
71
|
const currentBatchTarget = batchManager.currentlyActiveBatch;
|
|
@@ -98,7 +111,10 @@ export class UIControls {
|
|
|
98
111
|
// Only show body-related controls when there's actually a body to control
|
|
99
112
|
if (this.app.bodies && this.app.bodies.size > 0) {
|
|
100
113
|
let defaultVisualizationMode = this.app.uiState.bodyVisualizationMode;
|
|
101
|
-
if (
|
|
114
|
+
if (
|
|
115
|
+
this.visualizationModes.length > 0 &&
|
|
116
|
+
!this.visualizationModes.includes(defaultVisualizationMode)
|
|
117
|
+
) {
|
|
102
118
|
defaultVisualizationMode =
|
|
103
119
|
this.visualizationModes.find((m) => m !== "none") || "none";
|
|
104
120
|
this.app.uiState.bodyVisualizationMode = defaultVisualizationMode;
|
|
@@ -106,6 +122,7 @@ export class UIControls {
|
|
|
106
122
|
|
|
107
123
|
const controls = {
|
|
108
124
|
bodyVisualizationMode: defaultVisualizationMode,
|
|
125
|
+
showPointClouds: this.app.uiState.pointCloudsVisible !== false,
|
|
109
126
|
showAxes: this.app.uiState.axesVisible,
|
|
110
127
|
showTrails: this.app.uiState.trailsVisible,
|
|
111
128
|
smoothInterpolation: this.app.uiState.smoothInterpolation,
|
|
@@ -118,12 +135,24 @@ export class UIControls {
|
|
|
118
135
|
|
|
119
136
|
this.bodyFolder = this.gui.addFolder("Body Options");
|
|
120
137
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
138
|
+
// Nothing to switch between when every body is a point cloud.
|
|
139
|
+
if (this.visualizationModes.length > 0) {
|
|
140
|
+
this.bodyFolder
|
|
141
|
+
.add(controls, "bodyVisualizationMode", this.visualizationModes)
|
|
142
|
+
.name("Body Visualization Mode (B)")
|
|
143
|
+
.onChange((value) => {
|
|
144
|
+
this.updateVisualizationMode(value);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (this.hasPointClouds) {
|
|
149
|
+
this.bodyFolder
|
|
150
|
+
.add(controls, "showPointClouds")
|
|
151
|
+
.name("Show Point Clouds")
|
|
152
|
+
.onChange((value) => {
|
|
153
|
+
this.updatePointCloudsVisibility(value);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
127
156
|
|
|
128
157
|
this.bodyFolder
|
|
129
158
|
.add(controls, "showAxes")
|
|
@@ -629,6 +658,7 @@ export class UIControls {
|
|
|
629
658
|
switch (event.key.toLowerCase()) {
|
|
630
659
|
case "b":
|
|
631
660
|
const modes = this.visualizationModes;
|
|
661
|
+
if (modes.length === 0) break;
|
|
632
662
|
const currentIndex = modes.indexOf(
|
|
633
663
|
this.app.uiState.bodyVisualizationMode
|
|
634
664
|
);
|
|
@@ -710,6 +740,15 @@ export class UIControls {
|
|
|
710
740
|
this.app.uiState.bodyVisualizationMode = mode;
|
|
711
741
|
}
|
|
712
742
|
|
|
743
|
+
// Point-cloud bodies are outside Body Visualization Mode (see
|
|
744
|
+
// Body#pointsVisible), so their visibility rides on this instead.
|
|
745
|
+
updatePointCloudsVisibility(visible) {
|
|
746
|
+
this.app.uiState.pointCloudsVisible = visible;
|
|
747
|
+
this.app.bodies.forEach((body) => {
|
|
748
|
+
if (body.setPointCloudsVisible) body.setPointCloudsVisible(visible);
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
|
|
713
752
|
updateAxesVisibility(show) {
|
|
714
753
|
this.app.bodies.forEach((body) => {
|
|
715
754
|
body.toggleAxes(show);
|
|
@@ -391,6 +391,16 @@ export class ScalarPlotter {
|
|
|
391
391
|
);
|
|
392
392
|
}
|
|
393
393
|
|
|
394
|
+
// uPlot walks `incrs` and takes the first increment whose ticks fit the
|
|
395
|
+
// axis's available length. Offering exactly one (range/stepsPerYAxis) meant
|
|
396
|
+
// that in a short panel -- which is what the Analysis panel gives us -- no
|
|
397
|
+
// increment fit, and uPlot drew no ticks or labels at all. Coarser
|
|
398
|
+
// multiples let it degrade instead of giving up.
|
|
399
|
+
_yIncrements(min, max) {
|
|
400
|
+
const base = this.getChartInterval(min, max);
|
|
401
|
+
return [1, 2, 5, 10, 20, 50, 100].map((m) => base * m);
|
|
402
|
+
}
|
|
403
|
+
|
|
394
404
|
getChartInterval(min, max) {
|
|
395
405
|
const diff = max - min;
|
|
396
406
|
if (diff === 0)
|
|
@@ -419,6 +429,17 @@ export class ScalarPlotter {
|
|
|
419
429
|
return bestBatch;
|
|
420
430
|
}
|
|
421
431
|
|
|
432
|
+
// The x extent every chart's scale is pinned to: the whole timeline. Falls
|
|
433
|
+
// back to a unit span when there are no times, so uPlot is never handed
|
|
434
|
+
// NaN/undefined bounds.
|
|
435
|
+
_timeExtent() {
|
|
436
|
+
const n = this.times?.length ?? 0;
|
|
437
|
+
if (n === 0) return [0, 1];
|
|
438
|
+
const first = this.times[0];
|
|
439
|
+
const last = this.times[n - 1];
|
|
440
|
+
return last > first ? [first, last] : [first, first + 1];
|
|
441
|
+
}
|
|
442
|
+
|
|
422
443
|
_initializePlots() {
|
|
423
444
|
const limOffset = 1e-2;
|
|
424
445
|
this.scalarNames.forEach((name) => {
|
|
@@ -445,7 +466,15 @@ export class ScalarPlotter {
|
|
|
445
466
|
padding: [8, 8, 0, 8],
|
|
446
467
|
series,
|
|
447
468
|
scales: {
|
|
448
|
-
|
|
469
|
+
// uPlot treats a scale's `min`/`max` as outputs, not as
|
|
470
|
+
// a pin: the initial autoscale over the empty data
|
|
471
|
+
// passed below nulls them, and every later update goes
|
|
472
|
+
// through setData(data, false), which never revisits x.
|
|
473
|
+
// That left x null forever -- valToPos NaN, nothing
|
|
474
|
+
// drawn. `range` is the actual pin (the same thing
|
|
475
|
+
// ErrorMetrics does), and this axis is meant to span the
|
|
476
|
+
// whole timeline regardless, with the line growing into it.
|
|
477
|
+
x: { time: false, range: () => this._timeExtent() },
|
|
449
478
|
y: { min, max },
|
|
450
479
|
},
|
|
451
480
|
axes: [
|
|
@@ -463,7 +492,7 @@ export class ScalarPlotter {
|
|
|
463
492
|
ticks: { stroke: "rgb(73, 73, 73)" },
|
|
464
493
|
font: "12px Arial",
|
|
465
494
|
space: 30,
|
|
466
|
-
incrs:
|
|
495
|
+
incrs: this._yIncrements(min, max),
|
|
467
496
|
},
|
|
468
497
|
],
|
|
469
498
|
legend: { show: false },
|
|
@@ -667,7 +696,10 @@ export class ScalarPlotter {
|
|
|
667
696
|
}
|
|
668
697
|
|
|
669
698
|
if (!needRender) return;
|
|
670
|
-
|
|
699
|
+
// rebuildPaths must be true: the series data changes on every frame of
|
|
700
|
+
// playback, and redrawing without rebuilding just repaints the paths
|
|
701
|
+
// built for whatever data the chart first saw.
|
|
702
|
+
activeChart.redraw(true, true);
|
|
671
703
|
}
|
|
672
704
|
|
|
673
705
|
animate(now) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// How far the camera has to see, and how far out it may orbit, for a scene of
|
|
2
|
+
// a given horizontal extent. Pure arithmetic, no THREE/DOM, so it's unit
|
|
3
|
+
// testable on its own (see tests/js/cameraRange.test.js).
|
|
4
|
+
//
|
|
5
|
+
// The defaults in config.js are sized for the small scenes SimView started
|
|
6
|
+
// with (a few tens of metres). On a real recording -- a robot driving a few
|
|
7
|
+
// hundred metres across a mapped terrain -- a fixed 500 m far plane clips the
|
|
8
|
+
// terrain, and a fixed 500 m orbit limit means the whole run can never be
|
|
9
|
+
// framed at once. Both are treated as floors and widened from the terrain
|
|
10
|
+
// bounds instead.
|
|
11
|
+
|
|
12
|
+
// Framing a scene of diameter D at SimView's ~40 degree vertical FOV needs the
|
|
13
|
+
// camera roughly D / (2 * tan(fov/2)) ~= 1.4 * D away from the centre, so the
|
|
14
|
+
// orbit limit is 1.5 * D and the far plane covers that viewpoint plus the far
|
|
15
|
+
// side of the scene (2.5 * D), with a little margin on top.
|
|
16
|
+
const ORBIT_FACTOR = 1.5;
|
|
17
|
+
const FAR_FACTOR = 3;
|
|
18
|
+
|
|
19
|
+
export function cameraRangeForBounds(bounds, defaults = {}) {
|
|
20
|
+
const far = Number.isFinite(defaults.far) ? defaults.far : 0;
|
|
21
|
+
const maxDistance = Number.isFinite(defaults.maxDistance)
|
|
22
|
+
? defaults.maxDistance
|
|
23
|
+
: 0;
|
|
24
|
+
const fallback = { far, maxDistance };
|
|
25
|
+
|
|
26
|
+
if (!bounds || typeof bounds !== "object") return fallback;
|
|
27
|
+
const { minX, maxX, minY, maxY } = bounds;
|
|
28
|
+
if (![minX, maxX, minY, maxY].every((v) => Number.isFinite(v))) return fallback;
|
|
29
|
+
|
|
30
|
+
const diagonal = Math.hypot(maxX - minX, maxY - minY);
|
|
31
|
+
if (!(diagonal > 0)) return fallback;
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
far: Math.max(far, diagonal * FAR_FACTOR),
|
|
35
|
+
maxDistance: Math.max(maxDistance, diagonal * ORBIT_FACTOR),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -30,6 +30,12 @@ const BOOLEAN_FLAG_KEYS = [
|
|
|
30
30
|
"terrainVisualizationModes.normals",
|
|
31
31
|
];
|
|
32
32
|
|
|
33
|
+
// Deliberately NOT in the list above: `pointCloudsVisible`. Appending only
|
|
34
|
+
// works for flags that default off -- a link made before the flag existed has
|
|
35
|
+
// no bit for it, which decodes as false, so a default-on flag would arrive
|
|
36
|
+
// switched off and hide point clouds on every old link. Adding it needs a
|
|
37
|
+
// format version that can tell "absent" from "false".
|
|
38
|
+
|
|
33
39
|
function getPath(obj, path) {
|
|
34
40
|
return path.split(".").reduce((o, k) => (o && typeof o === "object" ? o[k] : undefined), obj);
|
|
35
41
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: simview
|
|
3
|
-
Version: 4.2.
|
|
3
|
+
Version: 4.2.1
|
|
4
4
|
Summary: THREE.js-based simulation visualization tool
|
|
5
5
|
Author-email: Jan Vlk <vlkjan6@fel.cvut.cz>, Ales Kucera <kuceral4@fel.cvut.cz>, David Korcak <david.korcak@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -56,6 +56,7 @@ simview/static/js/utils/batchVisibility.js
|
|
|
56
56
|
simview/static/js/utils/blobCodec.js
|
|
57
57
|
simview/static/js/utils/blobWindow.js
|
|
58
58
|
simview/static/js/utils/bodyTransforms.js
|
|
59
|
+
simview/static/js/utils/cameraRange.js
|
|
59
60
|
simview/static/js/utils/csv.js
|
|
60
61
|
simview/static/js/utils/episodes.js
|
|
61
62
|
simview/static/js/utils/errorMath.js
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{simview-4.2.0 → simview-4.2.1}/simview/static/lib/chroma-js-3.1.2/src/colors/colorbrewer.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|