UNPKG

@realsee/five

Version:

Realsee Renderer SDK

81 lines (76 loc) • 20.6 kB
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>features/clipper | 如视 Five SDK</title><meta name="description" content="Documentation for 如视 Five SDK"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">如视 Five SDK</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">features/clipper</a></li></ul></div><div class="tsd-panel tsd-typography"><h1 id="模型裁切-model-clipper" class="tsd-anchor-link">模型裁切 (Model Clipper)<a href="#模型裁切-model-clipper" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1> <ul> <li><strong>Summary</strong>: 使用 <code>parameter.clippers</code> 定义裁切盒,用于隐藏 (discard) 模型中特定区域的点云或网格。</li> <li><strong>Schema</strong>: <code>PBMClipperParameter</code> 数组,包含变换矩阵和楼层索引。</li> <li><strong>Concepts</strong>: Clipping Box (裁切盒), Matrix Transformation (矩阵变换), Negative Space (负空间).</li> <li><strong>Configuration</strong>: <code>five.model.clippers</code>.</li> <li><strong>Examples</strong>: 创建裁切盒并应用。</li> </ul> <h2 id="schema" class="tsd-anchor-link">Schema<a href="#schema" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2> <blockquote> <p><strong>Definition</strong>: <a href="../../five/model/materials/pbmMaterial.d.ts">PBMClipperParameter</a></p> </blockquote> <pre><code class="typescript"><span class="hl-8">/** 模型裁切参数 */</span><br/><span class="hl-3">interface</span><span class="hl-1"> </span><span class="hl-7">PBMClipperParameter</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-8">/**</span><br/><span class="hl-8"> * 裁切盒的变换矩阵。</span><br/><span class="hl-8"> * </span><span class="hl-3">@description</span><br/><span class="hl-8"> * 定义了一个变换后的立方体空间。</span><br/><span class="hl-8"> * 基础形状为边长为 1 的立方体,中心在 (0,0,0),范围 [-0.5, 0.5]。</span><br/><span class="hl-8"> * 凡是落在这个变换后立方体内部的模型点,都会被丢弃 (discard)。</span><br/><span class="hl-8"> */</span><br/><span class="hl-1"> </span><span class="hl-6">clippingBoxMatrix</span><span class="hl-1">: </span><span class="hl-7">THREE</span><span class="hl-1">.</span><span class="hl-7">Matrix4</span><span class="hl-1">;</span><br/><br/><span class="hl-1"> </span><span class="hl-8">/**</span><br/><span class="hl-8"> * (可选) 楼层索引。</span><br/><span class="hl-8"> * </span><span class="hl-3">@description</span><br/><span class="hl-8"> * 如果指定,则裁切仅对该楼层的点云生效。</span><br/><span class="hl-8"> * 如果未指定 (undefined),则对所有楼层生效。</span><br/><span class="hl-8"> */</span><br/><span class="hl-1"> </span><span class="hl-6">floorIndex</span><span class="hl-1">?: </span><span class="hl-7">number</span><span class="hl-1">;</span><br/><span class="hl-1">}</span> </code><button type="button">Copy</button></pre> <h2 id="concepts" class="tsd-anchor-link">Concepts<a href="#concepts" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2> <h3 id="clipping-box-裁切盒" class="tsd-anchor-link">Clipping Box (裁切盒)<a href="#clipping-box-裁切盒" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3> <p>Five 的裁切机制是基于<strong>负空间</strong>的:</p> <ul> <li>默认情况下,所有模型点都是可见的。</li> <li>当你添加一个 Clipper 时,你实际上是在定义一个“不可见区域”。</li> <li>任何位于 Clipper 定义的 3D 盒体内部的点,都不会被渲染。</li> </ul> <h3 id="matrix-transformation-矩阵变换" class="tsd-anchor-link">Matrix Transformation (矩阵变换)<a href="#matrix-transformation-矩阵变换" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3> <p>Clipper 的几何定义依赖于 <code>clippingBoxMatrix</code>。</p> <ul> <li>shader 内部逻辑是将世界坐标系下的点,乘以 <code>clippingBoxMatrix</code> 的<strong>逆矩阵</strong>。</li> <li>然后判断该点是否在 <code>[-0.5, 0.5]</code> 的单位立方体范围内。</li> <li>这意味着你可以直接使用 <code>THREE.Mesh</code> (BoxGeometry 1x1x1) 的 <code>matrix</code> 属性作为 <code>clippingBoxMatrix</code>,所见即所得。</li> </ul> <h2 id="configuration" class="tsd-anchor-link">Configuration<a href="#configuration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2> <p>你可以通过 <code>five.model.clippers</code> 属性来读写裁切配置。</p> <table> <thead> <tr> <th>属性</th> <th>类型</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td><code>five.model.clippers</code></td> <td><code>PBMClipperParameter[]</code></td> <td>设置裁切参数数组。设置新数组会覆盖旧配置。</td> </tr> </tbody> </table> <h2 id="examples" class="tsd-anchor-link">Examples<a href="#examples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2> <h3 id="基础用法-basic-usage" class="tsd-anchor-link">基础用法 (Basic Usage)<a href="#基础用法-basic-usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3> <p>创建一个不可见的 Box,将其位置和大小作为裁切区域。</p> <pre><code class="typescript"><span class="hl-10">import</span><span class="hl-1"> </span><span class="hl-3">*</span><span class="hl-1"> </span><span class="hl-10">as</span><span class="hl-1"> </span><span class="hl-6">THREE</span><span class="hl-1"> </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">&#39;three&#39;</span><span class="hl-1">;</span><br/><span class="hl-10">import</span><span class="hl-1"> { </span><span class="hl-6">Five</span><span class="hl-1"> } </span><span class="hl-10">from</span><span class="hl-1"> </span><span class="hl-9">&#39;@realsee/five&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-8">// 1. 创建一个辅助 Mesh 来定义裁切区域</span><br/><span class="hl-8">// 注意:必须使用 1x1x1 的 BoxGeometry,因为 Shader 是基于单位立方体判断的</span><br/><span class="hl-3">const</span><span class="hl-1"> </span><span class="hl-4">clipperMesh</span><span class="hl-1"> = </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-4">THREE</span><span class="hl-1">.</span><span class="hl-5">Mesh</span><span class="hl-1">(</span><br/><span class="hl-1"> </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-4">THREE</span><span class="hl-1">.</span><span class="hl-5">BoxGeometry</span><span class="hl-1">(</span><span class="hl-11">1</span><span class="hl-1">, </span><span class="hl-11">1</span><span class="hl-1">, </span><span class="hl-11">1</span><span class="hl-1">),</span><br/><span class="hl-1"> </span><span class="hl-3">new</span><span class="hl-1"> </span><span class="hl-4">THREE</span><span class="hl-1">.</span><span class="hl-5">MeshBasicMaterial</span><span class="hl-1">({ </span><span class="hl-6">color:</span><span class="hl-1"> </span><span class="hl-11">0xff0000</span><span class="hl-1">, </span><span class="hl-6">wireframe:</span><span class="hl-1"> </span><span class="hl-3">true</span><span class="hl-1"> })</span><br/><span class="hl-1">);</span><br/><br/><span class="hl-8">// 2. 设置裁切盒的位置、旋转和缩放</span><br/><span class="hl-6">clipperMesh</span><span class="hl-1">.</span><span class="hl-6">position</span><span class="hl-1">.</span><span class="hl-5">set</span><span class="hl-1">(</span><span class="hl-11">0</span><span class="hl-1">, </span><span class="hl-11">1.5</span><span class="hl-1">, </span><span class="hl-11">0</span><span class="hl-1">); </span><span class="hl-8">// 抬高位置</span><br/><span class="hl-6">clipperMesh</span><span class="hl-1">.</span><span class="hl-6">scale</span><span class="hl-1">.</span><span class="hl-5">set</span><span class="hl-1">(</span><span class="hl-11">2</span><span class="hl-1">, </span><span class="hl-11">3</span><span class="hl-1">, </span><span class="hl-11">2</span><span class="hl-1">); </span><span class="hl-8">// 设定大小为 2x3x2</span><br/><span class="hl-6">clipperMesh</span><span class="hl-1">.</span><span class="hl-6">rotation</span><span class="hl-1">.</span><span class="hl-6">y</span><span class="hl-1"> = </span><span class="hl-6">Math</span><span class="hl-1">.</span><span class="hl-4">PI</span><span class="hl-1"> / </span><span class="hl-11">4</span><span class="hl-1">; </span><span class="hl-8">// 旋转 45 度</span><br/><br/><span class="hl-8">// 更新矩阵,确保 .matrix 属性是最新的</span><br/><span class="hl-6">clipperMesh</span><span class="hl-1">.</span><span class="hl-5">updateMatrix</span><span class="hl-1">();</span><br/><br/><span class="hl-8">// (可选) 将辅助 Mesh 加入场景以便调试看到范围</span><br/><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">scene</span><span class="hl-1">.</span><span class="hl-5">add</span><span class="hl-1">(</span><span class="hl-6">clipperMesh</span><span class="hl-1">);</span><br/><br/><span class="hl-8">// 3. 应用裁切参数</span><br/><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">model</span><span class="hl-1">.</span><span class="hl-6">clippers</span><span class="hl-1"> = [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-6">clippingBoxMatrix:</span><span class="hl-1"> </span><span class="hl-6">clipperMesh</span><span class="hl-1">.</span><span class="hl-6">matrix</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-8">// floorIndex: 0 // 可选:仅裁切第 0 层</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-8">// 4. 触发重绘</span><br/><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">needsRender</span><span class="hl-1"> = </span><span class="hl-3">true</span><span class="hl-1">;</span> </code><button type="button">Copy</button></pre> <h3 id="动态更新-dynamic-update" class="tsd-anchor-link">动态更新 (Dynamic Update)<a href="#动态更新-dynamic-update" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3> <p>如果需要动态移动裁切盒,需要重新赋值 <code>five.model.clippers</code> 或手动触发更新机制(虽然 setter 会自动触发更新,但如果只修改数组内部对象可能需要重新赋值)。</p> <pre><code class="typescript"><span class="hl-3">function</span><span class="hl-1"> </span><span class="hl-5">updateClipper</span><span class="hl-1">(</span><span class="hl-6">mesh</span><span class="hl-1">: </span><span class="hl-7">THREE</span><span class="hl-1">.</span><span class="hl-7">Mesh</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-6">mesh</span><span class="hl-1">.</span><span class="hl-5">updateMatrix</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-8">// 重新赋值以触发 Five 内部的 setter 和 uniform 更新</span><br/><span class="hl-1"> </span><span class="hl-6">five</span><span class="hl-1">.</span><span class="hl-6">model</span><span class="hl-1">.</span><span class="hl-6">clippers</span><span class="hl-1"> = [{</span><br/><span class="hl-1"> </span><span class="hl-6">clippingBoxMatrix:</span><span class="hl-1"> </span><span class="hl-6">mesh</span><span class="hl-1">.</span><span class="hl-6">matrix</span><br/><span class="hl-1"> }];</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-8">// 在动画循环或交互事件中调用</span><br/><span class="hl-8">// ...</span> </code><button type="button">Copy</button></pre> <h2 id="debugging" class="tsd-anchor-link">Debugging<a href="#debugging" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2> <ul> <li><strong>辅助显示</strong>: 始终建议在开发阶段将用于生成矩阵的 <code>THREE.Mesh</code> (Wireframe 模式) 添加到 <code>five.scene</code> 中,这样可以直观地看到裁切范围是否正确。</li> <li><strong>单位问题</strong>: 确保 <code>BoxGeometry</code> 构造时没有传入参数 (默认 1,1,1) 或者显式传入 <code>(1, 1, 1)</code>。如果使用了 <code>(10, 10, 10)</code> 的几何体,那么 <code>scale</code> 设置为 1 时实际裁切范围是 10,可能会导致误解。建议统一使用单位几何体 + <code>scale</code> 的方式。</li> </ul> <h2 id="common-pitfalls" class="tsd-anchor-link">Common Pitfalls<a href="#common-pitfalls" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2> <ol> <li><strong>矩阵未更新</strong>: 修改了 Mesh 的 position/scale 后忘记调用 <code>updateMatrix()</code>,导致裁切位置没变。</li> <li><strong>几何体尺寸</strong>: 使用了非 <code>1x1x1</code> 的 BoxGeometry,导致裁切范围与 Mesh视觉大小不一致(Shader 始终假定是单位立方体)。</li> <li><strong>楼层索引</strong>: 设置了错误的 <code>floorIndex</code> 导致裁切看起来没生效(因为该区域的点可能属于另一个 floorIndex)。</li> <li><strong>坐标系</strong>: <code>clippingBoxMatrix</code> 是世界坐标系下的变换。如果模型本身有额外的父级变换(通常 Five 的模型直接在 Scene 下,或者是 Identity 变换),通常不需要额外处理。</li> </ol> <h2 id="related" class="tsd-anchor-link">Related<a href="#related" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2> <ul> <li><a href="features_model.html">Model</a>: 模型模块概览。</li> </ul> <hr> <pre><code class="yaml"><span class="hl-0">tags</span><span class="hl-1">: [</span><span class="hl-2">裁切</span><span class="hl-1">, </span><span class="hl-2">剖面</span><span class="hl-1">, </span><span class="hl-2">隐藏部分模型</span><span class="hl-1">, </span><span class="hl-2">开盖</span><span class="hl-1">, </span><span class="hl-2">房屋剖面</span><span class="hl-1">, </span><span class="hl-2">clipper</span><span class="hl-1">, </span><span class="hl-2">model</span><span class="hl-1">, </span><span class="hl-2">cut</span><span class="hl-1">, </span><span class="hl-2">discard</span><span class="hl-1">, </span><span class="hl-2">geometry</span><span class="hl-1">, </span><span class="hl-2">clipping-box</span><span class="hl-1">, </span><span class="hl-2">section-view</span><span class="hl-1">]</span> </code><button type="button">Copy</button></pre> </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#模型裁切-model-clipper"><span>模型裁切 (<wbr/>Model <wbr/>Clipper)</span></a><ul><li><a href="#schema"><span>Schema</span></a></li><li><a href="#concepts"><span>Concepts</span></a></li><li><ul><li><a href="#clipping-box-裁切盒"><span>Clipping <wbr/>Box (裁切盒)</span></a></li><li><a href="#matrix-transformation-矩阵变换"><span>Matrix <wbr/>Transformation (矩阵变换)</span></a></li></ul></li><li><a href="#configuration"><span>Configuration</span></a></li><li><a href="#examples"><span>Examples</span></a></li><li><ul><li><a href="#基础用法-basic-usage"><span>基础用法 (<wbr/>Basic <wbr/>Usage)</span></a></li><li><a href="#动态更新-dynamic-update"><span>动态更新 (<wbr/>Dynamic <wbr/>Update)</span></a></li></ul></li><li><a href="#debugging"><span>Debugging</span></a></li><li><a href="#common-pitfalls"><span>Common <wbr/>Pitfalls</span></a></li><li><a href="#related"><span>Related</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">如视 Five SDK</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>