forgecad 0.10.3 → 0.10.4
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/dist/assets/{AdminPage-CK7ObBz3.js → AdminPage-B3L3W1Uo.js} +1 -1
- package/dist/assets/{BenchmarkPage-Ds7Z2doN.js → BenchmarkPage-DXKVXMrJ.js} +2 -2
- package/dist/assets/{BlogPage-DlPbpt6A.js → BlogPage-B7BWxOCg.js} +1 -1
- package/dist/assets/{DocsPage-vZb3b3Y0.js → DocsPage-BPGGwht1.js} +28 -43
- package/dist/assets/{EditorApp-HLoKfe15.js → EditorApp-BWUGCdD5.js} +49 -16
- package/dist/assets/{EmbedViewer--KnqBKrJ.js → EmbedViewer-DygByZS2.js} +2 -2
- package/dist/assets/{LandingPageProofDriven-C_LssmnA.js → LandingPageProofDriven-BoVE7JGY.js} +54 -36
- package/dist/assets/{LegalPage-DGsyo4n1.js → LegalPage-Din8wv8d.js} +2 -2
- package/dist/assets/{PricingPage-BOE27B-R.js → PricingPage-C2PMzmDc.js} +2 -2
- package/dist/assets/{SettingsPage-f47cnk39.js → SettingsPage-BlJDCRe8.js} +1 -1
- package/dist/assets/{app-D6ccu2Xx.js → app-BsRYSfxY.js} +238 -3714
- package/dist/assets/{backendInit-DbTkQN9J.js → backendInit-6C0DLgH0.js} +5972 -1566
- package/dist/assets/cli/{render-BsngirjC.js → render-XXol_ET7.js} +724 -112
- package/dist/assets/{constructionHistoryWorker-PCwXrTDB.js → constructionHistoryWorker-cTHWRJEi.js} +528 -252
- package/dist/assets/{evalWorker-CS63PfZu.js → evalWorker-BssDYW9u.js} +1453 -902
- package/dist/assets/{inspectWorker-Y4cOzNyA.js → inspectWorker-ymhBV4Ll.js} +2635 -1024
- package/dist/assets/{jointPose-AMvCywzS.js → jointPose-B0blBj9A.js} +1 -1
- package/dist/assets/{landing-proof-driven-ORyigZ6p.css → landing-proof-driven-Cpf-MIbI.css} +73 -13
- package/dist/assets/{manifold-Crd_F2qx.js → manifold-B_7QXpGB.js} +1 -1
- package/dist/assets/{manifold-k2kRcc85.js → manifold-CNShmpEJ.js} +1 -1
- package/dist/assets/{manifold-CBry38ly.js → manifold-CYlIm-M6.js} +2 -2
- package/dist/assets/{reportWorker-CWvn0CEv.js → reportWorker-Cb5eyM7D.js} +1407 -892
- package/dist/cli/render.html +1 -1
- package/dist/docs/index.html +2 -2
- package/dist/docs-raw/AI/usage.md +17 -15
- package/dist/docs-raw/component-model.md +2 -2
- package/dist/docs-raw/generated/concepts.md +5 -1
- package/dist/docs-raw/generated/core.md +26 -0
- package/dist/docs-raw/generated/runtime-names.md +1 -1
- package/dist/docs-raw/guides/inspection-bundles.md +1 -1
- package/dist/docs-raw/simulation-workflow.md +1 -1
- package/dist/docs-raw/skills/{forgecad-make-a-model.md → forgecad-build-model.md} +18 -8
- package/dist/docs-raw/skills/{forgecad-spec-by-walking-through-it.md → forgecad-design-spec.md} +6 -6
- package/dist/docs-raw/skills/{forgecad-model-grader.md → forgecad-grade-model.md} +8 -6
- package/{dist-skill/website/skills/forgecad-visual-spec.md → dist/docs-raw/skills/forgecad-image-prompt.md} +7 -7
- package/dist/docs-raw/skills/{forgecad-render-inspect.md → forgecad-inspect-model.md} +6 -6
- package/{dist-skill/website/skills/forgecad-project.md → dist/docs-raw/skills/forgecad-project-sync.md} +5 -5
- package/dist/docs-raw/skills/{forgecad-3d-reconstruction.md → forgecad-reconstruct-cad-file.md} +7 -7
- package/dist/docs-raw/skills/{forgecad-image-replicator.md → forgecad-reconstruct-from-images.md} +12 -12
- package/dist/docs-raw/skills/{forgecad-mujoco-verify.md → forgecad-verify-mujoco.md} +6 -6
- package/dist/docs-raw/skills/index.md +9 -12
- package/dist/index.html +9 -9
- package/dist/llms.txt +7 -7
- package/dist/sitemap.xml +16 -16
- package/dist-cli/{check-compiler-HPF2T2FS.js → check-compiler-4RPB6SB5.js} +1 -1
- package/dist-cli/{check-query-propagation-HYSLTXAB.js → check-query-propagation-KN3DFQTX.js} +1 -1
- package/dist-cli/{chunk-WLUKAW3H.js → chunk-UHBRMYA6.js} +28802 -28152
- package/dist-cli/forgecad.js +660 -9
- package/dist-skill/CONTEXT.md +27 -1
- package/dist-skill/docs/generated/core.md +26 -0
- package/dist-skill/docs/generated/runtime-names.md +1 -1
- package/dist-skill/docs/guides/inspection-bundles.md +1 -1
- package/dist-skill/library/README.md +9 -12
- package/dist-skill/library/{forgecad-make-a-model → forgecad-build-model}/SKILL.md +16 -6
- package/dist-skill/library/{forgecad-spec-by-walking-through-it → forgecad-design-spec}/SKILL.md +4 -4
- package/dist-skill/library/{forgecad-spec-by-walking-through-it → forgecad-design-spec}/references/master-prompt.md +1 -1
- package/dist-skill/library/{forgecad-model-grader → forgecad-grade-model}/SKILL.md +6 -4
- package/dist-skill/library/forgecad-grade-model/agents/openai.yaml +4 -0
- package/dist-skill/library/{forgecad-visual-spec → forgecad-image-prompt}/SKILL.md +5 -5
- package/dist-skill/library/forgecad-image-prompt/agents/openai.yaml +4 -0
- package/dist-skill/library/{forgecad-render-inspect → forgecad-inspect-model}/SKILL.md +4 -4
- package/dist-skill/library/{forgecad-project → forgecad-project-sync}/SKILL.md +3 -3
- package/dist-skill/library/{forgecad-3d-reconstruction → forgecad-reconstruct-cad-file}/SKILL.md +5 -5
- package/dist-skill/library/forgecad-reconstruct-cad-file/agents/openai.yaml +4 -0
- package/dist-skill/library/{forgecad-image-replicator → forgecad-reconstruct-from-images}/SKILL.md +10 -10
- package/dist-skill/library/forgecad-reconstruct-from-images/agents/openai.yaml +4 -0
- package/dist-skill/library/{forgecad-mujoco-verify → forgecad-verify-mujoco}/SKILL.md +4 -4
- package/dist-skill/website/skills/{forgecad-make-a-model.md → forgecad-build-model.md} +18 -8
- package/dist-skill/website/skills/{forgecad-spec-by-walking-through-it.md → forgecad-design-spec.md} +6 -6
- package/dist-skill/website/skills/{forgecad-model-grader.md → forgecad-grade-model.md} +8 -6
- package/{dist/docs-raw/skills/forgecad-visual-spec.md → dist-skill/website/skills/forgecad-image-prompt.md} +7 -7
- package/dist-skill/website/skills/{forgecad-render-inspect.md → forgecad-inspect-model.md} +6 -6
- package/{dist/docs-raw/skills/forgecad-project.md → dist-skill/website/skills/forgecad-project-sync.md} +5 -5
- package/dist-skill/website/skills/{forgecad-3d-reconstruction.md → forgecad-reconstruct-cad-file.md} +7 -7
- package/dist-skill/website/skills/{forgecad-image-replicator.md → forgecad-reconstruct-from-images.md} +12 -12
- package/dist-skill/website/skills/{forgecad-mujoco-verify.md → forgecad-verify-mujoco.md} +6 -6
- package/dist-skill/website/skills/index.md +9 -12
- package/examples/api/texture-projection.forge.js +75 -0
- package/examples/assets/uv-grid.png +0 -0
- package/package.json +1 -1
- package/dist/docs-raw/skills/forgecad-blockout-model.md +0 -49
- package/dist/docs-raw/skills/forgecad-component-model.md +0 -53
- package/dist/docs-raw/skills/forgecad-reconstruction-benchmark.md +0 -60
- package/dist-skill/library/forgecad-3d-reconstruction/agents/openai.yaml +0 -4
- package/dist-skill/library/forgecad-blockout-model/SKILL.md +0 -42
- package/dist-skill/library/forgecad-component-model/SKILL.md +0 -46
- package/dist-skill/library/forgecad-image-replicator/agents/openai.yaml +0 -4
- package/dist-skill/library/forgecad-model-grader/agents/openai.yaml +0 -4
- package/dist-skill/library/forgecad-reconstruction-benchmark/SKILL.md +0 -48
- package/dist-skill/library/forgecad-reconstruction-benchmark/agents/openai.yaml +0 -4
- package/dist-skill/library/forgecad-visual-spec/agents/openai.yaml +0 -4
- package/dist-skill/website/skills/forgecad-blockout-model.md +0 -49
- package/dist-skill/website/skills/forgecad-component-model.md +0 -53
- package/dist-skill/website/skills/forgecad-reconstruction-benchmark.md +0 -60
- /package/dist/assets/{landing-proof-driven-DiGqdtWa.js → landing-proof-driven-BxZZh5r5.js} +0 -0
- /package/dist-skill/library/{forgecad-spec-by-walking-through-it → forgecad-design-spec}/references/default-profiles.md +0 -0
- /package/dist-skill/library/{forgecad-render-inspect → forgecad-inspect-model}/summarize_manifest.py +0 -0
- /package/dist-skill/library/{forgecad-image-replicator → forgecad-reconstruct-from-images}/scripts/compare_images.py +0 -0
- /package/dist-skill/library/{forgecad-mujoco-verify → forgecad-verify-mujoco}/scripts/mujoco_verify.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/EditorApp-C5f24ZN9.css","assets/landing-proof-driven-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/EditorApp-C5f24ZN9.css","assets/landing-proof-driven-Cpf-MIbI.css","assets/BenchmarkPage-BAbsyMaF.css","assets/PricingPage-BPF6HKyO.css","assets/LegalPage-BRlScr9A.css"])))=>i.map(i=>d[i]);
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
5
|
var _a2;
|
|
6
6
|
import { c as create, j as jsxRuntimeExports, r as reactExports, a as createWithEqualityFn, R as React, T as Tb, s as schedulerExports, b as clientExports, d as reactDomExports, u as useParams, e as useSearchParams, f as useNavigate, L as Link, g as useLocation, B as BrowserRouter, h as Routes, i as Route, N as Navigate } from "./vendor-react-6j1Kke-Y.js";
|
|
7
|
-
import { _ as __vitePreload, S as SDF_PROGRAM_OP, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, a as Scene, b as PCFSoftShadowMap, V as VSMShadowMap, c as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, d as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, e as Layers, f as Color, g as RGBAFormat, U as UnsignedByteType, h as Vector3, i as Vector2, j as Clock, T as THREE, D as DoubleSide, k as REVISION, M as Mesh, I as IcosahedronGeometry, l as ShaderMaterial, m as Spherical, Q as Quaternion, n as MOUSE, o as TOUCH, p as Ray, q as Plane, r as DataTextureLoader, H as HalfFloatType, F as FloatType, t as DataUtils, u as LinearFilter, v as RedFormat, w as InstancedBufferGeometry, x as Float32BufferAttribute, y as InstancedInterleavedBuffer, E as InterleavedBufferAttribute, G as WireframeGeometry, J as Box3, K as Sphere, X as UniformsUtils, Y as UniformsLib, Z as Vector4, $ as Line3, a0 as Matrix4, a1 as MathUtils, a2 as Uniform, a3 as WebGLRenderTarget, a4 as DepthTexture, a5 as BackSide, a6 as
|
|
7
|
+
import { _ as __vitePreload, S as SDF_PROGRAM_OP, z as zipSync, s as strToU8, W as WebGLRenderer, R as Raycaster, O as OrthographicCamera$1, P as PerspectiveCamera$1, a as Scene, b as PCFSoftShadowMap, V as VSMShadowMap, c as PCFShadowMap, B as BasicShadowMap, C as ColorManagement, L as LinearSRGBColorSpace, d as SRGBColorSpace, N as NoToneMapping, A as ACESFilmicToneMapping, e as Layers, f as Color, g as RGBAFormat, U as UnsignedByteType, h as Vector3, i as Vector2, j as Clock, T as THREE, D as DoubleSide, k as REVISION, M as Mesh, I as IcosahedronGeometry, l as ShaderMaterial, m as Spherical, Q as Quaternion, n as MOUSE, o as TOUCH, p as Ray, q as Plane, r as DataTextureLoader, H as HalfFloatType, F as FloatType, t as DataUtils, u as LinearFilter, v as RedFormat, w as InstancedBufferGeometry, x as Float32BufferAttribute, y as InstancedInterleavedBuffer, E as InterleavedBufferAttribute, G as WireframeGeometry, J as Box3, K as Sphere, X as UniformsUtils, Y as UniformsLib, Z as Vector4, $ as Line3, a0 as Matrix4, a1 as MathUtils, a2 as Uniform, a3 as WebGLRenderTarget, a4 as DepthTexture, a5 as BackSide, a6 as ClampToEdgeWrapping, a7 as PlaneGeometry, a8 as UVMapping, a9 as DataTexture, aa as Texture, ab as MeshBasicMaterial, ac as IntType, ad as ShortType, ae as ByteType, af as UnsignedIntType, ag as Loader, ah as LoadingManager, ai as LinearMipMapLinearFilter, aj as FileLoader, ak as NoBlending, al as CubeReflectionMapping, am as EquirectangularReflectionMapping, an as CubeTextureLoader, ao as WebGLCubeRenderTarget, ap as ConstraintSketch, aq as setSketchPlacement3D, ar as Sketch, as as PROFILE_BACKEND_MARKER, at as FrozenShape, au as setShapeCompilePlan, av as hasAnyPorts, aw as setShapePortsInternal, ax as markShapePortsUsed, ay as writeViewPreferences, az as setParamOverrides, aA as readViewPreferences, aB as resolveForgeRenderStyle, aC as isConstraintSketch, aD as updateConstraintValue, aE as linearizeMultiObjectSteps, aF as getShapeCompilePlan, aG as resolveCameraControlMode, aH as resolveComparisonOpacity, aI as resolveComparisonInspectMode, aJ as resolveBooleanPref, aK as resolveInspectQuantizeBands, aL as resolveInspectIsolineSpacing, aM as resolveInspectColormap, aN as resolveThicknessColorRange, aO as resolveInspectPointSampleCount, aP as SCAN_PROXY_GRANULARITY_DEFAULT, aQ as DEFAULT_MANUAL_SCENE_SETTINGS, aR as resolveManualSceneSettings, aS as publishSolverWasmRunDebug, aT as resolveForgeQualityPreset, aU as DEFAULT_INSPECT_ISOLINES_ENABLED, aV as SCAN_PROXY_MATRIX_GRANULARITY_MAX, aW as findJointAnimationClip, aX as resolveJointAnimation, aY as resolveJointViewValues, aZ as resolveImportPath, a_ as DEFAULT_INSPECT_CRITICAL_LINE_ENABLED, a$ as resolveScanProxyGranularity, b0 as DEFAULT_COMPARISON_REFERENCE_OPACITY, b1 as DEFAULT_COMPARISON_CANDIDATE_OPACITY, b2 as BufferGeometry, b3 as LineBasicMaterial, b4 as Line$1, b5 as LineDashedMaterial, b6 as CanvasTexture, b7 as Object3D, b8 as FogExp2, b9 as Fog, ba as AmbientLight, bb as HemisphereLight, bc as SpotLight, bd as PointLight, be as DirectionalLight, bf as BufferAttribute, bg as heatPointsForSide, bh as COMPARISON_COLORS, bi as comparisonHeatDepthTest, bj as comparisonHeatEdgeOpacity, bk as comparisonHeatPatchOpacity, bl as shapeToGeometry, bm as buildComparisonHeatPatchGeometry, bn as EdgesGeometry, bo as buildShapeFromCompilePlan, bp as VIEWPORT_CAMERA_STORAGE_KEY, bq as parseViewportCameraState, br as getKernelFaceNameForTriangle, bs as OBJECT_CONTEXT_MENU_MARGIN, bt as buildVisibleHistoryStacks, bu as sketchToSvg, bv as sketchToDxf, bw as runScript, bx as MeshPhysicalMaterial, by as LineSegments, bz as findDesignTraceNodeForConstructionStep, bA as formatDesignTraceAnchor, bB as waitForAnimationFrame, bC as selectBuildLedgerNodes, bD as worldAuthorPlaneToLocal, bE as compileSdfProgramEvaluator3, bF as SDF_LINEAR_OUTPUT_COLOR_GLSL, bG as GLSL3, bH as BoxGeometry, bI as Data3DTexture, bJ as buildSdfRaymarchFragmentShader, bK as SDF_RAYMARCH_PROXY_VERTEX_SHADER, bL as scanProxySourceBytes, bM as disposeScanProxyGeometry, bN as scanProxyGeometryFromPayload, bO as AdditiveBlending, bP as geometryWithVisibleVertexColors, bQ as MeshBVH, bR as makeColorScaleTexture, bS as colorScaleLUT, bT as makeInspectScalarUniforms, bU as updateInspectScalarUniforms, bV as descriptorToThreeTexture, bW as applyProjectedTexture, bX as getRenderStylePreset, bY as SCAN_RENDER_COLORS, bZ as NormalBlending, b_ as acceleratedRaycast, b$ as INSPECT_SCALAR_FRAGMENT_SHADER, c0 as INSPECT_SCALAR_VERTEX_SHADER, c1 as scanMaterialShellColor, c2 as ZEBRA_STRIPE_SOFTNESS, c3 as ZEBRA_STRIPE_SCALE, c4 as ZEBRA_LIGHT_COLOR, c5 as ZEBRA_DARK_COLOR, c6 as ZEBRA_ACCENT_COLOR, c7 as ZEBRA_STRIPE_FRAGMENT_SHADER, c8 as ZEBRA_STRIPE_VERTEX_SHADER, c9 as SCAN_PROXY_LAYER_STYLES, ca as scanMaterialLayerStyles, cb as SURFACE_FIELD_FRAGMENT_SHADER, cc as SURFACE_FIELD_VERTEX_SHADER, cd as WORLD_UP$1, ce as CatmullRomCurve3, cf as TubeGeometry, cg as DEFAULT_THICKNESS_COLOR_RANGE, ch as DEFAULT_COLORMAP, ci as colorScaleHexStops, cj as PERFORMANCE_SAMPLE_INTERVAL_SEC, ck as formatPerformanceCount, cl as NON_TEXT_INPUT_TYPES, cm as MeshStandardMaterial, cn as Shape, co as ShapeGeometry, cp as ShaderLib, cq as CylinderGeometry, cr as createResolvedExplodeConfig, cs as explodeBoundsCenter, ct as explodeMergeBounds, cu as resolveExplodeDirective, cv as computeExplodeMotion, cw as getSketchWorldMatrix, cx as explodeAdd, cy as hasExplodeOverride, cz as resolveExplodeLocalFanDirection, cA as explodeMul, cB as explodeLeafFanStage, cC as normalizeCutPlane, cD as toClippingPlane, cE as isObjectExcludedFromCutPlane, cF as getShapePorts, cG as getShapeUsedPorts, cH as DEFAULT_VIEW_CONFIG, cI as SECTION_EXPLORER_PLANE_NAME, cJ as ZERO_OFFSET, cK as scanProxyGridForBounds, cL as IDENTITY_MATRIX$2, cM as OBJECT_CONTEXT_MENU_WIDTH, cN as OBJECT_CONTEXT_MENU_HEIGHT, cO as triangleSoupFromMeshes, cP as compareTriangleSoups, cQ as buildGeometryComparisonPointCloud, cR as aabbOverlaps, cS as aabbOverlapVolume, cT as DEFAULT_COLLISION_INSPECTION_OPTIONS, cU as resolveScalarSceneSampleBudget, cV as INSPECT_POINT_SAMPLE_COUNT_MIN, cW as FOCUS_MODE_DIM_OPACITY, cX as DEFAULT_THICKNESS_INSPECTION_OPTIONS, cY as comparisonCandidateContextOpacity, cZ as Matrix3, c_ as initBackendForEvaluation } from "./backendInit-6C0DLgH0.js";
|
|
8
8
|
function getCsrfToken() {
|
|
9
9
|
const match = document.cookie.match(/(?:^|;\s*)fc-csrf-token=([^;]+)/);
|
|
10
10
|
return match == null ? void 0 : match[1];
|
|
@@ -13391,3329 +13391,6 @@ const Grid = /* @__PURE__ */ reactExports.forwardRef(({
|
|
|
13391
13391
|
args
|
|
13392
13392
|
}));
|
|
13393
13393
|
});
|
|
13394
|
-
const CENTER = 0;
|
|
13395
|
-
const AVERAGE = 1;
|
|
13396
|
-
const SAH = 2;
|
|
13397
|
-
const CONTAINED = 2;
|
|
13398
|
-
const TRIANGLE_INTERSECT_COST = 1.25;
|
|
13399
|
-
const TRAVERSAL_COST = 1;
|
|
13400
|
-
const BYTES_PER_NODE = 6 * 4 + 4 + 4;
|
|
13401
|
-
const IS_LEAFNODE_FLAG = 65535;
|
|
13402
|
-
const FLOAT32_EPSILON = Math.pow(2, -24);
|
|
13403
|
-
const SKIP_GENERATION = Symbol("SKIP_GENERATION");
|
|
13404
|
-
function getVertexCount(geo) {
|
|
13405
|
-
return geo.index ? geo.index.count : geo.attributes.position.count;
|
|
13406
|
-
}
|
|
13407
|
-
function getTriCount(geo) {
|
|
13408
|
-
return getVertexCount(geo) / 3;
|
|
13409
|
-
}
|
|
13410
|
-
function getIndexArray(vertexCount, BufferConstructor = ArrayBuffer) {
|
|
13411
|
-
if (vertexCount > 65535) {
|
|
13412
|
-
return new Uint32Array(new BufferConstructor(4 * vertexCount));
|
|
13413
|
-
} else {
|
|
13414
|
-
return new Uint16Array(new BufferConstructor(2 * vertexCount));
|
|
13415
|
-
}
|
|
13416
|
-
}
|
|
13417
|
-
function ensureIndex(geo, options) {
|
|
13418
|
-
if (!geo.index) {
|
|
13419
|
-
const vertexCount = geo.attributes.position.count;
|
|
13420
|
-
const BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;
|
|
13421
|
-
const index = getIndexArray(vertexCount, BufferConstructor);
|
|
13422
|
-
geo.setIndex(new BufferAttribute(index, 1));
|
|
13423
|
-
for (let i = 0; i < vertexCount; i++) {
|
|
13424
|
-
index[i] = i;
|
|
13425
|
-
}
|
|
13426
|
-
}
|
|
13427
|
-
}
|
|
13428
|
-
function getFullGeometryRange(geo, range) {
|
|
13429
|
-
const triCount = getTriCount(geo);
|
|
13430
|
-
const drawRange = range ? range : geo.drawRange;
|
|
13431
|
-
const start = drawRange.start / 3;
|
|
13432
|
-
const end = (drawRange.start + drawRange.count) / 3;
|
|
13433
|
-
const offset = Math.max(0, start);
|
|
13434
|
-
const count = Math.min(triCount, end) - offset;
|
|
13435
|
-
return [{
|
|
13436
|
-
offset: Math.floor(offset),
|
|
13437
|
-
count: Math.floor(count)
|
|
13438
|
-
}];
|
|
13439
|
-
}
|
|
13440
|
-
function getRootIndexRanges(geo, range) {
|
|
13441
|
-
if (!geo.groups || !geo.groups.length) {
|
|
13442
|
-
return getFullGeometryRange(geo, range);
|
|
13443
|
-
}
|
|
13444
|
-
const ranges = [];
|
|
13445
|
-
const rangeBoundaries = /* @__PURE__ */ new Set();
|
|
13446
|
-
const drawRange = range ? range : geo.drawRange;
|
|
13447
|
-
const drawRangeStart = drawRange.start / 3;
|
|
13448
|
-
const drawRangeEnd = (drawRange.start + drawRange.count) / 3;
|
|
13449
|
-
for (const group of geo.groups) {
|
|
13450
|
-
const groupStart = group.start / 3;
|
|
13451
|
-
const groupEnd = (group.start + group.count) / 3;
|
|
13452
|
-
rangeBoundaries.add(Math.max(drawRangeStart, groupStart));
|
|
13453
|
-
rangeBoundaries.add(Math.min(drawRangeEnd, groupEnd));
|
|
13454
|
-
}
|
|
13455
|
-
const sortedBoundaries = Array.from(rangeBoundaries.values()).sort((a2, b2) => a2 - b2);
|
|
13456
|
-
for (let i = 0; i < sortedBoundaries.length - 1; i++) {
|
|
13457
|
-
const start = sortedBoundaries[i];
|
|
13458
|
-
const end = sortedBoundaries[i + 1];
|
|
13459
|
-
ranges.push({
|
|
13460
|
-
offset: Math.floor(start),
|
|
13461
|
-
count: Math.floor(end - start)
|
|
13462
|
-
});
|
|
13463
|
-
}
|
|
13464
|
-
return ranges;
|
|
13465
|
-
}
|
|
13466
|
-
function hasGroupGaps(geometry, range) {
|
|
13467
|
-
const vertexCount = getTriCount(geometry);
|
|
13468
|
-
const groups = getRootIndexRanges(geometry, range).sort((a2, b2) => a2.offset - b2.offset);
|
|
13469
|
-
const finalGroup = groups[groups.length - 1];
|
|
13470
|
-
finalGroup.count = Math.min(vertexCount - finalGroup.offset, finalGroup.count);
|
|
13471
|
-
let total = 0;
|
|
13472
|
-
groups.forEach(({ count }) => total += count);
|
|
13473
|
-
return vertexCount !== total;
|
|
13474
|
-
}
|
|
13475
|
-
function getBounds(triangleBounds, offset, count, target, centroidTarget) {
|
|
13476
|
-
let minx = Infinity;
|
|
13477
|
-
let miny = Infinity;
|
|
13478
|
-
let minz = Infinity;
|
|
13479
|
-
let maxx = -Infinity;
|
|
13480
|
-
let maxy = -Infinity;
|
|
13481
|
-
let maxz = -Infinity;
|
|
13482
|
-
let cminx = Infinity;
|
|
13483
|
-
let cminy = Infinity;
|
|
13484
|
-
let cminz = Infinity;
|
|
13485
|
-
let cmaxx = -Infinity;
|
|
13486
|
-
let cmaxy = -Infinity;
|
|
13487
|
-
let cmaxz = -Infinity;
|
|
13488
|
-
for (let i = offset * 6, end = (offset + count) * 6; i < end; i += 6) {
|
|
13489
|
-
const cx = triangleBounds[i + 0];
|
|
13490
|
-
const hx = triangleBounds[i + 1];
|
|
13491
|
-
const lx = cx - hx;
|
|
13492
|
-
const rx = cx + hx;
|
|
13493
|
-
if (lx < minx) minx = lx;
|
|
13494
|
-
if (rx > maxx) maxx = rx;
|
|
13495
|
-
if (cx < cminx) cminx = cx;
|
|
13496
|
-
if (cx > cmaxx) cmaxx = cx;
|
|
13497
|
-
const cy = triangleBounds[i + 2];
|
|
13498
|
-
const hy = triangleBounds[i + 3];
|
|
13499
|
-
const ly = cy - hy;
|
|
13500
|
-
const ry = cy + hy;
|
|
13501
|
-
if (ly < miny) miny = ly;
|
|
13502
|
-
if (ry > maxy) maxy = ry;
|
|
13503
|
-
if (cy < cminy) cminy = cy;
|
|
13504
|
-
if (cy > cmaxy) cmaxy = cy;
|
|
13505
|
-
const cz = triangleBounds[i + 4];
|
|
13506
|
-
const hz = triangleBounds[i + 5];
|
|
13507
|
-
const lz = cz - hz;
|
|
13508
|
-
const rz = cz + hz;
|
|
13509
|
-
if (lz < minz) minz = lz;
|
|
13510
|
-
if (rz > maxz) maxz = rz;
|
|
13511
|
-
if (cz < cminz) cminz = cz;
|
|
13512
|
-
if (cz > cmaxz) cmaxz = cz;
|
|
13513
|
-
}
|
|
13514
|
-
target[0] = minx;
|
|
13515
|
-
target[1] = miny;
|
|
13516
|
-
target[2] = minz;
|
|
13517
|
-
target[3] = maxx;
|
|
13518
|
-
target[4] = maxy;
|
|
13519
|
-
target[5] = maxz;
|
|
13520
|
-
centroidTarget[0] = cminx;
|
|
13521
|
-
centroidTarget[1] = cminy;
|
|
13522
|
-
centroidTarget[2] = cminz;
|
|
13523
|
-
centroidTarget[3] = cmaxx;
|
|
13524
|
-
centroidTarget[4] = cmaxy;
|
|
13525
|
-
centroidTarget[5] = cmaxz;
|
|
13526
|
-
}
|
|
13527
|
-
function computeTriangleBounds(geo, target = null, offset = null, count = null) {
|
|
13528
|
-
const posAttr = geo.attributes.position;
|
|
13529
|
-
const index = geo.index ? geo.index.array : null;
|
|
13530
|
-
const triCount = getTriCount(geo);
|
|
13531
|
-
const normalized = posAttr.normalized;
|
|
13532
|
-
let triangleBounds;
|
|
13533
|
-
if (target === null) {
|
|
13534
|
-
triangleBounds = new Float32Array(triCount * 6);
|
|
13535
|
-
offset = 0;
|
|
13536
|
-
count = triCount;
|
|
13537
|
-
} else {
|
|
13538
|
-
triangleBounds = target;
|
|
13539
|
-
offset = offset || 0;
|
|
13540
|
-
count = count || triCount;
|
|
13541
|
-
}
|
|
13542
|
-
const posArr = posAttr.array;
|
|
13543
|
-
const bufferOffset = posAttr.offset || 0;
|
|
13544
|
-
let stride = 3;
|
|
13545
|
-
if (posAttr.isInterleavedBufferAttribute) {
|
|
13546
|
-
stride = posAttr.data.stride;
|
|
13547
|
-
}
|
|
13548
|
-
const getters = ["getX", "getY", "getZ"];
|
|
13549
|
-
for (let tri = offset; tri < offset + count; tri++) {
|
|
13550
|
-
const tri3 = tri * 3;
|
|
13551
|
-
const tri6 = tri * 6;
|
|
13552
|
-
let ai = tri3 + 0;
|
|
13553
|
-
let bi = tri3 + 1;
|
|
13554
|
-
let ci = tri3 + 2;
|
|
13555
|
-
if (index) {
|
|
13556
|
-
ai = index[ai];
|
|
13557
|
-
bi = index[bi];
|
|
13558
|
-
ci = index[ci];
|
|
13559
|
-
}
|
|
13560
|
-
if (!normalized) {
|
|
13561
|
-
ai = ai * stride + bufferOffset;
|
|
13562
|
-
bi = bi * stride + bufferOffset;
|
|
13563
|
-
ci = ci * stride + bufferOffset;
|
|
13564
|
-
}
|
|
13565
|
-
for (let el = 0; el < 3; el++) {
|
|
13566
|
-
let a2, b2, c2;
|
|
13567
|
-
if (normalized) {
|
|
13568
|
-
a2 = posAttr[getters[el]](ai);
|
|
13569
|
-
b2 = posAttr[getters[el]](bi);
|
|
13570
|
-
c2 = posAttr[getters[el]](ci);
|
|
13571
|
-
} else {
|
|
13572
|
-
a2 = posArr[ai + el];
|
|
13573
|
-
b2 = posArr[bi + el];
|
|
13574
|
-
c2 = posArr[ci + el];
|
|
13575
|
-
}
|
|
13576
|
-
let min = a2;
|
|
13577
|
-
if (b2 < min) min = b2;
|
|
13578
|
-
if (c2 < min) min = c2;
|
|
13579
|
-
let max2 = a2;
|
|
13580
|
-
if (b2 > max2) max2 = b2;
|
|
13581
|
-
if (c2 > max2) max2 = c2;
|
|
13582
|
-
const halfExtents = (max2 - min) / 2;
|
|
13583
|
-
const el2 = el * 2;
|
|
13584
|
-
triangleBounds[tri6 + el2 + 0] = min + halfExtents;
|
|
13585
|
-
triangleBounds[tri6 + el2 + 1] = halfExtents + (Math.abs(min) + halfExtents) * FLOAT32_EPSILON;
|
|
13586
|
-
}
|
|
13587
|
-
}
|
|
13588
|
-
return triangleBounds;
|
|
13589
|
-
}
|
|
13590
|
-
function arrayToBox(nodeIndex32, array, target) {
|
|
13591
|
-
target.min.x = array[nodeIndex32];
|
|
13592
|
-
target.min.y = array[nodeIndex32 + 1];
|
|
13593
|
-
target.min.z = array[nodeIndex32 + 2];
|
|
13594
|
-
target.max.x = array[nodeIndex32 + 3];
|
|
13595
|
-
target.max.y = array[nodeIndex32 + 4];
|
|
13596
|
-
target.max.z = array[nodeIndex32 + 5];
|
|
13597
|
-
return target;
|
|
13598
|
-
}
|
|
13599
|
-
function getLongestEdgeIndex(bounds) {
|
|
13600
|
-
let splitDimIdx = -1;
|
|
13601
|
-
let splitDist = -Infinity;
|
|
13602
|
-
for (let i = 0; i < 3; i++) {
|
|
13603
|
-
const dist = bounds[i + 3] - bounds[i];
|
|
13604
|
-
if (dist > splitDist) {
|
|
13605
|
-
splitDist = dist;
|
|
13606
|
-
splitDimIdx = i;
|
|
13607
|
-
}
|
|
13608
|
-
}
|
|
13609
|
-
return splitDimIdx;
|
|
13610
|
-
}
|
|
13611
|
-
function copyBounds(source, target) {
|
|
13612
|
-
target.set(source);
|
|
13613
|
-
}
|
|
13614
|
-
function unionBounds(a2, b2, target) {
|
|
13615
|
-
let aVal, bVal;
|
|
13616
|
-
for (let d = 0; d < 3; d++) {
|
|
13617
|
-
const d3 = d + 3;
|
|
13618
|
-
aVal = a2[d];
|
|
13619
|
-
bVal = b2[d];
|
|
13620
|
-
target[d] = aVal < bVal ? aVal : bVal;
|
|
13621
|
-
aVal = a2[d3];
|
|
13622
|
-
bVal = b2[d3];
|
|
13623
|
-
target[d3] = aVal > bVal ? aVal : bVal;
|
|
13624
|
-
}
|
|
13625
|
-
}
|
|
13626
|
-
function expandByTriangleBounds(startIndex, triangleBounds, bounds) {
|
|
13627
|
-
for (let d = 0; d < 3; d++) {
|
|
13628
|
-
const tCenter = triangleBounds[startIndex + 2 * d];
|
|
13629
|
-
const tHalf = triangleBounds[startIndex + 2 * d + 1];
|
|
13630
|
-
const tMin = tCenter - tHalf;
|
|
13631
|
-
const tMax = tCenter + tHalf;
|
|
13632
|
-
if (tMin < bounds[d]) {
|
|
13633
|
-
bounds[d] = tMin;
|
|
13634
|
-
}
|
|
13635
|
-
if (tMax > bounds[d + 3]) {
|
|
13636
|
-
bounds[d + 3] = tMax;
|
|
13637
|
-
}
|
|
13638
|
-
}
|
|
13639
|
-
}
|
|
13640
|
-
function computeSurfaceArea(bounds) {
|
|
13641
|
-
const d0 = bounds[3] - bounds[0];
|
|
13642
|
-
const d1 = bounds[4] - bounds[1];
|
|
13643
|
-
const d2 = bounds[5] - bounds[2];
|
|
13644
|
-
return 2 * (d0 * d1 + d1 * d2 + d2 * d0);
|
|
13645
|
-
}
|
|
13646
|
-
const BIN_COUNT = 32;
|
|
13647
|
-
const binsSort = (a2, b2) => a2.candidate - b2.candidate;
|
|
13648
|
-
const sahBins = new Array(BIN_COUNT).fill().map(() => {
|
|
13649
|
-
return {
|
|
13650
|
-
count: 0,
|
|
13651
|
-
bounds: new Float32Array(6),
|
|
13652
|
-
rightCacheBounds: new Float32Array(6),
|
|
13653
|
-
leftCacheBounds: new Float32Array(6),
|
|
13654
|
-
candidate: 0
|
|
13655
|
-
};
|
|
13656
|
-
});
|
|
13657
|
-
const leftBounds = new Float32Array(6);
|
|
13658
|
-
function getOptimalSplit(nodeBoundingData, centroidBoundingData, triangleBounds, offset, count, strategy) {
|
|
13659
|
-
let axis = -1;
|
|
13660
|
-
let pos = 0;
|
|
13661
|
-
if (strategy === CENTER) {
|
|
13662
|
-
axis = getLongestEdgeIndex(centroidBoundingData);
|
|
13663
|
-
if (axis !== -1) {
|
|
13664
|
-
pos = (centroidBoundingData[axis] + centroidBoundingData[axis + 3]) / 2;
|
|
13665
|
-
}
|
|
13666
|
-
} else if (strategy === AVERAGE) {
|
|
13667
|
-
axis = getLongestEdgeIndex(nodeBoundingData);
|
|
13668
|
-
if (axis !== -1) {
|
|
13669
|
-
pos = getAverage(triangleBounds, offset, count, axis);
|
|
13670
|
-
}
|
|
13671
|
-
} else if (strategy === SAH) {
|
|
13672
|
-
const rootSurfaceArea = computeSurfaceArea(nodeBoundingData);
|
|
13673
|
-
let bestCost = TRIANGLE_INTERSECT_COST * count;
|
|
13674
|
-
const cStart = offset * 6;
|
|
13675
|
-
const cEnd = (offset + count) * 6;
|
|
13676
|
-
for (let a2 = 0; a2 < 3; a2++) {
|
|
13677
|
-
const axisLeft = centroidBoundingData[a2];
|
|
13678
|
-
const axisRight = centroidBoundingData[a2 + 3];
|
|
13679
|
-
const axisLength = axisRight - axisLeft;
|
|
13680
|
-
const binWidth = axisLength / BIN_COUNT;
|
|
13681
|
-
if (count < BIN_COUNT / 4) {
|
|
13682
|
-
const truncatedBins = [...sahBins];
|
|
13683
|
-
truncatedBins.length = count;
|
|
13684
|
-
let b2 = 0;
|
|
13685
|
-
for (let c2 = cStart; c2 < cEnd; c2 += 6, b2++) {
|
|
13686
|
-
const bin = truncatedBins[b2];
|
|
13687
|
-
bin.candidate = triangleBounds[c2 + 2 * a2];
|
|
13688
|
-
bin.count = 0;
|
|
13689
|
-
const {
|
|
13690
|
-
bounds,
|
|
13691
|
-
leftCacheBounds,
|
|
13692
|
-
rightCacheBounds
|
|
13693
|
-
} = bin;
|
|
13694
|
-
for (let d = 0; d < 3; d++) {
|
|
13695
|
-
rightCacheBounds[d] = Infinity;
|
|
13696
|
-
rightCacheBounds[d + 3] = -Infinity;
|
|
13697
|
-
leftCacheBounds[d] = Infinity;
|
|
13698
|
-
leftCacheBounds[d + 3] = -Infinity;
|
|
13699
|
-
bounds[d] = Infinity;
|
|
13700
|
-
bounds[d + 3] = -Infinity;
|
|
13701
|
-
}
|
|
13702
|
-
expandByTriangleBounds(c2, triangleBounds, bounds);
|
|
13703
|
-
}
|
|
13704
|
-
truncatedBins.sort(binsSort);
|
|
13705
|
-
let splitCount = count;
|
|
13706
|
-
for (let bi = 0; bi < splitCount; bi++) {
|
|
13707
|
-
const bin = truncatedBins[bi];
|
|
13708
|
-
while (bi + 1 < splitCount && truncatedBins[bi + 1].candidate === bin.candidate) {
|
|
13709
|
-
truncatedBins.splice(bi + 1, 1);
|
|
13710
|
-
splitCount--;
|
|
13711
|
-
}
|
|
13712
|
-
}
|
|
13713
|
-
for (let c2 = cStart; c2 < cEnd; c2 += 6) {
|
|
13714
|
-
const center = triangleBounds[c2 + 2 * a2];
|
|
13715
|
-
for (let bi = 0; bi < splitCount; bi++) {
|
|
13716
|
-
const bin = truncatedBins[bi];
|
|
13717
|
-
if (center >= bin.candidate) {
|
|
13718
|
-
expandByTriangleBounds(c2, triangleBounds, bin.rightCacheBounds);
|
|
13719
|
-
} else {
|
|
13720
|
-
expandByTriangleBounds(c2, triangleBounds, bin.leftCacheBounds);
|
|
13721
|
-
bin.count++;
|
|
13722
|
-
}
|
|
13723
|
-
}
|
|
13724
|
-
}
|
|
13725
|
-
for (let bi = 0; bi < splitCount; bi++) {
|
|
13726
|
-
const bin = truncatedBins[bi];
|
|
13727
|
-
const leftCount = bin.count;
|
|
13728
|
-
const rightCount = count - bin.count;
|
|
13729
|
-
const leftBounds2 = bin.leftCacheBounds;
|
|
13730
|
-
const rightBounds = bin.rightCacheBounds;
|
|
13731
|
-
let leftProb = 0;
|
|
13732
|
-
if (leftCount !== 0) {
|
|
13733
|
-
leftProb = computeSurfaceArea(leftBounds2) / rootSurfaceArea;
|
|
13734
|
-
}
|
|
13735
|
-
let rightProb = 0;
|
|
13736
|
-
if (rightCount !== 0) {
|
|
13737
|
-
rightProb = computeSurfaceArea(rightBounds) / rootSurfaceArea;
|
|
13738
|
-
}
|
|
13739
|
-
const cost = TRAVERSAL_COST + TRIANGLE_INTERSECT_COST * (leftProb * leftCount + rightProb * rightCount);
|
|
13740
|
-
if (cost < bestCost) {
|
|
13741
|
-
axis = a2;
|
|
13742
|
-
bestCost = cost;
|
|
13743
|
-
pos = bin.candidate;
|
|
13744
|
-
}
|
|
13745
|
-
}
|
|
13746
|
-
} else {
|
|
13747
|
-
for (let i = 0; i < BIN_COUNT; i++) {
|
|
13748
|
-
const bin = sahBins[i];
|
|
13749
|
-
bin.count = 0;
|
|
13750
|
-
bin.candidate = axisLeft + binWidth + i * binWidth;
|
|
13751
|
-
const bounds = bin.bounds;
|
|
13752
|
-
for (let d = 0; d < 3; d++) {
|
|
13753
|
-
bounds[d] = Infinity;
|
|
13754
|
-
bounds[d + 3] = -Infinity;
|
|
13755
|
-
}
|
|
13756
|
-
}
|
|
13757
|
-
for (let c2 = cStart; c2 < cEnd; c2 += 6) {
|
|
13758
|
-
const triCenter = triangleBounds[c2 + 2 * a2];
|
|
13759
|
-
const relativeCenter = triCenter - axisLeft;
|
|
13760
|
-
let binIndex = ~~(relativeCenter / binWidth);
|
|
13761
|
-
if (binIndex >= BIN_COUNT) binIndex = BIN_COUNT - 1;
|
|
13762
|
-
const bin = sahBins[binIndex];
|
|
13763
|
-
bin.count++;
|
|
13764
|
-
expandByTriangleBounds(c2, triangleBounds, bin.bounds);
|
|
13765
|
-
}
|
|
13766
|
-
const lastBin = sahBins[BIN_COUNT - 1];
|
|
13767
|
-
copyBounds(lastBin.bounds, lastBin.rightCacheBounds);
|
|
13768
|
-
for (let i = BIN_COUNT - 2; i >= 0; i--) {
|
|
13769
|
-
const bin = sahBins[i];
|
|
13770
|
-
const nextBin = sahBins[i + 1];
|
|
13771
|
-
unionBounds(bin.bounds, nextBin.rightCacheBounds, bin.rightCacheBounds);
|
|
13772
|
-
}
|
|
13773
|
-
let leftCount = 0;
|
|
13774
|
-
for (let i = 0; i < BIN_COUNT - 1; i++) {
|
|
13775
|
-
const bin = sahBins[i];
|
|
13776
|
-
const binCount = bin.count;
|
|
13777
|
-
const bounds = bin.bounds;
|
|
13778
|
-
const nextBin = sahBins[i + 1];
|
|
13779
|
-
const rightBounds = nextBin.rightCacheBounds;
|
|
13780
|
-
if (binCount !== 0) {
|
|
13781
|
-
if (leftCount === 0) {
|
|
13782
|
-
copyBounds(bounds, leftBounds);
|
|
13783
|
-
} else {
|
|
13784
|
-
unionBounds(bounds, leftBounds, leftBounds);
|
|
13785
|
-
}
|
|
13786
|
-
}
|
|
13787
|
-
leftCount += binCount;
|
|
13788
|
-
let leftProb = 0;
|
|
13789
|
-
let rightProb = 0;
|
|
13790
|
-
if (leftCount !== 0) {
|
|
13791
|
-
leftProb = computeSurfaceArea(leftBounds) / rootSurfaceArea;
|
|
13792
|
-
}
|
|
13793
|
-
const rightCount = count - leftCount;
|
|
13794
|
-
if (rightCount !== 0) {
|
|
13795
|
-
rightProb = computeSurfaceArea(rightBounds) / rootSurfaceArea;
|
|
13796
|
-
}
|
|
13797
|
-
const cost = TRAVERSAL_COST + TRIANGLE_INTERSECT_COST * (leftProb * leftCount + rightProb * rightCount);
|
|
13798
|
-
if (cost < bestCost) {
|
|
13799
|
-
axis = a2;
|
|
13800
|
-
bestCost = cost;
|
|
13801
|
-
pos = bin.candidate;
|
|
13802
|
-
}
|
|
13803
|
-
}
|
|
13804
|
-
}
|
|
13805
|
-
}
|
|
13806
|
-
} else {
|
|
13807
|
-
console.warn(`MeshBVH: Invalid build strategy value ${strategy} used.`);
|
|
13808
|
-
}
|
|
13809
|
-
return { axis, pos };
|
|
13810
|
-
}
|
|
13811
|
-
function getAverage(triangleBounds, offset, count, axis) {
|
|
13812
|
-
let avg = 0;
|
|
13813
|
-
for (let i = offset, end = offset + count; i < end; i++) {
|
|
13814
|
-
avg += triangleBounds[i * 6 + axis * 2];
|
|
13815
|
-
}
|
|
13816
|
-
return avg / count;
|
|
13817
|
-
}
|
|
13818
|
-
class MeshBVHNode {
|
|
13819
|
-
constructor() {
|
|
13820
|
-
this.boundingData = new Float32Array(6);
|
|
13821
|
-
}
|
|
13822
|
-
}
|
|
13823
|
-
function partition(indirectBuffer, index, triangleBounds, offset, count, split) {
|
|
13824
|
-
let left = offset;
|
|
13825
|
-
let right = offset + count - 1;
|
|
13826
|
-
const pos = split.pos;
|
|
13827
|
-
const axisOffset = split.axis * 2;
|
|
13828
|
-
while (true) {
|
|
13829
|
-
while (left <= right && triangleBounds[left * 6 + axisOffset] < pos) {
|
|
13830
|
-
left++;
|
|
13831
|
-
}
|
|
13832
|
-
while (left <= right && triangleBounds[right * 6 + axisOffset] >= pos) {
|
|
13833
|
-
right--;
|
|
13834
|
-
}
|
|
13835
|
-
if (left < right) {
|
|
13836
|
-
for (let i = 0; i < 3; i++) {
|
|
13837
|
-
let t02 = index[left * 3 + i];
|
|
13838
|
-
index[left * 3 + i] = index[right * 3 + i];
|
|
13839
|
-
index[right * 3 + i] = t02;
|
|
13840
|
-
}
|
|
13841
|
-
for (let i = 0; i < 6; i++) {
|
|
13842
|
-
let tb = triangleBounds[left * 6 + i];
|
|
13843
|
-
triangleBounds[left * 6 + i] = triangleBounds[right * 6 + i];
|
|
13844
|
-
triangleBounds[right * 6 + i] = tb;
|
|
13845
|
-
}
|
|
13846
|
-
left++;
|
|
13847
|
-
right--;
|
|
13848
|
-
} else {
|
|
13849
|
-
return left;
|
|
13850
|
-
}
|
|
13851
|
-
}
|
|
13852
|
-
}
|
|
13853
|
-
function partition_indirect(indirectBuffer, index, triangleBounds, offset, count, split) {
|
|
13854
|
-
let left = offset;
|
|
13855
|
-
let right = offset + count - 1;
|
|
13856
|
-
const pos = split.pos;
|
|
13857
|
-
const axisOffset = split.axis * 2;
|
|
13858
|
-
while (true) {
|
|
13859
|
-
while (left <= right && triangleBounds[left * 6 + axisOffset] < pos) {
|
|
13860
|
-
left++;
|
|
13861
|
-
}
|
|
13862
|
-
while (left <= right && triangleBounds[right * 6 + axisOffset] >= pos) {
|
|
13863
|
-
right--;
|
|
13864
|
-
}
|
|
13865
|
-
if (left < right) {
|
|
13866
|
-
let t2 = indirectBuffer[left];
|
|
13867
|
-
indirectBuffer[left] = indirectBuffer[right];
|
|
13868
|
-
indirectBuffer[right] = t2;
|
|
13869
|
-
for (let i = 0; i < 6; i++) {
|
|
13870
|
-
let tb = triangleBounds[left * 6 + i];
|
|
13871
|
-
triangleBounds[left * 6 + i] = triangleBounds[right * 6 + i];
|
|
13872
|
-
triangleBounds[right * 6 + i] = tb;
|
|
13873
|
-
}
|
|
13874
|
-
left++;
|
|
13875
|
-
right--;
|
|
13876
|
-
} else {
|
|
13877
|
-
return left;
|
|
13878
|
-
}
|
|
13879
|
-
}
|
|
13880
|
-
}
|
|
13881
|
-
function IS_LEAF(n16, uint16Array2) {
|
|
13882
|
-
return uint16Array2[n16 + 15] === 65535;
|
|
13883
|
-
}
|
|
13884
|
-
function OFFSET(n32, uint32Array2) {
|
|
13885
|
-
return uint32Array2[n32 + 6];
|
|
13886
|
-
}
|
|
13887
|
-
function COUNT(n16, uint16Array2) {
|
|
13888
|
-
return uint16Array2[n16 + 14];
|
|
13889
|
-
}
|
|
13890
|
-
function LEFT_NODE(n32) {
|
|
13891
|
-
return n32 + 8;
|
|
13892
|
-
}
|
|
13893
|
-
function RIGHT_NODE(n32, uint32Array2) {
|
|
13894
|
-
return uint32Array2[n32 + 6];
|
|
13895
|
-
}
|
|
13896
|
-
function SPLIT_AXIS(n32, uint32Array2) {
|
|
13897
|
-
return uint32Array2[n32 + 7];
|
|
13898
|
-
}
|
|
13899
|
-
function BOUNDING_DATA_INDEX(n32) {
|
|
13900
|
-
return n32;
|
|
13901
|
-
}
|
|
13902
|
-
let float32Array, uint32Array, uint16Array, uint8Array;
|
|
13903
|
-
const MAX_POINTER = Math.pow(2, 32);
|
|
13904
|
-
function countNodes(node) {
|
|
13905
|
-
if ("count" in node) {
|
|
13906
|
-
return 1;
|
|
13907
|
-
} else {
|
|
13908
|
-
return 1 + countNodes(node.left) + countNodes(node.right);
|
|
13909
|
-
}
|
|
13910
|
-
}
|
|
13911
|
-
function populateBuffer(byteOffset, node, buffer) {
|
|
13912
|
-
float32Array = new Float32Array(buffer);
|
|
13913
|
-
uint32Array = new Uint32Array(buffer);
|
|
13914
|
-
uint16Array = new Uint16Array(buffer);
|
|
13915
|
-
uint8Array = new Uint8Array(buffer);
|
|
13916
|
-
return _populateBuffer(byteOffset, node);
|
|
13917
|
-
}
|
|
13918
|
-
function _populateBuffer(byteOffset, node) {
|
|
13919
|
-
const stride4Offset = byteOffset / 4;
|
|
13920
|
-
const stride2Offset = byteOffset / 2;
|
|
13921
|
-
const isLeaf = "count" in node;
|
|
13922
|
-
const boundingData = node.boundingData;
|
|
13923
|
-
for (let i = 0; i < 6; i++) {
|
|
13924
|
-
float32Array[stride4Offset + i] = boundingData[i];
|
|
13925
|
-
}
|
|
13926
|
-
if (isLeaf) {
|
|
13927
|
-
if (node.buffer) {
|
|
13928
|
-
const buffer = node.buffer;
|
|
13929
|
-
uint8Array.set(new Uint8Array(buffer), byteOffset);
|
|
13930
|
-
for (let offset = byteOffset, l2 = byteOffset + buffer.byteLength; offset < l2; offset += BYTES_PER_NODE) {
|
|
13931
|
-
const offset2 = offset / 2;
|
|
13932
|
-
if (!IS_LEAF(offset2, uint16Array)) {
|
|
13933
|
-
uint32Array[offset / 4 + 6] += stride4Offset;
|
|
13934
|
-
}
|
|
13935
|
-
}
|
|
13936
|
-
return byteOffset + buffer.byteLength;
|
|
13937
|
-
} else {
|
|
13938
|
-
const offset = node.offset;
|
|
13939
|
-
const count = node.count;
|
|
13940
|
-
uint32Array[stride4Offset + 6] = offset;
|
|
13941
|
-
uint16Array[stride2Offset + 14] = count;
|
|
13942
|
-
uint16Array[stride2Offset + 15] = IS_LEAFNODE_FLAG;
|
|
13943
|
-
return byteOffset + BYTES_PER_NODE;
|
|
13944
|
-
}
|
|
13945
|
-
} else {
|
|
13946
|
-
const left = node.left;
|
|
13947
|
-
const right = node.right;
|
|
13948
|
-
const splitAxis = node.splitAxis;
|
|
13949
|
-
let nextUnusedPointer;
|
|
13950
|
-
nextUnusedPointer = _populateBuffer(byteOffset + BYTES_PER_NODE, left);
|
|
13951
|
-
if (nextUnusedPointer / 4 > MAX_POINTER) {
|
|
13952
|
-
throw new Error("MeshBVH: Cannot store child pointer greater than 32 bits.");
|
|
13953
|
-
}
|
|
13954
|
-
uint32Array[stride4Offset + 6] = nextUnusedPointer / 4;
|
|
13955
|
-
nextUnusedPointer = _populateBuffer(nextUnusedPointer, right);
|
|
13956
|
-
uint32Array[stride4Offset + 7] = splitAxis;
|
|
13957
|
-
return nextUnusedPointer;
|
|
13958
|
-
}
|
|
13959
|
-
}
|
|
13960
|
-
function generateIndirectBuffer(geometry, useSharedArrayBuffer) {
|
|
13961
|
-
const triCount = (geometry.index ? geometry.index.count : geometry.attributes.position.count) / 3;
|
|
13962
|
-
const useUint32 = triCount > 2 ** 16;
|
|
13963
|
-
const byteCount = useUint32 ? 4 : 2;
|
|
13964
|
-
const buffer = useSharedArrayBuffer ? new SharedArrayBuffer(triCount * byteCount) : new ArrayBuffer(triCount * byteCount);
|
|
13965
|
-
const indirectBuffer = useUint32 ? new Uint32Array(buffer) : new Uint16Array(buffer);
|
|
13966
|
-
for (let i = 0, l2 = indirectBuffer.length; i < l2; i++) {
|
|
13967
|
-
indirectBuffer[i] = i;
|
|
13968
|
-
}
|
|
13969
|
-
return indirectBuffer;
|
|
13970
|
-
}
|
|
13971
|
-
function buildTree(bvh, triangleBounds, offset, count, options) {
|
|
13972
|
-
const {
|
|
13973
|
-
maxDepth,
|
|
13974
|
-
verbose,
|
|
13975
|
-
maxLeafTris,
|
|
13976
|
-
strategy,
|
|
13977
|
-
onProgress,
|
|
13978
|
-
indirect
|
|
13979
|
-
} = options;
|
|
13980
|
-
const indirectBuffer = bvh._indirectBuffer;
|
|
13981
|
-
const geometry = bvh.geometry;
|
|
13982
|
-
const indexArray = geometry.index ? geometry.index.array : null;
|
|
13983
|
-
const partionFunc = indirect ? partition_indirect : partition;
|
|
13984
|
-
const totalTriangles = getTriCount(geometry);
|
|
13985
|
-
const cacheCentroidBoundingData = new Float32Array(6);
|
|
13986
|
-
let reachedMaxDepth = false;
|
|
13987
|
-
const root = new MeshBVHNode();
|
|
13988
|
-
getBounds(triangleBounds, offset, count, root.boundingData, cacheCentroidBoundingData);
|
|
13989
|
-
splitNode(root, offset, count, cacheCentroidBoundingData);
|
|
13990
|
-
return root;
|
|
13991
|
-
function triggerProgress(trianglesProcessed) {
|
|
13992
|
-
if (onProgress) {
|
|
13993
|
-
onProgress(trianglesProcessed / totalTriangles);
|
|
13994
|
-
}
|
|
13995
|
-
}
|
|
13996
|
-
function splitNode(node, offset2, count2, centroidBoundingData = null, depth = 0) {
|
|
13997
|
-
if (!reachedMaxDepth && depth >= maxDepth) {
|
|
13998
|
-
reachedMaxDepth = true;
|
|
13999
|
-
if (verbose) {
|
|
14000
|
-
console.warn(`MeshBVH: Max depth of ${maxDepth} reached when generating BVH. Consider increasing maxDepth.`);
|
|
14001
|
-
console.warn(geometry);
|
|
14002
|
-
}
|
|
14003
|
-
}
|
|
14004
|
-
if (count2 <= maxLeafTris || depth >= maxDepth) {
|
|
14005
|
-
triggerProgress(offset2 + count2);
|
|
14006
|
-
node.offset = offset2;
|
|
14007
|
-
node.count = count2;
|
|
14008
|
-
return node;
|
|
14009
|
-
}
|
|
14010
|
-
const split = getOptimalSplit(node.boundingData, centroidBoundingData, triangleBounds, offset2, count2, strategy);
|
|
14011
|
-
if (split.axis === -1) {
|
|
14012
|
-
triggerProgress(offset2 + count2);
|
|
14013
|
-
node.offset = offset2;
|
|
14014
|
-
node.count = count2;
|
|
14015
|
-
return node;
|
|
14016
|
-
}
|
|
14017
|
-
const splitOffset = partionFunc(indirectBuffer, indexArray, triangleBounds, offset2, count2, split);
|
|
14018
|
-
if (splitOffset === offset2 || splitOffset === offset2 + count2) {
|
|
14019
|
-
triggerProgress(offset2 + count2);
|
|
14020
|
-
node.offset = offset2;
|
|
14021
|
-
node.count = count2;
|
|
14022
|
-
} else {
|
|
14023
|
-
node.splitAxis = split.axis;
|
|
14024
|
-
const left = new MeshBVHNode();
|
|
14025
|
-
const lstart = offset2;
|
|
14026
|
-
const lcount = splitOffset - offset2;
|
|
14027
|
-
node.left = left;
|
|
14028
|
-
getBounds(triangleBounds, lstart, lcount, left.boundingData, cacheCentroidBoundingData);
|
|
14029
|
-
splitNode(left, lstart, lcount, cacheCentroidBoundingData, depth + 1);
|
|
14030
|
-
const right = new MeshBVHNode();
|
|
14031
|
-
const rstart = splitOffset;
|
|
14032
|
-
const rcount = count2 - lcount;
|
|
14033
|
-
node.right = right;
|
|
14034
|
-
getBounds(triangleBounds, rstart, rcount, right.boundingData, cacheCentroidBoundingData);
|
|
14035
|
-
splitNode(right, rstart, rcount, cacheCentroidBoundingData, depth + 1);
|
|
14036
|
-
}
|
|
14037
|
-
return node;
|
|
14038
|
-
}
|
|
14039
|
-
}
|
|
14040
|
-
function buildPackedTree(bvh, options) {
|
|
14041
|
-
const geometry = bvh.geometry;
|
|
14042
|
-
if (options.indirect) {
|
|
14043
|
-
bvh._indirectBuffer = generateIndirectBuffer(geometry, options.useSharedArrayBuffer);
|
|
14044
|
-
if (hasGroupGaps(geometry, options.range) && !options.verbose) {
|
|
14045
|
-
console.warn(
|
|
14046
|
-
'MeshBVH: Provided geometry contains groups or a range that do not fully span the vertex contents while using the "indirect" option. BVH may incorrectly report intersections on unrendered portions of the geometry.'
|
|
14047
|
-
);
|
|
14048
|
-
}
|
|
14049
|
-
}
|
|
14050
|
-
if (!bvh._indirectBuffer) {
|
|
14051
|
-
ensureIndex(geometry, options);
|
|
14052
|
-
}
|
|
14053
|
-
const BufferConstructor = options.useSharedArrayBuffer ? SharedArrayBuffer : ArrayBuffer;
|
|
14054
|
-
const triangleBounds = computeTriangleBounds(geometry);
|
|
14055
|
-
const geometryRanges = options.indirect ? getFullGeometryRange(geometry, options.range) : getRootIndexRanges(geometry, options.range);
|
|
14056
|
-
bvh._roots = geometryRanges.map((range) => {
|
|
14057
|
-
const root = buildTree(bvh, triangleBounds, range.offset, range.count, options);
|
|
14058
|
-
const nodeCount = countNodes(root);
|
|
14059
|
-
const buffer = new BufferConstructor(BYTES_PER_NODE * nodeCount);
|
|
14060
|
-
populateBuffer(0, root, buffer);
|
|
14061
|
-
return buffer;
|
|
14062
|
-
});
|
|
14063
|
-
}
|
|
14064
|
-
class SeparatingAxisBounds {
|
|
14065
|
-
constructor() {
|
|
14066
|
-
this.min = Infinity;
|
|
14067
|
-
this.max = -Infinity;
|
|
14068
|
-
}
|
|
14069
|
-
setFromPointsField(points, field) {
|
|
14070
|
-
let min = Infinity;
|
|
14071
|
-
let max2 = -Infinity;
|
|
14072
|
-
for (let i = 0, l2 = points.length; i < l2; i++) {
|
|
14073
|
-
const p2 = points[i];
|
|
14074
|
-
const val = p2[field];
|
|
14075
|
-
min = val < min ? val : min;
|
|
14076
|
-
max2 = val > max2 ? val : max2;
|
|
14077
|
-
}
|
|
14078
|
-
this.min = min;
|
|
14079
|
-
this.max = max2;
|
|
14080
|
-
}
|
|
14081
|
-
setFromPoints(axis, points) {
|
|
14082
|
-
let min = Infinity;
|
|
14083
|
-
let max2 = -Infinity;
|
|
14084
|
-
for (let i = 0, l2 = points.length; i < l2; i++) {
|
|
14085
|
-
const p2 = points[i];
|
|
14086
|
-
const val = axis.dot(p2);
|
|
14087
|
-
min = val < min ? val : min;
|
|
14088
|
-
max2 = val > max2 ? val : max2;
|
|
14089
|
-
}
|
|
14090
|
-
this.min = min;
|
|
14091
|
-
this.max = max2;
|
|
14092
|
-
}
|
|
14093
|
-
isSeparated(other) {
|
|
14094
|
-
return this.min > other.max || other.min > this.max;
|
|
14095
|
-
}
|
|
14096
|
-
}
|
|
14097
|
-
SeparatingAxisBounds.prototype.setFromBox = (function() {
|
|
14098
|
-
const p2 = new Vector3();
|
|
14099
|
-
return function setFromBox(axis, box2) {
|
|
14100
|
-
const boxMin = box2.min;
|
|
14101
|
-
const boxMax = box2.max;
|
|
14102
|
-
let min = Infinity;
|
|
14103
|
-
let max2 = -Infinity;
|
|
14104
|
-
for (let x = 0; x <= 1; x++) {
|
|
14105
|
-
for (let y = 0; y <= 1; y++) {
|
|
14106
|
-
for (let z = 0; z <= 1; z++) {
|
|
14107
|
-
p2.x = boxMin.x * x + boxMax.x * (1 - x);
|
|
14108
|
-
p2.y = boxMin.y * y + boxMax.y * (1 - y);
|
|
14109
|
-
p2.z = boxMin.z * z + boxMax.z * (1 - z);
|
|
14110
|
-
const val = axis.dot(p2);
|
|
14111
|
-
min = Math.min(val, min);
|
|
14112
|
-
max2 = Math.max(val, max2);
|
|
14113
|
-
}
|
|
14114
|
-
}
|
|
14115
|
-
}
|
|
14116
|
-
this.min = min;
|
|
14117
|
-
this.max = max2;
|
|
14118
|
-
};
|
|
14119
|
-
})();
|
|
14120
|
-
const closestPointLineToLine = (function() {
|
|
14121
|
-
const dir1 = new Vector3();
|
|
14122
|
-
const dir2 = new Vector3();
|
|
14123
|
-
const v02 = new Vector3();
|
|
14124
|
-
return function closestPointLineToLine2(l1, l2, result) {
|
|
14125
|
-
const v0 = l1.start;
|
|
14126
|
-
const v10 = dir1;
|
|
14127
|
-
const v22 = l2.start;
|
|
14128
|
-
const v32 = dir2;
|
|
14129
|
-
v02.subVectors(v0, v22);
|
|
14130
|
-
dir1.subVectors(l1.end, l1.start);
|
|
14131
|
-
dir2.subVectors(l2.end, l2.start);
|
|
14132
|
-
const d0232 = v02.dot(v32);
|
|
14133
|
-
const d3210 = v32.dot(v10);
|
|
14134
|
-
const d3232 = v32.dot(v32);
|
|
14135
|
-
const d0210 = v02.dot(v10);
|
|
14136
|
-
const d1010 = v10.dot(v10);
|
|
14137
|
-
const denom = d1010 * d3232 - d3210 * d3210;
|
|
14138
|
-
let d, d2;
|
|
14139
|
-
if (denom !== 0) {
|
|
14140
|
-
d = (d0232 * d3210 - d0210 * d3232) / denom;
|
|
14141
|
-
} else {
|
|
14142
|
-
d = 0;
|
|
14143
|
-
}
|
|
14144
|
-
d2 = (d0232 + d * d3210) / d3232;
|
|
14145
|
-
result.x = d;
|
|
14146
|
-
result.y = d2;
|
|
14147
|
-
};
|
|
14148
|
-
})();
|
|
14149
|
-
const closestPointsSegmentToSegment = (function() {
|
|
14150
|
-
const paramResult = new Vector2();
|
|
14151
|
-
const temp12 = new Vector3();
|
|
14152
|
-
const temp22 = new Vector3();
|
|
14153
|
-
return function closestPointsSegmentToSegment2(l1, l2, target1, target2) {
|
|
14154
|
-
closestPointLineToLine(l1, l2, paramResult);
|
|
14155
|
-
let d = paramResult.x;
|
|
14156
|
-
let d2 = paramResult.y;
|
|
14157
|
-
if (d >= 0 && d <= 1 && d2 >= 0 && d2 <= 1) {
|
|
14158
|
-
l1.at(d, target1);
|
|
14159
|
-
l2.at(d2, target2);
|
|
14160
|
-
return;
|
|
14161
|
-
} else if (d >= 0 && d <= 1) {
|
|
14162
|
-
if (d2 < 0) {
|
|
14163
|
-
l2.at(0, target2);
|
|
14164
|
-
} else {
|
|
14165
|
-
l2.at(1, target2);
|
|
14166
|
-
}
|
|
14167
|
-
l1.closestPointToPoint(target2, true, target1);
|
|
14168
|
-
return;
|
|
14169
|
-
} else if (d2 >= 0 && d2 <= 1) {
|
|
14170
|
-
if (d < 0) {
|
|
14171
|
-
l1.at(0, target1);
|
|
14172
|
-
} else {
|
|
14173
|
-
l1.at(1, target1);
|
|
14174
|
-
}
|
|
14175
|
-
l2.closestPointToPoint(target1, true, target2);
|
|
14176
|
-
return;
|
|
14177
|
-
} else {
|
|
14178
|
-
let p2;
|
|
14179
|
-
if (d < 0) {
|
|
14180
|
-
p2 = l1.start;
|
|
14181
|
-
} else {
|
|
14182
|
-
p2 = l1.end;
|
|
14183
|
-
}
|
|
14184
|
-
let p22;
|
|
14185
|
-
if (d2 < 0) {
|
|
14186
|
-
p22 = l2.start;
|
|
14187
|
-
} else {
|
|
14188
|
-
p22 = l2.end;
|
|
14189
|
-
}
|
|
14190
|
-
const closestPoint = temp12;
|
|
14191
|
-
const closestPoint2 = temp22;
|
|
14192
|
-
l1.closestPointToPoint(p22, true, temp12);
|
|
14193
|
-
l2.closestPointToPoint(p2, true, temp22);
|
|
14194
|
-
if (closestPoint.distanceToSquared(p22) <= closestPoint2.distanceToSquared(p2)) {
|
|
14195
|
-
target1.copy(closestPoint);
|
|
14196
|
-
target2.copy(p22);
|
|
14197
|
-
return;
|
|
14198
|
-
} else {
|
|
14199
|
-
target1.copy(p2);
|
|
14200
|
-
target2.copy(closestPoint2);
|
|
14201
|
-
return;
|
|
14202
|
-
}
|
|
14203
|
-
}
|
|
14204
|
-
};
|
|
14205
|
-
})();
|
|
14206
|
-
const sphereIntersectTriangle = (function() {
|
|
14207
|
-
const closestPointTemp = new Vector3();
|
|
14208
|
-
const projectedPointTemp = new Vector3();
|
|
14209
|
-
const planeTemp = new Plane();
|
|
14210
|
-
const lineTemp = new Line3();
|
|
14211
|
-
return function sphereIntersectTriangle2(sphere, triangle3) {
|
|
14212
|
-
const { radius, center } = sphere;
|
|
14213
|
-
const { a: a2, b: b2, c: c2 } = triangle3;
|
|
14214
|
-
lineTemp.start = a2;
|
|
14215
|
-
lineTemp.end = b2;
|
|
14216
|
-
const closestPoint1 = lineTemp.closestPointToPoint(center, true, closestPointTemp);
|
|
14217
|
-
if (closestPoint1.distanceTo(center) <= radius) return true;
|
|
14218
|
-
lineTemp.start = a2;
|
|
14219
|
-
lineTemp.end = c2;
|
|
14220
|
-
const closestPoint2 = lineTemp.closestPointToPoint(center, true, closestPointTemp);
|
|
14221
|
-
if (closestPoint2.distanceTo(center) <= radius) return true;
|
|
14222
|
-
lineTemp.start = b2;
|
|
14223
|
-
lineTemp.end = c2;
|
|
14224
|
-
const closestPoint3 = lineTemp.closestPointToPoint(center, true, closestPointTemp);
|
|
14225
|
-
if (closestPoint3.distanceTo(center) <= radius) return true;
|
|
14226
|
-
const plane = triangle3.getPlane(planeTemp);
|
|
14227
|
-
const dp = Math.abs(plane.distanceToPoint(center));
|
|
14228
|
-
if (dp <= radius) {
|
|
14229
|
-
const pp = plane.projectPoint(center, projectedPointTemp);
|
|
14230
|
-
const cp = triangle3.containsPoint(pp);
|
|
14231
|
-
if (cp) return true;
|
|
14232
|
-
}
|
|
14233
|
-
return false;
|
|
14234
|
-
};
|
|
14235
|
-
})();
|
|
14236
|
-
const ZERO_EPSILON = 1e-15;
|
|
14237
|
-
function isNearZero(value) {
|
|
14238
|
-
return Math.abs(value) < ZERO_EPSILON;
|
|
14239
|
-
}
|
|
14240
|
-
class ExtendedTriangle extends Triangle {
|
|
14241
|
-
constructor(...args) {
|
|
14242
|
-
super(...args);
|
|
14243
|
-
this.isExtendedTriangle = true;
|
|
14244
|
-
this.satAxes = new Array(4).fill().map(() => new Vector3());
|
|
14245
|
-
this.satBounds = new Array(4).fill().map(() => new SeparatingAxisBounds());
|
|
14246
|
-
this.points = [this.a, this.b, this.c];
|
|
14247
|
-
this.sphere = new Sphere();
|
|
14248
|
-
this.plane = new Plane();
|
|
14249
|
-
this.needsUpdate = true;
|
|
14250
|
-
}
|
|
14251
|
-
intersectsSphere(sphere) {
|
|
14252
|
-
return sphereIntersectTriangle(sphere, this);
|
|
14253
|
-
}
|
|
14254
|
-
update() {
|
|
14255
|
-
const a2 = this.a;
|
|
14256
|
-
const b2 = this.b;
|
|
14257
|
-
const c2 = this.c;
|
|
14258
|
-
const points = this.points;
|
|
14259
|
-
const satAxes = this.satAxes;
|
|
14260
|
-
const satBounds = this.satBounds;
|
|
14261
|
-
const axis0 = satAxes[0];
|
|
14262
|
-
const sab0 = satBounds[0];
|
|
14263
|
-
this.getNormal(axis0);
|
|
14264
|
-
sab0.setFromPoints(axis0, points);
|
|
14265
|
-
const axis1 = satAxes[1];
|
|
14266
|
-
const sab1 = satBounds[1];
|
|
14267
|
-
axis1.subVectors(a2, b2);
|
|
14268
|
-
sab1.setFromPoints(axis1, points);
|
|
14269
|
-
const axis2 = satAxes[2];
|
|
14270
|
-
const sab2 = satBounds[2];
|
|
14271
|
-
axis2.subVectors(b2, c2);
|
|
14272
|
-
sab2.setFromPoints(axis2, points);
|
|
14273
|
-
const axis3 = satAxes[3];
|
|
14274
|
-
const sab3 = satBounds[3];
|
|
14275
|
-
axis3.subVectors(c2, a2);
|
|
14276
|
-
sab3.setFromPoints(axis3, points);
|
|
14277
|
-
this.sphere.setFromPoints(this.points);
|
|
14278
|
-
this.plane.setFromNormalAndCoplanarPoint(axis0, a2);
|
|
14279
|
-
this.needsUpdate = false;
|
|
14280
|
-
}
|
|
14281
|
-
}
|
|
14282
|
-
ExtendedTriangle.prototype.closestPointToSegment = (function() {
|
|
14283
|
-
const point1 = new Vector3();
|
|
14284
|
-
const point2 = new Vector3();
|
|
14285
|
-
const edge = new Line3();
|
|
14286
|
-
return function distanceToSegment(segment, target1 = null, target2 = null) {
|
|
14287
|
-
const { start, end } = segment;
|
|
14288
|
-
const points = this.points;
|
|
14289
|
-
let distSq;
|
|
14290
|
-
let closestDistanceSq = Infinity;
|
|
14291
|
-
for (let i = 0; i < 3; i++) {
|
|
14292
|
-
const nexti = (i + 1) % 3;
|
|
14293
|
-
edge.start.copy(points[i]);
|
|
14294
|
-
edge.end.copy(points[nexti]);
|
|
14295
|
-
closestPointsSegmentToSegment(edge, segment, point1, point2);
|
|
14296
|
-
distSq = point1.distanceToSquared(point2);
|
|
14297
|
-
if (distSq < closestDistanceSq) {
|
|
14298
|
-
closestDistanceSq = distSq;
|
|
14299
|
-
if (target1) target1.copy(point1);
|
|
14300
|
-
if (target2) target2.copy(point2);
|
|
14301
|
-
}
|
|
14302
|
-
}
|
|
14303
|
-
this.closestPointToPoint(start, point1);
|
|
14304
|
-
distSq = start.distanceToSquared(point1);
|
|
14305
|
-
if (distSq < closestDistanceSq) {
|
|
14306
|
-
closestDistanceSq = distSq;
|
|
14307
|
-
if (target1) target1.copy(point1);
|
|
14308
|
-
if (target2) target2.copy(start);
|
|
14309
|
-
}
|
|
14310
|
-
this.closestPointToPoint(end, point1);
|
|
14311
|
-
distSq = end.distanceToSquared(point1);
|
|
14312
|
-
if (distSq < closestDistanceSq) {
|
|
14313
|
-
closestDistanceSq = distSq;
|
|
14314
|
-
if (target1) target1.copy(point1);
|
|
14315
|
-
if (target2) target2.copy(end);
|
|
14316
|
-
}
|
|
14317
|
-
return Math.sqrt(closestDistanceSq);
|
|
14318
|
-
};
|
|
14319
|
-
})();
|
|
14320
|
-
ExtendedTriangle.prototype.intersectsTriangle = (function() {
|
|
14321
|
-
const saTri2 = new ExtendedTriangle();
|
|
14322
|
-
const arr1 = new Array(3);
|
|
14323
|
-
const arr2 = new Array(3);
|
|
14324
|
-
const cachedSatBounds = new SeparatingAxisBounds();
|
|
14325
|
-
const cachedSatBounds2 = new SeparatingAxisBounds();
|
|
14326
|
-
const cachedAxis = new Vector3();
|
|
14327
|
-
const dir = new Vector3();
|
|
14328
|
-
const dir1 = new Vector3();
|
|
14329
|
-
const dir2 = new Vector3();
|
|
14330
|
-
const tempDir = new Vector3();
|
|
14331
|
-
const edge = new Line3();
|
|
14332
|
-
const edge1 = new Line3();
|
|
14333
|
-
const edge2 = new Line3();
|
|
14334
|
-
const tempPoint = new Vector3();
|
|
14335
|
-
function triIntersectPlane(tri, plane, targetEdge) {
|
|
14336
|
-
const points = tri.points;
|
|
14337
|
-
let count = 0;
|
|
14338
|
-
let startPointIntersection = -1;
|
|
14339
|
-
for (let i = 0; i < 3; i++) {
|
|
14340
|
-
const { start, end } = edge;
|
|
14341
|
-
start.copy(points[i]);
|
|
14342
|
-
end.copy(points[(i + 1) % 3]);
|
|
14343
|
-
edge.delta(dir);
|
|
14344
|
-
const startIntersects = isNearZero(plane.distanceToPoint(start));
|
|
14345
|
-
if (isNearZero(plane.normal.dot(dir)) && startIntersects) {
|
|
14346
|
-
targetEdge.copy(edge);
|
|
14347
|
-
count = 2;
|
|
14348
|
-
break;
|
|
14349
|
-
}
|
|
14350
|
-
const doesIntersect = plane.intersectLine(edge, tempPoint);
|
|
14351
|
-
if (!doesIntersect && startIntersects) {
|
|
14352
|
-
tempPoint.copy(start);
|
|
14353
|
-
}
|
|
14354
|
-
if ((doesIntersect || startIntersects) && !isNearZero(tempPoint.distanceTo(end))) {
|
|
14355
|
-
if (count <= 1) {
|
|
14356
|
-
const point = count === 1 ? targetEdge.start : targetEdge.end;
|
|
14357
|
-
point.copy(tempPoint);
|
|
14358
|
-
if (startIntersects) {
|
|
14359
|
-
startPointIntersection = count;
|
|
14360
|
-
}
|
|
14361
|
-
} else if (count >= 2) {
|
|
14362
|
-
const point = startPointIntersection === 1 ? targetEdge.start : targetEdge.end;
|
|
14363
|
-
point.copy(tempPoint);
|
|
14364
|
-
count = 2;
|
|
14365
|
-
break;
|
|
14366
|
-
}
|
|
14367
|
-
count++;
|
|
14368
|
-
if (count === 2 && startPointIntersection === -1) {
|
|
14369
|
-
break;
|
|
14370
|
-
}
|
|
14371
|
-
}
|
|
14372
|
-
}
|
|
14373
|
-
return count;
|
|
14374
|
-
}
|
|
14375
|
-
return function intersectsTriangle(other, target = null, suppressLog = false) {
|
|
14376
|
-
if (this.needsUpdate) {
|
|
14377
|
-
this.update();
|
|
14378
|
-
}
|
|
14379
|
-
if (!other.isExtendedTriangle) {
|
|
14380
|
-
saTri2.copy(other);
|
|
14381
|
-
saTri2.update();
|
|
14382
|
-
other = saTri2;
|
|
14383
|
-
} else if (other.needsUpdate) {
|
|
14384
|
-
other.update();
|
|
14385
|
-
}
|
|
14386
|
-
const plane1 = this.plane;
|
|
14387
|
-
const plane2 = other.plane;
|
|
14388
|
-
if (Math.abs(plane1.normal.dot(plane2.normal)) > 1 - 1e-10) {
|
|
14389
|
-
const satBounds1 = this.satBounds;
|
|
14390
|
-
const satAxes1 = this.satAxes;
|
|
14391
|
-
arr2[0] = other.a;
|
|
14392
|
-
arr2[1] = other.b;
|
|
14393
|
-
arr2[2] = other.c;
|
|
14394
|
-
for (let i = 0; i < 4; i++) {
|
|
14395
|
-
const sb = satBounds1[i];
|
|
14396
|
-
const sa = satAxes1[i];
|
|
14397
|
-
cachedSatBounds.setFromPoints(sa, arr2);
|
|
14398
|
-
if (sb.isSeparated(cachedSatBounds)) return false;
|
|
14399
|
-
}
|
|
14400
|
-
const satBounds2 = other.satBounds;
|
|
14401
|
-
const satAxes2 = other.satAxes;
|
|
14402
|
-
arr1[0] = this.a;
|
|
14403
|
-
arr1[1] = this.b;
|
|
14404
|
-
arr1[2] = this.c;
|
|
14405
|
-
for (let i = 0; i < 4; i++) {
|
|
14406
|
-
const sb = satBounds2[i];
|
|
14407
|
-
const sa = satAxes2[i];
|
|
14408
|
-
cachedSatBounds.setFromPoints(sa, arr1);
|
|
14409
|
-
if (sb.isSeparated(cachedSatBounds)) return false;
|
|
14410
|
-
}
|
|
14411
|
-
for (let i = 0; i < 4; i++) {
|
|
14412
|
-
const sa1 = satAxes1[i];
|
|
14413
|
-
for (let i2 = 0; i2 < 4; i2++) {
|
|
14414
|
-
const sa2 = satAxes2[i2];
|
|
14415
|
-
cachedAxis.crossVectors(sa1, sa2);
|
|
14416
|
-
cachedSatBounds.setFromPoints(cachedAxis, arr1);
|
|
14417
|
-
cachedSatBounds2.setFromPoints(cachedAxis, arr2);
|
|
14418
|
-
if (cachedSatBounds.isSeparated(cachedSatBounds2)) return false;
|
|
14419
|
-
}
|
|
14420
|
-
}
|
|
14421
|
-
if (target) {
|
|
14422
|
-
if (!suppressLog) {
|
|
14423
|
-
console.warn("ExtendedTriangle.intersectsTriangle: Triangles are coplanar which does not support an output edge. Setting edge to 0, 0, 0.");
|
|
14424
|
-
}
|
|
14425
|
-
target.start.set(0, 0, 0);
|
|
14426
|
-
target.end.set(0, 0, 0);
|
|
14427
|
-
}
|
|
14428
|
-
return true;
|
|
14429
|
-
} else {
|
|
14430
|
-
const count1 = triIntersectPlane(this, plane2, edge1);
|
|
14431
|
-
if (count1 === 1 && other.containsPoint(edge1.end)) {
|
|
14432
|
-
if (target) {
|
|
14433
|
-
target.start.copy(edge1.end);
|
|
14434
|
-
target.end.copy(edge1.end);
|
|
14435
|
-
}
|
|
14436
|
-
return true;
|
|
14437
|
-
} else if (count1 !== 2) {
|
|
14438
|
-
return false;
|
|
14439
|
-
}
|
|
14440
|
-
const count2 = triIntersectPlane(other, plane1, edge2);
|
|
14441
|
-
if (count2 === 1 && this.containsPoint(edge2.end)) {
|
|
14442
|
-
if (target) {
|
|
14443
|
-
target.start.copy(edge2.end);
|
|
14444
|
-
target.end.copy(edge2.end);
|
|
14445
|
-
}
|
|
14446
|
-
return true;
|
|
14447
|
-
} else if (count2 !== 2) {
|
|
14448
|
-
return false;
|
|
14449
|
-
}
|
|
14450
|
-
edge1.delta(dir1);
|
|
14451
|
-
edge2.delta(dir2);
|
|
14452
|
-
if (dir1.dot(dir2) < 0) {
|
|
14453
|
-
let tmp = edge2.start;
|
|
14454
|
-
edge2.start = edge2.end;
|
|
14455
|
-
edge2.end = tmp;
|
|
14456
|
-
}
|
|
14457
|
-
const s1 = edge1.start.dot(dir1);
|
|
14458
|
-
const e1 = edge1.end.dot(dir1);
|
|
14459
|
-
const s2 = edge2.start.dot(dir1);
|
|
14460
|
-
const e2 = edge2.end.dot(dir1);
|
|
14461
|
-
const separated1 = e1 < s2;
|
|
14462
|
-
const separated2 = s1 < e2;
|
|
14463
|
-
if (s1 !== e2 && s2 !== e1 && separated1 === separated2) {
|
|
14464
|
-
return false;
|
|
14465
|
-
}
|
|
14466
|
-
if (target) {
|
|
14467
|
-
tempDir.subVectors(edge1.start, edge2.start);
|
|
14468
|
-
if (tempDir.dot(dir1) > 0) {
|
|
14469
|
-
target.start.copy(edge1.start);
|
|
14470
|
-
} else {
|
|
14471
|
-
target.start.copy(edge2.start);
|
|
14472
|
-
}
|
|
14473
|
-
tempDir.subVectors(edge1.end, edge2.end);
|
|
14474
|
-
if (tempDir.dot(dir1) < 0) {
|
|
14475
|
-
target.end.copy(edge1.end);
|
|
14476
|
-
} else {
|
|
14477
|
-
target.end.copy(edge2.end);
|
|
14478
|
-
}
|
|
14479
|
-
}
|
|
14480
|
-
return true;
|
|
14481
|
-
}
|
|
14482
|
-
};
|
|
14483
|
-
})();
|
|
14484
|
-
ExtendedTriangle.prototype.distanceToPoint = (function() {
|
|
14485
|
-
const target = new Vector3();
|
|
14486
|
-
return function distanceToPoint(point) {
|
|
14487
|
-
this.closestPointToPoint(point, target);
|
|
14488
|
-
return point.distanceTo(target);
|
|
14489
|
-
};
|
|
14490
|
-
})();
|
|
14491
|
-
ExtendedTriangle.prototype.distanceToTriangle = (function() {
|
|
14492
|
-
const point = new Vector3();
|
|
14493
|
-
const point2 = new Vector3();
|
|
14494
|
-
const cornerFields = ["a", "b", "c"];
|
|
14495
|
-
const line1 = new Line3();
|
|
14496
|
-
const line2 = new Line3();
|
|
14497
|
-
return function distanceToTriangle(other, target1 = null, target2 = null) {
|
|
14498
|
-
const lineTarget = target1 || target2 ? line1 : null;
|
|
14499
|
-
if (this.intersectsTriangle(other, lineTarget)) {
|
|
14500
|
-
if (target1 || target2) {
|
|
14501
|
-
if (target1) lineTarget.getCenter(target1);
|
|
14502
|
-
if (target2) lineTarget.getCenter(target2);
|
|
14503
|
-
}
|
|
14504
|
-
return 0;
|
|
14505
|
-
}
|
|
14506
|
-
let closestDistanceSq = Infinity;
|
|
14507
|
-
for (let i = 0; i < 3; i++) {
|
|
14508
|
-
let dist;
|
|
14509
|
-
const field = cornerFields[i];
|
|
14510
|
-
const otherVec = other[field];
|
|
14511
|
-
this.closestPointToPoint(otherVec, point);
|
|
14512
|
-
dist = otherVec.distanceToSquared(point);
|
|
14513
|
-
if (dist < closestDistanceSq) {
|
|
14514
|
-
closestDistanceSq = dist;
|
|
14515
|
-
if (target1) target1.copy(point);
|
|
14516
|
-
if (target2) target2.copy(otherVec);
|
|
14517
|
-
}
|
|
14518
|
-
const thisVec = this[field];
|
|
14519
|
-
other.closestPointToPoint(thisVec, point);
|
|
14520
|
-
dist = thisVec.distanceToSquared(point);
|
|
14521
|
-
if (dist < closestDistanceSq) {
|
|
14522
|
-
closestDistanceSq = dist;
|
|
14523
|
-
if (target1) target1.copy(thisVec);
|
|
14524
|
-
if (target2) target2.copy(point);
|
|
14525
|
-
}
|
|
14526
|
-
}
|
|
14527
|
-
for (let i = 0; i < 3; i++) {
|
|
14528
|
-
const f11 = cornerFields[i];
|
|
14529
|
-
const f12 = cornerFields[(i + 1) % 3];
|
|
14530
|
-
line1.set(this[f11], this[f12]);
|
|
14531
|
-
for (let i2 = 0; i2 < 3; i2++) {
|
|
14532
|
-
const f21 = cornerFields[i2];
|
|
14533
|
-
const f22 = cornerFields[(i2 + 1) % 3];
|
|
14534
|
-
line2.set(other[f21], other[f22]);
|
|
14535
|
-
closestPointsSegmentToSegment(line1, line2, point, point2);
|
|
14536
|
-
const dist = point.distanceToSquared(point2);
|
|
14537
|
-
if (dist < closestDistanceSq) {
|
|
14538
|
-
closestDistanceSq = dist;
|
|
14539
|
-
if (target1) target1.copy(point);
|
|
14540
|
-
if (target2) target2.copy(point2);
|
|
14541
|
-
}
|
|
14542
|
-
}
|
|
14543
|
-
}
|
|
14544
|
-
return Math.sqrt(closestDistanceSq);
|
|
14545
|
-
};
|
|
14546
|
-
})();
|
|
14547
|
-
class OrientedBox {
|
|
14548
|
-
constructor(min, max2, matrix) {
|
|
14549
|
-
this.isOrientedBox = true;
|
|
14550
|
-
this.min = new Vector3();
|
|
14551
|
-
this.max = new Vector3();
|
|
14552
|
-
this.matrix = new Matrix4();
|
|
14553
|
-
this.invMatrix = new Matrix4();
|
|
14554
|
-
this.points = new Array(8).fill().map(() => new Vector3());
|
|
14555
|
-
this.satAxes = new Array(3).fill().map(() => new Vector3());
|
|
14556
|
-
this.satBounds = new Array(3).fill().map(() => new SeparatingAxisBounds());
|
|
14557
|
-
this.alignedSatBounds = new Array(3).fill().map(() => new SeparatingAxisBounds());
|
|
14558
|
-
this.needsUpdate = false;
|
|
14559
|
-
if (min) this.min.copy(min);
|
|
14560
|
-
if (max2) this.max.copy(max2);
|
|
14561
|
-
if (matrix) this.matrix.copy(matrix);
|
|
14562
|
-
}
|
|
14563
|
-
set(min, max2, matrix) {
|
|
14564
|
-
this.min.copy(min);
|
|
14565
|
-
this.max.copy(max2);
|
|
14566
|
-
this.matrix.copy(matrix);
|
|
14567
|
-
this.needsUpdate = true;
|
|
14568
|
-
}
|
|
14569
|
-
copy(other) {
|
|
14570
|
-
this.min.copy(other.min);
|
|
14571
|
-
this.max.copy(other.max);
|
|
14572
|
-
this.matrix.copy(other.matrix);
|
|
14573
|
-
this.needsUpdate = true;
|
|
14574
|
-
}
|
|
14575
|
-
}
|
|
14576
|
-
OrientedBox.prototype.update = /* @__PURE__ */ (function() {
|
|
14577
|
-
return function update2() {
|
|
14578
|
-
const matrix = this.matrix;
|
|
14579
|
-
const min = this.min;
|
|
14580
|
-
const max2 = this.max;
|
|
14581
|
-
const points = this.points;
|
|
14582
|
-
for (let x = 0; x <= 1; x++) {
|
|
14583
|
-
for (let y = 0; y <= 1; y++) {
|
|
14584
|
-
for (let z = 0; z <= 1; z++) {
|
|
14585
|
-
const i = (1 << 0) * x | (1 << 1) * y | (1 << 2) * z;
|
|
14586
|
-
const v = points[i];
|
|
14587
|
-
v.x = x ? max2.x : min.x;
|
|
14588
|
-
v.y = y ? max2.y : min.y;
|
|
14589
|
-
v.z = z ? max2.z : min.z;
|
|
14590
|
-
v.applyMatrix4(matrix);
|
|
14591
|
-
}
|
|
14592
|
-
}
|
|
14593
|
-
}
|
|
14594
|
-
const satBounds = this.satBounds;
|
|
14595
|
-
const satAxes = this.satAxes;
|
|
14596
|
-
const minVec = points[0];
|
|
14597
|
-
for (let i = 0; i < 3; i++) {
|
|
14598
|
-
const axis = satAxes[i];
|
|
14599
|
-
const sb = satBounds[i];
|
|
14600
|
-
const index = 1 << i;
|
|
14601
|
-
const pi = points[index];
|
|
14602
|
-
axis.subVectors(minVec, pi);
|
|
14603
|
-
sb.setFromPoints(axis, points);
|
|
14604
|
-
}
|
|
14605
|
-
const alignedSatBounds = this.alignedSatBounds;
|
|
14606
|
-
alignedSatBounds[0].setFromPointsField(points, "x");
|
|
14607
|
-
alignedSatBounds[1].setFromPointsField(points, "y");
|
|
14608
|
-
alignedSatBounds[2].setFromPointsField(points, "z");
|
|
14609
|
-
this.invMatrix.copy(this.matrix).invert();
|
|
14610
|
-
this.needsUpdate = false;
|
|
14611
|
-
};
|
|
14612
|
-
})();
|
|
14613
|
-
OrientedBox.prototype.intersectsBox = (function() {
|
|
14614
|
-
const aabbBounds = new SeparatingAxisBounds();
|
|
14615
|
-
return function intersectsBox(box2) {
|
|
14616
|
-
if (this.needsUpdate) {
|
|
14617
|
-
this.update();
|
|
14618
|
-
}
|
|
14619
|
-
const min = box2.min;
|
|
14620
|
-
const max2 = box2.max;
|
|
14621
|
-
const satBounds = this.satBounds;
|
|
14622
|
-
const satAxes = this.satAxes;
|
|
14623
|
-
const alignedSatBounds = this.alignedSatBounds;
|
|
14624
|
-
aabbBounds.min = min.x;
|
|
14625
|
-
aabbBounds.max = max2.x;
|
|
14626
|
-
if (alignedSatBounds[0].isSeparated(aabbBounds)) return false;
|
|
14627
|
-
aabbBounds.min = min.y;
|
|
14628
|
-
aabbBounds.max = max2.y;
|
|
14629
|
-
if (alignedSatBounds[1].isSeparated(aabbBounds)) return false;
|
|
14630
|
-
aabbBounds.min = min.z;
|
|
14631
|
-
aabbBounds.max = max2.z;
|
|
14632
|
-
if (alignedSatBounds[2].isSeparated(aabbBounds)) return false;
|
|
14633
|
-
for (let i = 0; i < 3; i++) {
|
|
14634
|
-
const axis = satAxes[i];
|
|
14635
|
-
const sb = satBounds[i];
|
|
14636
|
-
aabbBounds.setFromBox(axis, box2);
|
|
14637
|
-
if (sb.isSeparated(aabbBounds)) return false;
|
|
14638
|
-
}
|
|
14639
|
-
return true;
|
|
14640
|
-
};
|
|
14641
|
-
})();
|
|
14642
|
-
OrientedBox.prototype.intersectsTriangle = (function() {
|
|
14643
|
-
const saTri = new ExtendedTriangle();
|
|
14644
|
-
const pointsArr = new Array(3);
|
|
14645
|
-
const cachedSatBounds = new SeparatingAxisBounds();
|
|
14646
|
-
const cachedSatBounds2 = new SeparatingAxisBounds();
|
|
14647
|
-
const cachedAxis = new Vector3();
|
|
14648
|
-
return function intersectsTriangle(triangle3) {
|
|
14649
|
-
if (this.needsUpdate) {
|
|
14650
|
-
this.update();
|
|
14651
|
-
}
|
|
14652
|
-
if (!triangle3.isExtendedTriangle) {
|
|
14653
|
-
saTri.copy(triangle3);
|
|
14654
|
-
saTri.update();
|
|
14655
|
-
triangle3 = saTri;
|
|
14656
|
-
} else if (triangle3.needsUpdate) {
|
|
14657
|
-
triangle3.update();
|
|
14658
|
-
}
|
|
14659
|
-
const satBounds = this.satBounds;
|
|
14660
|
-
const satAxes = this.satAxes;
|
|
14661
|
-
pointsArr[0] = triangle3.a;
|
|
14662
|
-
pointsArr[1] = triangle3.b;
|
|
14663
|
-
pointsArr[2] = triangle3.c;
|
|
14664
|
-
for (let i = 0; i < 3; i++) {
|
|
14665
|
-
const sb = satBounds[i];
|
|
14666
|
-
const sa = satAxes[i];
|
|
14667
|
-
cachedSatBounds.setFromPoints(sa, pointsArr);
|
|
14668
|
-
if (sb.isSeparated(cachedSatBounds)) return false;
|
|
14669
|
-
}
|
|
14670
|
-
const triSatBounds = triangle3.satBounds;
|
|
14671
|
-
const triSatAxes = triangle3.satAxes;
|
|
14672
|
-
const points = this.points;
|
|
14673
|
-
for (let i = 0; i < 3; i++) {
|
|
14674
|
-
const sb = triSatBounds[i];
|
|
14675
|
-
const sa = triSatAxes[i];
|
|
14676
|
-
cachedSatBounds.setFromPoints(sa, points);
|
|
14677
|
-
if (sb.isSeparated(cachedSatBounds)) return false;
|
|
14678
|
-
}
|
|
14679
|
-
for (let i = 0; i < 3; i++) {
|
|
14680
|
-
const sa1 = satAxes[i];
|
|
14681
|
-
for (let i2 = 0; i2 < 4; i2++) {
|
|
14682
|
-
const sa2 = triSatAxes[i2];
|
|
14683
|
-
cachedAxis.crossVectors(sa1, sa2);
|
|
14684
|
-
cachedSatBounds.setFromPoints(cachedAxis, pointsArr);
|
|
14685
|
-
cachedSatBounds2.setFromPoints(cachedAxis, points);
|
|
14686
|
-
if (cachedSatBounds.isSeparated(cachedSatBounds2)) return false;
|
|
14687
|
-
}
|
|
14688
|
-
}
|
|
14689
|
-
return true;
|
|
14690
|
-
};
|
|
14691
|
-
})();
|
|
14692
|
-
OrientedBox.prototype.closestPointToPoint = /* @__PURE__ */ (function() {
|
|
14693
|
-
return function closestPointToPoint2(point, target1) {
|
|
14694
|
-
if (this.needsUpdate) {
|
|
14695
|
-
this.update();
|
|
14696
|
-
}
|
|
14697
|
-
target1.copy(point).applyMatrix4(this.invMatrix).clamp(this.min, this.max).applyMatrix4(this.matrix);
|
|
14698
|
-
return target1;
|
|
14699
|
-
};
|
|
14700
|
-
})();
|
|
14701
|
-
OrientedBox.prototype.distanceToPoint = (function() {
|
|
14702
|
-
const target = new Vector3();
|
|
14703
|
-
return function distanceToPoint(point) {
|
|
14704
|
-
this.closestPointToPoint(point, target);
|
|
14705
|
-
return point.distanceTo(target);
|
|
14706
|
-
};
|
|
14707
|
-
})();
|
|
14708
|
-
OrientedBox.prototype.distanceToBox = (function() {
|
|
14709
|
-
const xyzFields = ["x", "y", "z"];
|
|
14710
|
-
const segments1 = new Array(12).fill().map(() => new Line3());
|
|
14711
|
-
const segments2 = new Array(12).fill().map(() => new Line3());
|
|
14712
|
-
const point1 = new Vector3();
|
|
14713
|
-
const point2 = new Vector3();
|
|
14714
|
-
return function distanceToBox(box2, threshold = 0, target1 = null, target2 = null) {
|
|
14715
|
-
if (this.needsUpdate) {
|
|
14716
|
-
this.update();
|
|
14717
|
-
}
|
|
14718
|
-
if (this.intersectsBox(box2)) {
|
|
14719
|
-
if (target1 || target2) {
|
|
14720
|
-
box2.getCenter(point2);
|
|
14721
|
-
this.closestPointToPoint(point2, point1);
|
|
14722
|
-
box2.closestPointToPoint(point1, point2);
|
|
14723
|
-
if (target1) target1.copy(point1);
|
|
14724
|
-
if (target2) target2.copy(point2);
|
|
14725
|
-
}
|
|
14726
|
-
return 0;
|
|
14727
|
-
}
|
|
14728
|
-
const threshold2 = threshold * threshold;
|
|
14729
|
-
const min = box2.min;
|
|
14730
|
-
const max2 = box2.max;
|
|
14731
|
-
const points = this.points;
|
|
14732
|
-
let closestDistanceSq = Infinity;
|
|
14733
|
-
for (let i = 0; i < 8; i++) {
|
|
14734
|
-
const p2 = points[i];
|
|
14735
|
-
point2.copy(p2).clamp(min, max2);
|
|
14736
|
-
const dist = p2.distanceToSquared(point2);
|
|
14737
|
-
if (dist < closestDistanceSq) {
|
|
14738
|
-
closestDistanceSq = dist;
|
|
14739
|
-
if (target1) target1.copy(p2);
|
|
14740
|
-
if (target2) target2.copy(point2);
|
|
14741
|
-
if (dist < threshold2) return Math.sqrt(dist);
|
|
14742
|
-
}
|
|
14743
|
-
}
|
|
14744
|
-
let count = 0;
|
|
14745
|
-
for (let i = 0; i < 3; i++) {
|
|
14746
|
-
for (let i1 = 0; i1 <= 1; i1++) {
|
|
14747
|
-
for (let i2 = 0; i2 <= 1; i2++) {
|
|
14748
|
-
const nextIndex = (i + 1) % 3;
|
|
14749
|
-
const nextIndex2 = (i + 2) % 3;
|
|
14750
|
-
const index = i1 << nextIndex | i2 << nextIndex2;
|
|
14751
|
-
const index2 = 1 << i | i1 << nextIndex | i2 << nextIndex2;
|
|
14752
|
-
const p1 = points[index];
|
|
14753
|
-
const p2 = points[index2];
|
|
14754
|
-
const line1 = segments1[count];
|
|
14755
|
-
line1.set(p1, p2);
|
|
14756
|
-
const f1 = xyzFields[i];
|
|
14757
|
-
const f2 = xyzFields[nextIndex];
|
|
14758
|
-
const f3 = xyzFields[nextIndex2];
|
|
14759
|
-
const line2 = segments2[count];
|
|
14760
|
-
const start = line2.start;
|
|
14761
|
-
const end = line2.end;
|
|
14762
|
-
start[f1] = min[f1];
|
|
14763
|
-
start[f2] = i1 ? min[f2] : max2[f2];
|
|
14764
|
-
start[f3] = i2 ? min[f3] : max2[f2];
|
|
14765
|
-
end[f1] = max2[f1];
|
|
14766
|
-
end[f2] = i1 ? min[f2] : max2[f2];
|
|
14767
|
-
end[f3] = i2 ? min[f3] : max2[f2];
|
|
14768
|
-
count++;
|
|
14769
|
-
}
|
|
14770
|
-
}
|
|
14771
|
-
}
|
|
14772
|
-
for (let x = 0; x <= 1; x++) {
|
|
14773
|
-
for (let y = 0; y <= 1; y++) {
|
|
14774
|
-
for (let z = 0; z <= 1; z++) {
|
|
14775
|
-
point2.x = x ? max2.x : min.x;
|
|
14776
|
-
point2.y = y ? max2.y : min.y;
|
|
14777
|
-
point2.z = z ? max2.z : min.z;
|
|
14778
|
-
this.closestPointToPoint(point2, point1);
|
|
14779
|
-
const dist = point2.distanceToSquared(point1);
|
|
14780
|
-
if (dist < closestDistanceSq) {
|
|
14781
|
-
closestDistanceSq = dist;
|
|
14782
|
-
if (target1) target1.copy(point1);
|
|
14783
|
-
if (target2) target2.copy(point2);
|
|
14784
|
-
if (dist < threshold2) return Math.sqrt(dist);
|
|
14785
|
-
}
|
|
14786
|
-
}
|
|
14787
|
-
}
|
|
14788
|
-
}
|
|
14789
|
-
for (let i = 0; i < 12; i++) {
|
|
14790
|
-
const l1 = segments1[i];
|
|
14791
|
-
for (let i2 = 0; i2 < 12; i2++) {
|
|
14792
|
-
const l2 = segments2[i2];
|
|
14793
|
-
closestPointsSegmentToSegment(l1, l2, point1, point2);
|
|
14794
|
-
const dist = point1.distanceToSquared(point2);
|
|
14795
|
-
if (dist < closestDistanceSq) {
|
|
14796
|
-
closestDistanceSq = dist;
|
|
14797
|
-
if (target1) target1.copy(point1);
|
|
14798
|
-
if (target2) target2.copy(point2);
|
|
14799
|
-
if (dist < threshold2) return Math.sqrt(dist);
|
|
14800
|
-
}
|
|
14801
|
-
}
|
|
14802
|
-
}
|
|
14803
|
-
return Math.sqrt(closestDistanceSq);
|
|
14804
|
-
};
|
|
14805
|
-
})();
|
|
14806
|
-
class PrimitivePool {
|
|
14807
|
-
constructor(getNewPrimitive) {
|
|
14808
|
-
this._getNewPrimitive = getNewPrimitive;
|
|
14809
|
-
this._primitives = [];
|
|
14810
|
-
}
|
|
14811
|
-
getPrimitive() {
|
|
14812
|
-
const primitives = this._primitives;
|
|
14813
|
-
if (primitives.length === 0) {
|
|
14814
|
-
return this._getNewPrimitive();
|
|
14815
|
-
} else {
|
|
14816
|
-
return primitives.pop();
|
|
14817
|
-
}
|
|
14818
|
-
}
|
|
14819
|
-
releasePrimitive(primitive) {
|
|
14820
|
-
this._primitives.push(primitive);
|
|
14821
|
-
}
|
|
14822
|
-
}
|
|
14823
|
-
class ExtendedTrianglePoolBase extends PrimitivePool {
|
|
14824
|
-
constructor() {
|
|
14825
|
-
super(() => new ExtendedTriangle());
|
|
14826
|
-
}
|
|
14827
|
-
}
|
|
14828
|
-
const ExtendedTrianglePool = /* @__PURE__ */ new ExtendedTrianglePoolBase();
|
|
14829
|
-
class _BufferStack {
|
|
14830
|
-
constructor() {
|
|
14831
|
-
this.float32Array = null;
|
|
14832
|
-
this.uint16Array = null;
|
|
14833
|
-
this.uint32Array = null;
|
|
14834
|
-
const stack = [];
|
|
14835
|
-
let prevBuffer = null;
|
|
14836
|
-
this.setBuffer = (buffer) => {
|
|
14837
|
-
if (prevBuffer) {
|
|
14838
|
-
stack.push(prevBuffer);
|
|
14839
|
-
}
|
|
14840
|
-
prevBuffer = buffer;
|
|
14841
|
-
this.float32Array = new Float32Array(buffer);
|
|
14842
|
-
this.uint16Array = new Uint16Array(buffer);
|
|
14843
|
-
this.uint32Array = new Uint32Array(buffer);
|
|
14844
|
-
};
|
|
14845
|
-
this.clearBuffer = () => {
|
|
14846
|
-
prevBuffer = null;
|
|
14847
|
-
this.float32Array = null;
|
|
14848
|
-
this.uint16Array = null;
|
|
14849
|
-
this.uint32Array = null;
|
|
14850
|
-
if (stack.length !== 0) {
|
|
14851
|
-
this.setBuffer(stack.pop());
|
|
14852
|
-
}
|
|
14853
|
-
};
|
|
14854
|
-
}
|
|
14855
|
-
}
|
|
14856
|
-
const BufferStack = new _BufferStack();
|
|
14857
|
-
let _box1, _box2;
|
|
14858
|
-
const boxStack = [];
|
|
14859
|
-
const boxPool = /* @__PURE__ */ new PrimitivePool(() => new Box3());
|
|
14860
|
-
function shapecast(bvh, root, intersectsBounds, intersectsRange, boundsTraverseOrder, byteOffset) {
|
|
14861
|
-
_box1 = boxPool.getPrimitive();
|
|
14862
|
-
_box2 = boxPool.getPrimitive();
|
|
14863
|
-
boxStack.push(_box1, _box2);
|
|
14864
|
-
BufferStack.setBuffer(bvh._roots[root]);
|
|
14865
|
-
const result = shapecastTraverse(0, bvh.geometry, intersectsBounds, intersectsRange, boundsTraverseOrder, byteOffset);
|
|
14866
|
-
BufferStack.clearBuffer();
|
|
14867
|
-
boxPool.releasePrimitive(_box1);
|
|
14868
|
-
boxPool.releasePrimitive(_box2);
|
|
14869
|
-
boxStack.pop();
|
|
14870
|
-
boxStack.pop();
|
|
14871
|
-
const length = boxStack.length;
|
|
14872
|
-
if (length > 0) {
|
|
14873
|
-
_box2 = boxStack[length - 1];
|
|
14874
|
-
_box1 = boxStack[length - 2];
|
|
14875
|
-
}
|
|
14876
|
-
return result;
|
|
14877
|
-
}
|
|
14878
|
-
function shapecastTraverse(nodeIndex32, geometry, intersectsBoundsFunc, intersectsRangeFunc, nodeScoreFunc = null, nodeIndexByteOffset = 0, depth = 0) {
|
|
14879
|
-
const { float32Array: float32Array2, uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
|
|
14880
|
-
let nodeIndex16 = nodeIndex32 * 2;
|
|
14881
|
-
const isLeaf = IS_LEAF(nodeIndex16, uint16Array2);
|
|
14882
|
-
if (isLeaf) {
|
|
14883
|
-
const offset = OFFSET(nodeIndex32, uint32Array2);
|
|
14884
|
-
const count = COUNT(nodeIndex16, uint16Array2);
|
|
14885
|
-
arrayToBox(BOUNDING_DATA_INDEX(nodeIndex32), float32Array2, _box1);
|
|
14886
|
-
return intersectsRangeFunc(offset, count, false, depth, nodeIndexByteOffset + nodeIndex32, _box1);
|
|
14887
|
-
} else {
|
|
14888
|
-
let getLeftOffset = function(nodeIndex322) {
|
|
14889
|
-
const { uint16Array: uint16Array3, uint32Array: uint32Array3 } = BufferStack;
|
|
14890
|
-
let nodeIndex162 = nodeIndex322 * 2;
|
|
14891
|
-
while (!IS_LEAF(nodeIndex162, uint16Array3)) {
|
|
14892
|
-
nodeIndex322 = LEFT_NODE(nodeIndex322);
|
|
14893
|
-
nodeIndex162 = nodeIndex322 * 2;
|
|
14894
|
-
}
|
|
14895
|
-
return OFFSET(nodeIndex322, uint32Array3);
|
|
14896
|
-
}, getRightEndOffset = function(nodeIndex322) {
|
|
14897
|
-
const { uint16Array: uint16Array3, uint32Array: uint32Array3 } = BufferStack;
|
|
14898
|
-
let nodeIndex162 = nodeIndex322 * 2;
|
|
14899
|
-
while (!IS_LEAF(nodeIndex162, uint16Array3)) {
|
|
14900
|
-
nodeIndex322 = RIGHT_NODE(nodeIndex322, uint32Array3);
|
|
14901
|
-
nodeIndex162 = nodeIndex322 * 2;
|
|
14902
|
-
}
|
|
14903
|
-
return OFFSET(nodeIndex322, uint32Array3) + COUNT(nodeIndex162, uint16Array3);
|
|
14904
|
-
};
|
|
14905
|
-
const left = LEFT_NODE(nodeIndex32);
|
|
14906
|
-
const right = RIGHT_NODE(nodeIndex32, uint32Array2);
|
|
14907
|
-
let c1 = left;
|
|
14908
|
-
let c2 = right;
|
|
14909
|
-
let score1, score2;
|
|
14910
|
-
let box1, box2;
|
|
14911
|
-
if (nodeScoreFunc) {
|
|
14912
|
-
box1 = _box1;
|
|
14913
|
-
box2 = _box2;
|
|
14914
|
-
arrayToBox(BOUNDING_DATA_INDEX(c1), float32Array2, box1);
|
|
14915
|
-
arrayToBox(BOUNDING_DATA_INDEX(c2), float32Array2, box2);
|
|
14916
|
-
score1 = nodeScoreFunc(box1);
|
|
14917
|
-
score2 = nodeScoreFunc(box2);
|
|
14918
|
-
if (score2 < score1) {
|
|
14919
|
-
c1 = right;
|
|
14920
|
-
c2 = left;
|
|
14921
|
-
const temp5 = score1;
|
|
14922
|
-
score1 = score2;
|
|
14923
|
-
score2 = temp5;
|
|
14924
|
-
box1 = box2;
|
|
14925
|
-
}
|
|
14926
|
-
}
|
|
14927
|
-
if (!box1) {
|
|
14928
|
-
box1 = _box1;
|
|
14929
|
-
arrayToBox(BOUNDING_DATA_INDEX(c1), float32Array2, box1);
|
|
14930
|
-
}
|
|
14931
|
-
const isC1Leaf = IS_LEAF(c1 * 2, uint16Array2);
|
|
14932
|
-
const c1Intersection = intersectsBoundsFunc(box1, isC1Leaf, score1, depth + 1, nodeIndexByteOffset + c1);
|
|
14933
|
-
let c1StopTraversal;
|
|
14934
|
-
if (c1Intersection === CONTAINED) {
|
|
14935
|
-
const offset = getLeftOffset(c1);
|
|
14936
|
-
const end = getRightEndOffset(c1);
|
|
14937
|
-
const count = end - offset;
|
|
14938
|
-
c1StopTraversal = intersectsRangeFunc(offset, count, true, depth + 1, nodeIndexByteOffset + c1, box1);
|
|
14939
|
-
} else {
|
|
14940
|
-
c1StopTraversal = c1Intersection && shapecastTraverse(
|
|
14941
|
-
c1,
|
|
14942
|
-
geometry,
|
|
14943
|
-
intersectsBoundsFunc,
|
|
14944
|
-
intersectsRangeFunc,
|
|
14945
|
-
nodeScoreFunc,
|
|
14946
|
-
nodeIndexByteOffset,
|
|
14947
|
-
depth + 1
|
|
14948
|
-
);
|
|
14949
|
-
}
|
|
14950
|
-
if (c1StopTraversal) return true;
|
|
14951
|
-
box2 = _box2;
|
|
14952
|
-
arrayToBox(BOUNDING_DATA_INDEX(c2), float32Array2, box2);
|
|
14953
|
-
const isC2Leaf = IS_LEAF(c2 * 2, uint16Array2);
|
|
14954
|
-
const c2Intersection = intersectsBoundsFunc(box2, isC2Leaf, score2, depth + 1, nodeIndexByteOffset + c2);
|
|
14955
|
-
let c2StopTraversal;
|
|
14956
|
-
if (c2Intersection === CONTAINED) {
|
|
14957
|
-
const offset = getLeftOffset(c2);
|
|
14958
|
-
const end = getRightEndOffset(c2);
|
|
14959
|
-
const count = end - offset;
|
|
14960
|
-
c2StopTraversal = intersectsRangeFunc(offset, count, true, depth + 1, nodeIndexByteOffset + c2, box2);
|
|
14961
|
-
} else {
|
|
14962
|
-
c2StopTraversal = c2Intersection && shapecastTraverse(
|
|
14963
|
-
c2,
|
|
14964
|
-
geometry,
|
|
14965
|
-
intersectsBoundsFunc,
|
|
14966
|
-
intersectsRangeFunc,
|
|
14967
|
-
nodeScoreFunc,
|
|
14968
|
-
nodeIndexByteOffset,
|
|
14969
|
-
depth + 1
|
|
14970
|
-
);
|
|
14971
|
-
}
|
|
14972
|
-
if (c2StopTraversal) return true;
|
|
14973
|
-
return false;
|
|
14974
|
-
}
|
|
14975
|
-
}
|
|
14976
|
-
const temp = /* @__PURE__ */ new Vector3();
|
|
14977
|
-
const temp1$2 = /* @__PURE__ */ new Vector3();
|
|
14978
|
-
function closestPointToPoint(bvh, point, target = {}, minThreshold = 0, maxThreshold = Infinity) {
|
|
14979
|
-
const minThresholdSq = minThreshold * minThreshold;
|
|
14980
|
-
const maxThresholdSq = maxThreshold * maxThreshold;
|
|
14981
|
-
let closestDistanceSq = Infinity;
|
|
14982
|
-
let closestDistanceTriIndex = null;
|
|
14983
|
-
bvh.shapecast(
|
|
14984
|
-
{
|
|
14985
|
-
boundsTraverseOrder: (box2) => {
|
|
14986
|
-
temp.copy(point).clamp(box2.min, box2.max);
|
|
14987
|
-
return temp.distanceToSquared(point);
|
|
14988
|
-
},
|
|
14989
|
-
intersectsBounds: (box2, isLeaf, score) => {
|
|
14990
|
-
return score < closestDistanceSq && score < maxThresholdSq;
|
|
14991
|
-
},
|
|
14992
|
-
intersectsTriangle: (tri, triIndex) => {
|
|
14993
|
-
tri.closestPointToPoint(point, temp);
|
|
14994
|
-
const distSq = point.distanceToSquared(temp);
|
|
14995
|
-
if (distSq < closestDistanceSq) {
|
|
14996
|
-
temp1$2.copy(temp);
|
|
14997
|
-
closestDistanceSq = distSq;
|
|
14998
|
-
closestDistanceTriIndex = triIndex;
|
|
14999
|
-
}
|
|
15000
|
-
if (distSq < minThresholdSq) {
|
|
15001
|
-
return true;
|
|
15002
|
-
} else {
|
|
15003
|
-
return false;
|
|
15004
|
-
}
|
|
15005
|
-
}
|
|
15006
|
-
}
|
|
15007
|
-
);
|
|
15008
|
-
if (closestDistanceSq === Infinity) return null;
|
|
15009
|
-
const closestDistance = Math.sqrt(closestDistanceSq);
|
|
15010
|
-
if (!target.point) target.point = temp1$2.clone();
|
|
15011
|
-
else target.point.copy(temp1$2);
|
|
15012
|
-
target.distance = closestDistance, target.faceIndex = closestDistanceTriIndex;
|
|
15013
|
-
return target;
|
|
15014
|
-
}
|
|
15015
|
-
const IS_GT_REVISION_169 = parseInt(REVISION) >= 169;
|
|
15016
|
-
const _vA = /* @__PURE__ */ new Vector3();
|
|
15017
|
-
const _vB = /* @__PURE__ */ new Vector3();
|
|
15018
|
-
const _vC = /* @__PURE__ */ new Vector3();
|
|
15019
|
-
const _uvA = /* @__PURE__ */ new Vector2();
|
|
15020
|
-
const _uvB = /* @__PURE__ */ new Vector2();
|
|
15021
|
-
const _uvC = /* @__PURE__ */ new Vector2();
|
|
15022
|
-
const _normalA = /* @__PURE__ */ new Vector3();
|
|
15023
|
-
const _normalB = /* @__PURE__ */ new Vector3();
|
|
15024
|
-
const _normalC = /* @__PURE__ */ new Vector3();
|
|
15025
|
-
const _intersectionPoint = /* @__PURE__ */ new Vector3();
|
|
15026
|
-
function checkIntersection(ray2, pA, pB, pC, point, side, near, far) {
|
|
15027
|
-
let intersect;
|
|
15028
|
-
if (side === BackSide) {
|
|
15029
|
-
intersect = ray2.intersectTriangle(pC, pB, pA, true, point);
|
|
15030
|
-
} else {
|
|
15031
|
-
intersect = ray2.intersectTriangle(pA, pB, pC, side !== DoubleSide, point);
|
|
15032
|
-
}
|
|
15033
|
-
if (intersect === null) return null;
|
|
15034
|
-
const distance = ray2.origin.distanceTo(point);
|
|
15035
|
-
if (distance < near || distance > far) return null;
|
|
15036
|
-
return {
|
|
15037
|
-
distance,
|
|
15038
|
-
point: point.clone()
|
|
15039
|
-
};
|
|
15040
|
-
}
|
|
15041
|
-
function checkBufferGeometryIntersection(ray2, position, normal, uv, uv1, a2, b2, c2, side, near, far) {
|
|
15042
|
-
_vA.fromBufferAttribute(position, a2);
|
|
15043
|
-
_vB.fromBufferAttribute(position, b2);
|
|
15044
|
-
_vC.fromBufferAttribute(position, c2);
|
|
15045
|
-
const intersection = checkIntersection(ray2, _vA, _vB, _vC, _intersectionPoint, side, near, far);
|
|
15046
|
-
if (intersection) {
|
|
15047
|
-
const barycoord = new Vector3();
|
|
15048
|
-
Triangle.getBarycoord(_intersectionPoint, _vA, _vB, _vC, barycoord);
|
|
15049
|
-
if (uv) {
|
|
15050
|
-
_uvA.fromBufferAttribute(uv, a2);
|
|
15051
|
-
_uvB.fromBufferAttribute(uv, b2);
|
|
15052
|
-
_uvC.fromBufferAttribute(uv, c2);
|
|
15053
|
-
intersection.uv = Triangle.getInterpolation(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2());
|
|
15054
|
-
}
|
|
15055
|
-
if (uv1) {
|
|
15056
|
-
_uvA.fromBufferAttribute(uv1, a2);
|
|
15057
|
-
_uvB.fromBufferAttribute(uv1, b2);
|
|
15058
|
-
_uvC.fromBufferAttribute(uv1, c2);
|
|
15059
|
-
intersection.uv1 = Triangle.getInterpolation(_intersectionPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2());
|
|
15060
|
-
}
|
|
15061
|
-
if (normal) {
|
|
15062
|
-
_normalA.fromBufferAttribute(normal, a2);
|
|
15063
|
-
_normalB.fromBufferAttribute(normal, b2);
|
|
15064
|
-
_normalC.fromBufferAttribute(normal, c2);
|
|
15065
|
-
intersection.normal = Triangle.getInterpolation(_intersectionPoint, _vA, _vB, _vC, _normalA, _normalB, _normalC, new Vector3());
|
|
15066
|
-
if (intersection.normal.dot(ray2.direction) > 0) {
|
|
15067
|
-
intersection.normal.multiplyScalar(-1);
|
|
15068
|
-
}
|
|
15069
|
-
}
|
|
15070
|
-
const face = {
|
|
15071
|
-
a: a2,
|
|
15072
|
-
b: b2,
|
|
15073
|
-
c: c2,
|
|
15074
|
-
normal: new Vector3(),
|
|
15075
|
-
materialIndex: 0
|
|
15076
|
-
};
|
|
15077
|
-
Triangle.getNormal(_vA, _vB, _vC, face.normal);
|
|
15078
|
-
intersection.face = face;
|
|
15079
|
-
intersection.faceIndex = a2;
|
|
15080
|
-
if (IS_GT_REVISION_169) {
|
|
15081
|
-
intersection.barycoord = barycoord;
|
|
15082
|
-
}
|
|
15083
|
-
}
|
|
15084
|
-
return intersection;
|
|
15085
|
-
}
|
|
15086
|
-
function intersectTri(geo, side, ray2, tri, intersections, near, far) {
|
|
15087
|
-
const triOffset = tri * 3;
|
|
15088
|
-
let a2 = triOffset + 0;
|
|
15089
|
-
let b2 = triOffset + 1;
|
|
15090
|
-
let c2 = triOffset + 2;
|
|
15091
|
-
const index = geo.index;
|
|
15092
|
-
if (geo.index) {
|
|
15093
|
-
a2 = index.getX(a2);
|
|
15094
|
-
b2 = index.getX(b2);
|
|
15095
|
-
c2 = index.getX(c2);
|
|
15096
|
-
}
|
|
15097
|
-
const { position, normal, uv, uv1 } = geo.attributes;
|
|
15098
|
-
const intersection = checkBufferGeometryIntersection(ray2, position, normal, uv, uv1, a2, b2, c2, side, near, far);
|
|
15099
|
-
if (intersection) {
|
|
15100
|
-
intersection.faceIndex = tri;
|
|
15101
|
-
if (intersections) intersections.push(intersection);
|
|
15102
|
-
return intersection;
|
|
15103
|
-
}
|
|
15104
|
-
return null;
|
|
15105
|
-
}
|
|
15106
|
-
function setTriangle(tri, i, index, pos) {
|
|
15107
|
-
const ta = tri.a;
|
|
15108
|
-
const tb = tri.b;
|
|
15109
|
-
const tc = tri.c;
|
|
15110
|
-
let i0 = i;
|
|
15111
|
-
let i1 = i + 1;
|
|
15112
|
-
let i2 = i + 2;
|
|
15113
|
-
if (index) {
|
|
15114
|
-
i0 = index.getX(i0);
|
|
15115
|
-
i1 = index.getX(i1);
|
|
15116
|
-
i2 = index.getX(i2);
|
|
15117
|
-
}
|
|
15118
|
-
ta.x = pos.getX(i0);
|
|
15119
|
-
ta.y = pos.getY(i0);
|
|
15120
|
-
ta.z = pos.getZ(i0);
|
|
15121
|
-
tb.x = pos.getX(i1);
|
|
15122
|
-
tb.y = pos.getY(i1);
|
|
15123
|
-
tb.z = pos.getZ(i1);
|
|
15124
|
-
tc.x = pos.getX(i2);
|
|
15125
|
-
tc.y = pos.getY(i2);
|
|
15126
|
-
tc.z = pos.getZ(i2);
|
|
15127
|
-
}
|
|
15128
|
-
function intersectTris(bvh, side, ray2, offset, count, intersections, near, far) {
|
|
15129
|
-
const { geometry, _indirectBuffer } = bvh;
|
|
15130
|
-
for (let i = offset, end = offset + count; i < end; i++) {
|
|
15131
|
-
intersectTri(geometry, side, ray2, i, intersections, near, far);
|
|
15132
|
-
}
|
|
15133
|
-
}
|
|
15134
|
-
function intersectClosestTri(bvh, side, ray2, offset, count, near, far) {
|
|
15135
|
-
const { geometry, _indirectBuffer } = bvh;
|
|
15136
|
-
let dist = Infinity;
|
|
15137
|
-
let res = null;
|
|
15138
|
-
for (let i = offset, end = offset + count; i < end; i++) {
|
|
15139
|
-
let intersection;
|
|
15140
|
-
intersection = intersectTri(geometry, side, ray2, i, null, near, far);
|
|
15141
|
-
if (intersection && intersection.distance < dist) {
|
|
15142
|
-
res = intersection;
|
|
15143
|
-
dist = intersection.distance;
|
|
15144
|
-
}
|
|
15145
|
-
}
|
|
15146
|
-
return res;
|
|
15147
|
-
}
|
|
15148
|
-
function iterateOverTriangles(offset, count, bvh, intersectsTriangleFunc, contained, depth, triangle3) {
|
|
15149
|
-
const { geometry } = bvh;
|
|
15150
|
-
const { index } = geometry;
|
|
15151
|
-
const pos = geometry.attributes.position;
|
|
15152
|
-
for (let i = offset, l2 = count + offset; i < l2; i++) {
|
|
15153
|
-
let tri;
|
|
15154
|
-
tri = i;
|
|
15155
|
-
setTriangle(triangle3, tri * 3, index, pos);
|
|
15156
|
-
triangle3.needsUpdate = true;
|
|
15157
|
-
if (intersectsTriangleFunc(triangle3, tri, contained, depth)) {
|
|
15158
|
-
return true;
|
|
15159
|
-
}
|
|
15160
|
-
}
|
|
15161
|
-
return false;
|
|
15162
|
-
}
|
|
15163
|
-
function refit(bvh, nodeIndices = null) {
|
|
15164
|
-
if (nodeIndices && Array.isArray(nodeIndices)) {
|
|
15165
|
-
nodeIndices = new Set(nodeIndices);
|
|
15166
|
-
}
|
|
15167
|
-
const geometry = bvh.geometry;
|
|
15168
|
-
const indexArr = geometry.index ? geometry.index.array : null;
|
|
15169
|
-
const posAttr = geometry.attributes.position;
|
|
15170
|
-
let buffer, uint32Array2, uint16Array2, float32Array2;
|
|
15171
|
-
let byteOffset = 0;
|
|
15172
|
-
const roots = bvh._roots;
|
|
15173
|
-
for (let i = 0, l2 = roots.length; i < l2; i++) {
|
|
15174
|
-
buffer = roots[i];
|
|
15175
|
-
uint32Array2 = new Uint32Array(buffer);
|
|
15176
|
-
uint16Array2 = new Uint16Array(buffer);
|
|
15177
|
-
float32Array2 = new Float32Array(buffer);
|
|
15178
|
-
_traverse2(0, byteOffset);
|
|
15179
|
-
byteOffset += buffer.byteLength;
|
|
15180
|
-
}
|
|
15181
|
-
function _traverse2(node32Index, byteOffset2, force = false) {
|
|
15182
|
-
const node16Index = node32Index * 2;
|
|
15183
|
-
const isLeaf = uint16Array2[node16Index + 15] === IS_LEAFNODE_FLAG;
|
|
15184
|
-
if (isLeaf) {
|
|
15185
|
-
const offset = uint32Array2[node32Index + 6];
|
|
15186
|
-
const count = uint16Array2[node16Index + 14];
|
|
15187
|
-
let minx = Infinity;
|
|
15188
|
-
let miny = Infinity;
|
|
15189
|
-
let minz = Infinity;
|
|
15190
|
-
let maxx = -Infinity;
|
|
15191
|
-
let maxy = -Infinity;
|
|
15192
|
-
let maxz = -Infinity;
|
|
15193
|
-
for (let i = 3 * offset, l2 = 3 * (offset + count); i < l2; i++) {
|
|
15194
|
-
let index = indexArr[i];
|
|
15195
|
-
const x = posAttr.getX(index);
|
|
15196
|
-
const y = posAttr.getY(index);
|
|
15197
|
-
const z = posAttr.getZ(index);
|
|
15198
|
-
if (x < minx) minx = x;
|
|
15199
|
-
if (x > maxx) maxx = x;
|
|
15200
|
-
if (y < miny) miny = y;
|
|
15201
|
-
if (y > maxy) maxy = y;
|
|
15202
|
-
if (z < minz) minz = z;
|
|
15203
|
-
if (z > maxz) maxz = z;
|
|
15204
|
-
}
|
|
15205
|
-
if (float32Array2[node32Index + 0] !== minx || float32Array2[node32Index + 1] !== miny || float32Array2[node32Index + 2] !== minz || float32Array2[node32Index + 3] !== maxx || float32Array2[node32Index + 4] !== maxy || float32Array2[node32Index + 5] !== maxz) {
|
|
15206
|
-
float32Array2[node32Index + 0] = minx;
|
|
15207
|
-
float32Array2[node32Index + 1] = miny;
|
|
15208
|
-
float32Array2[node32Index + 2] = minz;
|
|
15209
|
-
float32Array2[node32Index + 3] = maxx;
|
|
15210
|
-
float32Array2[node32Index + 4] = maxy;
|
|
15211
|
-
float32Array2[node32Index + 5] = maxz;
|
|
15212
|
-
return true;
|
|
15213
|
-
} else {
|
|
15214
|
-
return false;
|
|
15215
|
-
}
|
|
15216
|
-
} else {
|
|
15217
|
-
const left = node32Index + 8;
|
|
15218
|
-
const right = uint32Array2[node32Index + 6];
|
|
15219
|
-
const offsetLeft = left + byteOffset2;
|
|
15220
|
-
const offsetRight = right + byteOffset2;
|
|
15221
|
-
let forceChildren = force;
|
|
15222
|
-
let includesLeft = false;
|
|
15223
|
-
let includesRight = false;
|
|
15224
|
-
if (nodeIndices) {
|
|
15225
|
-
if (!forceChildren) {
|
|
15226
|
-
includesLeft = nodeIndices.has(offsetLeft);
|
|
15227
|
-
includesRight = nodeIndices.has(offsetRight);
|
|
15228
|
-
forceChildren = !includesLeft && !includesRight;
|
|
15229
|
-
}
|
|
15230
|
-
} else {
|
|
15231
|
-
includesLeft = true;
|
|
15232
|
-
includesRight = true;
|
|
15233
|
-
}
|
|
15234
|
-
const traverseLeft = forceChildren || includesLeft;
|
|
15235
|
-
const traverseRight = forceChildren || includesRight;
|
|
15236
|
-
let leftChange = false;
|
|
15237
|
-
if (traverseLeft) {
|
|
15238
|
-
leftChange = _traverse2(left, byteOffset2, forceChildren);
|
|
15239
|
-
}
|
|
15240
|
-
let rightChange = false;
|
|
15241
|
-
if (traverseRight) {
|
|
15242
|
-
rightChange = _traverse2(right, byteOffset2, forceChildren);
|
|
15243
|
-
}
|
|
15244
|
-
const didChange = leftChange || rightChange;
|
|
15245
|
-
if (didChange) {
|
|
15246
|
-
for (let i = 0; i < 3; i++) {
|
|
15247
|
-
const lefti = left + i;
|
|
15248
|
-
const righti = right + i;
|
|
15249
|
-
const minLeftValue = float32Array2[lefti];
|
|
15250
|
-
const maxLeftValue = float32Array2[lefti + 3];
|
|
15251
|
-
const minRightValue = float32Array2[righti];
|
|
15252
|
-
const maxRightValue = float32Array2[righti + 3];
|
|
15253
|
-
float32Array2[node32Index + i] = minLeftValue < minRightValue ? minLeftValue : minRightValue;
|
|
15254
|
-
float32Array2[node32Index + i + 3] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;
|
|
15255
|
-
}
|
|
15256
|
-
}
|
|
15257
|
-
return didChange;
|
|
15258
|
-
}
|
|
15259
|
-
}
|
|
15260
|
-
}
|
|
15261
|
-
function intersectRay(nodeIndex32, array, ray2, near, far) {
|
|
15262
|
-
let tmin, tmax, tymin, tymax, tzmin, tzmax;
|
|
15263
|
-
const invdirx = 1 / ray2.direction.x, invdiry = 1 / ray2.direction.y, invdirz = 1 / ray2.direction.z;
|
|
15264
|
-
const ox = ray2.origin.x;
|
|
15265
|
-
const oy = ray2.origin.y;
|
|
15266
|
-
const oz = ray2.origin.z;
|
|
15267
|
-
let minx = array[nodeIndex32];
|
|
15268
|
-
let maxx = array[nodeIndex32 + 3];
|
|
15269
|
-
let miny = array[nodeIndex32 + 1];
|
|
15270
|
-
let maxy = array[nodeIndex32 + 3 + 1];
|
|
15271
|
-
let minz = array[nodeIndex32 + 2];
|
|
15272
|
-
let maxz = array[nodeIndex32 + 3 + 2];
|
|
15273
|
-
if (invdirx >= 0) {
|
|
15274
|
-
tmin = (minx - ox) * invdirx;
|
|
15275
|
-
tmax = (maxx - ox) * invdirx;
|
|
15276
|
-
} else {
|
|
15277
|
-
tmin = (maxx - ox) * invdirx;
|
|
15278
|
-
tmax = (minx - ox) * invdirx;
|
|
15279
|
-
}
|
|
15280
|
-
if (invdiry >= 0) {
|
|
15281
|
-
tymin = (miny - oy) * invdiry;
|
|
15282
|
-
tymax = (maxy - oy) * invdiry;
|
|
15283
|
-
} else {
|
|
15284
|
-
tymin = (maxy - oy) * invdiry;
|
|
15285
|
-
tymax = (miny - oy) * invdiry;
|
|
15286
|
-
}
|
|
15287
|
-
if (tmin > tymax || tymin > tmax) return false;
|
|
15288
|
-
if (tymin > tmin || isNaN(tmin)) tmin = tymin;
|
|
15289
|
-
if (tymax < tmax || isNaN(tmax)) tmax = tymax;
|
|
15290
|
-
if (invdirz >= 0) {
|
|
15291
|
-
tzmin = (minz - oz) * invdirz;
|
|
15292
|
-
tzmax = (maxz - oz) * invdirz;
|
|
15293
|
-
} else {
|
|
15294
|
-
tzmin = (maxz - oz) * invdirz;
|
|
15295
|
-
tzmax = (minz - oz) * invdirz;
|
|
15296
|
-
}
|
|
15297
|
-
if (tmin > tzmax || tzmin > tmax) return false;
|
|
15298
|
-
if (tzmin > tmin || tmin !== tmin) tmin = tzmin;
|
|
15299
|
-
if (tzmax < tmax || tmax !== tmax) tmax = tzmax;
|
|
15300
|
-
return tmin <= far && tmax >= near;
|
|
15301
|
-
}
|
|
15302
|
-
function intersectTris_indirect(bvh, side, ray2, offset, count, intersections, near, far) {
|
|
15303
|
-
const { geometry, _indirectBuffer } = bvh;
|
|
15304
|
-
for (let i = offset, end = offset + count; i < end; i++) {
|
|
15305
|
-
let vi = _indirectBuffer ? _indirectBuffer[i] : i;
|
|
15306
|
-
intersectTri(geometry, side, ray2, vi, intersections, near, far);
|
|
15307
|
-
}
|
|
15308
|
-
}
|
|
15309
|
-
function intersectClosestTri_indirect(bvh, side, ray2, offset, count, near, far) {
|
|
15310
|
-
const { geometry, _indirectBuffer } = bvh;
|
|
15311
|
-
let dist = Infinity;
|
|
15312
|
-
let res = null;
|
|
15313
|
-
for (let i = offset, end = offset + count; i < end; i++) {
|
|
15314
|
-
let intersection;
|
|
15315
|
-
intersection = intersectTri(geometry, side, ray2, _indirectBuffer ? _indirectBuffer[i] : i, null, near, far);
|
|
15316
|
-
if (intersection && intersection.distance < dist) {
|
|
15317
|
-
res = intersection;
|
|
15318
|
-
dist = intersection.distance;
|
|
15319
|
-
}
|
|
15320
|
-
}
|
|
15321
|
-
return res;
|
|
15322
|
-
}
|
|
15323
|
-
function iterateOverTriangles_indirect(offset, count, bvh, intersectsTriangleFunc, contained, depth, triangle3) {
|
|
15324
|
-
const { geometry } = bvh;
|
|
15325
|
-
const { index } = geometry;
|
|
15326
|
-
const pos = geometry.attributes.position;
|
|
15327
|
-
for (let i = offset, l2 = count + offset; i < l2; i++) {
|
|
15328
|
-
let tri;
|
|
15329
|
-
tri = bvh.resolveTriangleIndex(i);
|
|
15330
|
-
setTriangle(triangle3, tri * 3, index, pos);
|
|
15331
|
-
triangle3.needsUpdate = true;
|
|
15332
|
-
if (intersectsTriangleFunc(triangle3, tri, contained, depth)) {
|
|
15333
|
-
return true;
|
|
15334
|
-
}
|
|
15335
|
-
}
|
|
15336
|
-
return false;
|
|
15337
|
-
}
|
|
15338
|
-
function raycast(bvh, root, side, ray2, intersects, near, far) {
|
|
15339
|
-
BufferStack.setBuffer(bvh._roots[root]);
|
|
15340
|
-
_raycast$1(0, bvh, side, ray2, intersects, near, far);
|
|
15341
|
-
BufferStack.clearBuffer();
|
|
15342
|
-
}
|
|
15343
|
-
function _raycast$1(nodeIndex32, bvh, side, ray2, intersects, near, far) {
|
|
15344
|
-
const { float32Array: float32Array2, uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
|
|
15345
|
-
const nodeIndex16 = nodeIndex32 * 2;
|
|
15346
|
-
const isLeaf = IS_LEAF(nodeIndex16, uint16Array2);
|
|
15347
|
-
if (isLeaf) {
|
|
15348
|
-
const offset = OFFSET(nodeIndex32, uint32Array2);
|
|
15349
|
-
const count = COUNT(nodeIndex16, uint16Array2);
|
|
15350
|
-
intersectTris(bvh, side, ray2, offset, count, intersects, near, far);
|
|
15351
|
-
} else {
|
|
15352
|
-
const leftIndex = LEFT_NODE(nodeIndex32);
|
|
15353
|
-
if (intersectRay(leftIndex, float32Array2, ray2, near, far)) {
|
|
15354
|
-
_raycast$1(leftIndex, bvh, side, ray2, intersects, near, far);
|
|
15355
|
-
}
|
|
15356
|
-
const rightIndex = RIGHT_NODE(nodeIndex32, uint32Array2);
|
|
15357
|
-
if (intersectRay(rightIndex, float32Array2, ray2, near, far)) {
|
|
15358
|
-
_raycast$1(rightIndex, bvh, side, ray2, intersects, near, far);
|
|
15359
|
-
}
|
|
15360
|
-
}
|
|
15361
|
-
}
|
|
15362
|
-
const _xyzFields$1 = ["x", "y", "z"];
|
|
15363
|
-
function raycastFirst(bvh, root, side, ray2, near, far) {
|
|
15364
|
-
BufferStack.setBuffer(bvh._roots[root]);
|
|
15365
|
-
const result = _raycastFirst$1(0, bvh, side, ray2, near, far);
|
|
15366
|
-
BufferStack.clearBuffer();
|
|
15367
|
-
return result;
|
|
15368
|
-
}
|
|
15369
|
-
function _raycastFirst$1(nodeIndex32, bvh, side, ray2, near, far) {
|
|
15370
|
-
const { float32Array: float32Array2, uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
|
|
15371
|
-
let nodeIndex16 = nodeIndex32 * 2;
|
|
15372
|
-
const isLeaf = IS_LEAF(nodeIndex16, uint16Array2);
|
|
15373
|
-
if (isLeaf) {
|
|
15374
|
-
const offset = OFFSET(nodeIndex32, uint32Array2);
|
|
15375
|
-
const count = COUNT(nodeIndex16, uint16Array2);
|
|
15376
|
-
return intersectClosestTri(bvh, side, ray2, offset, count, near, far);
|
|
15377
|
-
} else {
|
|
15378
|
-
const splitAxis = SPLIT_AXIS(nodeIndex32, uint32Array2);
|
|
15379
|
-
const xyzAxis = _xyzFields$1[splitAxis];
|
|
15380
|
-
const rayDir = ray2.direction[xyzAxis];
|
|
15381
|
-
const leftToRight = rayDir >= 0;
|
|
15382
|
-
let c1, c2;
|
|
15383
|
-
if (leftToRight) {
|
|
15384
|
-
c1 = LEFT_NODE(nodeIndex32);
|
|
15385
|
-
c2 = RIGHT_NODE(nodeIndex32, uint32Array2);
|
|
15386
|
-
} else {
|
|
15387
|
-
c1 = RIGHT_NODE(nodeIndex32, uint32Array2);
|
|
15388
|
-
c2 = LEFT_NODE(nodeIndex32);
|
|
15389
|
-
}
|
|
15390
|
-
const c1Intersection = intersectRay(c1, float32Array2, ray2, near, far);
|
|
15391
|
-
const c1Result = c1Intersection ? _raycastFirst$1(c1, bvh, side, ray2, near, far) : null;
|
|
15392
|
-
if (c1Result) {
|
|
15393
|
-
const point = c1Result.point[xyzAxis];
|
|
15394
|
-
const isOutside = leftToRight ? point <= float32Array2[c2 + splitAxis] : (
|
|
15395
|
-
// min bounding data
|
|
15396
|
-
point >= float32Array2[c2 + splitAxis + 3]
|
|
15397
|
-
);
|
|
15398
|
-
if (isOutside) {
|
|
15399
|
-
return c1Result;
|
|
15400
|
-
}
|
|
15401
|
-
}
|
|
15402
|
-
const c2Intersection = intersectRay(c2, float32Array2, ray2, near, far);
|
|
15403
|
-
const c2Result = c2Intersection ? _raycastFirst$1(c2, bvh, side, ray2, near, far) : null;
|
|
15404
|
-
if (c1Result && c2Result) {
|
|
15405
|
-
return c1Result.distance <= c2Result.distance ? c1Result : c2Result;
|
|
15406
|
-
} else {
|
|
15407
|
-
return c1Result || c2Result || null;
|
|
15408
|
-
}
|
|
15409
|
-
}
|
|
15410
|
-
}
|
|
15411
|
-
const boundingBox$1 = /* @__PURE__ */ new Box3();
|
|
15412
|
-
const triangle$1 = /* @__PURE__ */ new ExtendedTriangle();
|
|
15413
|
-
const triangle2$1 = /* @__PURE__ */ new ExtendedTriangle();
|
|
15414
|
-
const invertedMat$1 = /* @__PURE__ */ new Matrix4();
|
|
15415
|
-
const obb$4 = /* @__PURE__ */ new OrientedBox();
|
|
15416
|
-
const obb2$3 = /* @__PURE__ */ new OrientedBox();
|
|
15417
|
-
function intersectsGeometry(bvh, root, otherGeometry, geometryToBvh) {
|
|
15418
|
-
BufferStack.setBuffer(bvh._roots[root]);
|
|
15419
|
-
const result = _intersectsGeometry$1(0, bvh, otherGeometry, geometryToBvh);
|
|
15420
|
-
BufferStack.clearBuffer();
|
|
15421
|
-
return result;
|
|
15422
|
-
}
|
|
15423
|
-
function _intersectsGeometry$1(nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null) {
|
|
15424
|
-
const { float32Array: float32Array2, uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
|
|
15425
|
-
let nodeIndex16 = nodeIndex32 * 2;
|
|
15426
|
-
if (cachedObb === null) {
|
|
15427
|
-
if (!otherGeometry.boundingBox) {
|
|
15428
|
-
otherGeometry.computeBoundingBox();
|
|
15429
|
-
}
|
|
15430
|
-
obb$4.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
|
|
15431
|
-
cachedObb = obb$4;
|
|
15432
|
-
}
|
|
15433
|
-
const isLeaf = IS_LEAF(nodeIndex16, uint16Array2);
|
|
15434
|
-
if (isLeaf) {
|
|
15435
|
-
const thisGeometry = bvh.geometry;
|
|
15436
|
-
const thisIndex = thisGeometry.index;
|
|
15437
|
-
const thisPos = thisGeometry.attributes.position;
|
|
15438
|
-
const index = otherGeometry.index;
|
|
15439
|
-
const pos = otherGeometry.attributes.position;
|
|
15440
|
-
const offset = OFFSET(nodeIndex32, uint32Array2);
|
|
15441
|
-
const count = COUNT(nodeIndex16, uint16Array2);
|
|
15442
|
-
invertedMat$1.copy(geometryToBvh).invert();
|
|
15443
|
-
if (otherGeometry.boundsTree) {
|
|
15444
|
-
arrayToBox(BOUNDING_DATA_INDEX(nodeIndex32), float32Array2, obb2$3);
|
|
15445
|
-
obb2$3.matrix.copy(invertedMat$1);
|
|
15446
|
-
obb2$3.needsUpdate = true;
|
|
15447
|
-
const res = otherGeometry.boundsTree.shapecast({
|
|
15448
|
-
intersectsBounds: (box2) => obb2$3.intersectsBox(box2),
|
|
15449
|
-
intersectsTriangle: (tri) => {
|
|
15450
|
-
tri.a.applyMatrix4(geometryToBvh);
|
|
15451
|
-
tri.b.applyMatrix4(geometryToBvh);
|
|
15452
|
-
tri.c.applyMatrix4(geometryToBvh);
|
|
15453
|
-
tri.needsUpdate = true;
|
|
15454
|
-
for (let i = offset * 3, l2 = (count + offset) * 3; i < l2; i += 3) {
|
|
15455
|
-
setTriangle(triangle2$1, i, thisIndex, thisPos);
|
|
15456
|
-
triangle2$1.needsUpdate = true;
|
|
15457
|
-
if (tri.intersectsTriangle(triangle2$1)) {
|
|
15458
|
-
return true;
|
|
15459
|
-
}
|
|
15460
|
-
}
|
|
15461
|
-
return false;
|
|
15462
|
-
}
|
|
15463
|
-
});
|
|
15464
|
-
return res;
|
|
15465
|
-
} else {
|
|
15466
|
-
for (let i = offset * 3, l2 = (count + offset) * 3; i < l2; i += 3) {
|
|
15467
|
-
setTriangle(triangle$1, i, thisIndex, thisPos);
|
|
15468
|
-
triangle$1.a.applyMatrix4(invertedMat$1);
|
|
15469
|
-
triangle$1.b.applyMatrix4(invertedMat$1);
|
|
15470
|
-
triangle$1.c.applyMatrix4(invertedMat$1);
|
|
15471
|
-
triangle$1.needsUpdate = true;
|
|
15472
|
-
for (let i2 = 0, l22 = index.count; i2 < l22; i2 += 3) {
|
|
15473
|
-
setTriangle(triangle2$1, i2, index, pos);
|
|
15474
|
-
triangle2$1.needsUpdate = true;
|
|
15475
|
-
if (triangle$1.intersectsTriangle(triangle2$1)) {
|
|
15476
|
-
return true;
|
|
15477
|
-
}
|
|
15478
|
-
}
|
|
15479
|
-
}
|
|
15480
|
-
}
|
|
15481
|
-
} else {
|
|
15482
|
-
const left = nodeIndex32 + 8;
|
|
15483
|
-
const right = uint32Array2[nodeIndex32 + 6];
|
|
15484
|
-
arrayToBox(BOUNDING_DATA_INDEX(left), float32Array2, boundingBox$1);
|
|
15485
|
-
const leftIntersection = cachedObb.intersectsBox(boundingBox$1) && _intersectsGeometry$1(left, bvh, otherGeometry, geometryToBvh, cachedObb);
|
|
15486
|
-
if (leftIntersection) return true;
|
|
15487
|
-
arrayToBox(BOUNDING_DATA_INDEX(right), float32Array2, boundingBox$1);
|
|
15488
|
-
const rightIntersection = cachedObb.intersectsBox(boundingBox$1) && _intersectsGeometry$1(right, bvh, otherGeometry, geometryToBvh, cachedObb);
|
|
15489
|
-
if (rightIntersection) return true;
|
|
15490
|
-
return false;
|
|
15491
|
-
}
|
|
15492
|
-
}
|
|
15493
|
-
const tempMatrix$1 = /* @__PURE__ */ new Matrix4();
|
|
15494
|
-
const obb$3 = /* @__PURE__ */ new OrientedBox();
|
|
15495
|
-
const obb2$2 = /* @__PURE__ */ new OrientedBox();
|
|
15496
|
-
const temp1$1 = /* @__PURE__ */ new Vector3();
|
|
15497
|
-
const temp2$1 = /* @__PURE__ */ new Vector3();
|
|
15498
|
-
const temp3$1 = /* @__PURE__ */ new Vector3();
|
|
15499
|
-
const temp4$1 = /* @__PURE__ */ new Vector3();
|
|
15500
|
-
function closestPointToGeometry(bvh, otherGeometry, geometryToBvh, target1 = {}, target2 = {}, minThreshold = 0, maxThreshold = Infinity) {
|
|
15501
|
-
if (!otherGeometry.boundingBox) {
|
|
15502
|
-
otherGeometry.computeBoundingBox();
|
|
15503
|
-
}
|
|
15504
|
-
obb$3.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
|
|
15505
|
-
obb$3.needsUpdate = true;
|
|
15506
|
-
const geometry = bvh.geometry;
|
|
15507
|
-
const pos = geometry.attributes.position;
|
|
15508
|
-
const index = geometry.index;
|
|
15509
|
-
const otherPos = otherGeometry.attributes.position;
|
|
15510
|
-
const otherIndex = otherGeometry.index;
|
|
15511
|
-
const triangle3 = ExtendedTrianglePool.getPrimitive();
|
|
15512
|
-
const triangle22 = ExtendedTrianglePool.getPrimitive();
|
|
15513
|
-
let tempTarget1 = temp1$1;
|
|
15514
|
-
let tempTargetDest1 = temp2$1;
|
|
15515
|
-
let tempTarget2 = null;
|
|
15516
|
-
let tempTargetDest2 = null;
|
|
15517
|
-
if (target2) {
|
|
15518
|
-
tempTarget2 = temp3$1;
|
|
15519
|
-
tempTargetDest2 = temp4$1;
|
|
15520
|
-
}
|
|
15521
|
-
let closestDistance = Infinity;
|
|
15522
|
-
let closestDistanceTriIndex = null;
|
|
15523
|
-
let closestDistanceOtherTriIndex = null;
|
|
15524
|
-
tempMatrix$1.copy(geometryToBvh).invert();
|
|
15525
|
-
obb2$2.matrix.copy(tempMatrix$1);
|
|
15526
|
-
bvh.shapecast(
|
|
15527
|
-
{
|
|
15528
|
-
boundsTraverseOrder: (box2) => {
|
|
15529
|
-
return obb$3.distanceToBox(box2);
|
|
15530
|
-
},
|
|
15531
|
-
intersectsBounds: (box2, isLeaf, score) => {
|
|
15532
|
-
if (score < closestDistance && score < maxThreshold) {
|
|
15533
|
-
if (isLeaf) {
|
|
15534
|
-
obb2$2.min.copy(box2.min);
|
|
15535
|
-
obb2$2.max.copy(box2.max);
|
|
15536
|
-
obb2$2.needsUpdate = true;
|
|
15537
|
-
}
|
|
15538
|
-
return true;
|
|
15539
|
-
}
|
|
15540
|
-
return false;
|
|
15541
|
-
},
|
|
15542
|
-
intersectsRange: (offset, count) => {
|
|
15543
|
-
if (otherGeometry.boundsTree) {
|
|
15544
|
-
const otherBvh = otherGeometry.boundsTree;
|
|
15545
|
-
return otherBvh.shapecast({
|
|
15546
|
-
boundsTraverseOrder: (box2) => {
|
|
15547
|
-
return obb2$2.distanceToBox(box2);
|
|
15548
|
-
},
|
|
15549
|
-
intersectsBounds: (box2, isLeaf, score) => {
|
|
15550
|
-
return score < closestDistance && score < maxThreshold;
|
|
15551
|
-
},
|
|
15552
|
-
intersectsRange: (otherOffset, otherCount) => {
|
|
15553
|
-
for (let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2++) {
|
|
15554
|
-
setTriangle(triangle22, 3 * i2, otherIndex, otherPos);
|
|
15555
|
-
triangle22.a.applyMatrix4(geometryToBvh);
|
|
15556
|
-
triangle22.b.applyMatrix4(geometryToBvh);
|
|
15557
|
-
triangle22.c.applyMatrix4(geometryToBvh);
|
|
15558
|
-
triangle22.needsUpdate = true;
|
|
15559
|
-
for (let i = offset, l3 = offset + count; i < l3; i++) {
|
|
15560
|
-
setTriangle(triangle3, 3 * i, index, pos);
|
|
15561
|
-
triangle3.needsUpdate = true;
|
|
15562
|
-
const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
|
|
15563
|
-
if (dist < closestDistance) {
|
|
15564
|
-
tempTargetDest1.copy(tempTarget1);
|
|
15565
|
-
if (tempTargetDest2) {
|
|
15566
|
-
tempTargetDest2.copy(tempTarget2);
|
|
15567
|
-
}
|
|
15568
|
-
closestDistance = dist;
|
|
15569
|
-
closestDistanceTriIndex = i;
|
|
15570
|
-
closestDistanceOtherTriIndex = i2;
|
|
15571
|
-
}
|
|
15572
|
-
if (dist < minThreshold) {
|
|
15573
|
-
return true;
|
|
15574
|
-
}
|
|
15575
|
-
}
|
|
15576
|
-
}
|
|
15577
|
-
}
|
|
15578
|
-
});
|
|
15579
|
-
} else {
|
|
15580
|
-
const triCount = getTriCount(otherGeometry);
|
|
15581
|
-
for (let i2 = 0, l2 = triCount; i2 < l2; i2++) {
|
|
15582
|
-
setTriangle(triangle22, 3 * i2, otherIndex, otherPos);
|
|
15583
|
-
triangle22.a.applyMatrix4(geometryToBvh);
|
|
15584
|
-
triangle22.b.applyMatrix4(geometryToBvh);
|
|
15585
|
-
triangle22.c.applyMatrix4(geometryToBvh);
|
|
15586
|
-
triangle22.needsUpdate = true;
|
|
15587
|
-
for (let i = offset, l3 = offset + count; i < l3; i++) {
|
|
15588
|
-
setTriangle(triangle3, 3 * i, index, pos);
|
|
15589
|
-
triangle3.needsUpdate = true;
|
|
15590
|
-
const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
|
|
15591
|
-
if (dist < closestDistance) {
|
|
15592
|
-
tempTargetDest1.copy(tempTarget1);
|
|
15593
|
-
if (tempTargetDest2) {
|
|
15594
|
-
tempTargetDest2.copy(tempTarget2);
|
|
15595
|
-
}
|
|
15596
|
-
closestDistance = dist;
|
|
15597
|
-
closestDistanceTriIndex = i;
|
|
15598
|
-
closestDistanceOtherTriIndex = i2;
|
|
15599
|
-
}
|
|
15600
|
-
if (dist < minThreshold) {
|
|
15601
|
-
return true;
|
|
15602
|
-
}
|
|
15603
|
-
}
|
|
15604
|
-
}
|
|
15605
|
-
}
|
|
15606
|
-
}
|
|
15607
|
-
}
|
|
15608
|
-
);
|
|
15609
|
-
ExtendedTrianglePool.releasePrimitive(triangle3);
|
|
15610
|
-
ExtendedTrianglePool.releasePrimitive(triangle22);
|
|
15611
|
-
if (closestDistance === Infinity) {
|
|
15612
|
-
return null;
|
|
15613
|
-
}
|
|
15614
|
-
if (!target1.point) {
|
|
15615
|
-
target1.point = tempTargetDest1.clone();
|
|
15616
|
-
} else {
|
|
15617
|
-
target1.point.copy(tempTargetDest1);
|
|
15618
|
-
}
|
|
15619
|
-
target1.distance = closestDistance, target1.faceIndex = closestDistanceTriIndex;
|
|
15620
|
-
if (target2) {
|
|
15621
|
-
if (!target2.point) target2.point = tempTargetDest2.clone();
|
|
15622
|
-
else target2.point.copy(tempTargetDest2);
|
|
15623
|
-
target2.point.applyMatrix4(tempMatrix$1);
|
|
15624
|
-
tempTargetDest1.applyMatrix4(tempMatrix$1);
|
|
15625
|
-
target2.distance = tempTargetDest1.sub(target2.point).length();
|
|
15626
|
-
target2.faceIndex = closestDistanceOtherTriIndex;
|
|
15627
|
-
}
|
|
15628
|
-
return target1;
|
|
15629
|
-
}
|
|
15630
|
-
function refit_indirect(bvh, nodeIndices = null) {
|
|
15631
|
-
if (nodeIndices && Array.isArray(nodeIndices)) {
|
|
15632
|
-
nodeIndices = new Set(nodeIndices);
|
|
15633
|
-
}
|
|
15634
|
-
const geometry = bvh.geometry;
|
|
15635
|
-
const indexArr = geometry.index ? geometry.index.array : null;
|
|
15636
|
-
const posAttr = geometry.attributes.position;
|
|
15637
|
-
let buffer, uint32Array2, uint16Array2, float32Array2;
|
|
15638
|
-
let byteOffset = 0;
|
|
15639
|
-
const roots = bvh._roots;
|
|
15640
|
-
for (let i = 0, l2 = roots.length; i < l2; i++) {
|
|
15641
|
-
buffer = roots[i];
|
|
15642
|
-
uint32Array2 = new Uint32Array(buffer);
|
|
15643
|
-
uint16Array2 = new Uint16Array(buffer);
|
|
15644
|
-
float32Array2 = new Float32Array(buffer);
|
|
15645
|
-
_traverse2(0, byteOffset);
|
|
15646
|
-
byteOffset += buffer.byteLength;
|
|
15647
|
-
}
|
|
15648
|
-
function _traverse2(node32Index, byteOffset2, force = false) {
|
|
15649
|
-
const node16Index = node32Index * 2;
|
|
15650
|
-
const isLeaf = uint16Array2[node16Index + 15] === IS_LEAFNODE_FLAG;
|
|
15651
|
-
if (isLeaf) {
|
|
15652
|
-
const offset = uint32Array2[node32Index + 6];
|
|
15653
|
-
const count = uint16Array2[node16Index + 14];
|
|
15654
|
-
let minx = Infinity;
|
|
15655
|
-
let miny = Infinity;
|
|
15656
|
-
let minz = Infinity;
|
|
15657
|
-
let maxx = -Infinity;
|
|
15658
|
-
let maxy = -Infinity;
|
|
15659
|
-
let maxz = -Infinity;
|
|
15660
|
-
for (let i = offset, l2 = offset + count; i < l2; i++) {
|
|
15661
|
-
const t2 = 3 * bvh.resolveTriangleIndex(i);
|
|
15662
|
-
for (let j2 = 0; j2 < 3; j2++) {
|
|
15663
|
-
let index = t2 + j2;
|
|
15664
|
-
index = indexArr ? indexArr[index] : index;
|
|
15665
|
-
const x = posAttr.getX(index);
|
|
15666
|
-
const y = posAttr.getY(index);
|
|
15667
|
-
const z = posAttr.getZ(index);
|
|
15668
|
-
if (x < minx) minx = x;
|
|
15669
|
-
if (x > maxx) maxx = x;
|
|
15670
|
-
if (y < miny) miny = y;
|
|
15671
|
-
if (y > maxy) maxy = y;
|
|
15672
|
-
if (z < minz) minz = z;
|
|
15673
|
-
if (z > maxz) maxz = z;
|
|
15674
|
-
}
|
|
15675
|
-
}
|
|
15676
|
-
if (float32Array2[node32Index + 0] !== minx || float32Array2[node32Index + 1] !== miny || float32Array2[node32Index + 2] !== minz || float32Array2[node32Index + 3] !== maxx || float32Array2[node32Index + 4] !== maxy || float32Array2[node32Index + 5] !== maxz) {
|
|
15677
|
-
float32Array2[node32Index + 0] = minx;
|
|
15678
|
-
float32Array2[node32Index + 1] = miny;
|
|
15679
|
-
float32Array2[node32Index + 2] = minz;
|
|
15680
|
-
float32Array2[node32Index + 3] = maxx;
|
|
15681
|
-
float32Array2[node32Index + 4] = maxy;
|
|
15682
|
-
float32Array2[node32Index + 5] = maxz;
|
|
15683
|
-
return true;
|
|
15684
|
-
} else {
|
|
15685
|
-
return false;
|
|
15686
|
-
}
|
|
15687
|
-
} else {
|
|
15688
|
-
const left = node32Index + 8;
|
|
15689
|
-
const right = uint32Array2[node32Index + 6];
|
|
15690
|
-
const offsetLeft = left + byteOffset2;
|
|
15691
|
-
const offsetRight = right + byteOffset2;
|
|
15692
|
-
let forceChildren = force;
|
|
15693
|
-
let includesLeft = false;
|
|
15694
|
-
let includesRight = false;
|
|
15695
|
-
if (nodeIndices) {
|
|
15696
|
-
if (!forceChildren) {
|
|
15697
|
-
includesLeft = nodeIndices.has(offsetLeft);
|
|
15698
|
-
includesRight = nodeIndices.has(offsetRight);
|
|
15699
|
-
forceChildren = !includesLeft && !includesRight;
|
|
15700
|
-
}
|
|
15701
|
-
} else {
|
|
15702
|
-
includesLeft = true;
|
|
15703
|
-
includesRight = true;
|
|
15704
|
-
}
|
|
15705
|
-
const traverseLeft = forceChildren || includesLeft;
|
|
15706
|
-
const traverseRight = forceChildren || includesRight;
|
|
15707
|
-
let leftChange = false;
|
|
15708
|
-
if (traverseLeft) {
|
|
15709
|
-
leftChange = _traverse2(left, byteOffset2, forceChildren);
|
|
15710
|
-
}
|
|
15711
|
-
let rightChange = false;
|
|
15712
|
-
if (traverseRight) {
|
|
15713
|
-
rightChange = _traverse2(right, byteOffset2, forceChildren);
|
|
15714
|
-
}
|
|
15715
|
-
const didChange = leftChange || rightChange;
|
|
15716
|
-
if (didChange) {
|
|
15717
|
-
for (let i = 0; i < 3; i++) {
|
|
15718
|
-
const lefti = left + i;
|
|
15719
|
-
const righti = right + i;
|
|
15720
|
-
const minLeftValue = float32Array2[lefti];
|
|
15721
|
-
const maxLeftValue = float32Array2[lefti + 3];
|
|
15722
|
-
const minRightValue = float32Array2[righti];
|
|
15723
|
-
const maxRightValue = float32Array2[righti + 3];
|
|
15724
|
-
float32Array2[node32Index + i] = minLeftValue < minRightValue ? minLeftValue : minRightValue;
|
|
15725
|
-
float32Array2[node32Index + i + 3] = maxLeftValue > maxRightValue ? maxLeftValue : maxRightValue;
|
|
15726
|
-
}
|
|
15727
|
-
}
|
|
15728
|
-
return didChange;
|
|
15729
|
-
}
|
|
15730
|
-
}
|
|
15731
|
-
}
|
|
15732
|
-
function raycast_indirect(bvh, root, side, ray2, intersects, near, far) {
|
|
15733
|
-
BufferStack.setBuffer(bvh._roots[root]);
|
|
15734
|
-
_raycast(0, bvh, side, ray2, intersects, near, far);
|
|
15735
|
-
BufferStack.clearBuffer();
|
|
15736
|
-
}
|
|
15737
|
-
function _raycast(nodeIndex32, bvh, side, ray2, intersects, near, far) {
|
|
15738
|
-
const { float32Array: float32Array2, uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
|
|
15739
|
-
const nodeIndex16 = nodeIndex32 * 2;
|
|
15740
|
-
const isLeaf = IS_LEAF(nodeIndex16, uint16Array2);
|
|
15741
|
-
if (isLeaf) {
|
|
15742
|
-
const offset = OFFSET(nodeIndex32, uint32Array2);
|
|
15743
|
-
const count = COUNT(nodeIndex16, uint16Array2);
|
|
15744
|
-
intersectTris_indirect(bvh, side, ray2, offset, count, intersects, near, far);
|
|
15745
|
-
} else {
|
|
15746
|
-
const leftIndex = LEFT_NODE(nodeIndex32);
|
|
15747
|
-
if (intersectRay(leftIndex, float32Array2, ray2, near, far)) {
|
|
15748
|
-
_raycast(leftIndex, bvh, side, ray2, intersects, near, far);
|
|
15749
|
-
}
|
|
15750
|
-
const rightIndex = RIGHT_NODE(nodeIndex32, uint32Array2);
|
|
15751
|
-
if (intersectRay(rightIndex, float32Array2, ray2, near, far)) {
|
|
15752
|
-
_raycast(rightIndex, bvh, side, ray2, intersects, near, far);
|
|
15753
|
-
}
|
|
15754
|
-
}
|
|
15755
|
-
}
|
|
15756
|
-
const _xyzFields = ["x", "y", "z"];
|
|
15757
|
-
function raycastFirst_indirect(bvh, root, side, ray2, near, far) {
|
|
15758
|
-
BufferStack.setBuffer(bvh._roots[root]);
|
|
15759
|
-
const result = _raycastFirst(0, bvh, side, ray2, near, far);
|
|
15760
|
-
BufferStack.clearBuffer();
|
|
15761
|
-
return result;
|
|
15762
|
-
}
|
|
15763
|
-
function _raycastFirst(nodeIndex32, bvh, side, ray2, near, far) {
|
|
15764
|
-
const { float32Array: float32Array2, uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
|
|
15765
|
-
let nodeIndex16 = nodeIndex32 * 2;
|
|
15766
|
-
const isLeaf = IS_LEAF(nodeIndex16, uint16Array2);
|
|
15767
|
-
if (isLeaf) {
|
|
15768
|
-
const offset = OFFSET(nodeIndex32, uint32Array2);
|
|
15769
|
-
const count = COUNT(nodeIndex16, uint16Array2);
|
|
15770
|
-
return intersectClosestTri_indirect(bvh, side, ray2, offset, count, near, far);
|
|
15771
|
-
} else {
|
|
15772
|
-
const splitAxis = SPLIT_AXIS(nodeIndex32, uint32Array2);
|
|
15773
|
-
const xyzAxis = _xyzFields[splitAxis];
|
|
15774
|
-
const rayDir = ray2.direction[xyzAxis];
|
|
15775
|
-
const leftToRight = rayDir >= 0;
|
|
15776
|
-
let c1, c2;
|
|
15777
|
-
if (leftToRight) {
|
|
15778
|
-
c1 = LEFT_NODE(nodeIndex32);
|
|
15779
|
-
c2 = RIGHT_NODE(nodeIndex32, uint32Array2);
|
|
15780
|
-
} else {
|
|
15781
|
-
c1 = RIGHT_NODE(nodeIndex32, uint32Array2);
|
|
15782
|
-
c2 = LEFT_NODE(nodeIndex32);
|
|
15783
|
-
}
|
|
15784
|
-
const c1Intersection = intersectRay(c1, float32Array2, ray2, near, far);
|
|
15785
|
-
const c1Result = c1Intersection ? _raycastFirst(c1, bvh, side, ray2, near, far) : null;
|
|
15786
|
-
if (c1Result) {
|
|
15787
|
-
const point = c1Result.point[xyzAxis];
|
|
15788
|
-
const isOutside = leftToRight ? point <= float32Array2[c2 + splitAxis] : (
|
|
15789
|
-
// min bounding data
|
|
15790
|
-
point >= float32Array2[c2 + splitAxis + 3]
|
|
15791
|
-
);
|
|
15792
|
-
if (isOutside) {
|
|
15793
|
-
return c1Result;
|
|
15794
|
-
}
|
|
15795
|
-
}
|
|
15796
|
-
const c2Intersection = intersectRay(c2, float32Array2, ray2, near, far);
|
|
15797
|
-
const c2Result = c2Intersection ? _raycastFirst(c2, bvh, side, ray2, near, far) : null;
|
|
15798
|
-
if (c1Result && c2Result) {
|
|
15799
|
-
return c1Result.distance <= c2Result.distance ? c1Result : c2Result;
|
|
15800
|
-
} else {
|
|
15801
|
-
return c1Result || c2Result || null;
|
|
15802
|
-
}
|
|
15803
|
-
}
|
|
15804
|
-
}
|
|
15805
|
-
const boundingBox = /* @__PURE__ */ new Box3();
|
|
15806
|
-
const triangle = /* @__PURE__ */ new ExtendedTriangle();
|
|
15807
|
-
const triangle2 = /* @__PURE__ */ new ExtendedTriangle();
|
|
15808
|
-
const invertedMat = /* @__PURE__ */ new Matrix4();
|
|
15809
|
-
const obb$2 = /* @__PURE__ */ new OrientedBox();
|
|
15810
|
-
const obb2$1 = /* @__PURE__ */ new OrientedBox();
|
|
15811
|
-
function intersectsGeometry_indirect(bvh, root, otherGeometry, geometryToBvh) {
|
|
15812
|
-
BufferStack.setBuffer(bvh._roots[root]);
|
|
15813
|
-
const result = _intersectsGeometry(0, bvh, otherGeometry, geometryToBvh);
|
|
15814
|
-
BufferStack.clearBuffer();
|
|
15815
|
-
return result;
|
|
15816
|
-
}
|
|
15817
|
-
function _intersectsGeometry(nodeIndex32, bvh, otherGeometry, geometryToBvh, cachedObb = null) {
|
|
15818
|
-
const { float32Array: float32Array2, uint16Array: uint16Array2, uint32Array: uint32Array2 } = BufferStack;
|
|
15819
|
-
let nodeIndex16 = nodeIndex32 * 2;
|
|
15820
|
-
if (cachedObb === null) {
|
|
15821
|
-
if (!otherGeometry.boundingBox) {
|
|
15822
|
-
otherGeometry.computeBoundingBox();
|
|
15823
|
-
}
|
|
15824
|
-
obb$2.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
|
|
15825
|
-
cachedObb = obb$2;
|
|
15826
|
-
}
|
|
15827
|
-
const isLeaf = IS_LEAF(nodeIndex16, uint16Array2);
|
|
15828
|
-
if (isLeaf) {
|
|
15829
|
-
const thisGeometry = bvh.geometry;
|
|
15830
|
-
const thisIndex = thisGeometry.index;
|
|
15831
|
-
const thisPos = thisGeometry.attributes.position;
|
|
15832
|
-
const index = otherGeometry.index;
|
|
15833
|
-
const pos = otherGeometry.attributes.position;
|
|
15834
|
-
const offset = OFFSET(nodeIndex32, uint32Array2);
|
|
15835
|
-
const count = COUNT(nodeIndex16, uint16Array2);
|
|
15836
|
-
invertedMat.copy(geometryToBvh).invert();
|
|
15837
|
-
if (otherGeometry.boundsTree) {
|
|
15838
|
-
arrayToBox(BOUNDING_DATA_INDEX(nodeIndex32), float32Array2, obb2$1);
|
|
15839
|
-
obb2$1.matrix.copy(invertedMat);
|
|
15840
|
-
obb2$1.needsUpdate = true;
|
|
15841
|
-
const res = otherGeometry.boundsTree.shapecast({
|
|
15842
|
-
intersectsBounds: (box2) => obb2$1.intersectsBox(box2),
|
|
15843
|
-
intersectsTriangle: (tri) => {
|
|
15844
|
-
tri.a.applyMatrix4(geometryToBvh);
|
|
15845
|
-
tri.b.applyMatrix4(geometryToBvh);
|
|
15846
|
-
tri.c.applyMatrix4(geometryToBvh);
|
|
15847
|
-
tri.needsUpdate = true;
|
|
15848
|
-
for (let i = offset, l2 = count + offset; i < l2; i++) {
|
|
15849
|
-
setTriangle(triangle2, 3 * bvh.resolveTriangleIndex(i), thisIndex, thisPos);
|
|
15850
|
-
triangle2.needsUpdate = true;
|
|
15851
|
-
if (tri.intersectsTriangle(triangle2)) {
|
|
15852
|
-
return true;
|
|
15853
|
-
}
|
|
15854
|
-
}
|
|
15855
|
-
return false;
|
|
15856
|
-
}
|
|
15857
|
-
});
|
|
15858
|
-
return res;
|
|
15859
|
-
} else {
|
|
15860
|
-
for (let i = offset, l2 = count + offset; i < l2; i++) {
|
|
15861
|
-
const ti = bvh.resolveTriangleIndex(i);
|
|
15862
|
-
setTriangle(triangle, 3 * ti, thisIndex, thisPos);
|
|
15863
|
-
triangle.a.applyMatrix4(invertedMat);
|
|
15864
|
-
triangle.b.applyMatrix4(invertedMat);
|
|
15865
|
-
triangle.c.applyMatrix4(invertedMat);
|
|
15866
|
-
triangle.needsUpdate = true;
|
|
15867
|
-
for (let i2 = 0, l22 = index.count; i2 < l22; i2 += 3) {
|
|
15868
|
-
setTriangle(triangle2, i2, index, pos);
|
|
15869
|
-
triangle2.needsUpdate = true;
|
|
15870
|
-
if (triangle.intersectsTriangle(triangle2)) {
|
|
15871
|
-
return true;
|
|
15872
|
-
}
|
|
15873
|
-
}
|
|
15874
|
-
}
|
|
15875
|
-
}
|
|
15876
|
-
} else {
|
|
15877
|
-
const left = nodeIndex32 + 8;
|
|
15878
|
-
const right = uint32Array2[nodeIndex32 + 6];
|
|
15879
|
-
arrayToBox(BOUNDING_DATA_INDEX(left), float32Array2, boundingBox);
|
|
15880
|
-
const leftIntersection = cachedObb.intersectsBox(boundingBox) && _intersectsGeometry(left, bvh, otherGeometry, geometryToBvh, cachedObb);
|
|
15881
|
-
if (leftIntersection) return true;
|
|
15882
|
-
arrayToBox(BOUNDING_DATA_INDEX(right), float32Array2, boundingBox);
|
|
15883
|
-
const rightIntersection = cachedObb.intersectsBox(boundingBox) && _intersectsGeometry(right, bvh, otherGeometry, geometryToBvh, cachedObb);
|
|
15884
|
-
if (rightIntersection) return true;
|
|
15885
|
-
return false;
|
|
15886
|
-
}
|
|
15887
|
-
}
|
|
15888
|
-
const tempMatrix = /* @__PURE__ */ new Matrix4();
|
|
15889
|
-
const obb$1 = /* @__PURE__ */ new OrientedBox();
|
|
15890
|
-
const obb2 = /* @__PURE__ */ new OrientedBox();
|
|
15891
|
-
const temp1 = /* @__PURE__ */ new Vector3();
|
|
15892
|
-
const temp2 = /* @__PURE__ */ new Vector3();
|
|
15893
|
-
const temp3 = /* @__PURE__ */ new Vector3();
|
|
15894
|
-
const temp4 = /* @__PURE__ */ new Vector3();
|
|
15895
|
-
function closestPointToGeometry_indirect(bvh, otherGeometry, geometryToBvh, target1 = {}, target2 = {}, minThreshold = 0, maxThreshold = Infinity) {
|
|
15896
|
-
if (!otherGeometry.boundingBox) {
|
|
15897
|
-
otherGeometry.computeBoundingBox();
|
|
15898
|
-
}
|
|
15899
|
-
obb$1.set(otherGeometry.boundingBox.min, otherGeometry.boundingBox.max, geometryToBvh);
|
|
15900
|
-
obb$1.needsUpdate = true;
|
|
15901
|
-
const geometry = bvh.geometry;
|
|
15902
|
-
const pos = geometry.attributes.position;
|
|
15903
|
-
const index = geometry.index;
|
|
15904
|
-
const otherPos = otherGeometry.attributes.position;
|
|
15905
|
-
const otherIndex = otherGeometry.index;
|
|
15906
|
-
const triangle3 = ExtendedTrianglePool.getPrimitive();
|
|
15907
|
-
const triangle22 = ExtendedTrianglePool.getPrimitive();
|
|
15908
|
-
let tempTarget1 = temp1;
|
|
15909
|
-
let tempTargetDest1 = temp2;
|
|
15910
|
-
let tempTarget2 = null;
|
|
15911
|
-
let tempTargetDest2 = null;
|
|
15912
|
-
if (target2) {
|
|
15913
|
-
tempTarget2 = temp3;
|
|
15914
|
-
tempTargetDest2 = temp4;
|
|
15915
|
-
}
|
|
15916
|
-
let closestDistance = Infinity;
|
|
15917
|
-
let closestDistanceTriIndex = null;
|
|
15918
|
-
let closestDistanceOtherTriIndex = null;
|
|
15919
|
-
tempMatrix.copy(geometryToBvh).invert();
|
|
15920
|
-
obb2.matrix.copy(tempMatrix);
|
|
15921
|
-
bvh.shapecast(
|
|
15922
|
-
{
|
|
15923
|
-
boundsTraverseOrder: (box2) => {
|
|
15924
|
-
return obb$1.distanceToBox(box2);
|
|
15925
|
-
},
|
|
15926
|
-
intersectsBounds: (box2, isLeaf, score) => {
|
|
15927
|
-
if (score < closestDistance && score < maxThreshold) {
|
|
15928
|
-
if (isLeaf) {
|
|
15929
|
-
obb2.min.copy(box2.min);
|
|
15930
|
-
obb2.max.copy(box2.max);
|
|
15931
|
-
obb2.needsUpdate = true;
|
|
15932
|
-
}
|
|
15933
|
-
return true;
|
|
15934
|
-
}
|
|
15935
|
-
return false;
|
|
15936
|
-
},
|
|
15937
|
-
intersectsRange: (offset, count) => {
|
|
15938
|
-
if (otherGeometry.boundsTree) {
|
|
15939
|
-
const otherBvh = otherGeometry.boundsTree;
|
|
15940
|
-
return otherBvh.shapecast({
|
|
15941
|
-
boundsTraverseOrder: (box2) => {
|
|
15942
|
-
return obb2.distanceToBox(box2);
|
|
15943
|
-
},
|
|
15944
|
-
intersectsBounds: (box2, isLeaf, score) => {
|
|
15945
|
-
return score < closestDistance && score < maxThreshold;
|
|
15946
|
-
},
|
|
15947
|
-
intersectsRange: (otherOffset, otherCount) => {
|
|
15948
|
-
for (let i2 = otherOffset, l2 = otherOffset + otherCount; i2 < l2; i2++) {
|
|
15949
|
-
const ti2 = otherBvh.resolveTriangleIndex(i2);
|
|
15950
|
-
setTriangle(triangle22, 3 * ti2, otherIndex, otherPos);
|
|
15951
|
-
triangle22.a.applyMatrix4(geometryToBvh);
|
|
15952
|
-
triangle22.b.applyMatrix4(geometryToBvh);
|
|
15953
|
-
triangle22.c.applyMatrix4(geometryToBvh);
|
|
15954
|
-
triangle22.needsUpdate = true;
|
|
15955
|
-
for (let i = offset, l3 = offset + count; i < l3; i++) {
|
|
15956
|
-
const ti = bvh.resolveTriangleIndex(i);
|
|
15957
|
-
setTriangle(triangle3, 3 * ti, index, pos);
|
|
15958
|
-
triangle3.needsUpdate = true;
|
|
15959
|
-
const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
|
|
15960
|
-
if (dist < closestDistance) {
|
|
15961
|
-
tempTargetDest1.copy(tempTarget1);
|
|
15962
|
-
if (tempTargetDest2) {
|
|
15963
|
-
tempTargetDest2.copy(tempTarget2);
|
|
15964
|
-
}
|
|
15965
|
-
closestDistance = dist;
|
|
15966
|
-
closestDistanceTriIndex = i;
|
|
15967
|
-
closestDistanceOtherTriIndex = i2;
|
|
15968
|
-
}
|
|
15969
|
-
if (dist < minThreshold) {
|
|
15970
|
-
return true;
|
|
15971
|
-
}
|
|
15972
|
-
}
|
|
15973
|
-
}
|
|
15974
|
-
}
|
|
15975
|
-
});
|
|
15976
|
-
} else {
|
|
15977
|
-
const triCount = getTriCount(otherGeometry);
|
|
15978
|
-
for (let i2 = 0, l2 = triCount; i2 < l2; i2++) {
|
|
15979
|
-
setTriangle(triangle22, 3 * i2, otherIndex, otherPos);
|
|
15980
|
-
triangle22.a.applyMatrix4(geometryToBvh);
|
|
15981
|
-
triangle22.b.applyMatrix4(geometryToBvh);
|
|
15982
|
-
triangle22.c.applyMatrix4(geometryToBvh);
|
|
15983
|
-
triangle22.needsUpdate = true;
|
|
15984
|
-
for (let i = offset, l3 = offset + count; i < l3; i++) {
|
|
15985
|
-
const ti = bvh.resolveTriangleIndex(i);
|
|
15986
|
-
setTriangle(triangle3, 3 * ti, index, pos);
|
|
15987
|
-
triangle3.needsUpdate = true;
|
|
15988
|
-
const dist = triangle3.distanceToTriangle(triangle22, tempTarget1, tempTarget2);
|
|
15989
|
-
if (dist < closestDistance) {
|
|
15990
|
-
tempTargetDest1.copy(tempTarget1);
|
|
15991
|
-
if (tempTargetDest2) {
|
|
15992
|
-
tempTargetDest2.copy(tempTarget2);
|
|
15993
|
-
}
|
|
15994
|
-
closestDistance = dist;
|
|
15995
|
-
closestDistanceTriIndex = i;
|
|
15996
|
-
closestDistanceOtherTriIndex = i2;
|
|
15997
|
-
}
|
|
15998
|
-
if (dist < minThreshold) {
|
|
15999
|
-
return true;
|
|
16000
|
-
}
|
|
16001
|
-
}
|
|
16002
|
-
}
|
|
16003
|
-
}
|
|
16004
|
-
}
|
|
16005
|
-
}
|
|
16006
|
-
);
|
|
16007
|
-
ExtendedTrianglePool.releasePrimitive(triangle3);
|
|
16008
|
-
ExtendedTrianglePool.releasePrimitive(triangle22);
|
|
16009
|
-
if (closestDistance === Infinity) {
|
|
16010
|
-
return null;
|
|
16011
|
-
}
|
|
16012
|
-
if (!target1.point) {
|
|
16013
|
-
target1.point = tempTargetDest1.clone();
|
|
16014
|
-
} else {
|
|
16015
|
-
target1.point.copy(tempTargetDest1);
|
|
16016
|
-
}
|
|
16017
|
-
target1.distance = closestDistance, target1.faceIndex = closestDistanceTriIndex;
|
|
16018
|
-
if (target2) {
|
|
16019
|
-
if (!target2.point) target2.point = tempTargetDest2.clone();
|
|
16020
|
-
else target2.point.copy(tempTargetDest2);
|
|
16021
|
-
target2.point.applyMatrix4(tempMatrix);
|
|
16022
|
-
tempTargetDest1.applyMatrix4(tempMatrix);
|
|
16023
|
-
target2.distance = tempTargetDest1.sub(target2.point).length();
|
|
16024
|
-
target2.faceIndex = closestDistanceOtherTriIndex;
|
|
16025
|
-
}
|
|
16026
|
-
return target1;
|
|
16027
|
-
}
|
|
16028
|
-
function isSharedArrayBufferSupported() {
|
|
16029
|
-
return typeof SharedArrayBuffer !== "undefined";
|
|
16030
|
-
}
|
|
16031
|
-
const _bufferStack1 = new BufferStack.constructor();
|
|
16032
|
-
const _bufferStack2 = new BufferStack.constructor();
|
|
16033
|
-
const _boxPool = new PrimitivePool(() => new Box3());
|
|
16034
|
-
const _leftBox1 = new Box3();
|
|
16035
|
-
const _rightBox1 = new Box3();
|
|
16036
|
-
const _leftBox2 = new Box3();
|
|
16037
|
-
const _rightBox2 = new Box3();
|
|
16038
|
-
let _active = false;
|
|
16039
|
-
function bvhcast(bvh, otherBvh, matrixToLocal, intersectsRanges) {
|
|
16040
|
-
if (_active) {
|
|
16041
|
-
throw new Error("MeshBVH: Recursive calls to bvhcast not supported.");
|
|
16042
|
-
}
|
|
16043
|
-
_active = true;
|
|
16044
|
-
const roots = bvh._roots;
|
|
16045
|
-
const otherRoots = otherBvh._roots;
|
|
16046
|
-
let result;
|
|
16047
|
-
let offset1 = 0;
|
|
16048
|
-
let offset2 = 0;
|
|
16049
|
-
const invMat = new Matrix4().copy(matrixToLocal).invert();
|
|
16050
|
-
for (let i = 0, il = roots.length; i < il; i++) {
|
|
16051
|
-
_bufferStack1.setBuffer(roots[i]);
|
|
16052
|
-
offset2 = 0;
|
|
16053
|
-
const localBox = _boxPool.getPrimitive();
|
|
16054
|
-
arrayToBox(BOUNDING_DATA_INDEX(0), _bufferStack1.float32Array, localBox);
|
|
16055
|
-
localBox.applyMatrix4(invMat);
|
|
16056
|
-
for (let j2 = 0, jl = otherRoots.length; j2 < jl; j2++) {
|
|
16057
|
-
_bufferStack2.setBuffer(otherRoots[j2]);
|
|
16058
|
-
result = _traverse(
|
|
16059
|
-
0,
|
|
16060
|
-
0,
|
|
16061
|
-
matrixToLocal,
|
|
16062
|
-
invMat,
|
|
16063
|
-
intersectsRanges,
|
|
16064
|
-
offset1,
|
|
16065
|
-
offset2,
|
|
16066
|
-
0,
|
|
16067
|
-
0,
|
|
16068
|
-
localBox
|
|
16069
|
-
);
|
|
16070
|
-
_bufferStack2.clearBuffer();
|
|
16071
|
-
offset2 += otherRoots[j2].length;
|
|
16072
|
-
if (result) {
|
|
16073
|
-
break;
|
|
16074
|
-
}
|
|
16075
|
-
}
|
|
16076
|
-
_boxPool.releasePrimitive(localBox);
|
|
16077
|
-
_bufferStack1.clearBuffer();
|
|
16078
|
-
offset1 += roots[i].length;
|
|
16079
|
-
if (result) {
|
|
16080
|
-
break;
|
|
16081
|
-
}
|
|
16082
|
-
}
|
|
16083
|
-
_active = false;
|
|
16084
|
-
return result;
|
|
16085
|
-
}
|
|
16086
|
-
function _traverse(node1Index32, node2Index32, matrix2to1, matrix1to2, intersectsRangesFunc, node1IndexByteOffset = 0, node2IndexByteOffset = 0, depth1 = 0, depth2 = 0, currBox = null, reversed = false) {
|
|
16087
|
-
let bufferStack1, bufferStack2;
|
|
16088
|
-
if (reversed) {
|
|
16089
|
-
bufferStack1 = _bufferStack2;
|
|
16090
|
-
bufferStack2 = _bufferStack1;
|
|
16091
|
-
} else {
|
|
16092
|
-
bufferStack1 = _bufferStack1;
|
|
16093
|
-
bufferStack2 = _bufferStack2;
|
|
16094
|
-
}
|
|
16095
|
-
const float32Array1 = bufferStack1.float32Array, uint32Array1 = bufferStack1.uint32Array, uint16Array1 = bufferStack1.uint16Array, float32Array2 = bufferStack2.float32Array, uint32Array2 = bufferStack2.uint32Array, uint16Array2 = bufferStack2.uint16Array;
|
|
16096
|
-
const node1Index16 = node1Index32 * 2;
|
|
16097
|
-
const node2Index16 = node2Index32 * 2;
|
|
16098
|
-
const isLeaf1 = IS_LEAF(node1Index16, uint16Array1);
|
|
16099
|
-
const isLeaf2 = IS_LEAF(node2Index16, uint16Array2);
|
|
16100
|
-
let result = false;
|
|
16101
|
-
if (isLeaf2 && isLeaf1) {
|
|
16102
|
-
if (reversed) {
|
|
16103
|
-
result = intersectsRangesFunc(
|
|
16104
|
-
OFFSET(node2Index32, uint32Array2),
|
|
16105
|
-
COUNT(node2Index32 * 2, uint16Array2),
|
|
16106
|
-
OFFSET(node1Index32, uint32Array1),
|
|
16107
|
-
COUNT(node1Index32 * 2, uint16Array1),
|
|
16108
|
-
depth2,
|
|
16109
|
-
node2IndexByteOffset + node2Index32,
|
|
16110
|
-
depth1,
|
|
16111
|
-
node1IndexByteOffset + node1Index32
|
|
16112
|
-
);
|
|
16113
|
-
} else {
|
|
16114
|
-
result = intersectsRangesFunc(
|
|
16115
|
-
OFFSET(node1Index32, uint32Array1),
|
|
16116
|
-
COUNT(node1Index32 * 2, uint16Array1),
|
|
16117
|
-
OFFSET(node2Index32, uint32Array2),
|
|
16118
|
-
COUNT(node2Index32 * 2, uint16Array2),
|
|
16119
|
-
depth1,
|
|
16120
|
-
node1IndexByteOffset + node1Index32,
|
|
16121
|
-
depth2,
|
|
16122
|
-
node2IndexByteOffset + node2Index32
|
|
16123
|
-
);
|
|
16124
|
-
}
|
|
16125
|
-
} else if (isLeaf2) {
|
|
16126
|
-
const newBox = _boxPool.getPrimitive();
|
|
16127
|
-
arrayToBox(BOUNDING_DATA_INDEX(node2Index32), float32Array2, newBox);
|
|
16128
|
-
newBox.applyMatrix4(matrix2to1);
|
|
16129
|
-
const cl1 = LEFT_NODE(node1Index32);
|
|
16130
|
-
const cr1 = RIGHT_NODE(node1Index32, uint32Array1);
|
|
16131
|
-
arrayToBox(BOUNDING_DATA_INDEX(cl1), float32Array1, _leftBox1);
|
|
16132
|
-
arrayToBox(BOUNDING_DATA_INDEX(cr1), float32Array1, _rightBox1);
|
|
16133
|
-
const intersectCl1 = newBox.intersectsBox(_leftBox1);
|
|
16134
|
-
const intersectCr1 = newBox.intersectsBox(_rightBox1);
|
|
16135
|
-
result = intersectCl1 && _traverse(
|
|
16136
|
-
node2Index32,
|
|
16137
|
-
cl1,
|
|
16138
|
-
matrix1to2,
|
|
16139
|
-
matrix2to1,
|
|
16140
|
-
intersectsRangesFunc,
|
|
16141
|
-
node2IndexByteOffset,
|
|
16142
|
-
node1IndexByteOffset,
|
|
16143
|
-
depth2,
|
|
16144
|
-
depth1 + 1,
|
|
16145
|
-
newBox,
|
|
16146
|
-
!reversed
|
|
16147
|
-
) || intersectCr1 && _traverse(
|
|
16148
|
-
node2Index32,
|
|
16149
|
-
cr1,
|
|
16150
|
-
matrix1to2,
|
|
16151
|
-
matrix2to1,
|
|
16152
|
-
intersectsRangesFunc,
|
|
16153
|
-
node2IndexByteOffset,
|
|
16154
|
-
node1IndexByteOffset,
|
|
16155
|
-
depth2,
|
|
16156
|
-
depth1 + 1,
|
|
16157
|
-
newBox,
|
|
16158
|
-
!reversed
|
|
16159
|
-
);
|
|
16160
|
-
_boxPool.releasePrimitive(newBox);
|
|
16161
|
-
} else {
|
|
16162
|
-
const cl2 = LEFT_NODE(node2Index32);
|
|
16163
|
-
const cr2 = RIGHT_NODE(node2Index32, uint32Array2);
|
|
16164
|
-
arrayToBox(BOUNDING_DATA_INDEX(cl2), float32Array2, _leftBox2);
|
|
16165
|
-
arrayToBox(BOUNDING_DATA_INDEX(cr2), float32Array2, _rightBox2);
|
|
16166
|
-
const leftIntersects = currBox.intersectsBox(_leftBox2);
|
|
16167
|
-
const rightIntersects = currBox.intersectsBox(_rightBox2);
|
|
16168
|
-
if (leftIntersects && rightIntersects) {
|
|
16169
|
-
result = _traverse(
|
|
16170
|
-
node1Index32,
|
|
16171
|
-
cl2,
|
|
16172
|
-
matrix2to1,
|
|
16173
|
-
matrix1to2,
|
|
16174
|
-
intersectsRangesFunc,
|
|
16175
|
-
node1IndexByteOffset,
|
|
16176
|
-
node2IndexByteOffset,
|
|
16177
|
-
depth1,
|
|
16178
|
-
depth2 + 1,
|
|
16179
|
-
currBox,
|
|
16180
|
-
reversed
|
|
16181
|
-
) || _traverse(
|
|
16182
|
-
node1Index32,
|
|
16183
|
-
cr2,
|
|
16184
|
-
matrix2to1,
|
|
16185
|
-
matrix1to2,
|
|
16186
|
-
intersectsRangesFunc,
|
|
16187
|
-
node1IndexByteOffset,
|
|
16188
|
-
node2IndexByteOffset,
|
|
16189
|
-
depth1,
|
|
16190
|
-
depth2 + 1,
|
|
16191
|
-
currBox,
|
|
16192
|
-
reversed
|
|
16193
|
-
);
|
|
16194
|
-
} else if (leftIntersects) {
|
|
16195
|
-
if (isLeaf1) {
|
|
16196
|
-
result = _traverse(
|
|
16197
|
-
node1Index32,
|
|
16198
|
-
cl2,
|
|
16199
|
-
matrix2to1,
|
|
16200
|
-
matrix1to2,
|
|
16201
|
-
intersectsRangesFunc,
|
|
16202
|
-
node1IndexByteOffset,
|
|
16203
|
-
node2IndexByteOffset,
|
|
16204
|
-
depth1,
|
|
16205
|
-
depth2 + 1,
|
|
16206
|
-
currBox,
|
|
16207
|
-
reversed
|
|
16208
|
-
);
|
|
16209
|
-
} else {
|
|
16210
|
-
const newBox = _boxPool.getPrimitive();
|
|
16211
|
-
newBox.copy(_leftBox2).applyMatrix4(matrix2to1);
|
|
16212
|
-
const cl1 = LEFT_NODE(node1Index32);
|
|
16213
|
-
const cr1 = RIGHT_NODE(node1Index32, uint32Array1);
|
|
16214
|
-
arrayToBox(BOUNDING_DATA_INDEX(cl1), float32Array1, _leftBox1);
|
|
16215
|
-
arrayToBox(BOUNDING_DATA_INDEX(cr1), float32Array1, _rightBox1);
|
|
16216
|
-
const intersectCl1 = newBox.intersectsBox(_leftBox1);
|
|
16217
|
-
const intersectCr1 = newBox.intersectsBox(_rightBox1);
|
|
16218
|
-
result = intersectCl1 && _traverse(
|
|
16219
|
-
cl2,
|
|
16220
|
-
cl1,
|
|
16221
|
-
matrix1to2,
|
|
16222
|
-
matrix2to1,
|
|
16223
|
-
intersectsRangesFunc,
|
|
16224
|
-
node2IndexByteOffset,
|
|
16225
|
-
node1IndexByteOffset,
|
|
16226
|
-
depth2,
|
|
16227
|
-
depth1 + 1,
|
|
16228
|
-
newBox,
|
|
16229
|
-
!reversed
|
|
16230
|
-
) || intersectCr1 && _traverse(
|
|
16231
|
-
cl2,
|
|
16232
|
-
cr1,
|
|
16233
|
-
matrix1to2,
|
|
16234
|
-
matrix2to1,
|
|
16235
|
-
intersectsRangesFunc,
|
|
16236
|
-
node2IndexByteOffset,
|
|
16237
|
-
node1IndexByteOffset,
|
|
16238
|
-
depth2,
|
|
16239
|
-
depth1 + 1,
|
|
16240
|
-
newBox,
|
|
16241
|
-
!reversed
|
|
16242
|
-
);
|
|
16243
|
-
_boxPool.releasePrimitive(newBox);
|
|
16244
|
-
}
|
|
16245
|
-
} else if (rightIntersects) {
|
|
16246
|
-
if (isLeaf1) {
|
|
16247
|
-
result = _traverse(
|
|
16248
|
-
node1Index32,
|
|
16249
|
-
cr2,
|
|
16250
|
-
matrix2to1,
|
|
16251
|
-
matrix1to2,
|
|
16252
|
-
intersectsRangesFunc,
|
|
16253
|
-
node1IndexByteOffset,
|
|
16254
|
-
node2IndexByteOffset,
|
|
16255
|
-
depth1,
|
|
16256
|
-
depth2 + 1,
|
|
16257
|
-
currBox,
|
|
16258
|
-
reversed
|
|
16259
|
-
);
|
|
16260
|
-
} else {
|
|
16261
|
-
const newBox = _boxPool.getPrimitive();
|
|
16262
|
-
newBox.copy(_rightBox2).applyMatrix4(matrix2to1);
|
|
16263
|
-
const cl1 = LEFT_NODE(node1Index32);
|
|
16264
|
-
const cr1 = RIGHT_NODE(node1Index32, uint32Array1);
|
|
16265
|
-
arrayToBox(BOUNDING_DATA_INDEX(cl1), float32Array1, _leftBox1);
|
|
16266
|
-
arrayToBox(BOUNDING_DATA_INDEX(cr1), float32Array1, _rightBox1);
|
|
16267
|
-
const intersectCl1 = newBox.intersectsBox(_leftBox1);
|
|
16268
|
-
const intersectCr1 = newBox.intersectsBox(_rightBox1);
|
|
16269
|
-
result = intersectCl1 && _traverse(
|
|
16270
|
-
cr2,
|
|
16271
|
-
cl1,
|
|
16272
|
-
matrix1to2,
|
|
16273
|
-
matrix2to1,
|
|
16274
|
-
intersectsRangesFunc,
|
|
16275
|
-
node2IndexByteOffset,
|
|
16276
|
-
node1IndexByteOffset,
|
|
16277
|
-
depth2,
|
|
16278
|
-
depth1 + 1,
|
|
16279
|
-
newBox,
|
|
16280
|
-
!reversed
|
|
16281
|
-
) || intersectCr1 && _traverse(
|
|
16282
|
-
cr2,
|
|
16283
|
-
cr1,
|
|
16284
|
-
matrix1to2,
|
|
16285
|
-
matrix2to1,
|
|
16286
|
-
intersectsRangesFunc,
|
|
16287
|
-
node2IndexByteOffset,
|
|
16288
|
-
node1IndexByteOffset,
|
|
16289
|
-
depth2,
|
|
16290
|
-
depth1 + 1,
|
|
16291
|
-
newBox,
|
|
16292
|
-
!reversed
|
|
16293
|
-
);
|
|
16294
|
-
_boxPool.releasePrimitive(newBox);
|
|
16295
|
-
}
|
|
16296
|
-
}
|
|
16297
|
-
}
|
|
16298
|
-
return result;
|
|
16299
|
-
}
|
|
16300
|
-
const obb = /* @__PURE__ */ new OrientedBox();
|
|
16301
|
-
const tempBox = /* @__PURE__ */ new Box3();
|
|
16302
|
-
const DEFAULT_OPTIONS = {
|
|
16303
|
-
strategy: CENTER,
|
|
16304
|
-
maxDepth: 40,
|
|
16305
|
-
maxLeafTris: 10,
|
|
16306
|
-
useSharedArrayBuffer: false,
|
|
16307
|
-
setBoundingBox: true,
|
|
16308
|
-
onProgress: null,
|
|
16309
|
-
indirect: false,
|
|
16310
|
-
verbose: true,
|
|
16311
|
-
range: null
|
|
16312
|
-
};
|
|
16313
|
-
class MeshBVH {
|
|
16314
|
-
static serialize(bvh, options = {}) {
|
|
16315
|
-
options = {
|
|
16316
|
-
cloneBuffers: true,
|
|
16317
|
-
...options
|
|
16318
|
-
};
|
|
16319
|
-
const geometry = bvh.geometry;
|
|
16320
|
-
const rootData = bvh._roots;
|
|
16321
|
-
const indirectBuffer = bvh._indirectBuffer;
|
|
16322
|
-
const indexAttribute = geometry.getIndex();
|
|
16323
|
-
let result;
|
|
16324
|
-
if (options.cloneBuffers) {
|
|
16325
|
-
result = {
|
|
16326
|
-
roots: rootData.map((root) => root.slice()),
|
|
16327
|
-
index: indexAttribute ? indexAttribute.array.slice() : null,
|
|
16328
|
-
indirectBuffer: indirectBuffer ? indirectBuffer.slice() : null
|
|
16329
|
-
};
|
|
16330
|
-
} else {
|
|
16331
|
-
result = {
|
|
16332
|
-
roots: rootData,
|
|
16333
|
-
index: indexAttribute ? indexAttribute.array : null,
|
|
16334
|
-
indirectBuffer
|
|
16335
|
-
};
|
|
16336
|
-
}
|
|
16337
|
-
return result;
|
|
16338
|
-
}
|
|
16339
|
-
static deserialize(data, geometry, options = {}) {
|
|
16340
|
-
options = {
|
|
16341
|
-
setIndex: true,
|
|
16342
|
-
indirect: Boolean(data.indirectBuffer),
|
|
16343
|
-
...options
|
|
16344
|
-
};
|
|
16345
|
-
const { index, roots, indirectBuffer } = data;
|
|
16346
|
-
const bvh = new MeshBVH(geometry, { ...options, [SKIP_GENERATION]: true });
|
|
16347
|
-
bvh._roots = roots;
|
|
16348
|
-
bvh._indirectBuffer = indirectBuffer || null;
|
|
16349
|
-
if (options.setIndex) {
|
|
16350
|
-
const indexAttribute = geometry.getIndex();
|
|
16351
|
-
if (indexAttribute === null) {
|
|
16352
|
-
const newIndex = new BufferAttribute(data.index, 1, false);
|
|
16353
|
-
geometry.setIndex(newIndex);
|
|
16354
|
-
} else if (indexAttribute.array !== index) {
|
|
16355
|
-
indexAttribute.array.set(index);
|
|
16356
|
-
indexAttribute.needsUpdate = true;
|
|
16357
|
-
}
|
|
16358
|
-
}
|
|
16359
|
-
return bvh;
|
|
16360
|
-
}
|
|
16361
|
-
get indirect() {
|
|
16362
|
-
return !!this._indirectBuffer;
|
|
16363
|
-
}
|
|
16364
|
-
constructor(geometry, options = {}) {
|
|
16365
|
-
if (!geometry.isBufferGeometry) {
|
|
16366
|
-
throw new Error("MeshBVH: Only BufferGeometries are supported.");
|
|
16367
|
-
} else if (geometry.index && geometry.index.isInterleavedBufferAttribute) {
|
|
16368
|
-
throw new Error("MeshBVH: InterleavedBufferAttribute is not supported for the index attribute.");
|
|
16369
|
-
}
|
|
16370
|
-
options = Object.assign({
|
|
16371
|
-
...DEFAULT_OPTIONS,
|
|
16372
|
-
// undocumented options
|
|
16373
|
-
// Whether to skip generating the tree. Used for deserialization.
|
|
16374
|
-
[SKIP_GENERATION]: false
|
|
16375
|
-
}, options);
|
|
16376
|
-
if (options.useSharedArrayBuffer && !isSharedArrayBufferSupported()) {
|
|
16377
|
-
throw new Error("MeshBVH: SharedArrayBuffer is not available.");
|
|
16378
|
-
}
|
|
16379
|
-
this.geometry = geometry;
|
|
16380
|
-
this._roots = null;
|
|
16381
|
-
this._indirectBuffer = null;
|
|
16382
|
-
if (!options[SKIP_GENERATION]) {
|
|
16383
|
-
buildPackedTree(this, options);
|
|
16384
|
-
if (!geometry.boundingBox && options.setBoundingBox) {
|
|
16385
|
-
geometry.boundingBox = this.getBoundingBox(new Box3());
|
|
16386
|
-
}
|
|
16387
|
-
}
|
|
16388
|
-
this.resolveTriangleIndex = options.indirect ? (i) => this._indirectBuffer[i] : (i) => i;
|
|
16389
|
-
}
|
|
16390
|
-
refit(nodeIndices = null) {
|
|
16391
|
-
const refitFunc = this.indirect ? refit_indirect : refit;
|
|
16392
|
-
return refitFunc(this, nodeIndices);
|
|
16393
|
-
}
|
|
16394
|
-
traverse(callback, rootIndex = 0) {
|
|
16395
|
-
const buffer = this._roots[rootIndex];
|
|
16396
|
-
const uint32Array2 = new Uint32Array(buffer);
|
|
16397
|
-
const uint16Array2 = new Uint16Array(buffer);
|
|
16398
|
-
_traverse2(0);
|
|
16399
|
-
function _traverse2(node32Index, depth = 0) {
|
|
16400
|
-
const node16Index = node32Index * 2;
|
|
16401
|
-
const isLeaf = uint16Array2[node16Index + 15] === IS_LEAFNODE_FLAG;
|
|
16402
|
-
if (isLeaf) {
|
|
16403
|
-
const offset = uint32Array2[node32Index + 6];
|
|
16404
|
-
const count = uint16Array2[node16Index + 14];
|
|
16405
|
-
callback(depth, isLeaf, new Float32Array(buffer, node32Index * 4, 6), offset, count);
|
|
16406
|
-
} else {
|
|
16407
|
-
const left = node32Index + BYTES_PER_NODE / 4;
|
|
16408
|
-
const right = uint32Array2[node32Index + 6];
|
|
16409
|
-
const splitAxis = uint32Array2[node32Index + 7];
|
|
16410
|
-
const stopTraversal = callback(depth, isLeaf, new Float32Array(buffer, node32Index * 4, 6), splitAxis);
|
|
16411
|
-
if (!stopTraversal) {
|
|
16412
|
-
_traverse2(left, depth + 1);
|
|
16413
|
-
_traverse2(right, depth + 1);
|
|
16414
|
-
}
|
|
16415
|
-
}
|
|
16416
|
-
}
|
|
16417
|
-
}
|
|
16418
|
-
/* Core Cast Functions */
|
|
16419
|
-
raycast(ray2, materialOrSide = FrontSide, near = 0, far = Infinity) {
|
|
16420
|
-
const roots = this._roots;
|
|
16421
|
-
const geometry = this.geometry;
|
|
16422
|
-
const intersects = [];
|
|
16423
|
-
const isMaterial = materialOrSide.isMaterial;
|
|
16424
|
-
const isArrayMaterial = Array.isArray(materialOrSide);
|
|
16425
|
-
const groups = geometry.groups;
|
|
16426
|
-
const side = isMaterial ? materialOrSide.side : materialOrSide;
|
|
16427
|
-
const raycastFunc = this.indirect ? raycast_indirect : raycast;
|
|
16428
|
-
for (let i = 0, l2 = roots.length; i < l2; i++) {
|
|
16429
|
-
const materialSide = isArrayMaterial ? materialOrSide[groups[i].materialIndex].side : side;
|
|
16430
|
-
const startCount = intersects.length;
|
|
16431
|
-
raycastFunc(this, i, materialSide, ray2, intersects, near, far);
|
|
16432
|
-
if (isArrayMaterial) {
|
|
16433
|
-
const materialIndex = groups[i].materialIndex;
|
|
16434
|
-
for (let j2 = startCount, jl = intersects.length; j2 < jl; j2++) {
|
|
16435
|
-
intersects[j2].face.materialIndex = materialIndex;
|
|
16436
|
-
}
|
|
16437
|
-
}
|
|
16438
|
-
}
|
|
16439
|
-
return intersects;
|
|
16440
|
-
}
|
|
16441
|
-
raycastFirst(ray2, materialOrSide = FrontSide, near = 0, far = Infinity) {
|
|
16442
|
-
const roots = this._roots;
|
|
16443
|
-
const geometry = this.geometry;
|
|
16444
|
-
const isMaterial = materialOrSide.isMaterial;
|
|
16445
|
-
const isArrayMaterial = Array.isArray(materialOrSide);
|
|
16446
|
-
let closestResult = null;
|
|
16447
|
-
const groups = geometry.groups;
|
|
16448
|
-
const side = isMaterial ? materialOrSide.side : materialOrSide;
|
|
16449
|
-
const raycastFirstFunc = this.indirect ? raycastFirst_indirect : raycastFirst;
|
|
16450
|
-
for (let i = 0, l2 = roots.length; i < l2; i++) {
|
|
16451
|
-
const materialSide = isArrayMaterial ? materialOrSide[groups[i].materialIndex].side : side;
|
|
16452
|
-
const result = raycastFirstFunc(this, i, materialSide, ray2, near, far);
|
|
16453
|
-
if (result != null && (closestResult == null || result.distance < closestResult.distance)) {
|
|
16454
|
-
closestResult = result;
|
|
16455
|
-
if (isArrayMaterial) {
|
|
16456
|
-
result.face.materialIndex = groups[i].materialIndex;
|
|
16457
|
-
}
|
|
16458
|
-
}
|
|
16459
|
-
}
|
|
16460
|
-
return closestResult;
|
|
16461
|
-
}
|
|
16462
|
-
intersectsGeometry(otherGeometry, geomToMesh) {
|
|
16463
|
-
let result = false;
|
|
16464
|
-
const roots = this._roots;
|
|
16465
|
-
const intersectsGeometryFunc = this.indirect ? intersectsGeometry_indirect : intersectsGeometry;
|
|
16466
|
-
for (let i = 0, l2 = roots.length; i < l2; i++) {
|
|
16467
|
-
result = intersectsGeometryFunc(this, i, otherGeometry, geomToMesh);
|
|
16468
|
-
if (result) {
|
|
16469
|
-
break;
|
|
16470
|
-
}
|
|
16471
|
-
}
|
|
16472
|
-
return result;
|
|
16473
|
-
}
|
|
16474
|
-
shapecast(callbacks) {
|
|
16475
|
-
const triangle3 = ExtendedTrianglePool.getPrimitive();
|
|
16476
|
-
const iterateFunc = this.indirect ? iterateOverTriangles_indirect : iterateOverTriangles;
|
|
16477
|
-
let {
|
|
16478
|
-
boundsTraverseOrder,
|
|
16479
|
-
intersectsBounds,
|
|
16480
|
-
intersectsRange,
|
|
16481
|
-
intersectsTriangle
|
|
16482
|
-
} = callbacks;
|
|
16483
|
-
if (intersectsRange && intersectsTriangle) {
|
|
16484
|
-
const originalIntersectsRange = intersectsRange;
|
|
16485
|
-
intersectsRange = (offset, count, contained, depth, nodeIndex) => {
|
|
16486
|
-
if (!originalIntersectsRange(offset, count, contained, depth, nodeIndex)) {
|
|
16487
|
-
return iterateFunc(offset, count, this, intersectsTriangle, contained, depth, triangle3);
|
|
16488
|
-
}
|
|
16489
|
-
return true;
|
|
16490
|
-
};
|
|
16491
|
-
} else if (!intersectsRange) {
|
|
16492
|
-
if (intersectsTriangle) {
|
|
16493
|
-
intersectsRange = (offset, count, contained, depth) => {
|
|
16494
|
-
return iterateFunc(offset, count, this, intersectsTriangle, contained, depth, triangle3);
|
|
16495
|
-
};
|
|
16496
|
-
} else {
|
|
16497
|
-
intersectsRange = (offset, count, contained) => {
|
|
16498
|
-
return contained;
|
|
16499
|
-
};
|
|
16500
|
-
}
|
|
16501
|
-
}
|
|
16502
|
-
let result = false;
|
|
16503
|
-
let byteOffset = 0;
|
|
16504
|
-
const roots = this._roots;
|
|
16505
|
-
for (let i = 0, l2 = roots.length; i < l2; i++) {
|
|
16506
|
-
const root = roots[i];
|
|
16507
|
-
result = shapecast(this, i, intersectsBounds, intersectsRange, boundsTraverseOrder, byteOffset);
|
|
16508
|
-
if (result) {
|
|
16509
|
-
break;
|
|
16510
|
-
}
|
|
16511
|
-
byteOffset += root.byteLength;
|
|
16512
|
-
}
|
|
16513
|
-
ExtendedTrianglePool.releasePrimitive(triangle3);
|
|
16514
|
-
return result;
|
|
16515
|
-
}
|
|
16516
|
-
bvhcast(otherBvh, matrixToLocal, callbacks) {
|
|
16517
|
-
let {
|
|
16518
|
-
intersectsRanges,
|
|
16519
|
-
intersectsTriangles
|
|
16520
|
-
} = callbacks;
|
|
16521
|
-
const triangle1 = ExtendedTrianglePool.getPrimitive();
|
|
16522
|
-
const indexAttr1 = this.geometry.index;
|
|
16523
|
-
const positionAttr1 = this.geometry.attributes.position;
|
|
16524
|
-
const assignTriangle1 = this.indirect ? (i1) => {
|
|
16525
|
-
const ti = this.resolveTriangleIndex(i1);
|
|
16526
|
-
setTriangle(triangle1, ti * 3, indexAttr1, positionAttr1);
|
|
16527
|
-
} : (i1) => {
|
|
16528
|
-
setTriangle(triangle1, i1 * 3, indexAttr1, positionAttr1);
|
|
16529
|
-
};
|
|
16530
|
-
const triangle22 = ExtendedTrianglePool.getPrimitive();
|
|
16531
|
-
const indexAttr2 = otherBvh.geometry.index;
|
|
16532
|
-
const positionAttr2 = otherBvh.geometry.attributes.position;
|
|
16533
|
-
const assignTriangle2 = otherBvh.indirect ? (i2) => {
|
|
16534
|
-
const ti2 = otherBvh.resolveTriangleIndex(i2);
|
|
16535
|
-
setTriangle(triangle22, ti2 * 3, indexAttr2, positionAttr2);
|
|
16536
|
-
} : (i2) => {
|
|
16537
|
-
setTriangle(triangle22, i2 * 3, indexAttr2, positionAttr2);
|
|
16538
|
-
};
|
|
16539
|
-
if (intersectsTriangles) {
|
|
16540
|
-
const iterateOverDoubleTriangles = (offset1, count1, offset2, count2, depth1, index1, depth2, index2) => {
|
|
16541
|
-
for (let i2 = offset2, l2 = offset2 + count2; i2 < l2; i2++) {
|
|
16542
|
-
assignTriangle2(i2);
|
|
16543
|
-
triangle22.a.applyMatrix4(matrixToLocal);
|
|
16544
|
-
triangle22.b.applyMatrix4(matrixToLocal);
|
|
16545
|
-
triangle22.c.applyMatrix4(matrixToLocal);
|
|
16546
|
-
triangle22.needsUpdate = true;
|
|
16547
|
-
for (let i1 = offset1, l1 = offset1 + count1; i1 < l1; i1++) {
|
|
16548
|
-
assignTriangle1(i1);
|
|
16549
|
-
triangle1.needsUpdate = true;
|
|
16550
|
-
if (intersectsTriangles(triangle1, triangle22, i1, i2, depth1, index1, depth2, index2)) {
|
|
16551
|
-
return true;
|
|
16552
|
-
}
|
|
16553
|
-
}
|
|
16554
|
-
}
|
|
16555
|
-
return false;
|
|
16556
|
-
};
|
|
16557
|
-
if (intersectsRanges) {
|
|
16558
|
-
const originalIntersectsRanges = intersectsRanges;
|
|
16559
|
-
intersectsRanges = function(offset1, count1, offset2, count2, depth1, index1, depth2, index2) {
|
|
16560
|
-
if (!originalIntersectsRanges(offset1, count1, offset2, count2, depth1, index1, depth2, index2)) {
|
|
16561
|
-
return iterateOverDoubleTriangles(offset1, count1, offset2, count2, depth1, index1, depth2, index2);
|
|
16562
|
-
}
|
|
16563
|
-
return true;
|
|
16564
|
-
};
|
|
16565
|
-
} else {
|
|
16566
|
-
intersectsRanges = iterateOverDoubleTriangles;
|
|
16567
|
-
}
|
|
16568
|
-
}
|
|
16569
|
-
return bvhcast(this, otherBvh, matrixToLocal, intersectsRanges);
|
|
16570
|
-
}
|
|
16571
|
-
/* Derived Cast Functions */
|
|
16572
|
-
intersectsBox(box2, boxToMesh) {
|
|
16573
|
-
obb.set(box2.min, box2.max, boxToMesh);
|
|
16574
|
-
obb.needsUpdate = true;
|
|
16575
|
-
return this.shapecast(
|
|
16576
|
-
{
|
|
16577
|
-
intersectsBounds: (box3) => obb.intersectsBox(box3),
|
|
16578
|
-
intersectsTriangle: (tri) => obb.intersectsTriangle(tri)
|
|
16579
|
-
}
|
|
16580
|
-
);
|
|
16581
|
-
}
|
|
16582
|
-
intersectsSphere(sphere) {
|
|
16583
|
-
return this.shapecast(
|
|
16584
|
-
{
|
|
16585
|
-
intersectsBounds: (box2) => sphere.intersectsBox(box2),
|
|
16586
|
-
intersectsTriangle: (tri) => tri.intersectsSphere(sphere)
|
|
16587
|
-
}
|
|
16588
|
-
);
|
|
16589
|
-
}
|
|
16590
|
-
closestPointToGeometry(otherGeometry, geometryToBvh, target1 = {}, target2 = {}, minThreshold = 0, maxThreshold = Infinity) {
|
|
16591
|
-
const closestPointToGeometryFunc = this.indirect ? closestPointToGeometry_indirect : closestPointToGeometry;
|
|
16592
|
-
return closestPointToGeometryFunc(
|
|
16593
|
-
this,
|
|
16594
|
-
otherGeometry,
|
|
16595
|
-
geometryToBvh,
|
|
16596
|
-
target1,
|
|
16597
|
-
target2,
|
|
16598
|
-
minThreshold,
|
|
16599
|
-
maxThreshold
|
|
16600
|
-
);
|
|
16601
|
-
}
|
|
16602
|
-
closestPointToPoint(point, target = {}, minThreshold = 0, maxThreshold = Infinity) {
|
|
16603
|
-
return closestPointToPoint(
|
|
16604
|
-
this,
|
|
16605
|
-
point,
|
|
16606
|
-
target,
|
|
16607
|
-
minThreshold,
|
|
16608
|
-
maxThreshold
|
|
16609
|
-
);
|
|
16610
|
-
}
|
|
16611
|
-
getBoundingBox(target) {
|
|
16612
|
-
target.makeEmpty();
|
|
16613
|
-
const roots = this._roots;
|
|
16614
|
-
roots.forEach((buffer) => {
|
|
16615
|
-
arrayToBox(0, new Float32Array(buffer), tempBox);
|
|
16616
|
-
target.union(tempBox);
|
|
16617
|
-
});
|
|
16618
|
-
return target;
|
|
16619
|
-
}
|
|
16620
|
-
}
|
|
16621
|
-
function convertRaycastIntersect(hit, object, raycaster) {
|
|
16622
|
-
if (hit === null) {
|
|
16623
|
-
return null;
|
|
16624
|
-
}
|
|
16625
|
-
hit.point.applyMatrix4(object.matrixWorld);
|
|
16626
|
-
hit.distance = hit.point.distanceTo(raycaster.ray.origin);
|
|
16627
|
-
hit.object = object;
|
|
16628
|
-
return hit;
|
|
16629
|
-
}
|
|
16630
|
-
const ray = /* @__PURE__ */ new Ray();
|
|
16631
|
-
const direction = /* @__PURE__ */ new Vector3();
|
|
16632
|
-
const tmpInverseMatrix = /* @__PURE__ */ new Matrix4();
|
|
16633
|
-
const origMeshRaycastFunc = Mesh.prototype.raycast;
|
|
16634
|
-
const origBatchedRaycastFunc = BatchedMesh.prototype.raycast;
|
|
16635
|
-
const _worldScale = /* @__PURE__ */ new Vector3();
|
|
16636
|
-
const _mesh = /* @__PURE__ */ new Mesh();
|
|
16637
|
-
const _batchIntersects = [];
|
|
16638
|
-
function acceleratedRaycast(raycaster, intersects) {
|
|
16639
|
-
if (this.isBatchedMesh) {
|
|
16640
|
-
acceleratedBatchedMeshRaycast.call(this, raycaster, intersects);
|
|
16641
|
-
} else {
|
|
16642
|
-
acceleratedMeshRaycast.call(this, raycaster, intersects);
|
|
16643
|
-
}
|
|
16644
|
-
}
|
|
16645
|
-
function acceleratedBatchedMeshRaycast(raycaster, intersects) {
|
|
16646
|
-
if (this.boundsTrees) {
|
|
16647
|
-
const boundsTrees = this.boundsTrees;
|
|
16648
|
-
const drawInfo = this._drawInfo || this._instanceInfo;
|
|
16649
|
-
const drawRanges = this._drawRanges || this._geometryInfo;
|
|
16650
|
-
const matrixWorld = this.matrixWorld;
|
|
16651
|
-
_mesh.material = this.material;
|
|
16652
|
-
_mesh.geometry = this.geometry;
|
|
16653
|
-
const oldBoundsTree = _mesh.geometry.boundsTree;
|
|
16654
|
-
const oldDrawRange = _mesh.geometry.drawRange;
|
|
16655
|
-
if (_mesh.geometry.boundingSphere === null) {
|
|
16656
|
-
_mesh.geometry.boundingSphere = new Sphere();
|
|
16657
|
-
}
|
|
16658
|
-
for (let i = 0, l2 = drawInfo.length; i < l2; i++) {
|
|
16659
|
-
if (!this.getVisibleAt(i)) {
|
|
16660
|
-
continue;
|
|
16661
|
-
}
|
|
16662
|
-
const geometryId = drawInfo[i].geometryIndex;
|
|
16663
|
-
_mesh.geometry.boundsTree = boundsTrees[geometryId];
|
|
16664
|
-
this.getMatrixAt(i, _mesh.matrixWorld).premultiply(matrixWorld);
|
|
16665
|
-
if (!_mesh.geometry.boundsTree) {
|
|
16666
|
-
this.getBoundingBoxAt(geometryId, _mesh.geometry.boundingBox);
|
|
16667
|
-
this.getBoundingSphereAt(geometryId, _mesh.geometry.boundingSphere);
|
|
16668
|
-
const drawRange = drawRanges[geometryId];
|
|
16669
|
-
_mesh.geometry.setDrawRange(drawRange.start, drawRange.count);
|
|
16670
|
-
}
|
|
16671
|
-
_mesh.raycast(raycaster, _batchIntersects);
|
|
16672
|
-
for (let j2 = 0, l3 = _batchIntersects.length; j2 < l3; j2++) {
|
|
16673
|
-
const intersect = _batchIntersects[j2];
|
|
16674
|
-
intersect.object = this;
|
|
16675
|
-
intersect.batchId = i;
|
|
16676
|
-
intersects.push(intersect);
|
|
16677
|
-
}
|
|
16678
|
-
_batchIntersects.length = 0;
|
|
16679
|
-
}
|
|
16680
|
-
_mesh.geometry.boundsTree = oldBoundsTree;
|
|
16681
|
-
_mesh.geometry.drawRange = oldDrawRange;
|
|
16682
|
-
_mesh.material = null;
|
|
16683
|
-
_mesh.geometry = null;
|
|
16684
|
-
} else {
|
|
16685
|
-
origBatchedRaycastFunc.call(this, raycaster, intersects);
|
|
16686
|
-
}
|
|
16687
|
-
}
|
|
16688
|
-
function acceleratedMeshRaycast(raycaster, intersects) {
|
|
16689
|
-
if (this.geometry.boundsTree) {
|
|
16690
|
-
if (this.material === void 0) return;
|
|
16691
|
-
tmpInverseMatrix.copy(this.matrixWorld).invert();
|
|
16692
|
-
ray.copy(raycaster.ray).applyMatrix4(tmpInverseMatrix);
|
|
16693
|
-
_worldScale.setFromMatrixScale(this.matrixWorld);
|
|
16694
|
-
direction.copy(ray.direction).multiply(_worldScale);
|
|
16695
|
-
const scaleFactor = direction.length();
|
|
16696
|
-
const near = raycaster.near / scaleFactor;
|
|
16697
|
-
const far = raycaster.far / scaleFactor;
|
|
16698
|
-
const bvh = this.geometry.boundsTree;
|
|
16699
|
-
if (raycaster.firstHitOnly === true) {
|
|
16700
|
-
const hit = convertRaycastIntersect(bvh.raycastFirst(ray, this.material, near, far), this, raycaster);
|
|
16701
|
-
if (hit) {
|
|
16702
|
-
intersects.push(hit);
|
|
16703
|
-
}
|
|
16704
|
-
} else {
|
|
16705
|
-
const hits = bvh.raycast(ray, this.material, near, far);
|
|
16706
|
-
for (let i = 0, l2 = hits.length; i < l2; i++) {
|
|
16707
|
-
const hit = convertRaycastIntersect(hits[i], this, raycaster);
|
|
16708
|
-
if (hit) {
|
|
16709
|
-
intersects.push(hit);
|
|
16710
|
-
}
|
|
16711
|
-
}
|
|
16712
|
-
}
|
|
16713
|
-
} else {
|
|
16714
|
-
origMeshRaycastFunc.call(this, raycaster, intersects);
|
|
16715
|
-
}
|
|
16716
|
-
}
|
|
16717
13394
|
const getBufferForType = (type, width, height) => {
|
|
16718
13395
|
let out;
|
|
16719
13396
|
switch (type) {
|
|
@@ -19042,7 +15719,7 @@ const movePath = (value, from, to) => {
|
|
|
19042
15719
|
if (value.startsWith(`${from}/`)) return `${to}${value.slice(from.length)}`;
|
|
19043
15720
|
return value;
|
|
19044
15721
|
};
|
|
19045
|
-
const FORGE_IMPORT_RE = /\b(?:importMesh|importStep|importSvgSketch|Import\.mesh|Import\.step|Import\.svgSketch|Import\.dxfSketch|compareWith)\s*\(\s*(?:"([^"]+)"|'([^']+)')/g;
|
|
15722
|
+
const FORGE_IMPORT_RE = /\b(?:importMesh|importStep|importSvgSketch|Import\.mesh|Import\.step|Import\.image|Import\.svgSketch|Import\.dxfSketch|compareWith)\s*\(\s*(?:"([^"]+)"|'([^']+)')/g;
|
|
19046
15723
|
const REQUIRE_RE = /\brequire\s*\(\s*(?:"([^"]+)"|'([^']+)')/g;
|
|
19047
15724
|
const ES_IMPORT_RE = /\bfrom\s+(?:"([^"]+)"|'([^']+)')/g;
|
|
19048
15725
|
const VIRTUAL_MODULES = /* @__PURE__ */ new Set(["forgecad", "@forge/runtime", "@forgecad/runtime"]);
|
|
@@ -19062,6 +15739,7 @@ function extractImports(code) {
|
|
|
19062
15739
|
importSvgSketch: "forgeSvg",
|
|
19063
15740
|
"Import.mesh": "forgeMesh",
|
|
19064
15741
|
"Import.step": "forgeMesh",
|
|
15742
|
+
"Import.image": "forgeMesh",
|
|
19065
15743
|
"Import.svgSketch": "forgeSvg",
|
|
19066
15744
|
"Import.dxfSketch": "forgeDxf",
|
|
19067
15745
|
compareWith: "compareWith"
|
|
@@ -19071,7 +15749,7 @@ function extractImports(code) {
|
|
|
19071
15749
|
while ((m2 = forgeRe.exec(code)) !== null) {
|
|
19072
15750
|
const path = m2[1] ?? m2[2];
|
|
19073
15751
|
const fn = (_a3 = m2[0].match(
|
|
19074
|
-
/\b(importMesh|importStep|importSvgSketch|Import\.mesh|Import\.step|Import\.svgSketch|Import\.dxfSketch|compareWith)/
|
|
15752
|
+
/\b(importMesh|importStep|importSvgSketch|Import\.mesh|Import\.step|Import\.image|Import\.svgSketch|Import\.dxfSketch|compareWith)/
|
|
19075
15753
|
)) == null ? void 0 : _a3[1];
|
|
19076
15754
|
add(path, kindMap[fn] ?? "forgeMesh");
|
|
19077
15755
|
}
|
|
@@ -19298,7 +15976,7 @@ const CRASH_COOLDOWN_MS = 2e3;
|
|
|
19298
15976
|
class EvalWorkerClient {
|
|
19299
15977
|
constructor(workerFactory = () => new Worker(new URL(
|
|
19300
15978
|
/* @vite-ignore */
|
|
19301
|
-
"/assets/evalWorker-
|
|
15979
|
+
"/assets/evalWorker-BssDYW9u.js",
|
|
19302
15980
|
import.meta.url
|
|
19303
15981
|
), { type: "module" })) {
|
|
19304
15982
|
__publicField(this, "worker", null);
|
|
@@ -20769,133 +17447,37 @@ function buildRunState(previewFile, runResult, state2) {
|
|
|
20769
17447
|
nextObjectSettingsByFile
|
|
20770
17448
|
};
|
|
20771
17449
|
}
|
|
20772
|
-
|
|
20773
|
-
|
|
17450
|
+
const KERNELS = [
|
|
17451
|
+
{ id: "manifold", name: "manifold", location: "local", label: "Manifold" },
|
|
17452
|
+
{ id: "occt", name: "occt", location: "local", label: "OCCT" },
|
|
17453
|
+
{ id: "truck", name: "truck", location: "local", label: "Truck" },
|
|
17454
|
+
{ id: "sdf", name: "sdf", location: "local", label: "SDF" },
|
|
17455
|
+
{ id: "server-occt", name: "occt", location: "server", label: "Server OCCT" }
|
|
17456
|
+
];
|
|
17457
|
+
function availableKernels(canUseServer) {
|
|
17458
|
+
return KERNELS.filter((kernel) => kernel.location === "local" || canUseServer);
|
|
17459
|
+
}
|
|
17460
|
+
function kernelId(kernel) {
|
|
17461
|
+
return kernel.location === "server" ? "server-occt" : kernel.name;
|
|
20774
17462
|
}
|
|
20775
|
-
function
|
|
20776
|
-
|
|
17463
|
+
function kernelFromId(id) {
|
|
17464
|
+
const kernel = KERNELS.find((entry) => entry.id === id);
|
|
17465
|
+
if (!kernel) throw new Error(`Unknown kernel: ${id}`);
|
|
17466
|
+
return kernel;
|
|
17467
|
+
}
|
|
17468
|
+
function resolveAvailableKernel(preferred, kernels) {
|
|
17469
|
+
if (kernels.length === 0) throw new Error("No kernels are available");
|
|
17470
|
+
const exact = kernels.find((kernel) => kernel.name === preferred.name && kernel.location === preferred.location);
|
|
17471
|
+
if (exact) return exact;
|
|
17472
|
+
return kernels.find((kernel) => kernel.name === "manifold" && kernel.location === "local") ?? kernels[0];
|
|
17473
|
+
}
|
|
17474
|
+
function computeBackendFromParts(activeBackend, computeTarget) {
|
|
17475
|
+
return kernelId({ name: activeBackend, location: computeTarget });
|
|
20777
17476
|
}
|
|
20778
17477
|
function formatComputeBackendLabel(backend) {
|
|
20779
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
20782
|
-
case "occt":
|
|
20783
|
-
return "Local OCCT";
|
|
20784
|
-
case "truck":
|
|
20785
|
-
return "Local Truck";
|
|
20786
|
-
case "sdf":
|
|
20787
|
-
return "Local SDF";
|
|
20788
|
-
case "server-occt":
|
|
20789
|
-
return "Server OCCT";
|
|
20790
|
-
}
|
|
20791
|
-
}
|
|
20792
|
-
const VIEW_PREFERENCES_KEY = "fc-view-preferences-v1";
|
|
20793
|
-
const INSPECT_POINT_SAMPLE_COUNT_MIN = 100;
|
|
20794
|
-
const INSPECT_POINT_SAMPLE_COUNT_MAX = 2e4;
|
|
20795
|
-
const DEFAULT_INSPECT_POINT_SAMPLE_COUNT = 15e3;
|
|
20796
|
-
const DEFAULT_COMPARISON_INSPECT_MODE = "difference-only";
|
|
20797
|
-
const DEFAULT_COMPARISON_CANDIDATE_OPACITY = 0.42;
|
|
20798
|
-
const DEFAULT_COMPARISON_REFERENCE_OPACITY = 0.2;
|
|
20799
|
-
const THICKNESS_COLOR_RANGE_MIN = 0;
|
|
20800
|
-
const THICKNESS_COLOR_RANGE_MAX = 1e3;
|
|
20801
|
-
const THICKNESS_COLOR_RANGE_MIN_SPAN = 1e-3;
|
|
20802
|
-
const DEFAULT_THICKNESS_COLOR_RANGE = {
|
|
20803
|
-
min: 0,
|
|
20804
|
-
max: 6
|
|
20805
|
-
};
|
|
20806
|
-
const DEFAULT_INSPECT_ISOLINES_ENABLED = false;
|
|
20807
|
-
const DEFAULT_INSPECT_ISOLINE_SPACING = 1;
|
|
20808
|
-
const DEFAULT_INSPECT_CRITICAL_LINE_ENABLED = true;
|
|
20809
|
-
const DEFAULT_MANUAL_SCENE_SETTINGS = {
|
|
20810
|
-
enabled: false,
|
|
20811
|
-
backgroundColor: "#f6f7f8",
|
|
20812
|
-
groundVisible: true,
|
|
20813
|
-
groundColor: "#eef0f2",
|
|
20814
|
-
ambientIntensity: 0.3,
|
|
20815
|
-
keyIntensity: 1.45,
|
|
20816
|
-
fillIntensity: 0.55,
|
|
20817
|
-
rimIntensity: 0.2,
|
|
20818
|
-
environmentIntensity: 0.9
|
|
20819
|
-
};
|
|
20820
|
-
const resolveInspectPointSampleCount = (value) => {
|
|
20821
|
-
const numeric = typeof value === "number" ? value : Number(value);
|
|
20822
|
-
if (!Number.isFinite(numeric)) return DEFAULT_INSPECT_POINT_SAMPLE_COUNT;
|
|
20823
|
-
return Math.max(INSPECT_POINT_SAMPLE_COUNT_MIN, Math.min(INSPECT_POINT_SAMPLE_COUNT_MAX, Math.round(numeric)));
|
|
20824
|
-
};
|
|
20825
|
-
const resolveComparisonInspectMode = (value) => value === "difference-only" ? value : DEFAULT_COMPARISON_INSPECT_MODE;
|
|
20826
|
-
const resolveCameraControlMode = (value) => value === "fly" ? value : "orbit";
|
|
20827
|
-
const HEX_COLOR_RE = /^#[0-9a-f]{6}$/i;
|
|
20828
|
-
const resolveHexColor = (value, fallback) => {
|
|
20829
|
-
return typeof value === "string" && HEX_COLOR_RE.test(value) ? value : fallback;
|
|
20830
|
-
};
|
|
20831
|
-
const resolveClampedNumber = (value, fallback, min, max2) => {
|
|
20832
|
-
const numeric = typeof value === "number" ? value : Number(value);
|
|
20833
|
-
if (!Number.isFinite(numeric)) return fallback;
|
|
20834
|
-
return Math.max(min, Math.min(max2, numeric));
|
|
20835
|
-
};
|
|
20836
|
-
const resolveComparisonOpacity = (value, fallback) => resolveClampedNumber(value, fallback, 0, 1);
|
|
20837
|
-
const resolveThicknessColorRange = (value) => {
|
|
20838
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
20839
|
-
return DEFAULT_THICKNESS_COLOR_RANGE;
|
|
20840
|
-
}
|
|
20841
|
-
const raw = value;
|
|
20842
|
-
const min = resolveClampedNumber(raw.min, DEFAULT_THICKNESS_COLOR_RANGE.min, THICKNESS_COLOR_RANGE_MIN, THICKNESS_COLOR_RANGE_MAX);
|
|
20843
|
-
const max2 = resolveClampedNumber(raw.max, DEFAULT_THICKNESS_COLOR_RANGE.max, THICKNESS_COLOR_RANGE_MIN, THICKNESS_COLOR_RANGE_MAX);
|
|
20844
|
-
if (max2 - min >= THICKNESS_COLOR_RANGE_MIN_SPAN) return { min, max: max2 };
|
|
20845
|
-
const defaultSpan = DEFAULT_THICKNESS_COLOR_RANGE.max - DEFAULT_THICKNESS_COLOR_RANGE.min;
|
|
20846
|
-
const expandedMax = Math.min(THICKNESS_COLOR_RANGE_MAX, min + defaultSpan);
|
|
20847
|
-
if (expandedMax - min >= THICKNESS_COLOR_RANGE_MIN_SPAN) return { min, max: expandedMax };
|
|
20848
|
-
const expandedMin = Math.max(THICKNESS_COLOR_RANGE_MIN, max2 - defaultSpan);
|
|
20849
|
-
if (max2 - expandedMin >= THICKNESS_COLOR_RANGE_MIN_SPAN) return { min: expandedMin, max: max2 };
|
|
20850
|
-
return DEFAULT_THICKNESS_COLOR_RANGE;
|
|
20851
|
-
};
|
|
20852
|
-
const resolveInspectColormap = (value) => resolveColormapName(value);
|
|
20853
|
-
const resolveBooleanPref = (value, fallback) => typeof value === "boolean" ? value : fallback;
|
|
20854
|
-
const resolveInspectIsolineSpacing = (value) => {
|
|
20855
|
-
const numeric = typeof value === "number" ? value : Number(value);
|
|
20856
|
-
if (!Number.isFinite(numeric) || numeric <= 0) return DEFAULT_INSPECT_ISOLINE_SPACING;
|
|
20857
|
-
return numeric;
|
|
20858
|
-
};
|
|
20859
|
-
const resolveManualSceneSettings = (value) => {
|
|
20860
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
20861
|
-
return DEFAULT_MANUAL_SCENE_SETTINGS;
|
|
20862
|
-
}
|
|
20863
|
-
const raw = value;
|
|
20864
|
-
return {
|
|
20865
|
-
enabled: typeof raw.enabled === "boolean" ? raw.enabled : DEFAULT_MANUAL_SCENE_SETTINGS.enabled,
|
|
20866
|
-
backgroundColor: resolveHexColor(raw.backgroundColor, DEFAULT_MANUAL_SCENE_SETTINGS.backgroundColor),
|
|
20867
|
-
groundVisible: typeof raw.groundVisible === "boolean" ? raw.groundVisible : DEFAULT_MANUAL_SCENE_SETTINGS.groundVisible,
|
|
20868
|
-
groundColor: resolveHexColor(raw.groundColor, DEFAULT_MANUAL_SCENE_SETTINGS.groundColor),
|
|
20869
|
-
ambientIntensity: resolveClampedNumber(raw.ambientIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.ambientIntensity, 0, 3),
|
|
20870
|
-
keyIntensity: resolveClampedNumber(raw.keyIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.keyIntensity, 0, 5),
|
|
20871
|
-
fillIntensity: resolveClampedNumber(raw.fillIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.fillIntensity, 0, 3),
|
|
20872
|
-
rimIntensity: resolveClampedNumber(raw.rimIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.rimIntensity, 0, 3),
|
|
20873
|
-
environmentIntensity: resolveClampedNumber(raw.environmentIntensity, DEFAULT_MANUAL_SCENE_SETTINGS.environmentIntensity, 0, 3)
|
|
20874
|
-
};
|
|
20875
|
-
};
|
|
20876
|
-
const readViewPreferences = () => {
|
|
20877
|
-
if (typeof window === "undefined") return {};
|
|
20878
|
-
try {
|
|
20879
|
-
const raw = localStorage.getItem(VIEW_PREFERENCES_KEY);
|
|
20880
|
-
if (!raw) return {};
|
|
20881
|
-
const parsed = JSON.parse(raw);
|
|
20882
|
-
if (!parsed || typeof parsed !== "object") return {};
|
|
20883
|
-
return parsed;
|
|
20884
|
-
} catch {
|
|
20885
|
-
return {};
|
|
20886
|
-
}
|
|
20887
|
-
};
|
|
20888
|
-
const writeViewPreferences = (patch) => {
|
|
20889
|
-
if (typeof window === "undefined") return;
|
|
20890
|
-
try {
|
|
20891
|
-
const next = { ...readViewPreferences(), ...patch };
|
|
20892
|
-
if ("objectSettingsByFile" in patch) {
|
|
20893
|
-
delete next.objectSettings;
|
|
20894
|
-
}
|
|
20895
|
-
localStorage.setItem(VIEW_PREFERENCES_KEY, JSON.stringify(next));
|
|
20896
|
-
} catch {
|
|
20897
|
-
}
|
|
20898
|
-
};
|
|
17478
|
+
const kernel = kernelFromId(backend);
|
|
17479
|
+
return kernel.location === "server" ? kernel.label : `Local ${kernel.label}`;
|
|
17480
|
+
}
|
|
20899
17481
|
function computeServerSnapshot(state2, serverFiles, serverFolders, sharedModel2, sharedBundle2, initialFile) {
|
|
20900
17482
|
const nextState = computeServerSnapshot$1(state2, serverFiles, serverFolders, sharedModel2, sharedBundle2, STARTUP_HASH_FILE, initialFile);
|
|
20901
17483
|
writeViewPreferences({ objectSettingsByFile: nextState.objectSettingsByFile });
|
|
@@ -21095,6 +17677,14 @@ function recordViewCommandDebug(command) {
|
|
|
21095
17677
|
console.debug("[forgecad view-command]", entry);
|
|
21096
17678
|
}
|
|
21097
17679
|
const initialViewPreferences = readViewPreferences();
|
|
17680
|
+
function resolveInitialKernel() {
|
|
17681
|
+
const savedLocation = initialViewPreferences.computeTarget === "server" ? "server" : "local";
|
|
17682
|
+
return resolveAvailableKernel(
|
|
17683
|
+
{ name: initialViewPreferences.activeBackend, location: savedLocation },
|
|
17684
|
+
availableKernels(canUseServerCompute())
|
|
17685
|
+
);
|
|
17686
|
+
}
|
|
17687
|
+
const initialKernel = resolveInitialKernel();
|
|
21098
17688
|
const initialInspectChannel = resolveInitialViewInspectChannel(initialViewPreferences.inspectChannel);
|
|
21099
17689
|
const initialInspectDisplayMode = resolveInspectDisplayMode(initialViewPreferences.inspectDisplayMode);
|
|
21100
17690
|
const initialStoredRenderStyle = resolveForgeRenderStyle(initialViewPreferences.renderStyle);
|
|
@@ -21623,7 +18213,7 @@ const useForgeStore = create((set, get) => ({
|
|
|
21623
18213
|
set({ meshPreviewFile: meshPath });
|
|
21624
18214
|
if (meshPath) get().execute();
|
|
21625
18215
|
},
|
|
21626
|
-
activeBackend:
|
|
18216
|
+
activeBackend: initialKernel.name,
|
|
21627
18217
|
setActiveBackend: (backend) => {
|
|
21628
18218
|
writeViewPreferences({ activeBackend: backend, computeTarget: "local" });
|
|
21629
18219
|
clearRunResultCache();
|
|
@@ -21631,23 +18221,26 @@ const useForgeStore = create((set, get) => ({
|
|
|
21631
18221
|
get().execute();
|
|
21632
18222
|
},
|
|
21633
18223
|
setComputeBackend: (backend) => {
|
|
21634
|
-
const
|
|
21635
|
-
|
|
18224
|
+
const kernel = kernelFromId(backend);
|
|
18225
|
+
if (!availableKernels(canUseServerCompute()).some((available) => available.id === kernel.id)) return;
|
|
18226
|
+
writeViewPreferences({ activeBackend: kernel.name, computeTarget: kernel.location });
|
|
21636
18227
|
clearRunResultCache();
|
|
21637
|
-
set({ activeBackend:
|
|
21638
|
-
if (
|
|
18228
|
+
set({ activeBackend: kernel.name, computeTarget: kernel.location });
|
|
18229
|
+
if (kernel.location === "server") {
|
|
21639
18230
|
startServerPolling();
|
|
21640
18231
|
}
|
|
21641
18232
|
get().execute();
|
|
21642
18233
|
},
|
|
21643
|
-
computeTarget:
|
|
18234
|
+
computeTarget: initialKernel.location,
|
|
21644
18235
|
setComputeTarget: (target) => {
|
|
21645
|
-
const
|
|
21646
|
-
|
|
21647
|
-
|
|
18236
|
+
const kernel = resolveAvailableKernel(
|
|
18237
|
+
{ name: target === "server" ? "occt" : get().activeBackend, location: target },
|
|
18238
|
+
availableKernels(canUseServerCompute())
|
|
18239
|
+
);
|
|
18240
|
+
writeViewPreferences({ activeBackend: kernel.name, computeTarget: kernel.location });
|
|
21648
18241
|
clearRunResultCache();
|
|
21649
|
-
set({ activeBackend:
|
|
21650
|
-
if (
|
|
18242
|
+
set({ activeBackend: kernel.name, computeTarget: kernel.location });
|
|
18243
|
+
if (kernel.location === "server") {
|
|
21651
18244
|
startServerPolling();
|
|
21652
18245
|
}
|
|
21653
18246
|
get().execute();
|
|
@@ -22191,10 +18784,13 @@ const useForgeStore = create((set, get) => ({
|
|
|
22191
18784
|
writeViewPreferences({ inspectIsolineSpacing: next });
|
|
22192
18785
|
set({ inspectIsolineSpacing: next });
|
|
22193
18786
|
},
|
|
22194
|
-
|
|
22195
|
-
|
|
22196
|
-
|
|
22197
|
-
|
|
18787
|
+
inspectQuantizeBands: resolveInspectQuantizeBands(initialViewPreferences.inspectQuantizeBands),
|
|
18788
|
+
setInspectQuantizeBands: (bands) => {
|
|
18789
|
+
const next = resolveInspectQuantizeBands(bands);
|
|
18790
|
+
writeViewPreferences({ inspectQuantizeBands: next });
|
|
18791
|
+
set({ inspectQuantizeBands: next });
|
|
18792
|
+
},
|
|
18793
|
+
inspectCriticalLineEnabled: resolveBooleanPref(initialViewPreferences.inspectCriticalLineEnabled, DEFAULT_INSPECT_CRITICAL_LINE_ENABLED),
|
|
22198
18794
|
setInspectCriticalLineEnabled: (enabled) => {
|
|
22199
18795
|
const next = resolveBooleanPref(enabled, DEFAULT_INSPECT_CRITICAL_LINE_ENABLED);
|
|
22200
18796
|
writeViewPreferences({ inspectCriticalLineEnabled: next });
|
|
@@ -27104,7 +23700,7 @@ function OrbitTargetPulseLayer() {
|
|
|
27104
23700
|
class ConstructionHistoryWorkerClient {
|
|
27105
23701
|
constructor(workerFactory = () => new Worker(new URL(
|
|
27106
23702
|
/* @vite-ignore */
|
|
27107
|
-
"/assets/constructionHistoryWorker-
|
|
23703
|
+
"/assets/constructionHistoryWorker-cTHWRJEi.js",
|
|
27108
23704
|
import.meta.url
|
|
27109
23705
|
), { type: "module" })) {
|
|
27110
23706
|
__publicField(this, "worker", null);
|
|
@@ -29616,7 +26212,7 @@ function generateReportInWorker(options) {
|
|
|
29616
26212
|
return new Promise((resolve2, reject) => {
|
|
29617
26213
|
const worker = new Worker(new URL(
|
|
29618
26214
|
/* @vite-ignore */
|
|
29619
|
-
"/assets/reportWorker-
|
|
26215
|
+
"/assets/reportWorker-Cb5eyM7D.js",
|
|
29620
26216
|
import.meta.url
|
|
29621
26217
|
), { type: "module" });
|
|
29622
26218
|
const cleanup = () => {
|
|
@@ -29776,7 +26372,7 @@ function tessellateArc(center, start, end, radius, clockwise, segments) {
|
|
|
29776
26372
|
const startAngle = Math.atan2(start[1] - center[1], start[0] - center[0]);
|
|
29777
26373
|
const endAngle = Math.atan2(end[1] - center[1], end[0] - center[0]);
|
|
29778
26374
|
let sweep = endAngle - startAngle;
|
|
29779
|
-
const
|
|
26375
|
+
const direction = clockwise ? -1 : 1;
|
|
29780
26376
|
if (clockwise) {
|
|
29781
26377
|
if (sweep > 0) sweep -= 2 * Math.PI;
|
|
29782
26378
|
sweep = -sweep;
|
|
@@ -29786,7 +26382,7 @@ function tessellateArc(center, start, end, radius, clockwise, segments) {
|
|
|
29786
26382
|
const points = [start];
|
|
29787
26383
|
for (let k2 = 1; k2 <= segments; k2++) {
|
|
29788
26384
|
const t2 = k2 / segments * sweep;
|
|
29789
|
-
const angle = startAngle +
|
|
26385
|
+
const angle = startAngle + direction * t2;
|
|
29790
26386
|
points.push([center[0] + radius * Math.cos(angle), center[1] + radius * Math.sin(angle)]);
|
|
29791
26387
|
}
|
|
29792
26388
|
return points;
|
|
@@ -30471,8 +27067,8 @@ const applyOrbitPose = (camera, target, radius, turn, pitchDeg) => {
|
|
|
30471
27067
|
const yaw = normalizedTurn * Math.PI * 2;
|
|
30472
27068
|
const pitch = MathUtils.degToRad(clampedPitch);
|
|
30473
27069
|
const cosPitch = Math.cos(pitch);
|
|
30474
|
-
const
|
|
30475
|
-
camera.position.copy(target).addScaledVector(
|
|
27070
|
+
const direction = new Vector3(Math.sin(yaw) * cosPitch, -Math.cos(yaw) * cosPitch, Math.sin(pitch)).normalize();
|
|
27071
|
+
camera.position.copy(target).addScaledVector(direction, radius);
|
|
30476
27072
|
camera.up.set(0, 0, 1);
|
|
30477
27073
|
camera.lookAt(target);
|
|
30478
27074
|
if ("updateProjectionMatrix" in camera && typeof camera.updateProjectionMatrix === "function") {
|
|
@@ -30512,8 +27108,8 @@ function setOverrideOrbitCamera(session, turn, pitchDeg) {
|
|
|
30512
27108
|
const yaw = normalizedTurn * Math.PI * 2;
|
|
30513
27109
|
const pitch = MathUtils.degToRad(clampedPitch);
|
|
30514
27110
|
const cosPitch = Math.cos(pitch);
|
|
30515
|
-
const
|
|
30516
|
-
session.camera.position.copy(session.center).addScaledVector(
|
|
27111
|
+
const direction = new Vector3(Math.sin(yaw) * cosPitch, -Math.cos(yaw) * cosPitch, Math.sin(pitch)).normalize();
|
|
27112
|
+
session.camera.position.copy(session.center).addScaledVector(direction, session.distance);
|
|
30517
27113
|
session.camera.lookAt(session.center);
|
|
30518
27114
|
session.camera.updateProjectionMatrix();
|
|
30519
27115
|
}
|
|
@@ -33384,144 +29980,6 @@ function LedgerMetric({ label, value }) {
|
|
|
33384
29980
|
}
|
|
33385
29981
|
);
|
|
33386
29982
|
}
|
|
33387
|
-
const INSPECT_SCALAR_VERTEX_SHADER = `
|
|
33388
|
-
attribute float aValue;
|
|
33389
|
-
varying float vValue;
|
|
33390
|
-
varying vec3 vViewNormal;
|
|
33391
|
-
varying vec3 vViewDirection;
|
|
33392
|
-
#include <clipping_planes_pars_vertex>
|
|
33393
|
-
|
|
33394
|
-
void main() {
|
|
33395
|
-
vValue = aValue;
|
|
33396
|
-
vViewNormal = normalize(normalMatrix * normal);
|
|
33397
|
-
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
|
|
33398
|
-
vViewDirection = normalize(-mvPosition.xyz);
|
|
33399
|
-
gl_Position = projectionMatrix * mvPosition;
|
|
33400
|
-
#include <clipping_planes_vertex>
|
|
33401
|
-
}
|
|
33402
|
-
`;
|
|
33403
|
-
const INSPECT_SCALAR_FRAGMENT_SHADER = `
|
|
33404
|
-
uniform sampler2D uColorScale;
|
|
33405
|
-
uniform float uDomainMin;
|
|
33406
|
-
uniform float uDomainMax;
|
|
33407
|
-
uniform bool uIsoEnabled;
|
|
33408
|
-
uniform float uIsoSpacing;
|
|
33409
|
-
uniform bool uCriticalEnabled;
|
|
33410
|
-
uniform float uCriticalThreshold;
|
|
33411
|
-
uniform bool uShadingEnabled;
|
|
33412
|
-
uniform vec3 uLightDirection;
|
|
33413
|
-
uniform float uAmbient;
|
|
33414
|
-
varying float vValue;
|
|
33415
|
-
varying vec3 vViewNormal;
|
|
33416
|
-
varying vec3 vViewDirection;
|
|
33417
|
-
#include <clipping_planes_pars_fragment>
|
|
33418
|
-
|
|
33419
|
-
void main() {
|
|
33420
|
-
#include <clipping_planes_fragment>
|
|
33421
|
-
|
|
33422
|
-
float span = max(uDomainMax - uDomainMin, 1e-6);
|
|
33423
|
-
float t = clamp((vValue - uDomainMin) / span, 0.0, 1.0);
|
|
33424
|
-
// LUT is pre-baked perceptual sRGB; the texture is NoColorSpace so this fetch
|
|
33425
|
-
// is NOT decoded. Do not apply any further linearization here (critique M1).
|
|
33426
|
-
vec3 color = texture2D(uColorScale, vec2(t, 0.5)).rgb;
|
|
33427
|
-
|
|
33428
|
-
// Anti-aliased isolines / critical line via the fwidth contour trick.
|
|
33429
|
-
if (uIsoEnabled || uCriticalEnabled) {
|
|
33430
|
-
if (uIsoEnabled && uIsoSpacing > 1e-6) {
|
|
33431
|
-
float f = vValue / uIsoSpacing;
|
|
33432
|
-
float grad = fwidth(f);
|
|
33433
|
-
// Distance (in cycles) to the nearest integer contour, anti-aliased by grad.
|
|
33434
|
-
// grad * 1.3 matches the exact contour width of the validated lab preview
|
|
33435
|
-
// (render.mjs) that the user signed off on.
|
|
33436
|
-
float line = abs(fract(f - 0.5) - 0.5) / max(grad * 1.3, 1e-6);
|
|
33437
|
-
float a = 1.0 - clamp(line, 0.0, 1.0);
|
|
33438
|
-
color = mix(color, vec3(0.08, 0.094, 0.118), 0.85 * a);
|
|
33439
|
-
}
|
|
33440
|
-
if (uCriticalEnabled) {
|
|
33441
|
-
float gradV = fwidth(vValue);
|
|
33442
|
-
float dist = abs(vValue - uCriticalThreshold) / max(gradV * 1.6, 1e-6);
|
|
33443
|
-
float a = 1.0 - clamp(dist, 0.0, 1.0);
|
|
33444
|
-
color = mix(color, vec3(1.0, 0.235, 0.235), a);
|
|
33445
|
-
}
|
|
33446
|
-
}
|
|
33447
|
-
|
|
33448
|
-
if (uShadingEnabled) {
|
|
33449
|
-
vec3 n = normalize(vViewNormal);
|
|
33450
|
-
// Two-sided Lambert: inspection surfaces are viewed from either face.
|
|
33451
|
-
float lambert = abs(dot(n, normalize(uLightDirection)));
|
|
33452
|
-
float shade = uAmbient + (1.0 - uAmbient) * lambert;
|
|
33453
|
-
color *= shade;
|
|
33454
|
-
float rim = pow(1.0 - clamp(dot(n, normalize(vViewDirection)), 0.0, 1.0), 2.0);
|
|
33455
|
-
color += vec3(0.025, 0.04, 0.055) * rim;
|
|
33456
|
-
}
|
|
33457
|
-
|
|
33458
|
-
gl_FragColor = vec4(color, 1.0);
|
|
33459
|
-
}
|
|
33460
|
-
`;
|
|
33461
|
-
const COLOR_SCALE_LUT_LENGTH = 256 * 4;
|
|
33462
|
-
function makeColorScaleTexture(lut) {
|
|
33463
|
-
if (!(lut instanceof Uint8Array)) {
|
|
33464
|
-
throw new TypeError("makeColorScaleTexture: lut must be a Uint8Array of RGBA bytes.");
|
|
33465
|
-
}
|
|
33466
|
-
if (lut.length !== COLOR_SCALE_LUT_LENGTH) {
|
|
33467
|
-
throw new RangeError(
|
|
33468
|
-
`makeColorScaleTexture: lut must be exactly ${COLOR_SCALE_LUT_LENGTH} bytes (256 RGBA stops), got ${lut.length}.`
|
|
33469
|
-
);
|
|
33470
|
-
}
|
|
33471
|
-
const texture = new DataTexture(lut, 256, 1, RGBAFormat, UnsignedByteType);
|
|
33472
|
-
texture.colorSpace = NoColorSpace;
|
|
33473
|
-
texture.minFilter = LinearFilter;
|
|
33474
|
-
texture.magFilter = LinearFilter;
|
|
33475
|
-
texture.wrapS = ClampToEdgeWrapping;
|
|
33476
|
-
texture.wrapT = ClampToEdgeWrapping;
|
|
33477
|
-
texture.generateMipmaps = false;
|
|
33478
|
-
texture.unpackAlignment = 1;
|
|
33479
|
-
texture.needsUpdate = true;
|
|
33480
|
-
return texture;
|
|
33481
|
-
}
|
|
33482
|
-
const DEFAULT_LIGHT_DIRECTION = new Vector3(0.45, 0.55, 0.75).normalize();
|
|
33483
|
-
const DEFAULT_AMBIENT = 0.42;
|
|
33484
|
-
function makeInspectScalarUniforms(params) {
|
|
33485
|
-
if (!Number.isFinite(params.domainMin) || !Number.isFinite(params.domainMax)) {
|
|
33486
|
-
throw new RangeError(
|
|
33487
|
-
`makeInspectScalarUniforms: domainMin/domainMax must be finite, got [${params.domainMin}, ${params.domainMax}].`
|
|
33488
|
-
);
|
|
33489
|
-
}
|
|
33490
|
-
return {
|
|
33491
|
-
uColorScale: { value: params.colorScale },
|
|
33492
|
-
uDomainMin: { value: params.domainMin },
|
|
33493
|
-
uDomainMax: { value: params.domainMax },
|
|
33494
|
-
uIsoEnabled: { value: params.isoEnabled ?? false },
|
|
33495
|
-
uIsoSpacing: { value: params.isoSpacing ?? 0 },
|
|
33496
|
-
uCriticalEnabled: { value: params.criticalEnabled ?? false },
|
|
33497
|
-
uCriticalThreshold: { value: params.criticalThreshold ?? 0 },
|
|
33498
|
-
uShadingEnabled: { value: params.shadingEnabled ?? true },
|
|
33499
|
-
uLightDirection: { value: (params.lightDirection ?? DEFAULT_LIGHT_DIRECTION).clone() },
|
|
33500
|
-
uAmbient: { value: params.ambient ?? DEFAULT_AMBIENT }
|
|
33501
|
-
};
|
|
33502
|
-
}
|
|
33503
|
-
function updateInspectScalarUniforms(uniforms, params) {
|
|
33504
|
-
if (params.colorScale !== void 0) uniforms.uColorScale.value = params.colorScale;
|
|
33505
|
-
if (params.domainMin !== void 0) {
|
|
33506
|
-
if (!Number.isFinite(params.domainMin)) {
|
|
33507
|
-
throw new RangeError(`updateInspectScalarUniforms: domainMin must be finite, got ${params.domainMin}.`);
|
|
33508
|
-
}
|
|
33509
|
-
uniforms.uDomainMin.value = params.domainMin;
|
|
33510
|
-
}
|
|
33511
|
-
if (params.domainMax !== void 0) {
|
|
33512
|
-
if (!Number.isFinite(params.domainMax)) {
|
|
33513
|
-
throw new RangeError(`updateInspectScalarUniforms: domainMax must be finite, got ${params.domainMax}.`);
|
|
33514
|
-
}
|
|
33515
|
-
uniforms.uDomainMax.value = params.domainMax;
|
|
33516
|
-
}
|
|
33517
|
-
if (params.isoEnabled !== void 0) uniforms.uIsoEnabled.value = params.isoEnabled;
|
|
33518
|
-
if (params.isoSpacing !== void 0) uniforms.uIsoSpacing.value = params.isoSpacing;
|
|
33519
|
-
if (params.criticalEnabled !== void 0) uniforms.uCriticalEnabled.value = params.criticalEnabled;
|
|
33520
|
-
if (params.criticalThreshold !== void 0) uniforms.uCriticalThreshold.value = params.criticalThreshold;
|
|
33521
|
-
if (params.shadingEnabled !== void 0) uniforms.uShadingEnabled.value = params.shadingEnabled;
|
|
33522
|
-
if (params.lightDirection !== void 0) uniforms.uLightDirection.value.copy(params.lightDirection);
|
|
33523
|
-
if (params.ambient !== void 0) uniforms.uAmbient.value = params.ambient;
|
|
33524
|
-
}
|
|
33525
29983
|
const PREVIEW_RENDER_ORDER_STEP = 1;
|
|
33526
29984
|
const HATCH_DIRECTION_A = new Vector2(Math.cos(MathUtils.degToRad(35)), Math.sin(MathUtils.degToRad(35)));
|
|
33527
29985
|
const HATCH_DIRECTION_B = new Vector2(Math.cos(MathUtils.degToRad(125)), Math.sin(MathUtils.degToRad(125)));
|
|
@@ -35054,7 +31512,7 @@ function ForgeObject({
|
|
|
35054
31512
|
onDoubleClick,
|
|
35055
31513
|
onContextMenu
|
|
35056
31514
|
}) {
|
|
35057
|
-
var _a3, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
31515
|
+
var _a3, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
35058
31516
|
const wantsDirectSdf = Boolean(
|
|
35059
31517
|
canRenderSdfDirectly(obj.sdf) && inspectChannel === "none" && renderStyle !== "scan" && renderStyle !== "matrix" && renderMode !== "wireframe" && !debugHighlightColor
|
|
35060
31518
|
);
|
|
@@ -35147,6 +31605,7 @@ function ForgeObject({
|
|
|
35147
31605
|
colorScale: inspectColormapTexture,
|
|
35148
31606
|
domainMin: effectiveColorScale.domainMin,
|
|
35149
31607
|
domainMax: effectiveColorScale.domainMax,
|
|
31608
|
+
quantizeBands: (inspectScalarParams == null ? void 0 : inspectScalarParams.quantizeBands) ?? 0,
|
|
35150
31609
|
isoEnabled: (inspectScalarParams == null ? void 0 : inspectScalarParams.isolinesEnabled) ?? false,
|
|
35151
31610
|
isoSpacing: (inspectScalarParams == null ? void 0 : inspectScalarParams.isolineSpacing) ?? 0,
|
|
35152
31611
|
criticalEnabled: Boolean((inspectScalarParams == null ? void 0 : inspectScalarParams.criticalEnabled) && (inspectScalarParams == null ? void 0 : inspectScalarParams.criticalThreshold) != null),
|
|
@@ -35195,6 +31654,7 @@ function ForgeObject({
|
|
|
35195
31654
|
updateInspectScalarUniforms(inspectScalarUniforms, {
|
|
35196
31655
|
domainMin: effectiveColorScale.domainMin,
|
|
35197
31656
|
domainMax: effectiveColorScale.domainMax,
|
|
31657
|
+
quantizeBands: inspectScalarParams.quantizeBands,
|
|
35198
31658
|
isoEnabled: inspectScalarParams.isolinesEnabled,
|
|
35199
31659
|
isoSpacing: inspectScalarParams.isolineSpacing,
|
|
35200
31660
|
criticalEnabled: inspectScalarParams.criticalEnabled && inspectScalarParams.criticalThreshold != null,
|
|
@@ -35208,13 +31668,35 @@ function ForgeObject({
|
|
|
35208
31668
|
Object.values(scanAnalysisGeometries ?? {}).forEach((geometry) => geometry == null ? void 0 : geometry.dispose());
|
|
35209
31669
|
};
|
|
35210
31670
|
}, [scanAnalysisGeometries]);
|
|
31671
|
+
const textureDescriptor = (_a3 = obj.materialProps) == null ? void 0 : _a3.texture;
|
|
31672
|
+
const projectedTexture = reactExports.useMemo(() => {
|
|
31673
|
+
if (!textureDescriptor) return null;
|
|
31674
|
+
return descriptorToThreeTexture(textureDescriptor.image, { colorSpace: "srgb" });
|
|
31675
|
+
}, [textureDescriptor]);
|
|
31676
|
+
const solidMaterialRef = reactExports.useRef(null);
|
|
31677
|
+
const setSolidMaterial = reactExports.useCallback(
|
|
31678
|
+
(material) => {
|
|
31679
|
+
solidMaterialRef.current = material;
|
|
31680
|
+
if (material && projectedTexture && textureDescriptor) {
|
|
31681
|
+
applyProjectedTexture(material, textureDescriptor.projection, projectedTexture);
|
|
31682
|
+
}
|
|
31683
|
+
},
|
|
31684
|
+
[projectedTexture, textureDescriptor]
|
|
31685
|
+
);
|
|
31686
|
+
reactExports.useEffect(() => {
|
|
31687
|
+
const material = solidMaterialRef.current;
|
|
31688
|
+
if (material && projectedTexture && textureDescriptor) {
|
|
31689
|
+
applyProjectedTexture(material, textureDescriptor.projection, projectedTexture);
|
|
31690
|
+
invalidate2();
|
|
31691
|
+
}
|
|
31692
|
+
}, [projectedTexture, textureDescriptor, invalidate2]);
|
|
35211
31693
|
if (!settings.visible) return null;
|
|
35212
31694
|
const effectiveRenderMode = isInteracting && renderMode === "overlay" ? "solid" : renderMode;
|
|
35213
31695
|
const renderStylePreset = getRenderStylePreset(renderStyle);
|
|
35214
31696
|
const materialDefaults = renderStylePreset.material;
|
|
35215
31697
|
const surfaceField = renderStylePreset.surfaceField;
|
|
35216
|
-
const authoredMaterialOpacity = (
|
|
35217
|
-
const authoredMaterialTransmission = (
|
|
31698
|
+
const authoredMaterialOpacity = (_b2 = obj.materialProps) == null ? void 0 : _b2.opacity;
|
|
31699
|
+
const authoredMaterialTransmission = (_c = obj.materialProps) == null ? void 0 : _c.transmission;
|
|
35218
31700
|
const hasAuthoredTransparency = authoredMaterialOpacity !== void 0 && authoredMaterialOpacity < 0.99 || authoredMaterialTransmission !== void 0 && authoredMaterialTransmission > 0;
|
|
35219
31701
|
const transparentDefaults = hasAuthoredTransparency ? materialDefaults.authoredTransparent : materialDefaults;
|
|
35220
31702
|
const meshOpacity = settings.opacity;
|
|
@@ -35307,7 +31789,8 @@ function ForgeObject({
|
|
|
35307
31789
|
polygonOffset: inspectChannel === "floating",
|
|
35308
31790
|
polygonOffsetFactor: -1,
|
|
35309
31791
|
polygonOffsetUnits: -1
|
|
35310
|
-
}
|
|
31792
|
+
},
|
|
31793
|
+
hasInspectMeshColors ? "inspect-vertex-colors" : "inspect-solid-color"
|
|
35311
31794
|
) }),
|
|
35312
31795
|
showSolid && inspectChannel === "normals" && /* @__PURE__ */ jsxRuntimeExports.jsx("mesh", { geometry: solidGeo, userData: { forgeMesh: true }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35313
31796
|
"meshNormalMaterial",
|
|
@@ -35492,25 +31975,26 @@ function ForgeObject({
|
|
|
35492
31975
|
) : /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35493
31976
|
"meshPhysicalMaterial",
|
|
35494
31977
|
{
|
|
31978
|
+
ref: setSolidMaterial,
|
|
35495
31979
|
color: settings.color,
|
|
35496
|
-
metalness: ((
|
|
35497
|
-
roughness: ((
|
|
35498
|
-
clearcoat: ((
|
|
35499
|
-
clearcoatRoughness: ((
|
|
31980
|
+
metalness: ((_d = obj.materialProps) == null ? void 0 : _d.metalness) ?? materialDefaults.metalness,
|
|
31981
|
+
roughness: ((_e = obj.materialProps) == null ? void 0 : _e.roughness) ?? transparentDefaults.roughness,
|
|
31982
|
+
clearcoat: ((_f = obj.materialProps) == null ? void 0 : _f.clearcoat) ?? transparentDefaults.clearcoat,
|
|
31983
|
+
clearcoatRoughness: ((_g = obj.materialProps) == null ? void 0 : _g.clearcoatRoughness) ?? transparentDefaults.clearcoatRoughness,
|
|
35500
31984
|
transmission,
|
|
35501
|
-
ior: ((
|
|
35502
|
-
thickness: ((
|
|
35503
|
-
reflectivity: ((
|
|
35504
|
-
specularIntensity: ((
|
|
35505
|
-
specularColor: ((
|
|
31985
|
+
ior: ((_h = obj.materialProps) == null ? void 0 : _h.ior) ?? 1.5,
|
|
31986
|
+
thickness: ((_i = obj.materialProps) == null ? void 0 : _i.thickness) ?? transparentDefaults.thickness,
|
|
31987
|
+
reflectivity: ((_j = obj.materialProps) == null ? void 0 : _j.reflectivity) ?? transparentDefaults.reflectivity,
|
|
31988
|
+
specularIntensity: ((_k = obj.materialProps) == null ? void 0 : _k.specularIntensity) ?? transparentDefaults.specularIntensity,
|
|
31989
|
+
specularColor: ((_l = obj.materialProps) == null ? void 0 : _l.specularColor) ?? "#ffffff",
|
|
35506
31990
|
flatShading: !hasSmoothNormals,
|
|
35507
31991
|
side: DoubleSide,
|
|
35508
31992
|
transparent: isTransparent,
|
|
35509
31993
|
opacity: materialOpacity,
|
|
35510
31994
|
depthWrite: !isTransparent,
|
|
35511
|
-
emissive: isHovered ? settings.color : ((
|
|
35512
|
-
emissiveIntensity: isHovered ? 0.3 : ((
|
|
35513
|
-
wireframe: ((
|
|
31995
|
+
emissive: isHovered ? settings.color : ((_m = obj.materialProps) == null ? void 0 : _m.emissive) ?? "#000000",
|
|
31996
|
+
emissiveIntensity: isHovered ? 0.3 : ((_n = obj.materialProps) == null ? void 0 : _n.emissiveIntensity) ?? 0,
|
|
31997
|
+
wireframe: ((_o = obj.materialProps) == null ? void 0 : _o.wireframe) ?? false,
|
|
35514
31998
|
clippingPlanes: effectiveClippingPlanes
|
|
35515
31999
|
}
|
|
35516
32000
|
) }),
|
|
@@ -35600,13 +32084,13 @@ const resolveArcReferenceDirection = (axisWorld) => {
|
|
|
35600
32084
|
return fallback.normalize();
|
|
35601
32085
|
};
|
|
35602
32086
|
const resolveSegmentMeshTransform = (start, end) => {
|
|
35603
|
-
const
|
|
35604
|
-
const length =
|
|
32087
|
+
const direction = end.clone().sub(start);
|
|
32088
|
+
const length = direction.length();
|
|
35605
32089
|
if (length <= 1e-6) return null;
|
|
35606
|
-
|
|
32090
|
+
direction.multiplyScalar(1 / length);
|
|
35607
32091
|
return {
|
|
35608
32092
|
midpoint: start.clone().add(end).multiplyScalar(0.5),
|
|
35609
|
-
quaternion: new Quaternion().setFromUnitVectors(WORLD_UP$1,
|
|
32093
|
+
quaternion: new Quaternion().setFromUnitVectors(WORLD_UP$1, direction),
|
|
35610
32094
|
length
|
|
35611
32095
|
};
|
|
35612
32096
|
};
|
|
@@ -35731,8 +32215,8 @@ function HoveredJointOverlay({ state: state2, config }) {
|
|
|
35731
32215
|
const points = [];
|
|
35732
32216
|
for (let i = 0; i <= steps; i += 1) {
|
|
35733
32217
|
const theta = arcAngleRad * (i / steps);
|
|
35734
|
-
const
|
|
35735
|
-
points.push(state2.pivotWorld.clone().addScaledVector(
|
|
32218
|
+
const direction = arcStartDirection.clone().applyAxisAngle(state2.axisWorld, theta);
|
|
32219
|
+
points.push(state2.pivotWorld.clone().addScaledVector(direction, arcRadius));
|
|
35736
32220
|
}
|
|
35737
32221
|
return points;
|
|
35738
32222
|
}, [
|
|
@@ -36460,6 +32944,7 @@ function InspectionLegend({
|
|
|
36460
32944
|
displayMode,
|
|
36461
32945
|
warnings,
|
|
36462
32946
|
details,
|
|
32947
|
+
swatches: liveSwatches,
|
|
36463
32948
|
thicknessColorRange,
|
|
36464
32949
|
onThicknessColorRangeChange,
|
|
36465
32950
|
colorScale,
|
|
@@ -36474,6 +32959,7 @@ function InspectionLegend({
|
|
|
36474
32959
|
unitLabel,
|
|
36475
32960
|
criticalValue
|
|
36476
32961
|
});
|
|
32962
|
+
const swatches = liveSwatches && liveSwatches.length > 0 ? liveSwatches : definition == null ? void 0 : definition.swatches;
|
|
36477
32963
|
const sliderGradient = colorScaleHexStops((colorScale == null ? void 0 : colorScale.colormap) ?? "viridis");
|
|
36478
32964
|
reactExports.useEffect(() => {
|
|
36479
32965
|
var _a3;
|
|
@@ -36488,10 +32974,13 @@ function InspectionLegend({
|
|
|
36488
32974
|
if (!definition) return null;
|
|
36489
32975
|
const warning = warnings[0];
|
|
36490
32976
|
const showThicknessControls = channel === "thickness" && thicknessColorRange !== void 0 && onThicknessColorRangeChange !== void 0;
|
|
32977
|
+
const swatchCount = (swatches == null ? void 0 : swatches.length) ?? 0;
|
|
32978
|
+
const hasScrollableSwatches = swatchCount > 10;
|
|
36491
32979
|
const effectivePanelStyle = {
|
|
36492
32980
|
...panelStyle,
|
|
36493
32981
|
...compact ? { padding: "7px 8px" } : {},
|
|
36494
|
-
...showThicknessControls ? { pointerEvents: "auto" } : {}
|
|
32982
|
+
...showThicknessControls || hasScrollableSwatches ? { pointerEvents: "auto" } : {},
|
|
32983
|
+
...hasScrollableSwatches ? { maxHeight: "min(320px, calc(100vh - 24px))", overflowY: "auto" } : {}
|
|
36495
32984
|
};
|
|
36496
32985
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: panelRef, className: "fc-viewport-floating-panel fc-inspection-legend", style: effectivePanelStyle, children: [
|
|
36497
32986
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: titleStyle, children: [
|
|
@@ -36513,14 +33002,14 @@ function InspectionLegend({
|
|
|
36513
33002
|
"div",
|
|
36514
33003
|
{
|
|
36515
33004
|
style: {
|
|
36516
|
-
marginBottom: definition.ramp ||
|
|
33005
|
+
marginBottom: definition.ramp || swatches ? 8 : 0,
|
|
36517
33006
|
color: "var(--fc-text)",
|
|
36518
33007
|
minWidth: 0
|
|
36519
33008
|
},
|
|
36520
33009
|
children: details
|
|
36521
33010
|
}
|
|
36522
33011
|
),
|
|
36523
|
-
|
|
33012
|
+
swatches && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36524
33013
|
"div",
|
|
36525
33014
|
{
|
|
36526
33015
|
style: {
|
|
@@ -36528,7 +33017,7 @@ function InspectionLegend({
|
|
|
36528
33017
|
gridTemplateColumns: compact ? "minmax(0, 1fr)" : swatchGridStyle.gridTemplateColumns,
|
|
36529
33018
|
marginTop: definition.ramp ? 8 : 0
|
|
36530
33019
|
},
|
|
36531
|
-
children:
|
|
33020
|
+
children: swatches.map((item) => /* @__PURE__ */ jsxRuntimeExports.jsx(Swatch, { item }, `${item.label}:${item.detail}`))
|
|
36532
33021
|
}
|
|
36533
33022
|
),
|
|
36534
33023
|
warning && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -37943,16 +34432,16 @@ function releasePointerCapture(event) {
|
|
|
37943
34432
|
const target = event.target;
|
|
37944
34433
|
(_a3 = target.releasePointerCapture) == null ? void 0 : _a3.call(target, event.pointerId);
|
|
37945
34434
|
}
|
|
37946
|
-
function calculateAxisDragDelta(clickPoint, axis,
|
|
34435
|
+
function calculateAxisDragDelta(clickPoint, axis, ray) {
|
|
37947
34436
|
const axisLenSq = axis.dot(axis);
|
|
37948
34437
|
if (axisLenSq <= 1e-8) return 0;
|
|
37949
|
-
const startOffset = axis.dot(clickPoint) - axis.dot(
|
|
37950
|
-
const rayAxisDot = axis.dot(
|
|
34438
|
+
const startOffset = axis.dot(clickPoint) - axis.dot(ray.origin);
|
|
34439
|
+
const rayAxisDot = axis.dot(ray.direction);
|
|
37951
34440
|
if (Math.abs(rayAxisDot) <= 1e-8) {
|
|
37952
34441
|
return -startOffset / axisLenSq;
|
|
37953
34442
|
}
|
|
37954
|
-
dragAxisScratchA.copy(
|
|
37955
|
-
dragAxisScratchB.copy(
|
|
34443
|
+
dragAxisScratchA.copy(ray.direction).multiplyScalar(axisLenSq / rayAxisDot).sub(axis);
|
|
34444
|
+
dragAxisScratchB.copy(ray.direction).multiplyScalar(startOffset / rayAxisDot).add(ray.origin).sub(clickPoint);
|
|
37956
34445
|
const denom = dragAxisScratchA.dot(dragAxisScratchA);
|
|
37957
34446
|
return denom <= 1e-8 ? 0 : -dragAxisScratchA.dot(dragAxisScratchB) / denom;
|
|
37958
34447
|
}
|
|
@@ -38534,7 +35023,7 @@ function SectionCapMaterial({
|
|
|
38534
35023
|
const objectColor = parseExportColor(color, 6003669);
|
|
38535
35024
|
const baseColor = objectColor.clone().lerp(new Color("#f5f7fb"), 0.1);
|
|
38536
35025
|
const lineColor = objectColor.clone().lerp(new Color("#111111"), 0.45);
|
|
38537
|
-
const
|
|
35026
|
+
const direction = new Vector2(Math.cos(hatchAngleRad), Math.sin(hatchAngleRad));
|
|
38538
35027
|
const mat = new MeshStandardMaterial({
|
|
38539
35028
|
color: baseColor,
|
|
38540
35029
|
roughness: 0.48,
|
|
@@ -38551,7 +35040,7 @@ function SectionCapMaterial({
|
|
|
38551
35040
|
});
|
|
38552
35041
|
mat.onBeforeCompile = (shader) => {
|
|
38553
35042
|
shader.uniforms.hatchLineColor = { value: lineColor };
|
|
38554
|
-
shader.uniforms.hatchDirection = { value:
|
|
35043
|
+
shader.uniforms.hatchDirection = { value: direction };
|
|
38555
35044
|
shader.uniforms.hatchSpacing = { value: hatchSpacing };
|
|
38556
35045
|
shader.uniforms.hatchLineWidth = { value: hatchLineWidth };
|
|
38557
35046
|
shader.vertexShader = shader.vertexShader.replace("#include <common>", "#include <common>\nattribute vec2 planeUv;\nvarying vec2 vSectionPlaneUv;").replace("#include <begin_vertex>", "#include <begin_vertex>\nvSectionPlaneUv = planeUv;");
|
|
@@ -42045,11 +38534,11 @@ const computeExplodeTreeOffsets = (root, explodeAmount, explodeConfig) => {
|
|
|
42045
38534
|
const center = explodeBoundsCenter(node.bounds) ?? parentCenter;
|
|
42046
38535
|
const directive = resolveExplodeDirective([node.path.join("/")], node.label, void 0, config);
|
|
42047
38536
|
const motion = depth > 1 && node.children.length === 0 && !hasExplodeOverride(directive) ? (() => {
|
|
42048
|
-
const
|
|
38537
|
+
const direction = resolveExplodeLocalFanDirection(center, parentCenter, parentDirection, node.key);
|
|
42049
38538
|
return {
|
|
42050
|
-
direction
|
|
42051
|
-
branchDirection: parentDirection ??
|
|
42052
|
-
offset: explodeMul(
|
|
38539
|
+
direction,
|
|
38540
|
+
branchDirection: parentDirection ?? direction,
|
|
38541
|
+
offset: explodeMul(direction, config.amount * explodeLeafFanStage(config, depth))
|
|
42053
38542
|
};
|
|
42054
38543
|
})() : computeExplodeMotion({
|
|
42055
38544
|
pathKeys: [node.path.join("/")],
|
|
@@ -42412,6 +38901,7 @@ function useViewportState() {
|
|
|
42412
38901
|
const inspectColormap = useForgeStore((s) => s.inspectColormap);
|
|
42413
38902
|
const inspectIsolinesEnabled = useForgeStore((s) => s.inspectIsolinesEnabled);
|
|
42414
38903
|
const inspectIsolineSpacing = useForgeStore((s) => s.inspectIsolineSpacing);
|
|
38904
|
+
const inspectQuantizeBands = useForgeStore((s) => s.inspectQuantizeBands);
|
|
42415
38905
|
const inspectCriticalLineEnabled = useForgeStore((s) => s.inspectCriticalLineEnabled);
|
|
42416
38906
|
const comparisonInspectMode = useForgeStore((s) => s.comparisonInspectMode);
|
|
42417
38907
|
const comparisonCandidateOpacity = useForgeStore((s) => s.comparisonCandidateOpacity);
|
|
@@ -42827,6 +39317,7 @@ function useViewportState() {
|
|
|
42827
39317
|
inspectColormap,
|
|
42828
39318
|
inspectIsolinesEnabled,
|
|
42829
39319
|
inspectIsolineSpacing,
|
|
39320
|
+
inspectQuantizeBands,
|
|
42830
39321
|
inspectCriticalLineEnabled,
|
|
42831
39322
|
comparisonInspectMode,
|
|
42832
39323
|
comparisonCandidateOpacity,
|
|
@@ -44513,6 +41004,7 @@ function mergeResults(results, channel, analysisId) {
|
|
|
44513
41004
|
meshColorObjects: [],
|
|
44514
41005
|
scalarSurfaceObjects: [],
|
|
44515
41006
|
collisionGeometryObjects: [],
|
|
41007
|
+
legendSwatches: [],
|
|
44516
41008
|
warnings: []
|
|
44517
41009
|
};
|
|
44518
41010
|
for (const result of results) {
|
|
@@ -44521,6 +41013,7 @@ function mergeResults(results, channel, analysisId) {
|
|
|
44521
41013
|
merged.meshColorObjects.push(...result.meshColorObjects);
|
|
44522
41014
|
merged.scalarSurfaceObjects.push(...result.scalarSurfaceObjects);
|
|
44523
41015
|
merged.collisionGeometryObjects.push(...result.collisionGeometryObjects);
|
|
41016
|
+
merged.legendSwatches.push(...result.legendSwatches);
|
|
44524
41017
|
merged.warnings.push(...result.warnings);
|
|
44525
41018
|
}
|
|
44526
41019
|
return merged;
|
|
@@ -44528,7 +41021,7 @@ function mergeResults(results, channel, analysisId) {
|
|
|
44528
41021
|
class InspectWorkerClient {
|
|
44529
41022
|
constructor(workerFactory = () => new Worker(new URL(
|
|
44530
41023
|
/* @vite-ignore */
|
|
44531
|
-
"/assets/inspectWorker-
|
|
41024
|
+
"/assets/inspectWorker-ymhBV4Ll.js",
|
|
44532
41025
|
import.meta.url
|
|
44533
41026
|
), { type: "module" })) {
|
|
44534
41027
|
__publicField(this, "reqId", 0);
|
|
@@ -44940,6 +41433,7 @@ function resultToState(channel, result) {
|
|
|
44940
41433
|
}
|
|
44941
41434
|
])
|
|
44942
41435
|
),
|
|
41436
|
+
legendSwatches: result.legendSwatches,
|
|
44943
41437
|
warnings: result.warnings,
|
|
44944
41438
|
error: null
|
|
44945
41439
|
};
|
|
@@ -44953,6 +41447,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
44953
41447
|
pointClouds: {},
|
|
44954
41448
|
scalarSurfaces: {},
|
|
44955
41449
|
collisionGeometries: [],
|
|
41450
|
+
legendSwatches: [],
|
|
44956
41451
|
warnings: [],
|
|
44957
41452
|
error: null
|
|
44958
41453
|
});
|
|
@@ -44967,6 +41462,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
44967
41462
|
pointClouds: {},
|
|
44968
41463
|
scalarSurfaces: {},
|
|
44969
41464
|
collisionGeometries: [],
|
|
41465
|
+
legendSwatches: [],
|
|
44970
41466
|
warnings: [],
|
|
44971
41467
|
error: null
|
|
44972
41468
|
});
|
|
@@ -44982,6 +41478,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
44982
41478
|
pointClouds: {},
|
|
44983
41479
|
scalarSurfaces: {},
|
|
44984
41480
|
collisionGeometries: [],
|
|
41481
|
+
legendSwatches: [],
|
|
44985
41482
|
warnings: [],
|
|
44986
41483
|
error: null
|
|
44987
41484
|
});
|
|
@@ -45021,6 +41518,7 @@ function useInspectWorkerAnalysis(args) {
|
|
|
45021
41518
|
pointClouds: {},
|
|
45022
41519
|
scalarSurfaces: {},
|
|
45023
41520
|
collisionGeometries: [],
|
|
41521
|
+
legendSwatches: [],
|
|
45024
41522
|
warnings: [],
|
|
45025
41523
|
error: error instanceof Error ? error.message : String(error)
|
|
45026
41524
|
});
|
|
@@ -45062,19 +41560,19 @@ function dominantAxis(normal) {
|
|
|
45062
41560
|
if (ay >= ax && ay >= az) return "y";
|
|
45063
41561
|
return "z";
|
|
45064
41562
|
}
|
|
45065
|
-
function anchoredCellIndex(value, cellSize,
|
|
41563
|
+
function anchoredCellIndex(value, cellSize, direction) {
|
|
45066
41564
|
const scaled = value / cellSize;
|
|
45067
41565
|
const base = Math.floor(scaled);
|
|
45068
41566
|
const onBoundary = Math.abs(scaled - Math.round(scaled)) < 1e-7;
|
|
45069
|
-
return onBoundary &&
|
|
41567
|
+
return onBoundary && direction < 0 ? base - 1 : base;
|
|
45070
41568
|
}
|
|
45071
41569
|
function voxelCellFromSurfaceAnchor(point, normal, cellSize, side) {
|
|
45072
41570
|
const cell = voxelCellFromPoint(point, cellSize);
|
|
45073
41571
|
const axis = dominantAxis(normal);
|
|
45074
41572
|
const normalValue = normal[axis];
|
|
45075
41573
|
const outsideDirection = normalValue < 0 ? -1 : 1;
|
|
45076
|
-
const
|
|
45077
|
-
cell[axis] = anchoredCellIndex(point[axis], cellSize,
|
|
41574
|
+
const direction = side === "outside" ? outsideDirection : -outsideDirection;
|
|
41575
|
+
cell[axis] = anchoredCellIndex(point[axis], cellSize, direction);
|
|
45078
41576
|
return cell;
|
|
45079
41577
|
}
|
|
45080
41578
|
function parseVoxelCellKey(key) {
|
|
@@ -45526,6 +42024,7 @@ function Viewport() {
|
|
|
45526
42024
|
inspectColormap,
|
|
45527
42025
|
inspectIsolinesEnabled,
|
|
45528
42026
|
inspectIsolineSpacing,
|
|
42027
|
+
inspectQuantizeBands,
|
|
45529
42028
|
inspectCriticalLineEnabled,
|
|
45530
42029
|
comparisonInspectMode,
|
|
45531
42030
|
comparisonCandidateOpacity,
|
|
@@ -45691,13 +42190,21 @@ function Viewport() {
|
|
|
45691
42190
|
if (!scalarChannelInfo) return void 0;
|
|
45692
42191
|
return {
|
|
45693
42192
|
colorScale: inspectColorScale,
|
|
42193
|
+
quantizeBands: inspectQuantizeBands,
|
|
45694
42194
|
isolinesEnabled: inspectIsolinesEnabled,
|
|
45695
42195
|
isolineSpacing: inspectIsolineSpacing,
|
|
45696
42196
|
criticalEnabled: inspectCriticalLineEnabled,
|
|
45697
42197
|
criticalThreshold: scalarChannelInfo.criticalThreshold,
|
|
45698
42198
|
shadingEnabled: true
|
|
45699
42199
|
};
|
|
45700
|
-
}, [
|
|
42200
|
+
}, [
|
|
42201
|
+
scalarChannelInfo,
|
|
42202
|
+
inspectColorScale,
|
|
42203
|
+
inspectQuantizeBands,
|
|
42204
|
+
inspectIsolinesEnabled,
|
|
42205
|
+
inspectIsolineSpacing,
|
|
42206
|
+
inspectCriticalLineEnabled
|
|
42207
|
+
]);
|
|
45701
42208
|
const comparisonAnalysis = useGeometryComparison({
|
|
45702
42209
|
enabled: comparisonInspectActive,
|
|
45703
42210
|
candidate: result,
|
|
@@ -45709,6 +42216,23 @@ function Viewport() {
|
|
|
45709
42216
|
const inspectLoading = inspectChannelActive && (comparisonInspectActive ? comparisonAnalysis.status === "loading" : inspectAnalysis.status === "loading");
|
|
45710
42217
|
const inspectError = comparisonInspectActive ? comparisonAnalysis.error : inspectAnalysis.error;
|
|
45711
42218
|
const inspectWarnings = comparisonInspectActive ? comparisonAnalysis.warnings : inspectAnalysis.warnings;
|
|
42219
|
+
const maskLegendSwatches = reactExports.useMemo(() => {
|
|
42220
|
+
const swatches = [];
|
|
42221
|
+
objects.forEach((obj, objIndex) => {
|
|
42222
|
+
const settings = objectSettings[obj.id] ?? DEFAULT_OBJECT_SETTINGS;
|
|
42223
|
+
if (settings.visible === false) return;
|
|
42224
|
+
swatches.push({
|
|
42225
|
+
label: obj.name || `Object ${objIndex + 1}`,
|
|
42226
|
+
detail: obj.id,
|
|
42227
|
+
color: maskColorForIndex(objIndex)
|
|
42228
|
+
});
|
|
42229
|
+
});
|
|
42230
|
+
return swatches;
|
|
42231
|
+
}, [objectSettings, objects]);
|
|
42232
|
+
const inspectLegendSwatches = reactExports.useMemo(() => {
|
|
42233
|
+
if (inspectChannel === "mask") return maskLegendSwatches;
|
|
42234
|
+
return inspectAnalysis.legendSwatches.length > 0 ? inspectAnalysis.legendSwatches : void 0;
|
|
42235
|
+
}, [inspectAnalysis.legendSwatches, inspectChannel, maskLegendSwatches]);
|
|
45712
42236
|
const historyGeometryLoading = historyMode && historyGeometryStatus.status === "loading";
|
|
45713
42237
|
const viewportBusyPhase = isEvaluating || evaluationPhase === "exporting" ? evaluationPhase : historyGeometryLoading ? "history" : inspectLoading ? "inspecting" : null;
|
|
45714
42238
|
const viewportBusyLabel = historyGeometryLoading ? "Building timeline geometry" : inspectLoading ? `Generating ${inspectChannelLabel(inspectChannel)} inspect view` : void 0;
|
|
@@ -45779,7 +42303,7 @@ function Viewport() {
|
|
|
45779
42303
|
candidates.sort((a2, b2) => a2.distance - b2.distance);
|
|
45780
42304
|
return candidates[0].normal;
|
|
45781
42305
|
};
|
|
45782
|
-
const voxelBlockHitsOnRay = (
|
|
42306
|
+
const voxelBlockHitsOnRay = (ray, cellSize) => {
|
|
45783
42307
|
const hits = [];
|
|
45784
42308
|
const halfExtent = cellSize * 0.55;
|
|
45785
42309
|
const hitPoint = new Vector3();
|
|
@@ -45790,9 +42314,9 @@ function Viewport() {
|
|
|
45790
42314
|
new Vector3(center.x - halfExtent, center.y - halfExtent, center.z - halfExtent),
|
|
45791
42315
|
new Vector3(center.x + halfExtent, center.y + halfExtent, center.z + halfExtent)
|
|
45792
42316
|
);
|
|
45793
|
-
const intersection =
|
|
42317
|
+
const intersection = ray.intersectBox(bounds, hitPoint);
|
|
45794
42318
|
if (!intersection) continue;
|
|
45795
|
-
const alongRay = intersection.clone().sub(
|
|
42319
|
+
const alongRay = intersection.clone().sub(ray.origin).dot(ray.direction);
|
|
45796
42320
|
hits.push({ cell: { x, y, z }, normal: voxelNormalFromBoxHit(intersection, bounds), alongRay });
|
|
45797
42321
|
}
|
|
45798
42322
|
hits.sort((a2, b2) => a2.alongRay - b2.alongRay);
|
|
@@ -45915,6 +42439,7 @@ function Viewport() {
|
|
|
45915
42439
|
channel: inspectChannel,
|
|
45916
42440
|
displayMode: inspectDisplayMode,
|
|
45917
42441
|
warnings: inspectWarnings,
|
|
42442
|
+
swatches: inspectLegendSwatches,
|
|
45918
42443
|
thicknessColorRange,
|
|
45919
42444
|
onThicknessColorRangeChange: setThicknessColorRange,
|
|
45920
42445
|
colorScale: scalarChannelInfo ? inspectColorScale : void 0,
|
|
@@ -46969,7 +43494,7 @@ function Viewport() {
|
|
|
46969
43494
|
}
|
|
46970
43495
|
);
|
|
46971
43496
|
}
|
|
46972
|
-
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
43497
|
+
const EditorApp$1 = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-BWUGCdD5.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
46973
43498
|
const PENDING_SHARE_COPY_KEY = "fc-pending-share-copy";
|
|
46974
43499
|
function storePendingShareCopy(shareId) {
|
|
46975
43500
|
sessionStorage.setItem(PENDING_SHARE_COPY_KEY, shareId);
|
|
@@ -47158,7 +43683,7 @@ const PublishedModelPage$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Objec
|
|
|
47158
43683
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
47159
43684
|
const siteUrl = "https://forgecad.io";
|
|
47160
43685
|
const defaultImage = "https://forgecad.io/brand/social-card.png";
|
|
47161
|
-
const pages$1 = [{ "path": "/", "title": "ForgeCAD - AI-Native CAD for
|
|
43686
|
+
const pages$1 = [{ "path": "/", "title": "ForgeCAD - AI-Native CAD for Products, Manufacturing, and Robotics", "description": "ForgeCAD generates editable parametric CAD for real products, manufacturing components, robotics simulation assets, and AI training data with validation evidence and STEP/STL/3MF exports.", "priority": "1.0", "changefreq": "weekly" }, { "path": "/docs", "title": "ForgeCAD Documentation - AI-Native Parametric CAD", "description": "Learn ForgeCAD's AI-native CAD API, agent workflow, validation loop, exports, assemblies, sketches, simulation metadata, and manufacturing-ready model checks.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/ai-native-cad", "title": "AI-Native CAD Workflow - ForgeCAD", "description": "How ForgeCAD supports AI-driven CAD: editable code, validation evidence, manufacturing feedback, and parallel product idea iteration.", "priority": "0.9", "changefreq": "weekly" }, { "path": "/docs/ai-usage", "title": "AI CAD Agent Setup - ForgeCAD", "description": "Set up Codex, Claude Code, OpenCode, or another agent to build, validate, inspect, export, and publish ForgeCAD models.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/cli", "title": "ForgeCAD CLI - Validate, Inspect, Export, Publish", "description": "Use the ForgeCAD CLI to run .forge.js models, render evidence, inspect manufacturability, export STEP/STL/3MF, and sync projects.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/docs/simready-quickstart", "title": "ForgeCAD SimReady Quickstart - Source-Authored Simulation Metadata", "description": "Author ForgeCAD assemblies with physical bodies, materials, colliders, joints, controllers, offline SimReady checks, and simulator exports.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/simulation-workflow", "title": "ForgeCAD Simulation Workflow - MuJoCo, Gym, and Isaac Lab Handoff", "description": "Take a ForgeCAD robot through MJCF export, MuJoCo playback, Gymnasium training, force-push interaction tests, and Isaac Lab integration planning.", "priority": "0.8", "changefreq": "weekly" }, { "path": "/docs/skills/forgecad-build-model", "title": "AI CAD Model-Making Skill - ForgeCAD", "description": "A workflow for AI agents to create manufacture-realistic ForgeCAD models with validation, renders, inspection evidence, and exports.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/benchmark", "title": "ForgeCAD Benchmark - AI CAD Model Generation", "description": "Benchmark AI agents generating real ForgeCAD models with executable code, visual evidence, validation output, and geometry checks.", "priority": "0.7", "changefreq": "weekly" }, { "path": "/blog", "title": "ForgeCAD Blog - AI-Native CAD and Manufacturing Workflows", "description": "Product notes, tutorials, examples, and technical updates on AI-native CAD, parametric modeling, validation, and manufacturing exports.", "priority": "0.6", "changefreq": "weekly" }, { "path": "/pricing", "title": "ForgeCAD Pricing", "description": "ForgeCAD plans for browser CAD, local CLI workflows, AI agent model generation, project publishing, and commercial use.", "priority": "0.5", "changefreq": "monthly" }, { "path": "/terms", "title": "ForgeCAD Terms of Service", "description": "Terms for ForgeCAD accounts, projects, hosted services, CLI use, commercial use, automation, and AI-assisted workflows.", "priority": "0.3", "changefreq": "yearly" }, { "path": "/privacy", "title": "ForgeCAD Privacy Policy", "description": "How ForgeCAD handles account, project, billing, analytics, and service data for the website, CLI, and hosted app.", "priority": "0.3", "changefreq": "yearly" }, { "path": "/license", "title": "ForgeCAD Software License", "description": "ForgeCAD license terms for Free, Pro, Enterprise, embedded, backend, local CLI, and AI workflow usage.", "priority": "0.3", "changefreq": "yearly" }];
|
|
47162
43687
|
const seoConfig = {
|
|
47163
43688
|
siteUrl,
|
|
47164
43689
|
defaultImage,
|
|
@@ -47235,17 +43760,17 @@ function SeoMetadata() {
|
|
|
47235
43760
|
}, [location.pathname]);
|
|
47236
43761
|
return null;
|
|
47237
43762
|
}
|
|
47238
|
-
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-
|
|
47239
|
-
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-
|
|
47240
|
-
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-
|
|
47241
|
-
reactExports.lazy(() => __vitePreload(() => import("./BenchmarkPage-
|
|
47242
|
-
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-
|
|
43763
|
+
reactExports.lazy(() => __vitePreload(() => import("./LandingPageProofDriven-BoVE7JGY.js"), true ? __vite__mapDeps([1]) : void 0).then((m2) => ({ default: m2.LandingPageProofDriven })));
|
|
43764
|
+
const DocsPage = reactExports.lazy(() => __vitePreload(() => import("./DocsPage-BPGGwht1.js"), true ? [] : void 0).then((m2) => ({ default: m2.DocsPage })));
|
|
43765
|
+
reactExports.lazy(() => __vitePreload(() => import("./BlogPage-B7BWxOCg.js"), true ? [] : void 0).then((m2) => ({ default: m2.BlogPage })));
|
|
43766
|
+
reactExports.lazy(() => __vitePreload(() => import("./BenchmarkPage-DXKVXMrJ.js"), true ? __vite__mapDeps([1,2]) : void 0).then((m2) => ({ default: m2.BenchmarkPage })));
|
|
43767
|
+
reactExports.lazy(() => __vitePreload(() => import("./AdminPage-B3L3W1Uo.js"), true ? [] : void 0).then((m2) => ({ default: m2.AdminPage })));
|
|
47243
43768
|
reactExports.lazy(() => __vitePreload(() => Promise.resolve().then(() => PublishedModelPage$1), true ? void 0 : void 0).then((m2) => ({ default: m2.PublishedModelPage })));
|
|
47244
|
-
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-
|
|
47245
|
-
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-
|
|
47246
|
-
reactExports.lazy(() => __vitePreload(() => import("./LegalPage-
|
|
47247
|
-
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-
|
|
47248
|
-
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer
|
|
43769
|
+
reactExports.lazy(() => __vitePreload(() => import("./SettingsPage-BlJDCRe8.js"), true ? [] : void 0).then((m2) => ({ default: m2.SettingsPage })));
|
|
43770
|
+
reactExports.lazy(() => __vitePreload(() => import("./PricingPage-C2PMzmDc.js"), true ? __vite__mapDeps([1,3]) : void 0).then((m2) => ({ default: m2.PricingPage })));
|
|
43771
|
+
reactExports.lazy(() => __vitePreload(() => import("./LegalPage-Din8wv8d.js"), true ? __vite__mapDeps([1,4]) : void 0).then((m2) => ({ default: m2.LegalPage })));
|
|
43772
|
+
const EditorApp = reactExports.lazy(() => __vitePreload(() => import("./EditorApp-BWUGCdD5.js"), true ? __vite__mapDeps([0]) : void 0).then((m2) => ({ default: m2.EditorApp })));
|
|
43773
|
+
const EmbedViewer = reactExports.lazy(() => __vitePreload(() => import("./EmbedViewer-DygByZS2.js"), true ? [] : void 0).then((m2) => ({ default: m2.EmbedViewer })));
|
|
47249
43774
|
const embedMode = isEmbedMode() && !window.location.pathname.startsWith("/m/");
|
|
47250
43775
|
const EDITABLE_CRASH_FILE = /\.(?:forge\.js|[cm]?[jt]sx?|json|md|txt|svg|dxf)$/i;
|
|
47251
43776
|
function firstMeaningfulLine(text) {
|
|
@@ -47465,7 +43990,7 @@ function App() {
|
|
|
47465
43990
|
applyTheme(localStorage.getItem("fc-theme") || "dark");
|
|
47466
43991
|
clientExports.createRoot(document.getElementById("root")).render(/* @__PURE__ */ jsxRuntimeExports.jsx(App, {}));
|
|
47467
43992
|
export {
|
|
47468
|
-
|
|
43993
|
+
VOXEL_INTENT_TOOL_ORDER as $,
|
|
47469
43994
|
AuthApiError as A,
|
|
47470
43995
|
BrandMark as B,
|
|
47471
43996
|
captureViewportImageBlobFromStore as C,
|
|
@@ -47490,49 +44015,48 @@ export {
|
|
|
47490
44015
|
animationSpeedToSlider as V,
|
|
47491
44016
|
formatAnimationSpeed as W,
|
|
47492
44017
|
resolveJointRange as X,
|
|
47493
|
-
|
|
47494
|
-
|
|
47495
|
-
|
|
44018
|
+
availableKernels as Y,
|
|
44019
|
+
useJointsConfig as Z,
|
|
44020
|
+
useJointAnimationValues as _,
|
|
47496
44021
|
applyTheme as a,
|
|
47497
|
-
|
|
47498
|
-
|
|
47499
|
-
|
|
47500
|
-
|
|
47501
|
-
|
|
47502
|
-
|
|
47503
|
-
|
|
47504
|
-
|
|
47505
|
-
|
|
47506
|
-
|
|
47507
|
-
|
|
47508
|
-
|
|
47509
|
-
|
|
47510
|
-
|
|
47511
|
-
|
|
47512
|
-
|
|
47513
|
-
|
|
47514
|
-
|
|
47515
|
-
|
|
47516
|
-
|
|
47517
|
-
|
|
47518
|
-
|
|
47519
|
-
|
|
47520
|
-
|
|
47521
|
-
|
|
47522
|
-
|
|
47523
|
-
|
|
47524
|
-
|
|
47525
|
-
|
|
47526
|
-
|
|
47527
|
-
|
|
47528
|
-
|
|
47529
|
-
|
|
47530
|
-
|
|
47531
|
-
|
|
47532
|
-
|
|
47533
|
-
|
|
47534
|
-
|
|
47535
|
-
useDrawStore as az,
|
|
44022
|
+
VOXEL_INTENT_TOOL_LABELS as a0,
|
|
44023
|
+
VOXEL_INTENT_TOOL_COLORS as a1,
|
|
44024
|
+
VOXEL_INTENT_PLACEMENT_ORDER as a2,
|
|
44025
|
+
VOXEL_INTENT_PLACEMENT_LABELS as a3,
|
|
44026
|
+
highlightLanguageForProjectFile as a4,
|
|
44027
|
+
hasProjectTextFileExtension as a5,
|
|
44028
|
+
expandBoundsByTransformedAabb as a6,
|
|
44029
|
+
Canvas as a7,
|
|
44030
|
+
ActiveCameraBridge as a8,
|
|
44031
|
+
PerspectiveCamera as a9,
|
|
44032
|
+
buildShareUrl as aA,
|
|
44033
|
+
share as aB,
|
|
44034
|
+
ControlsInteractionBridge as aa,
|
|
44035
|
+
SceneConfigurator as ab,
|
|
44036
|
+
LocalEnvironment as ac,
|
|
44037
|
+
ForgeObject as ad,
|
|
44038
|
+
RenderLabelsOverlay as ae,
|
|
44039
|
+
Grid as af,
|
|
44040
|
+
OrbitControls2 as ag,
|
|
44041
|
+
TOUCH_GESTURES_3D as ah,
|
|
44042
|
+
MOUSE_BUTTONS_3D as ai,
|
|
44043
|
+
ViewController as aj,
|
|
44044
|
+
ModelJourneyBar as ak,
|
|
44045
|
+
useJointAnimationLoop as al,
|
|
44046
|
+
computeJointNodeMatrices as am,
|
|
44047
|
+
computeObjectJointMatrices as an,
|
|
44048
|
+
readLastActiveFileForUser as ao,
|
|
44049
|
+
ToastContainer as ap,
|
|
44050
|
+
isMobile as aq,
|
|
44051
|
+
useFeatureFlag as ar,
|
|
44052
|
+
decodeSharedHash as as,
|
|
44053
|
+
decodeSharedBundle as at,
|
|
44054
|
+
getExternalUrl as au,
|
|
44055
|
+
getGistId as av,
|
|
44056
|
+
Viewport as aw,
|
|
44057
|
+
shouldBlockBrowserShortcut as ax,
|
|
44058
|
+
useDrawStore as ay,
|
|
44059
|
+
storePendingShareCopy as az,
|
|
47536
44060
|
authFetch as b,
|
|
47537
44061
|
authApi as c,
|
|
47538
44062
|
showToast as d,
|