@realsee/five
Version:
Realsee Renderer SDK
567 lines (531 loc) • 46.5 kB
JavaScript
/**
* @license
* @realsee/five
* Generated: 10/28/2026
* Version: 6.9.3
* Terms:
* Realsee SDK License Agreement
* Update: July 28, 2021
* THIS LICENSE AGREEMENT BETWEEN YOU AND 【BEIKE REALSEE TECHNOLOGY (HK)
* LIMITED】(“Realsee”) FORMS A LEGALLY BINDING CONTRACT BETWEEN YOU AND REALSEE IN
* RELATION TO YOUR USE OF THE SDK. This License Agreement accompanies the Realsee
* Software Development Kit(s) for the software and related explanatory materials
* (the "SDK") and includes any upgrades, modified versions, updates, additions,
* and copies of the SDK licensed to You by Realsee.
* BY DOWNLOADING, INSTALLING, OR OTHERWISE ACCESSING OR USING THE SDK, YOU AGREE
* THAT YOU HAVE READ, UNDERSTOOD, AND AGREE TO BE BOUND BY THIS AGREEMENT. YOU ARE
* AGREEING ON YOUR OWN BEHALF AND/OR ON BEHALF OF YOUR COMPANY OR ORGANIZATION TO
* THE TERMS AND CONDITIONS STATED BELOW.
* This Agreement applies to Your use of the SDK in the country in which You
* legally install it (“Territory”) and is subject to the laws of such Territory
* and further subject to Section 12 below. Different terms, conditions, and
* limitations may apply to the use of the SDK in any additional countries.
* 1. DEFINITIONS.
* “Agreement” means this Realsee SDK License Agreement.
* “Developer”, “You” and “Your” means the person(s) or entity acquiring or using
* the SDK or otherwise exercising rights under the terms of this Agreement.
* “Documentation” means the technical or other specifications or documentation
* that Realsee may provide to You for use in connection with the SDK.
* “Integrated Product” means any software, website, or on-line service developed
* by You based on or using the SDK (collectively, the “Integrated Product”).
* “Intellectual Property” means any patents, patent rights, trademarks, service
* marks, registered and unregistered designs, applications for any of the
* foregoing, copyright, and any other similar protected rights in any country and
* to the extent recognised by any relevant jurisdiction as intellectual property,
* trade secrets, know-how and confidential information. Realsee reserves all
* rights not expressly granted to You.
* “Realsee” means [Beike Realsee Technology (HK) Limited, a company incorporated
* and validly existing under the laws of Hong Kong].
* “SDK” means the Realsee-proprietary Software Development Kits (SDK) provided
* hereunder, includes all development tools (including any compiler and debugger),
* application programming interfaces (“APIs”), libraries, binary utilities, header
* files, Documentation, content, data, code samples, and other materials provided
* to You in connection with this Agreement, whether delivered through a download,
* or any other media or form, and is licensed, not sold, to You by Realsee for use
* only under the terms of this Agreement. The terms of this Agreement will govern
* any updates provided by Realsee that replace and/or supplement the original SDK
* delivered to You, unless such update is accompanied by a separate license, in
* which case the terms of such license will govern.
* 2. LICENSED USES AND RESTRICTIONS.
* 2.1 Subject to the restrictions contained in this Section 2, Realsee grants to
* You during the term, a limited, non-exclusive, revocable, non-sublicensable,
* non-transferable license to install and use the SDK within the Territory only
* for the purpose of internal development.
* 2.2 Restrictions. You acknowledge and agree that, You shall not, and shall
* ensure that Your affiliates, employees, agents, representatives, officers,
* representatives, and subcontractors do not (directly or indirectly):
* 2.2.1 decompile, reverse engineer, disassemble or attempt to derive the source
* code of, those components of the SDK provided in object code form, or any part
* thereof;
* 2.2.2 remove, alter, or obscure any copyright notice or other proprietary rights
* notice on any part of the SDK;
* 2.2.3 sell, assign, pledge, rent, lease, lend, upload to or host on any website
* or server for use by any third party except You, redistribute, or sublicense the
* SDK (or any part thereof), or operate the SDK (or any part thereof) in the
* capacity of a service bureau or other hosted services provider, in whole or in
* part, nor may You enable others to do so;
* 2.2.4 or alter, modify, customize or improve the SDK, or any part thereof;
* 2.2.5 use the SDK (or any part thereof) for any illegal purpose, in any manner
* that is inconsistent with the terms of this Agreement, or to engage in any
* illegal activity;
* 2.2.6 use the SDK (or any part thereof) in any manner that may damage the
* operation of Realsee’s products or services; or
* 2.2.7 use the SDK or any information contained therein or otherwise provided by
* Realsee for the purpose of developing, or having developed, any product
* competitive with any Realsee product or service, as determined by Realsee in its
* sole discretion;
* 2.2.8 include any portion of the SDK in Your Developer products.
* 2.3 Realsee has the right to impose reasonable conditions such as a reasonable
* fee for use of the SDK in Integrated Product in the future.
* 2.4 You may make a limited number of copies of the SDK to be used by Your
* employees or consultants as provided herein, and not for general business
* purposes, and such employees or consultants shall be subject to the obligations
* and restrictions in this Agreement.
* 2.5 All licenses not expressly granted in this Agreement are reserved and no
* other licenses, immunity, or rights, express or implied, are granted by Realsee,
* by implication, estoppel, or otherwise.
* 3. CONFIDENTIALITY.
* The SDK and all source code, Documentation, specifications, engineering details,
* and related information pertaining to the SDK, whether in oral, written,
* graphic, or electronic form, are and shall remain the confidential and
* proprietary information of Realsee or its licensors (collectively, the
* “Confidential Information”). You shall (i) disclose Confidential Information to
* only those directors and employees (collectively, “Affiliates”) whose duties
* justify their need to know such information and who have been clearly informed
* of their obligation to maintain the confidential, proprietary, and/or trade
* secret status of such Confidential Information; and (ii) use Confidential
* Information solely in accordance with the license granted hereunder. In any
* event, You and Your Affiliates shall treat Confidential Information as strictly
* confidential and shall use the same care to prevent disclosure of such
* information as You use with respect to Your own similar confidential and/or
* proprietary information, which shall not be less than the care a reasonable
* person would use under similar circumstances. All Confidential Information, and
* any copies thereof, shall be returned promptly to Realsee upon request. You
* shall ensure that Your Affiliates comply with the provisions of this Section 3,
* and You shall be liable for any breach of this Section 3 resulting from the act
* or omission of any of Your Affiliates. You shall not disclose Confidential
* Information to any third party, including, without limitation, any of Your
* subcontractors.
* 4. PROPRIETARY RIGHTS.
* 4.1 As between You and Realsee, Realsee and/or its licensors retain ownership of
* all right, title, and interest in, to, and under the SDK, including, without
* limitation, all patents, copyrights, trade secrets, trademarks and other
* intellectual property and other proprietary rights therein, and reserve all
* rights not expressly granted to You.
* 4.2 The items contained in the SDK are the intellectual property of Realsee and
* its licensors and are protected by PRC copyright and patent law, international
* treaty provisions and applicable laws of the country in which it is being used.
* You agree to protect all copyright and other ownership interests of Realsee
* and/or its licensors in all items in the SDK supplied under this License
* Agreement. You agree that all copies of the items in the SDK, reproduced for any
* reason by You, contain the same copyright notices, and other proprietary notices
* as appropriate, as appear on or in the original items delivered by Realsee in
* the SDK. Realsee and/or its licensors retain title and ownership of the items in
* the SDK, the media on which it is loaded, and all subsequent copies, regardless
* of the form or media in or on which the original and other copies may exist.
* Except as stated above, this Agreement does not grant You any rights to patents,
* copyrights, trade secrets, trademarks or any other rights in respect to the
* items in the SDK.
* 5. TERM AND TERMINATION.
* 5.1 This Agreement is effective until terminated. Realsee has the right to
* terminate this Agreement immediately, without judicial intervention, if You fail
* to comply with any term herein. Upon any such termination You must remove all
* full and partial copies of the items in the SDK from Your computer and
* discontinue the use of the items in the SDK.
* 5.2 Realsee may at any time, terminate the Agreement with You if: (A) You have
* breached any provision of the Agreement; or (B) Realsee is required to do so by
* law; or (C) Realsee decides to no longer provide the SDK or certain parts of the
* SDK to users in the country in which You are resident or from which You use the
* service, or the provision of the SDK or certain SDK services to You by Realsee
* is, in Realsee's sole discretion, no longer legally or commercially viable.
* 5.3 When the Agreement comes to an end, all of the legal rights, obligations and
* liabilities that You and Realsee have benefited from, been subject to (or which
* have accrued over time whilst the Agreement has been in force) or which are
* expressed to continue indefinitely, shall be unaffected by this cessation, and
* the provisions of Section 3, 4, 6, 7 and 8 shall continue to apply to such
* rights, obligations and liabilities indefinitely.
* 6. DISCLAIMER OF WARRANTY.
* YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT, TO THE EXTENT PERMITTED BY APPLICABLE
* LAW, USE OF THE SDK (OR ANY PART THEREOF) IS AT YOUR SOLE RISK AND THAT THE
* ENTIRE RISK AS TO SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS
* WITH YOU. REALSEE LICENSES THE SDK TO YOU ONLY ON AN "AS-IS" BASIS. REALSEE
* MAKES NO REPRESENTATION WITH RESPECT TO THE ADEQUACY OF ANY ITEMS IN THE SDK,
* WHETHER OR NOT USED BY YOU IN THE DEVELOPMENT OF INTEGRATED PRODUCT, FOR ANY
* PARTICULAR PURPOSE OR WITH RESPECT TO THEIR ADEQUACY TO PRODUCE ANY PARTICULAR
* RESULT. REALSEE AND ITS LICENSORS SHALL NOT BE LIABLE FOR LOSS OR DAMAGE ARISING
* OUT OF THIS AGREEMENT OR FROM THE DISTRIBUTION OR USE OF INTEGRATED PRODUCT
* CONTAINING PORTIONS OF THE SDK. REALSEE AND ITS LICENSORS DISCLAIM ALL
* WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED
* CONDITIONS OR WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* OR NONINFRINGEMENT OF ANY THIRD PARTY RIGHT IN RESPECT OF THE ITEMS IN THE SDK
* OR ANY SERVICES RELATED TO THE SDK.
* REALSEE IS UNDER NO OBLIGATION TO PROVIDE ANY SUPPORT UNDER THIS LICENSE
* AGREEMENT, INCLUDING UPGRADES OR FUTURE VERSIONS OF THE SDK OR ANY PORTIONS
* THEREOF, TO YOU, END USER OR TO ANY OTHER PARTY.
* 7. LIMITATION OF LIABILITY.
* TO THE EXTENT NOT PROHIBITED BY APPLICABLE LAW, IN NO EVENT WILL REALSEE OR ITS
* LICENSORS BE LIABLE FOR ANY DIRECT, INCIDENTAL, SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES, INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE,
* LOSS OF BUSINESS, REVENUE, OR PROFITS, LOSS OF OPPORTUNITY (WHETHER DIRECT OR
* INDIRECT), CORRUPTION OR LOSS OF DATA, LOSS OF REPUTATION OR SAVINGS, DOWNTIME,
* OR DAMAGE TO, LOSS OF OR REPLACEMENT OF DATA OR TRANSACTIONS, COST OF
* PROCUREMENT OF SUBSTITUTE SERVICES, BUSINESS INTERRUPTION, OR ANY OTHER
* COMMERCIAL DAMAGES OR LOSSES, ARISING OUT OF OR RELATED TO YOUR USE OR INABILITY
* TO USE THE SDK (OR ANY PART THEREOF), ANY INTEGRATED PRODUCT, OR ANY THIRD PARTY
* SOFTWARE, APPLICATIONS, OR SERVICES IN CONJUNCTION WITH THE SDK (OR ANY PART
* THEREOF), HOWEVER CAUSED, REGARDLESS OF THE THEORY OF LIABILITY (CONTRACT, TORT,
* OR OTHERWISE) AND EVEN IF REALSEE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGES. IN NO EVENT WILL REALSEE’S TOTAL LIABILITY TO YOU FOR ALL DAMAGES
* EXCEED ONE HUNDRED DOLLARS ($100.00). THE FOREGOING LIMITATIONS WILL APPLY EVEN
* IF THE ABOVE STATED REMEDY FAILS OF ITS ESSENTIAL PURPOSE. THE LIMITATIONS
* CONTAINED IN SECTIONS 6 AND THIS SECTION 7 ARE A FUNDAMENTAL PART OF THE BASIS
* OF REALSEE’S BARGAIN HEREUNDER, AND REALSEE WOULD NOT ENTER INTO THIS AGREEMENT
* OR PROVIDE YOU WITH ACCESS TO THE SDK ABSENT SUCH LIMITATIONS.
* 8. INDEMNIFICATION.
* To the extent permitted by applicable law, You agree to indemnify, defend and
* hold harmless Realsee, its affiliates and each of their directors, officers,
* employees, independent contractors, and agents (each a “Realsee Indemnified
* Party”) from any and all claims, losses, liabilities, damages, expenses, and
* costs (including without limitation attorneys’ fees and court costs) incurred by
* a Realsee Indemnified Party as a result of: (i) Your non-compliance with any
* terms of this Agreement; (ii) Your use of the SDK (or any part thereof); or
* (iii) Your use of any Integrated Product, including any claim that Integrated
* Product infringes the copyright, trademark, trade secret or other intellectual
* property right of a third party.
* 9. ACKNOWLEDGEMENTS.
* Portions of the SDK may utilize or include third party software and other
* copyrighted material. Acknowledgments, licensing terms, and disclaimers for such
* material are contained in Documentation for the SDK or may otherwise accompany
* such material, and Your use of such materials governed by their respective
* terms. In the event of conflict between the terms of this Agreement and an
* applicable open source or third party agreement, the open source or third party
* agreement will control solely with respect to the open source software or third
* party software. Moreover, You shall not subject any items (including not limited
* to source code, object code, and any software) included in the SDK to any open
* source license.
* 10. NON-BLOCKING OF REALSEE DEVELOPMENT.
* You acknowledge that Realsee is currently developing or may develop technologies
* and products in the future that have or may have design and/or functionality
* similar to Integrated Product that You may develop based on Your license herein.
* Nothing in this Agreement shall impair, limit or curtail Realsee's right to
* continue with its development, maintenance and/or distribution of Realsee's
* technology or products.
* 11. GENERAL.
* 11.1 Export Control. You may not use or otherwise export or re-export the SDK
* (or any part thereof) except as authorized by United States law and the laws of
* the jurisdiction(s) in which the SDK (or any part thereof) was obtained. In
* particular, but without limitation, the SDK may not be exported or re-exported
* (i) into any U.S. embargoed countries or (ii) to anyone on the U.S. Treasury
* Department's list of Specially Designated Nationals or the U.S. Department of
* Commerce Denied Person's List or Entity List. By using the SDK (or any part
* thereof), You represent and warrant that You are not located in any such country
* or on any such list.
* 11.2 Governing Law. This Agreement and the rights of the parties hereunder shall
* be governed by and construed in accordance with the laws of People’s Republic of
* China (for purpose of this Agreement, excluding Hong Kong, Taiwan, and Macau),
* without reference to its conflict of laws principles. Any dispute, controversy
* or claim arising from or in connection with this Agreement, or the breach,
* termination or invalidity thereof, shall be submitted to China International
* Economic and Trade Arbitration Commission (“CIETAC”) for arbitration in Beijing
* which shall be conducted in accordance with the CIETAC's arbitration rules in
* effect at the time of applying for arbitration. The arbitral award is final and
* binding upon both parties.
* 11.3 Severability. If any provision of this Agreement is held by a court of
* competent jurisdiction to be unenforceable for any reason, the remaining
* provisions hereof will be unaffected and remain in full force and effect.
* 11.4. Modifications. Realsee reserves the right, from time to time, with or
* without notice to You, to make revisions to this Agreement in our sole and
* absolute discretion. The most current version of this Agreement will supersede
* all previous versions and shall be made available on the website where the SDK
* is made available, or by such other means as Realsee may determine in its
* discretion. Any modified versions of this Agreement hereto shall take effect
* from the time that it is made available. You shall be responsible for regularly
* checking for notice of any such modifications. You agree that Your continued use
* of the SDK constitutes Your agreement to the modified Agreement.
* 11.5 Relationship of the Parties. This Agreement will not be construed as
* creating an agency, partnership, joint venture, fiduciary duty, or any other
* form of legal association between You and Realsee, and You will not represent to
* the contrary, whether expressly, by implication, appearance, or otherwise.
* 11.6 Entire Agreement; Governing Language. This Agreement constitutes the entire
* agreement between You and Realsee with respect to the use of the SDK licensed
* hereunder and supersedes all prior understandings regarding such subject matter.
* No amendment to or modification of this Agreement will be binding unless in
* writing and signed by Realsee. You and Realsee hereto confirm that this
* Agreement and all related documents shall be drafted in English.
*/(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`@realsee/five`),require(`three`)):typeof define==`function`&&define.amd?define([`exports`,`@realsee/five`,`three`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.FiveSDK_ShaderLib={},e.FiveSDK,e.THREE))})(this,function(e,t,n){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var r=Object.create,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,l=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var s=o(t),l=0,u=s.length,d;l<u;l++)d=s[l],!c.call(e,d)&&d!==n&&i(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=a(t,d))||r.enumerable});return e};n=((e,t,n)=>(n=e==null?{}:r(s(e)),l(t||!e||!e.__esModule?i(n,`default`,{value:e,enumerable:!0}):n,e)))(n,1);var u={type:[`pointcloud`],fragment:{mainBefore:`
#if defined(USE_PLANE_DISTANCE)
struct Plane {
vec3 normal;
float constant;
};
uniform Plane evennessPlanes[6];
uniform vec3 evennessPlaneNormal;
uniform float evennessPlaneConstant;
uniform float evennessPlaneDepth;
#endif
`,mainStart:``,mainEnd:`
#if defined(USE_PLANE_DISTANCE)
bool inside = true;
for (int i = 0; i < 6; i++) {
if (dot(evennessPlanes[i].normal, vWorldPosition.xyz) + evennessPlanes[i].constant > 0.0) {
inside = false;
break;
}
}
if (inside) {
float distanceToPlane = (dot(evennessPlaneNormal, vWorldPosition.xyz) + evennessPlaneConstant) / length(evennessPlaneNormal);
float progress = distanceToPlane * (1.0 / evennessPlaneDepth);
if(distanceToPlane > 0.0) {
gl_FragColor = mix(vec4(0.0,1.0,0.0,1.0), vec4(1.0,0.0,0.0,1.0), progress);
}else{
gl_FragColor = mix(vec4(0.0,1.0,0.0,1.0), vec4(0.0,0.0,1.0,1.0), progress);
}
}
#endif
`},uniforms:{evennessPlaneNormal:new n.Uniform(new n.Vector3),evennessPlaneConstant:new n.Uniform(0),evennessPlanes:new n.Uniform([]),evennessPlaneDepth:new n.Uniform(0)},defines:{USE_PLANE_DISTANCE:!1}},d=class extends t.CustomShader{constructor(){super(u),Object.defineProperties(this,{evennessPlane:{get(){return{depth:this.uniforms.evennessPlaneDepth.value,points:this.uniforms.evennessPoints.value}},set(e){let{points:t,depth:r}=e,i=!1;if(t.length!==0&&t.length%4==0){i=!0;let e=t[0],a=t[1],o=t[2],s=t[3],c=new n.Vector3().subVectors(a,e),l=new n.Vector3().subVectors(o,e),u=new n.Vector3().crossVectors(c,l).normalize(),d=-u.dot(e),f=r,p=e.clone().add(u.clone().negate().multiplyScalar(f)),m=e.clone().add(u.clone().multiplyScalar(f)),h=a.clone().add(u.clone().negate().multiplyScalar(f)),g=a.clone().add(u.clone().multiplyScalar(f)),_=o.clone().add(u.clone().negate().multiplyScalar(f)),v=o.clone().add(u.clone().multiplyScalar(f)),y=s.clone().add(u.clone().negate().multiplyScalar(f)),b=s.clone().add(u.clone().multiplyScalar(f)),x=new n.Plane().setFromCoplanarPoints(m,g,v),S=new n.Plane().setFromCoplanarPoints(_,h,p),C=new n.Plane().setFromCoplanarPoints(g,m,p),w=new n.Plane().setFromCoplanarPoints(y,b,v),T=new n.Plane().setFromCoplanarPoints(v,g,h),E=new n.Plane().setFromCoplanarPoints(p,m,b);this.uniforms.evennessPlanes.value=[{normal:x.normal,constant:x.constant},{normal:S.normal,constant:S.constant},{normal:C.normal,constant:C.constant},{normal:w.normal,constant:w.constant},{normal:T.normal,constant:T.constant},{normal:E.normal,constant:E.constant}],this.uniforms.evennessPlaneDepth.value=r,this.uniforms.evennessPlaneNormal.value=u,this.uniforms.evennessPlaneConstant.value=d}this.defines.USE_PLANE_DISTANCE=i,this.needsUpdate=!0}}}),this.evennessPlane={depth:0,points:[]}}},f=`
#if NUM_SWEEP_OBJECTS > 0
uniform float sweepProgress;
uniform float sweepRange;
uniform float interval; // 直接定义间隔距离
uniform float threshold; // 绝对线宽值
struct SWEEP_OBJECT {
vec3 min;
vec3 max;
};
uniform SWEEP_OBJECT sweepBoxs[NUM_SWEEP_OBJECTS];
#endif
`,p=`
#if NUM_SWEEP_OBJECTS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_SWEEP_OBJECTS; i ++ ) {
vec3 minPos = sweepBoxs[ i ].min;
vec3 maxPos = sweepBoxs[ i ].max;
// 计算包围盒中心点
vec3 center = (minPos + maxPos) * 0.5;
// 计算包围盒半尺寸
vec3 halfSize = (maxPos - minPos) * 0.5;
// 计算顶点到中心的相对距离(标准化到0-1范围)
vec3 relativePos = (vWorldPosition.xyz - center) / halfSize;
float maxDistance = length(relativePos) / sqrt(3.0);
// 计算扩散不透明度(基于进度和距离)+-sweepRange之间的才有opactiy,其他的为0
float distanceFromSweep = abs(maxDistance - sweepProgress);
// 指数衰减:exp(-k*x) 形式
float k = 5.0 / sweepRange; // 控制衰减速度
float sweepOpacity = exp(-k * distanceFromSweep) * 0.8;
if(vWorldPosition.x > minPos.x && vWorldPosition.x < maxPos.x &&
vWorldPosition.y > minPos.y && vWorldPosition.y < maxPos.y &&
vWorldPosition.z > minPos.z && vWorldPosition.z < maxPos.z) {
if(maxDistance < sweepProgress + sweepRange && maxDistance > sweepProgress - sweepRange) {
// 混合颜色
gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(1.0,1.0,1.0), sweepOpacity);
}
}
}
#pragma unroll_loop_end
#endif
`,m=``,h=class extends t.CustomShader{constructor(){super({type:[`basic`,`phong`,`pointcloud`],fragment:{mainBefore:f,mainStart:m,mainEnd:p},uniforms:{sweepProgress:new n.Uniform(0),sweepRange:new n.Uniform(0),sweepBoxs:new n.Uniform([]),interval:new n.Uniform(.04),threshold:new n.Uniform(.002)},defines:{NUM_SWEEP_OBJECTS:0}}),Object.defineProperties(this,{sweepBoxs:{get(){return this.uniforms.sweepBoxs.value},set(e){let t=e.length;t>0&&(this.defines.NUM_SWEEP_OBJECTS=t,this.needsUpdate=!0,this.uniforms.sweepBoxs.value=e)}}}),this.sweepBoxs=[]}onBeforeCompile(e,t){let n=String(this.sweepBoxs.length);e.vertexShader=e.vertexShader.replace(/NUM_SWEEP_OBJECTS/g,n),e.fragmentShader=e.fragmentShader.replace(/NUM_SWEEP_OBJECTS/g,n)}},g=`
uniform float pointCloudExpand_progress;
vec4 pointCloudExpand_permute(vec4 x) { return mod(((x * 34.0) + 1.0) * x, 289.0); }
vec4 pointCloudExpand_taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
float pointCloudExpand_gln_simplex(vec3 v) {
const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
// First corner
vec3 i = floor(v + dot(v, C.yyy));
vec3 x0 = v - i + dot(i, C.xxx);
// Other corners
vec3 g = step(x0.yzx, x0.xyz);
vec3 l = 1.0 - g;
vec3 i1 = min(g.xyz, l.zxy);
vec3 i2 = max(g.xyz, l.zxy);
// x0 = x0 - 0. + 0.0 * C
vec3 x1 = x0 - i1 + 1.0 * C.xxx;
vec3 x2 = x0 - i2 + 2.0 * C.xxx;
vec3 x3 = x0 - 1. + 3.0 * C.xxx;
// Permutations
i = mod(i, 289.0);
vec4 p = pointCloudExpand_permute(pointCloudExpand_permute(pointCloudExpand_permute(i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y +
vec4(0.0, i1.y, i2.y, 1.0)) +
i.x + vec4(0.0, i1.x, i2.x, 1.0));
// Gradients
// ( N*N points uniformly over a square, mapped onto an octahedron.)
float n_ = 1.0 / 7.0; // N=7
vec3 ns = n_ * D.wyz - D.xzx;
vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,N*N)
vec4 x_ = floor(j * ns.z);
vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)
vec4 x = x_ * ns.x + ns.yyyy;
vec4 y = y_ * ns.x + ns.yyyy;
vec4 h = 1.0 - abs(x) - abs(y);
vec4 b0 = vec4(x.xy, y.xy);
vec4 b1 = vec4(x.zw, y.zw);
vec4 s0 = floor(b0) * 2.0 + 1.0;
vec4 s1 = floor(b1) * 2.0 + 1.0;
vec4 sh = -step(h, vec4(0.0));
vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
vec3 p0 = vec3(a0.xy, h.x);
vec3 p1 = vec3(a0.zw, h.y);
vec3 p2 = vec3(a1.xy, h.z);
vec3 p3 = vec3(a1.zw, h.w);
// Normalise gradients
vec4 norm =
pointCloudExpand_taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
p0 *= norm.x;
p1 *= norm.y;
p2 *= norm.z;
p3 *= norm.w;
// Mix final noise value
vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
m = m * m;
return 42.0 * dot(m * m, vec4(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
}
`,_=`
float pointCloudExpand_sizeScale = 1.0;
float pointCloudExpand_sizeBasis = 0.0;
vec4 pointCloudExpand_basis = vec4((modelBoundingMax + modelBoundingMin) / 2.0, 1.0);
float pointCloudExpand_boundingRadius = length(modelBoundingMax - modelBoundingMin) / 2.0;
float pointCloudExpand_p = length(vWorldPosition - pointCloudExpand_basis) / pointCloudExpand_boundingRadius;
float pointCloudExpand_progress = smoothstep(pointCloudExpand_p, pointCloudExpand_p - 0.03, 1.0 - pointCloudExpand_progress);
float pointCloudExpand_noise = pointCloudExpand_gln_simplex(vWorldPosition.xyz * 10.0);
pointCloudExpand_progress = step(abs(pointCloudExpand_noise), pointCloudExpand_progress);
pointCloudExpand_sizeScale = mix(pointCloudExpand_sizeScale, 0.0, pointCloudExpand_progress);
float pointCloudExpand_progress2 = step(pointCloudExpand_progress, 1.0 - pointCloudExpand_p);
pointCloudExpand_sizeBasis = mix(0.1 * step(abs(pointCloudExpand_noise), 0.5 / pointCloudExpand_boundingRadius), pointCloudExpand_sizeBasis, pointCloudExpand_progress2);
gl_PointSize = gl_PointSize * pointCloudExpand_sizeScale + pointCloudExpand_sizeBasis;
vPointSize = gl_PointSize;
`,v=class extends t.CustomShader{constructor(){super({type:[`pointcloud`],vertex:{mainBefore:g,mainEnd:_},uniforms:{pointCloudExpand_progress:new n.Uniform(0)}})}get progress(){return this.uniforms.pointCloudExpand_progress.value}set progress(e){this.uniforms.pointCloudExpand_progress.value=e}};function y(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||(n=Promise))(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})}var b="(function(){function e(e){onmessage=t=>{Promise.resolve(t.data).then(t=>e(t)).then(({output:e,transfer:t})=>postMessage(e,t)).catch(e=>postMessage({$$error:e}))}}function t(e,t,n){let r=new OffscreenCanvas(t,n).getContext(`2d`);if(!r)throw Error(`Failed to get canvas context`);r.clearRect(0,0,t,n),r.fillStyle=`rgba(0,0,0,1.0)`,r.beginPath();let i=e[0][0],a=e[0][0],o=e[0][1],s=e[0][1];e.forEach(e=>{let t=e[0],n=e[1];i=Math.min(i,t),a=Math.max(a,t),o=Math.min(o,n),s=Math.max(s,n)});let c=a-i,l=s-o,u=c>=l?t/c:t/l;return e.map(e=>[e[0]-i,e[1]-o]).map(e=>[e[0]*u,e[1]*u]).forEach((e,t)=>{let[n,i]=e;t===0?r.moveTo(n,i):r.lineTo(n,i)}),r.closePath(),r.fill(),r.getImageData(0,0,t,n)}function n(e,n,r){let i=new ImageData(n,r),a=e.map(e=>t(e.polygon,e.width,e.height));for(let e=0;e<n;e++)for(let t=0;t<r;t++){let r=0,o=0,s=0;for(let i=0;i<a.length;i++)if(a[i].data[(e+t*n)*4+3]===255){let e=i%8,t=Math.floor(i/8);t===0?r|=1<<e:t===1?o|=1<<e:t===2&&(s|=1<<e)}let c=(e+t*n)*4;i.data[c]=r,i.data[c+1]=o,i.data[c+2]=s,i.data[c+3]=255}return i}e(e=>Promise.resolve(e).then(({canvasDataList:e,width:t,height:r})=>{let i=n(e,t,r);return{output:{imageData:i},transfer:[i.data.buffer]}}))})();",x=typeof self<`u`&&self.Blob&&new Blob([`(self.URL || self.webkitURL).revokeObjectURL(self.location.href);`,b],{type:`text/javascript;charset=utf-8`});function S(e){let t;try{if(t=x&&(self.URL||self.webkitURL).createObjectURL(x),!t)throw``;let n=new Worker(t,{name:e==null?void 0:e.name});return n.addEventListener(`error`,()=>{(self.URL||self.webkitURL).revokeObjectURL(t)}),n}catch(t){return new Worker(`data:text/javascript;charset=utf-8,`+encodeURIComponent(b),{name:e==null?void 0:e.name})}}var C=class{constructor(e,t){this.disposed=!1,this.pool=t,this.workerCreator=e,this.queue=[],this.workers=[],this.workerResolvers=[],this.workerStatus=0}setWorkerCreator(e){this.workerCreator=e}initWorker(e){if(!this.workerCreator)throw Error(`workerCreator is not defined`);if(!this.workers[e]){let t=this.workerCreator(e);t.addEventListener(`message`,this.onMessage.bind(this,e)),this.workers[e]=t}}getIdleWorker(){for(let e=0;e<this.pool;e++)if(!(this.workerStatus&1<<e))return e;return-1}onMessage(e,t){let n=this.workerResolvers[e];if(t.data&&`$$error`in t.data?n==null||n.reject(t.data.$$error):n==null||n.resolve(t.data),this.workerResolvers[e]=void 0,this.queue.length){let{resolve:t,reject:n,input:r,transfer:i}=this.queue.shift();this.workerResolvers[e]={resolve:t,reject:n},this.workers[e].postMessage(r,i)}else this.workerStatus^=1<<e}postMessage(e,t=[]){return new Promise((n,r)=>{if(this.disposed){r(Error(`disposed`));return}let i=this.getIdleWorker();i===-1?this.queue.push({resolve:n,reject:r,input:e,transfer:t}):(this.initWorker(i),this.workerStatus|=1<<i,this.workerResolvers[i]={resolve:n,reject:r},this.workers[i].postMessage(e,t))})}dispose(){this.disposed=!0,this.workers.forEach(e=>{e.terminate()}),this.workers.length=0,this.workerResolvers.forEach(e=>{e==null||e.reject(Error(`disposed`))}),this.workerResolvers.length=0,this.queue.forEach(e=>{e.reject(Error(`disposed`))}),this.queue.length=0,this.workerStatus=0}};function w(e){if(e.length<3)throw Error(`At least 3 points are required to compute alignment matrix`);let t=e[0],r=e[1],i=e[2],a=new n.Vector3().subVectors(r,t),o=new n.Vector3().subVectors(i,t),s=new n.Vector3().crossVectors(a,o);if(s.lengthSq()<1e-4)for(let r=3;r<e.length&&(i=e[r],o=new n.Vector3().subVectors(i,t),s=new n.Vector3().crossVectors(a,o),!(s.lengthSq()>=1e-4));r++);if(s.lengthSq()<1e-4)throw Error(`All points are collinear, cannot compute normal`);s.normalize();let c=new n.Vector3;e.forEach(e=>c.add(e)),c.divideScalar(e.length);let l=new n.Vector3(0,1,0),u=new n.Quaternion,d=s.dot(l);if(!(Math.abs(d-1)<1e-4))if(Math.abs(d+1)<1e-4){let e=new n.Vector3(1,0,0);u.setFromAxisAngle(e,Math.PI)}else{let e=new n.Vector3().crossVectors(s,l).normalize(),t=Math.acos(d);u.setFromAxisAngle(e,t)}let f=new n.Matrix4().makeTranslation(-c.x,-c.y,-c.z),p=new n.Matrix4().makeRotationFromQuaternion(u),m=new n.Matrix4;m.multiplyMatrices(p,f);let h=e.map(e=>{let t=e.clone().applyMatrix4(m);return[t.x,t.z]});if(h.length>0){let e=h[0],t=h[h.length-1];(e[0]!==t[0]||e[1]!==t[1])&&h.push([e[0],e[1]])}return{transformMatrix:m,points2D:h}}var T=`
uniform sampler2D polygonTexture;
struct PolygonClipper {
mat4 polygonTransformInverse;
float polygonHeight;
vec2 minPos;
float polygonScale;
bool cutOutSide;
float floorIndex;
};
#if NUM_POLYGON_CLIPPER > 0
uniform PolygonClipper polygonClippers[NUM_POLYGON_CLIPPER];
#endif
`,E=`
for(int i = 0; i < NUM_POLYGON_CLIPPER; i++){
PolygonClipper polygonClipper = polygonClippers[i];
mat4 polygonTransformInverse = polygonClipper.polygonTransformInverse;
float polygonHeight = polygonClipper.polygonHeight;
vec2 minPos = polygonClipper.minPos;
float polygonScale = polygonClipper.polygonScale;
bool cutOutSide = polygonClipper.cutOutSide;
float clipperFloorIndex = polygonClipper.floorIndex;
// 楼层判断:如果 floorIndex < 0,对所有楼层生效;否则只对特定楼层生效
bool isFloorMatch = clipperFloorIndex < 0.0 || abs(floorIndex - clipperFloorIndex) < 1.0;
if (!isFloorMatch) {
continue;
}
vec4 worldPosition = vFinalPosition;
vec4 positionInPolygonSpace = polygonTransformInverse * worldPosition;
vec2 normalizedPos = vec2(
(positionInPolygonSpace.x - minPos.x) / polygonScale,
(positionInPolygonSpace.z - minPos.y) / polygonScale
);
if(cutOutSide) {
if (normalizedPos.x < 0.0 || normalizedPos.x > 1.0 || normalizedPos.y < 0.0 || normalizedPos.y > 1.0 || positionInPolygonSpace.y < 0.0 || positionInPolygonSpace.y > polygonHeight) {
discard;
}else{
vec2 uv = vec2(normalizedPos.x, 1.0 - normalizedPos.y);
vec4 color = texture2D(polygonTexture, uv);
int channel = i / 8;
float bit = (float(i) / 8.0 - floor(float(i) / 8.0)) * 8.0;
float power = pow(2.0, bit);
float channelValue;
if(i < 8) { // 使用r通道
channelValue = color.r * 255.0;
} else if(i < 16) { // 使用g通道
channelValue = color.g * 255.0;
} else if(i < 24) { // 使用b通道
channelValue = color.b * 255.0;
} else { // 使用a通道
channelValue = color.a * 255.0;
}
float masked = floor(channelValue / power + 0.001);
if(mod(masked, 2.0) < 0.5) {
discard;
}
}
}else{
if (normalizedPos.x > 0.0 && normalizedPos.x < 1.0 && normalizedPos.y > 0.0 && normalizedPos.y < 1.0 && positionInPolygonSpace.y > 0.0 && positionInPolygonSpace.y < polygonHeight) {
vec2 uv = vec2(normalizedPos.x, 1.0 - normalizedPos.y);
vec4 color = texture2D(polygonTexture, uv);
int channel = i / 8;
float bit = (float(i) / 8.0 - floor(float(i) / 8.0)) * 8.0;
float power = pow(2.0, bit);
float channelValue;
if(i < 8) { // 使用r通道
channelValue = color.r * 255.0;
} else if(i < 16) { // 使用g通道
channelValue = color.g * 255.0;
} else if(i < 24) { // 使用b通道
channelValue = color.b * 255.0;
} else { // 使用a通道
channelValue = color.a * 255.0;
}
float masked = floor(channelValue / power + 0.001);
if(mod(masked, 2.0) > 0.0) {
discard;
}
}
}
}
`,D=class{constructor(){this.canvasCache=new Map,this.canvas=document.createElement(`canvas`),this.canvas.width=512,this.canvas.height=512,this.polygonTexture=new n.CanvasTexture(this.canvas),this.polygonCount=0}setSize(e){this.canvas.width=e,this.canvas.height=e}generatePolygonCanvas(e){let t=JSON.stringify(e);if(this.canvasCache.has(t))return this.canvasCache.get(t);{let n=document.createElement(`canvas`);n.width=this.canvas.width,n.height=this.canvas.height;let r=n.getContext(`2d`);if(!r)throw Error(`Failed to get canvas context`);if(this.polygonCount>=24)throw Error(`polygon count exceed 24, please clear the canvas`);r.clearRect(0,0,this.canvas.width,this.canvas.height),r.fillStyle=`rgba(0,0,0,1.0)`,r.beginPath();let i=e[0][0],a=e[0][0],o=e[0][1],s=e[0][1];e.forEach(e=>{let t=e[0],n=e[1];i=Math.min(i,t),a=Math.max(a,t),o=Math.min(o,n),s=Math.max(s,n)});let c=a-i,l=s-o,u=this.canvas.width,d=c>=l?u/c:u/l;return e.map(e=>[e[0]-i,e[1]-o]).map(e=>[e[0]*d,e[1]*d]).forEach((e,t)=>{let[n,i]=e;t===0?r.moveTo(n,i):r.lineTo(n,i)}),r.closePath(),r.fill(),this.polygonCount++,this.canvasCache.set(t,n),n}}static generatePolygonGeometry(e,t){let r=new n.BufferGeometry,i=e.slice(0,-1),a=i.map(e=>[e[0],0,e[1]]),o=i.map(e=>[e[0],t,e[1]]),s=[...a,...o],c=i.length,l=[];for(let e=1;e<c-1;e++)l.push(0,e,e+1);for(let e=1;e<c-1;e++)l.push(c,c+e,c+e+1);for(let e=0;e<c;e++){let t=(e+1)%c;l.push(e,t,c+e),l.push(t,c+t,c+e)}return r.setAttribute(`position`,new n.Float32BufferAttribute(s.flat(),3)),r.setIndex(l),r.computeVertexNormals(),r}generatePolygonTexture(e){let t=this.canvas.getContext(`2d`,{willReadFrequently:!0});if(!t)throw Error(`Failed to get canvas context`);let r=t.createImageData(this.canvas.width,this.canvas.height);for(let t=0;t<this.canvas.width;t++)for(let n=0;n<this.canvas.height;n++){let i=0,a=0,o=0;for(let r=0;r<e.length;r++){let s=e[r].getContext(`2d`,{willReadFrequently:!0});if(!s)throw Error(`Failed to get canvas context`);if(s.getImageData(t,n,1,1).data[3]===255){let e=r%8,t=Math.floor(r/8);t===0?i|=1<<e:t===1?a|=1<<e:t===2&&(o|=1<<e)}}let s=(t+n*this.canvas.width)*4;r.data[s]=i,r.data[s+1]=a,r.data[s+2]=o,r.data[s+3]=255}return t.putImageData(r,0,0),new n.CanvasTexture(this.canvas)}},O=class extends t.CustomShader{constructor(e=512){super({type:[`basic`,`phong`,`pointcloud`],fragment:{mainBefore:T,mainEnd:E},uniforms:{polygonClippers:new n.Uniform([]),polygonTexture:new n.Uniform(null)}}),this._polygonClippers=[],this.polygonGenerater=new D,this._radio=512,this.radio=e,this.workerPool=new C(()=>new S,1)}setPolygonClippersAsync(e){return y(this,void 0,void 0,function*(){this._polygonClippers=e;let t=this.uniforms;t.polygonClippers.value=e.map(e=>{let t=new n.Matrix4().getInverse(e.polygonTransform),r=e.polygonHeight,i=e.cutOutSide,a=e.polygon,o=e.floorIndex===void 0?-1:e.floorIndex,s=a[0][0],c=a[0][0],l=a[0][1],u=a[0][1];return a.forEach(e=>{let t=e[0],n=e[1];s=Math.min(s,t),c=Math.max(c,t),l=Math.min(l,n),u=Math.max(u,n)}),{polygonTransformInverse:t,polygonHeight:r,minPos:new n.Vector2(s,l),polygonScale:c-s>=u-l?c-s:u-l,cutOutSide:i,floorIndex:o}});let r=e.map(e=>({polygon:e.polygon,width:this.polygonGenerater.canvas.width,height:this.polygonGenerater.canvas.height})),i=yield this.workerPool.postMessage({canvasDataList:r,width:this.polygonGenerater.canvas.width,height:this.polygonGenerater.canvas.height}),a=document.createElement(`canvas`);a.width=this.polygonGenerater.canvas.width,a.height=this.polygonGenerater.canvas.height;let o=a.getContext(`2d`);if(o){o.putImageData(i.imageData,0,0);let e=new n.CanvasTexture(a);e.minFilter=n.NearestFilter,e.magFilter=n.NearestFilter,this.uniforms.polygonTexture.value=e,this.needsUpdate=!0}})}get polygonClippers(){return this._polygonClippers}set polygonClippers(e){this._polygonClippers=e}get radio(){return this._radio}set radio(e){this._radio=e,this.polygonGenerater.setSize(e)}dispose(){this.workerPool.dispose()}onBeforeCompile(e,t){let n=String(this.polygonClippers.length);e.vertexShader=e.vertexShader.replace(/NUM_POLYGON_CLIPPER/g,n),e.fragmentShader=e.fragmentShader.replace(/NUM_POLYGON_CLIPPER/g,n)}},k=`
#if NUM_SHINE_OBJECTS > 0
uniform float shineProgress;
struct SHINE_OBJECT {
vec3 min;
vec3 max;
};
uniform SHINE_OBJECT shineBoxes[NUM_SHINE_OBJECTS];
#endif
`,A=`
#if NUM_SHINE_OBJECTS > 0
#pragma unroll_loop_start
for ( int i = 0; i < NUM_SHINE_OBJECTS; i ++ ) {
vec3 min = shineBoxes[ i ].min;
vec3 max = shineBoxes[ i ].max;
vec3 boxCenter = 0.5 * (min + max);
if(vFinalPosition.x > min.x && vFinalPosition.x < max.x && vFinalPosition.y > min.y && vFinalPosition.y < max.y && vFinalPosition.z > min.z && vFinalPosition.z < max.z) {
//如果在盒子里,就整体按照progress进行透明度变化
vec3 shineColor = vec3(1.0,0.0,0.0);
float mixProgress = shineProgress * shineProgress * shineProgress * 0.4;
gl_FragColor.rgb = mix(gl_FragColor.rgb, shineColor, mixProgress);
}
}
#pragma unroll_loop_end
#endif
`,j=``,M=class extends t.CustomShader{constructor(){super({type:[`basic`,`phong`,`none`],fragment:{mainBefore:k,mainStart:j,mainEnd:A},uniforms:{shineProgress:new n.Uniform(0),shineBoxes:new n.Uniform([])},defines:{NUM_SHINE_OBJECTS:0}}),Object.defineProperties(this,{shineBoxes:{get(){return this.uniforms.shineBoxes.value},set(e){let t=e.length;t>0&&(this.defines.NUM_SHINE_OBJECTS=t,this.uniforms.shineBoxes.value=e)}}}),this.shineBoxes=[]}onBeforeCompile(e,t){let n=String(this.shineBoxes.length);e.vertexShader=e.vertexShader.replace(/NUM_SHINE_OBJECTS/g,n),e.fragmentShader=e.fragmentShader.replace(/NUM_SHINE_OBJECTS/g,n)}},N={animationDuration:800,sweepColor:[1,1,1],sweepRange:.15,frustumWidth:1/6,frustumHeight:1/6};function P(e){return Math.max(-1,Math.min(1,e))}function F(e){var t,n,r,i;return{animationDuration:Math.max(100,Math.min(1e4,(t=e.animationDuration)==null?N.animationDuration:t)),sweepColor:e.sweepColor?[Math.max(0,Math.min(1,e.sweepColor[0])),Math.max(0,Math.min(1,e.sweepColor[1])),Math.max(0,Math.min(1,e.sweepColor[2]))]:[...N.sweepColor],sweepRange:Math.max(.01,Math.min(1,(n=e.sweepRange)==null?N.sweepRange:n)),frustumWidth:Math.max(.01,Math.min(1,(r=e.frustumWidth)==null?N.frustumWidth:r)),frustumHeight:Math.max(.01,Math.min(1,(i=e.frustumHeight)==null?N.frustumHeight:i))}}function I(e,t,r){let i=t,a=r,o=P(e.x-i),s=P(e.x+i),c=P(e.y-a),l=P(e.y+a),u=(o+s)/2,d=(c+l)/2,f=(s-o)/2,p=(l-c)/2,m=t/2,h=r/2,g=Math.max(f,m),_=Math.max(p,h);return{center:new n.Vector2(u,d),extent:new n.Vector2(g,_)}}function L(e,t){return Math.min(1,e/t)}var R=(e,t)=>{let r=!0,i=!1,a=!1,o=null,s=F(t==null?{}:t),c=null,l=1,u=!1,d=(t,r,i,o)=>{if(o){u=!1;return}if(u)return!1;if(i<700)return;if(a)return!1;u=!0;let d=e.model.intersectRaycaster(t);if(!d||d.length===0)return;let p=d[0].point,m=P(r.x),h=P(r.y),g=I(new n.Vector2(m,h),s.frustumWidth,s.frustumHeight),_=e.camera.position.distanceTo(p)*Math.sqrt(s.frustumWidth*s.frustumWidth+s.frustumHeight*s.frustumHeight);c||(c=new V);let v=new n.Matrix4;return v.multiplyMatrices(e.camera.projectionMatrix,e.camera.matrixWorldInverse),c.uniforms.sweepViewProjectionMatrix.value.copy(v),c.uniforms.sweepCenter.value.copy(g.center),c.uniforms.sweepExtent.value.copy(g.extent),c.uniforms.sweepRange.value=_*s.sweepRange,c.uniforms.sweepColor.value.set(s.sweepColor[0],s.sweepColor[1],s.sweepColor[2]),c.uniforms.sweepOrigin.value.copy(p),c.uniforms.sweepProgress.value=0,l=_,e.model.customShaders=[c],f(),!1};function f(){a=!0;let t=performance.now(),r=new n.Matrix4;function u(){if(!a||i)return;let n=L(performance.now()-t,s.animationDuration);c&&(c.uniforms.sweepProgress.value=n*l,r.multiplyMatrices(e.camera.projectionMatrix,e.camera.matrixWorldInverse),c.uniforms.sweepViewProjectionMatrix.value.copy(r)),e.needsRender=!0,e.modelSceneNeedsRender=!0,n>=1?p():o=requestAnimationFrame(u)}o=requestAnimationFrame(u)}function p(){o!==null&&(cancelAnimationFrame(o),o=null),a=!1,e.model.customShaders=[]}function m(){e.on(`wantsPressGesture`,d)}function h(){e.off(`wantsPressGesture`,d)}return m(),{enable(){i||r||(r=!0,m())},disable(){i||r&&(r=!1,h(),p())},dispose(){i||(i=!0,r=!1,h(),p(),c=null)},updateParams(e){i||(s=F(Object.assign(Object.assign({},s),e)))}}},z=`
uniform float sweepProgress;
uniform vec2 sweepCenter;
uniform vec2 sweepExtent;
uniform float sweepRange;
uniform vec3 sweepColor;
uniform vec3 sweepOrigin;
uniform mat4 sweepViewProjectionMatrix;
`,B=`
// 用当前帧的 VP 矩阵计算片元在屏幕上的实际 NDC 位置
// 注意:projectionMatrix 和 viewMatrix 是 THREE.js 内置的当前帧 uniform(仅 vertex shader 可用)
// 所以我们用自定义的 sweepViewProjectionMatrix(每帧更新)来做
vec4 clipPos = sweepViewProjectionMatrix * vFinalPosition;
vec2 fragNDC = clipPos.xy / clipPos.w;
// 判断是否在子视锥内(屏幕空间固定矩形区域)
vec2 absDiff = abs(fragNDC - sweepCenter);
if (absDiff.x <= sweepExtent.x && absDiff.y <= sweepExtent.y && sweepProgress > 0.0) {
// 计算片元世界坐标到扫光原点的欧氏距离(沿物体表面扩散)
float worldDist = distance(vFinalPosition.xyz, sweepOrigin);
// sweepProgress 是当前扫光半径(世界空间绝对值)
// sweepRange 是扫光波前的宽度(世界空间绝对值)
if (worldDist <= sweepProgress + sweepRange && worldDist >= sweepProgress - sweepRange) {
float k = 5.0 / sweepRange;
float distanceFromSweep = abs(worldDist - sweepProgress);
float intensity = exp(-k * distanceFromSweep) * 0.8;
gl_FragColor.rgb = mix(gl_FragColor.rgb, sweepColor, intensity);
}
}
`,V=class extends t.CustomShader{constructor(){super({type:[`basic`,`phong`,`pointcloud`],fragment:{mainBefore:z,mainStart:``,mainEnd:B},uniforms:{sweepProgress:new n.Uniform(0),sweepCenter:new n.Uniform(new n.Vector2(0,0)),sweepExtent:new n.Uniform(new n.Vector2(1/6,1/6)),sweepRange:new n.Uniform(.3),sweepColor:new n.Uniform(new n.Vector3(1,1,1)),sweepOrigin:new n.Uniform(new n.Vector3(0,0,0)),sweepViewProjectionMatrix:new n.Uniform(new n.Matrix4)},defines:{}})}};e.EvenessPlaneShader=d,e.PointCloudExpandShader=v,e.PolygonCuterShader=O,e.PolygonGenerater=D,e.ShineModelShader=M,e.SweepModelScreenPlugin=R,e.SweepModelScreenShader=V,e.SweepModelShader=h,e.clampNDC=P,e.clampParams=F,e.computeAlignmentMatrix=w,e.computeFrustumExtent=I,e.computeProgress=L});