@hology/core 0.0.225 → 0.0.227
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +14 -14
- package/README.md +2 -2
- package/dist/effects/vfx/trail-renderer.d.ts +1 -1
- package/dist/gameplay/ai/build-tile.js +1 -1
- package/dist/gameplay/ai/dynamic-tiled-navmesh.d.ts +1 -0
- package/dist/gameplay/ai/dynamic-tiled-navmesh.js +1 -1
- package/dist/gameplay/ai/dynamic-tiled-navmesh.worker.js +1 -1
- package/dist/gameplay/animation/root-motion.d.ts +3 -2
- package/dist/gameplay/animation/root-motion.js +1 -1
- package/dist/shader/builtin/decal-standard-shader.d.ts +1 -1
- package/dist/shader-nodes/depth.d.ts +1 -1
- package/dist/shader-nodes/effects.d.ts +1 -1
- package/dist/shader-nodes/math.d.ts +2 -2
- package/dist/test/root-motion.test.d.ts +2 -0
- package/dist/test/root-motion.test.js +4 -0
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/LICENSE.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# Hology Interactive AB Limited License
|
|
2
|
-
|
|
3
|
-
This software package, including all associated files and documentation (the "Software"), is licensed to you (the "Licensee") by Hology Interactive AB for use exclusively with the product "Hology Engine."
|
|
4
|
-
|
|
5
|
-
By using, copying, modifying, or distributing the Software, Licensee agrees to be bound by the terms of this license.
|
|
6
|
-
|
|
7
|
-
1. License Grant: Hology Interactive AB grants Licensee a limited, non-exclusive, non-transferable license to use the Software solely for the purpose of developing and running software developed with "Hology Engine."
|
|
8
|
-
|
|
9
|
-
2. Restrictions: Licensee may not use, copy, modify, or distribute the Software for any other purpose, including but not limited to the creation of derivative works, standalone applications, or any products not directly associated with "Hology Engine."
|
|
10
|
-
|
|
11
|
-
3. Ownership: Hology Interactive AB retains all intellectual property rights to the Software. This license does not transfer ownership of the Software to Licensee.
|
|
12
|
-
|
|
13
|
-
4. Warranty Disclaimer: THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE CREATOR OF THIS PACKAGE BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE.
|
|
14
|
-
|
|
1
|
+
# Hology Interactive AB Limited License
|
|
2
|
+
|
|
3
|
+
This software package, including all associated files and documentation (the "Software"), is licensed to you (the "Licensee") by Hology Interactive AB for use exclusively with the product "Hology Engine."
|
|
4
|
+
|
|
5
|
+
By using, copying, modifying, or distributing the Software, Licensee agrees to be bound by the terms of this license.
|
|
6
|
+
|
|
7
|
+
1. License Grant: Hology Interactive AB grants Licensee a limited, non-exclusive, non-transferable license to use the Software solely for the purpose of developing and running software developed with "Hology Engine."
|
|
8
|
+
|
|
9
|
+
2. Restrictions: Licensee may not use, copy, modify, or distribute the Software for any other purpose, including but not limited to the creation of derivative works, standalone applications, or any products not directly associated with "Hology Engine."
|
|
10
|
+
|
|
11
|
+
3. Ownership: Hology Interactive AB retains all intellectual property rights to the Software. This license does not transfer ownership of the Software to Licensee.
|
|
12
|
+
|
|
13
|
+
4. Warranty Disclaimer: THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE CREATOR OF THIS PACKAGE BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE.
|
|
14
|
+
|
|
15
15
|
6. Contact: For any inquiries regarding this license, please email hello@hology.app
|
package/README.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
# Hology Engine Core
|
|
2
|
-
|
|
1
|
+
# Hology Engine Core
|
|
2
|
+
|
|
3
3
|
For the development with Hology Engine (https://hology.app/)
|
|
@@ -78,7 +78,7 @@ export declare class Trail extends THREE.Object3D {
|
|
|
78
78
|
static getTrailShaderNodes(billboard: boolean): {
|
|
79
79
|
position: import("three-shader-graph").Vec4Node;
|
|
80
80
|
color: import("three-shader-graph").Vec4Node;
|
|
81
|
-
fraction: import("three-shader-graph").
|
|
81
|
+
fraction: import("three-shader-graph").FloatNode;
|
|
82
82
|
};
|
|
83
83
|
static applyTrailShaderParameters(nodeShader: THREE.ShaderMaterial): void;
|
|
84
84
|
static createBaseMaterial(texture?: THREE.Texture, scrollSpeed?: number, opacityChannel?: OutputTextureSetting['opacityChannel'], billboard?: boolean): NodeShaderMaterial;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{NavMeshCreateParams as e,Raw as t,RecastBuildContext as i,TriangleAreasArray as l,TrianglesArray as o,VerticesArray as r,allocCompactHeightfield as a,allocContourSet as s,allocHeightfield as n,allocPolyMesh as d,allocPolyMeshDetail as c,buildCompactHeightfield as h,buildContours as g,buildDistanceField as m,buildPolyMesh as u,buildPolyMeshDetail as b,buildRegions as f,calcGridSize as S,cloneRcConfig as R,createHeightfield as w,createNavMeshData as p,createRcConfig as C,erodeWalkableArea as M,filterLedgeSpans as _,filterLowHangingWalkableObstacles as x,filterWalkableLowHeightSpans as A,freeCompactHeightfield as k,freeContourSet as y,freeHeightfield as z,markWalkableTriangles as E,rasterizeTriangles as v,vec3 as T}from"@recast-navigation/core";import{dtIlog2 as B,dtNextPow2 as O}from"@recast-navigation/generators";import*as P from"three";export const buildConfig=({recastConfig:e,navMeshBounds:[t,i]})=>{const l=C(e),o=S(t,i,l.cs);l.width=o.width,l.height=o.height,l.minRegionArea=l.minRegionArea*l.minRegionArea,l.mergeRegionArea=l.mergeRegionArea*l.mergeRegionArea,l.tileSize=Math.floor(l.tileSize),l.borderSize=l.walkableRadius+3,l.width=l.tileSize+2*l.borderSize,l.height=l.tileSize+2*l.borderSize,l.detailSampleDist=l.detailSampleDist<.9?0:l.cs*l.detailSampleDist,l.detailSampleMaxError=l.ch*l.detailSampleMaxError;const r=Math.floor(l.tileSize),a=Math.floor((o.width+r-1)/r),s=Math.floor((o.height+r-1)/r),n=l.tileSize*l.cs,d=T.fromArray(t);let c=Math.min(Math.floor(B(O(a*s))),14);c>14&&(c=14);const h=22-c;return{config:l,orig:d,tileBits:c,polyBits:h,maxTiles:1<<c,maxPolysPerTile:1<<h,tcs:n,tileWidth:a,tileHeight:s}};export const buildTile=({positions:S,indices:C,navMeshBounds:T,recastConfig:B,tileX:O,tileY:H,tileBoundsMin:L,tileBoundsMax:G,keepIntermediates:D})=>{const $=new i,F=S,V=C.length,W=new r;W.copy(F);const I=C,K=C.length/3;(new o).copy(I);const X={tileX:O,tileY:H},Y=()=>{D||(X.compactHeightfield&&k(X.compactHeightfield),X.heightfield&&z(X.heightfield),X.contourSet&&y(X.contourSet))},N=e=>($.log(t.Module.RC_LOG_ERROR,e),Y(),{success:!1,error:e,tileIntermediates:X,buildContext:$}),{config:U}=buildConfig({recastConfig:B,navMeshBounds:T}),j=R(U),q=[...L],J=[...G];q[0]-=j.borderSize*j.cs,q[2]-=j.borderSize*j.cs,J[0]+=j.borderSize*j.cs,J[2]+=j.borderSize*j.cs,j.set_bmin(0,q[0]),j.set_bmin(1,q[1]),j.set_bmin(2,q[2]),j.set_bmax(0,J[0]),j.set_bmax(1,J[1]),j.set_bmax(2,J[2]),$.resetTimers(),$.startTimer(t.Module.RC_TIMER_TOTAL),$.log(t.Module.RC_LOG_PROGRESS,`Building tile at x: ${O}, y: ${H}`),$.log(t.Module.RC_LOG_PROGRESS,` - ${U.width} x ${U.height} cells`),$.log(t.Module.RC_LOG_PROGRESS,` - ${V/1e3}fK verts, ${K/1e3}K tris`);const Q=n();if(X.heightfield=Q,!w($,Q,j.width,j.height,q,J,j.cs,j.ch))return N("Could not create heightfield");const Z=((e,t,i)=>{const l=[],o=new P.Vector3,r=new P.Vector3,a=new P.Vector3,s=new P.Triangle;for(let n=0;n<t.length;n+=3){const d=t[n],c=t[n+1],h=t[n+2];o.fromArray(e,3*d),r.fromArray(e,3*c),a.fromArray(e,3*h),s.set(o,r,a),s.intersectsBox(i)&&l.push(d,c,h)}return l})(S,C,new P.Box3(new P.Vector3(q[0],q[1],q[2]),new P.Vector3(J[0],J[1],J[2]))),ee=Z.length/3,te=new o;te.copy(Z);const ie=new l;ie.resize(ee),E($,j.walkableSlopeAngle,W,V,te,ee,ie);const le=v($,W,V,te,ie,ee,Q,j.walkableClimb);if(ie.destroy(),!le)return N("Could not rasterize triangles");x($,j.walkableClimb,Q),_($,j.walkableHeight,j.walkableClimb,Q),A($,j.walkableHeight,Q);const oe=a();if(X.compactHeightfield=oe,!h($,j.walkableHeight,j.walkableClimb,Q,oe))return N("Could not build compact heightfield");if(D||(z(X.heightfield),X.heightfield=void 0),!M($,j.walkableRadius,oe))return N("Could not erode walkable area");if(!m($,oe))return N("Failed to build distance field");if(!f($,oe,j.borderSize,j.minRegionArea,j.mergeRegionArea))return N("Failed to build regions");const re=s();if(X.contourSet=re,!g($,oe,j.maxSimplificationError,j.maxEdgeLen,re,t.Module.RC_CONTOUR_TESS_WALL_EDGES))return N("Failed to create contours");const ae=d();if(!u($,re,j.maxVertsPerPoly,ae))return N("Failed to triangulate contours");const se=c();if(!b($,ae,oe,j.detailSampleDist,j.detailSampleMaxError,se))return N("Failed to build detail mesh");D||(k(oe),X.compactHeightfield=void 0,y(re),X.contourSet=void 0);for(let e=0;e<ae.npolys();e++)ae.areas(e)==t.Recast.WALKABLE_AREA&&ae.setAreas(e,0),0==ae.areas(e)&&ae.setFlags(e,1);const ne=new e;ne.setPolyMeshCreateParams(ae),ne.setPolyMeshDetailCreateParams(se),ne.setWalkableHeight(j.walkableHeight),ne.setWalkableRadius(j.walkableRadius),ne.setWalkableClimb(j.walkableClimb),ne.setCellSize(j.cs),ne.setCellHeight(j.ch),ne.setBuildBvTree(!0),ne.setTileX(O),ne.setTileY(H);const de=p(ne);return de.success?($.log(t.Module.RC_LOG_PROGRESS,`>> Polymesh: ${ae.nverts()} vertices ${ae.npolys()} polygons`),Y(),{success:!0,data:de.navMeshData,tileIntermediates:X,buildContext:$}):N("Failed to create Detour navmesh data")};/*
|
|
1
|
+
import{NavMeshCreateParams as e,Raw as t,RecastBuildContext as i,TriangleAreasArray as l,TrianglesArray as o,VerticesArray as r,allocCompactHeightfield as a,allocContourSet as s,allocHeightfield as n,allocPolyMesh as d,allocPolyMeshDetail as c,buildCompactHeightfield as h,buildContours as g,buildDistanceField as m,buildPolyMesh as u,buildPolyMeshDetail as b,buildRegions as f,calcGridSize as S,cloneRcConfig as R,createHeightfield as w,createNavMeshData as p,createRcConfig as C,erodeWalkableArea as M,filterLedgeSpans as _,filterLowHangingWalkableObstacles as x,filterWalkableLowHeightSpans as A,freeCompactHeightfield as k,freeContourSet as y,freeHeightfield as z,markWalkableTriangles as E,rasterizeTriangles as v,vec3 as T}from"@recast-navigation/core";import{dtIlog2 as B,dtNextPow2 as O}from"@recast-navigation/generators";import*as P from"three";export const buildConfig=({recastConfig:e,navMeshBounds:[t,i]})=>{const l=C(e),o=S(t,i,l.cs);l.width=o.width,l.height=o.height,l.minRegionArea=l.minRegionArea*l.minRegionArea,l.mergeRegionArea=l.mergeRegionArea*l.mergeRegionArea,l.tileSize=Math.floor(l.tileSize),l.borderSize=l.walkableRadius+3,l.width=l.tileSize+2*l.borderSize,l.height=l.tileSize+2*l.borderSize,l.detailSampleDist=l.detailSampleDist<.9?0:l.cs*l.detailSampleDist,l.detailSampleMaxError=l.ch*l.detailSampleMaxError;const r=Math.floor(l.tileSize),a=Math.floor((o.width+r-1)/r),s=Math.floor((o.height+r-1)/r),n=l.tileSize*l.cs,d=T.fromArray(t);let c=Math.min(Math.floor(B(O(a*s))),14);c>14&&(c=14);const h=22-c;return{config:l,orig:d,tileBits:c,polyBits:h,maxTiles:1<<c,maxPolysPerTile:1<<h,tcs:n,tileWidth:a,tileHeight:s}};export const buildTile=({positions:S,indices:C,navMeshBounds:T,recastConfig:B,tileX:O,tileY:H,tileBoundsMin:L,tileBoundsMax:G,keepIntermediates:D})=>{const $=new i,F=S,V=C.length/3,W=new r;W.copy(F);const I=C,K=C.length/3;(new o).copy(I);const X={tileX:O,tileY:H},Y=()=>{D||(X.compactHeightfield&&k(X.compactHeightfield),X.heightfield&&z(X.heightfield),X.contourSet&&y(X.contourSet))},N=e=>($.log(t.Module.RC_LOG_ERROR,e),Y(),{success:!1,error:e,tileIntermediates:X,buildContext:$}),{config:U}=buildConfig({recastConfig:B,navMeshBounds:T}),j=R(U),q=[...L],J=[...G];q[0]-=j.borderSize*j.cs,q[2]-=j.borderSize*j.cs,J[0]+=j.borderSize*j.cs,J[2]+=j.borderSize*j.cs,j.set_bmin(0,q[0]),j.set_bmin(1,q[1]),j.set_bmin(2,q[2]),j.set_bmax(0,J[0]),j.set_bmax(1,J[1]),j.set_bmax(2,J[2]),$.resetTimers(),$.startTimer(t.Module.RC_TIMER_TOTAL),$.log(t.Module.RC_LOG_PROGRESS,`Building tile at x: ${O}, y: ${H}`),$.log(t.Module.RC_LOG_PROGRESS,` - ${U.width} x ${U.height} cells`),$.log(t.Module.RC_LOG_PROGRESS,` - ${V/1e3}fK verts, ${K/1e3}K tris`);const Q=n();if(X.heightfield=Q,!w($,Q,j.width,j.height,q,J,j.cs,j.ch))return N("Could not create heightfield");const Z=((e,t,i)=>{const l=[],o=new P.Vector3,r=new P.Vector3,a=new P.Vector3,s=new P.Triangle;for(let n=0;n<t.length;n+=3){const d=t[n],c=t[n+1],h=t[n+2];o.fromArray(e,3*d),r.fromArray(e,3*c),a.fromArray(e,3*h),s.set(o,r,a),s.intersectsBox(i)&&l.push(d,c,h)}return l})(S,C,new P.Box3(new P.Vector3(q[0],q[1],q[2]),new P.Vector3(J[0],J[1],J[2]))),ee=Z.length/3,te=new o;te.copy(Z);const ie=new l;ie.resize(ee),E($,j.walkableSlopeAngle,W,V,te,ee,ie);const le=v($,W,V,te,ie,ee,Q,j.walkableClimb);if(ie.destroy(),!le)return N("Could not rasterize triangles");x($,j.walkableClimb,Q),_($,j.walkableHeight,j.walkableClimb,Q),A($,j.walkableHeight,Q);const oe=a();if(X.compactHeightfield=oe,!h($,j.walkableHeight,j.walkableClimb,Q,oe))return N("Could not build compact heightfield");if(D||(z(X.heightfield),X.heightfield=void 0),!M($,j.walkableRadius,oe))return N("Could not erode walkable area");if(!m($,oe))return N("Failed to build distance field");if(!f($,oe,j.borderSize,j.minRegionArea,j.mergeRegionArea))return N("Failed to build regions");const re=s();if(X.contourSet=re,!g($,oe,j.maxSimplificationError,j.maxEdgeLen,re,t.Module.RC_CONTOUR_TESS_WALL_EDGES))return N("Failed to create contours");const ae=d();if(!u($,re,j.maxVertsPerPoly,ae))return N("Failed to triangulate contours");const se=c();if(!b($,ae,oe,j.detailSampleDist,j.detailSampleMaxError,se))return N("Failed to build detail mesh");D||(k(oe),X.compactHeightfield=void 0,y(re),X.contourSet=void 0);for(let e=0;e<ae.npolys();e++)ae.areas(e)==t.Recast.WALKABLE_AREA&&ae.setAreas(e,0),0==ae.areas(e)&&ae.setFlags(e,1);const ne=new e;ne.setPolyMeshCreateParams(ae),ne.setPolyMeshDetailCreateParams(se),ne.setWalkableHeight(j.walkableHeight),ne.setWalkableRadius(j.walkableRadius),ne.setWalkableClimb(j.walkableClimb),ne.setCellSize(j.cs),ne.setCellHeight(j.ch),ne.setBuildBvTree(!0),ne.setTileX(O),ne.setTileY(H);const de=p(ne);return de.success?($.log(t.Module.RC_LOG_PROGRESS,`>> Polymesh: ${ae.nverts()} vertices ${ae.npolys()} polygons`),Y(),{success:!0,data:de.navMeshData,tileIntermediates:X,buildContext:$}):N("Failed to create Detour navmesh data")};/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{NavMesh as t,NavMeshParams as e,Raw as s,UnsignedCharArray as i,recastConfigDefaults as o,statusToReadableString as
|
|
1
|
+
import{NavMesh as t,NavMeshParams as e,Raw as s,UnsignedCharArray as i,recastConfigDefaults as o,statusToReadableString as r}from"recast-navigation";import{buildConfig as n,buildTile as a}from"./build-tile.js";import{Subject as h}from"rxjs";import{hasWorkerBuilder as l,createWorker as c}from"../../worker/index.js";import{hasSharedArrayBufferSupport as d}from"../../utils/buffer.js";export const MAX_NAV_MESH_WORKERS=4;export class NavMeshWorkerPool{constructor(t=c){this.workerFactory=t,this.slots=[],this.queue=[],this.workerLimit=0}schedule(t,e,s,i,o){this.workerLimit=Math.max(this.workerLimit,Math.min(4,Math.max(1,o))),this.queue.push({owner:t,data:e,transfer:s,onResult:i,cancelled:!1}),this.drain()}cancel(t){this.queue=this.queue.filter(e=>e.owner!==t);for(const e of this.slots)e.job?.owner===t&&(e.job.cancelled=!0)}drain(){for(;this.queue.length>0;){let t=this.slots.find(t=>null==t.job);if(null==t){if(this.slots.length>=this.workerLimit)return;t=this.createSlot(),this.slots.push(t)}const e=this.queue.shift();t.job=e,t.worker.postMessage(e.data,e.transfer)}}createSlot(){const t={worker:this.workerFactory()};return t.worker.onmessage=e=>{const s=t.job;t.job=void 0;try{null==s||s.cancelled||s.onResult(e)}finally{this.drain()}},t.worker.onerror=e=>{t.job=void 0,t.worker.terminate();const s=this.slots.indexOf(t);s>=0&&this.slots.splice(s,1),console.error("Navmesh worker failed",e),this.drain()},t}}const u=new NavMeshWorkerPool;export class DynamicTiledNavMesh{constructor(s){this.navMeshVersion=0,this.onNavMeshUpdate=new h;const i=s.navMeshBounds.min,r=s.navMeshBounds.max,a=[i.toArray(),r.toArray()],l=s.navMeshBounds.min;this.navMeshBoundsMin=i,this.navMeshBoundsMax=r,this.navMeshBounds=a,this.navMeshOrigin=l,this.cacheId=s.cacheId,this.workerLimit=Math.min(4,Math.max(0,s.workers));const c={...o,...s.recastConfig};this.recastConfig=c;const d=new t,{tileWidth:u,tileHeight:M,tcs:f,maxPolysPerTile:m}=n({recastConfig:c,navMeshBounds:a});this.tileWidth=u,this.tileHeight=M,this.tcs=f;const v=e.create({orig:l,tileWidth:c.tileSize*c.cs,tileHeight:c.tileSize*c.cs,maxTiles:s.maxTiles,maxPolys:m});d.initTiled(v),this.navMesh=d}onResult(t){if(t.data.error)return void console.error(t.data.error);const{tileX:e,tileY:o,navMeshData:n}=t.data,a=new i;a.copy(n),this.navMesh.removeTile(this.navMesh.getTileRefAt(e,o,0));const h=this.navMesh.addTile(a,s.Module.DT_TILE_FREE_DATA,0);s.Detour.statusFailed(h.status)&&(console.error(s.Module.RC_LOG_WARNING,`Failed to add tile to nav mesh\n\ttx: ${e}, ty: ${o},status: ${r(h.status)} (${h.status})`),a.destroy()),this.navMeshVersion++,this.onNavMeshUpdate.next([this.navMeshVersion,[e,o]])}buildTile(t,e,[s,i],o=!1){const r=d&&t.buffer instanceof window.SharedArrayBuffer,n=r?t:new Float32Array(t),h=r?e:new Uint32Array(e),c={tileX:s,tileY:i,tileBoundsMin:[this.navMeshBoundsMin.x+s*this.tcs,this.navMeshBoundsMin.y,this.navMeshBoundsMin.z+i*this.tcs],tileBoundsMax:[this.navMeshBoundsMax.x+(s+1)*this.tcs,this.navMeshBoundsMax.y,this.navMeshBoundsMax.z+(i+1)*this.tcs],recastConfig:this.recastConfig,navMeshBounds:this.navMeshBounds,keepIntermediates:!1,positions:n,indices:h};return this.workerLimit>0&&l()?(u.schedule(this,c,r?void 0:[n.buffer,h.buffer],t=>this.onResult(t),this.workerLimit),Promise.resolve()):new Promise(t=>{requestIdleCallback(()=>{const e=this.cacheId+JSON.stringify({tileX:c.tileX,tileY:c.tileY});if(o){const s=localStorage.getItem(e);if(null!=s){const e=f(s);return this.onResult({data:{tileX:c.tileX,tileY:c.tileY,navMeshData:e}}),void t({})}}else localStorage.removeItem(e);const s=a(c);if(!s.success||!s.data)return;const i=s.data.toTypedArray();localStorage.setItem(e,M(i)),this.onResult({data:{tileX:c.tileX,tileY:c.tileY,navMeshData:i}}),t(s)})})}buildAllTiles(t,e){const{tileWidth:s,tileHeight:i}=this;for(let o=0;o<i;o++)for(let i=0;i<s;i++)this.buildTile(t,e,[i,o])}getTileForWorldPosition(t){return[Math.floor((t.x-this.navMeshBoundsMin.x)/this.tcs),Math.floor((t.z-this.navMeshBoundsMin.z)/this.tcs)]}getTilesForBounds(t){const e=this.getTileForWorldPosition(t.min),s=this.getTileForWorldPosition(t.max),i=[];for(let t=e[1];t<=s[1];t++)for(let o=e[0];o<=s[0];o++)i.push([o,t]);return i}destroy(){u.cancel(this),this.navMesh.destroy(),this.onNavMeshUpdate.complete()}}const M=function(t){return btoa(String.fromCharCode(...t))},f=function(t){if(!t)return null;const e=atob(t),s=e.length,i=new Uint8Array(s);for(let t=0;t<s;t++)i[t]=e.charCodeAt(t);return i};/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{init as
|
|
1
|
+
import{init as e}from"recast-navigation";import{buildTile as t}from"./build-tile.js";let s=!1;const i=[];export function setupNavMeshWorker(){e().then(()=>{s=!0;for(const e of i)o(e)}),self.onmessage=e=>{s?o(e.data):i.push(e.data)}}const o=e=>{const s=t(e);if(!s.success||!s.data)return console.error("NavMesh tile build failed",{tileX:e.tileX,tileY:e.tileY,error:s.success?"No tile data generated":s.error,positions:e.positions.length,indices:e.indices.length}),void self.postMessage({tileX:e.tileX,tileY:e.tileY,error:s.success?"No tile data generated":s.error});if(!s.success||!s.data)return;const i=s.data.toTypedArray();s.data.destroy(),self.postMessage({tileX:e.tileX,tileY:e.tileY,navMeshData:i},[i.buffer])};/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { AnimationClip, VectorKeyframeTrack, Bone } from "three";
|
|
1
|
+
import { AnimationClip, VectorKeyframeTrack, Bone, Object3D } from "three";
|
|
2
2
|
export declare class RootMotionClip extends AnimationClip {
|
|
3
3
|
motionTrack: VectorKeyframeTrack;
|
|
4
4
|
displacement: number;
|
|
5
5
|
fixedInPlace: boolean;
|
|
6
6
|
private rootBone?;
|
|
7
|
+
private animationRoot?;
|
|
7
8
|
private source;
|
|
8
|
-
static fromClip(source: AnimationClip, fixedInPlace?: boolean, rootBone?: Bone): RootMotionClip;
|
|
9
|
+
static fromClip(source: AnimationClip, fixedInPlace?: boolean, rootBone?: Bone, animationRoot?: Object3D): RootMotionClip;
|
|
9
10
|
/**
|
|
10
11
|
* If the animation is in place or does not have a root bone,
|
|
11
12
|
* you can create a root motion clip using this function with a specific distance
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{AnimationClip as
|
|
1
|
+
import{AnimationClip as t,Vector3 as o,Quaternion as e,Matrix3 as n,Matrix4 as r}from"three";import{getAnimationClipRigId as i,setAnimationClipRigId as a}from"./retarget.js";export class RootMotionClip extends t{constructor(){super(...arguments),this.displacement=0,this.fixedInPlace=!1}static fromClip(t,s=!1,l,c){const u=new RootMotionClip(t.name,t.duration,t.tracks.slice(),t.blendMode);if(u.fixedInPlace=s,u.rootBone=l,u.animationRoot=c,u.source=t,u.uuid=t.uuid,a(u,i(t)),u.motionTrack=null!=l?t.tracks.find(t=>t.name===`${l.name}.position`):t.tracks.find(t=>t.name.endsWith(".position")),u.motionTrack){u.tracks.splice(u.tracks.indexOf(u.motionTrack),1);const t=(new o).fromArray(u.motionTrack.values,0),i=(new o).fromArray(u.motionTrack.values,u.motionTrack.values.length-3),a=new o(0,1,0);if(null!=l?.parent){l.parent.updateWorldMatrix(!0,!1);const t=l.parent.getWorldQuaternion(new e);a.applyQuaternion(t.invert()).normalize()}const s=u.motionTrack.clone(),d=new o;for(let t=0;t<u.motionTrack.values.length;t+=3){d.fromArray(u.motionTrack.values,t);const o=d.dot(a);d.copy(a).multiplyScalar(o),s.values[t+0]=d.x,s.values[t+1]=d.y,s.values[t+2]=d.z}u.tracks.push(s);const m=i.sub(t);if(m.addScaledVector(a,-m.dot(a)),null!=l?.parent&&null!=c){c.updateWorldMatrix(!0,!1),l.parent.updateWorldMatrix(!0,!1);const t=(new r).copy(c.matrixWorld).invert().multiply(l.parent.matrixWorld);m.applyMatrix3((new n).setFromMatrix4(t))}u.displacement=m.length()}else console.error("Could not find root motion track",t,l);return u}static fromClipWithDistance(t,o){const e=new RootMotionClip(t.name,t.duration,t.tracks.slice(),t.blendMode);return e.fixedInPlace=!0,e.source=t,e.uuid=t.uuid,a(e,i(t)),e.displacement=o,e}clone(){const t=RootMotionClip.fromClip(this.source.clone(),this.fixedInPlace,this.rootBone,this.animationRoot);return t.displacement=this.displacement,t}}let s=53912381;export class BoneLayer{constructor(){this.uuid=s++,this.order=0,this.boneMask=[]}}/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -20,7 +20,7 @@ export declare class DecalStandardShader extends DecalNodeShader {
|
|
|
20
20
|
atlasSize: Vector2;
|
|
21
21
|
atlasTile: number;
|
|
22
22
|
output(): {
|
|
23
|
-
color: import("three-shader-graph
|
|
23
|
+
color: import("three-shader-graph").RgbaNode;
|
|
24
24
|
normal: Vec3Node;
|
|
25
25
|
roughness: FloatNode;
|
|
26
26
|
};
|
|
@@ -9,7 +9,7 @@ export declare const sceneNormalUniformName = "hology_scene_normal_map";
|
|
|
9
9
|
export declare const depthSampler: import("three-shader-graph").UniformSampler2d;
|
|
10
10
|
export declare function sampleSceneDepth(uv: Vec2Node): FloatNode;
|
|
11
11
|
export declare function sampleSceneLinearEyeDepth(uv: Vec2Node): FloatNode;
|
|
12
|
-
export declare const highPrecisionEyeDepth:
|
|
12
|
+
export declare const highPrecisionEyeDepth: FloatNode;
|
|
13
13
|
export declare const fragmentLinearEyeDepth: FloatNode;
|
|
14
14
|
export declare const resolution: import("three-shader-graph").UniformVec2Node;
|
|
15
15
|
export declare const screenUV: Vec2Node;
|
|
@@ -10,5 +10,5 @@ export declare function edgeDepthEffect(power?: number | FloatNode): FloatNode;
|
|
|
10
10
|
* Creates a fade effect based on the distance between the scene geometry and the current fragment.
|
|
11
11
|
* This is useful for softening the intersections of meshes with the environment (e.g., water shorelines or force fields).
|
|
12
12
|
*/
|
|
13
|
-
export declare function depthFadeEffect(distance: FloatNode):
|
|
13
|
+
export declare function depthFadeEffect(distance: FloatNode): FloatNode;
|
|
14
14
|
//# sourceMappingURL=effects.d.ts.map
|
|
@@ -16,8 +16,8 @@ export declare function oneMinus<T extends FloatNode | Vec2Node | Vec3Node | Vec
|
|
|
16
16
|
*/
|
|
17
17
|
export declare function vectorToRadial(vec: Vec2Node): {
|
|
18
18
|
coords: Vec2Node;
|
|
19
|
-
radius:
|
|
20
|
-
angle:
|
|
19
|
+
radius: FloatNode;
|
|
20
|
+
angle: FloatNode;
|
|
21
21
|
};
|
|
22
22
|
export declare function remap(value: FloatNode, inMin: FloatNode, inMax: FloatNode, outMin: FloatNode, outMax: FloatNode): FloatNode;
|
|
23
23
|
export declare function hueShift(color: Vec3Node, shift: FloatNode): Vec3Node;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{expect as o,test as e}from"vitest";import{AnimationClip as t,Bone as n,Group as i,VectorKeyframeTrack as a}from"three";import{RootMotionClip as r}from"../gameplay/animation/root-motion.js";function s(o,e,s=1){const m=new i,l=new i;l.rotation.x=o,l.scale.setScalar(s),m.add(l);const c=new n;c.name="mixamorigHips",l.add(c);const p=new a("mixamorigHips.position",[0,1],e);return r.fromClip(new t("run",1,[p]),!0,c,m)}e("removes horizontal root motion while preserving Y-up hip movement",()=>{const e=s(0,[1,10,2,4,12,6]);o(Array.from(e.tracks[0].values)).toEqual([0,10,0,0,12,0]),o(e.displacement).toBeCloseTo(5)}),e("includes scale between the animation root and the animated hip parent",()=>{const e=s(-Math.PI/2,[0,0,1,0,3,1],100);o(e.displacement).toBeCloseTo(300)}),e("uses the root parent orientation to identify vertical motion",()=>{const e=s(-Math.PI/2,[1,2,10,4,6,12]),t=Array.from(e.tracks[0].values);o(t[0]).toBeCloseTo(0),o(t[1]).toBeCloseTo(0),o(t[2]).toBeCloseTo(10),o(t[3]).toBeCloseTo(0),o(t[4]).toBeCloseTo(0),o(t[5]).toBeCloseTo(12),o(e.displacement).toBeCloseTo(5)});/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|