mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-04-29 16:25:49 +00:00
vehicle spawning and mounting improvements
This commit is contained in:
parent
bc7d30c5c6
commit
76b2d11e14
114 changed files with 2118 additions and 1538 deletions
|
|
@ -1 +1 @@
|
|||
import{s as e}from"./SettingsProvider-BeB5OnG9.js";import{a as t,c as n,i as r,l as i,n as a,o,r as s,s as c,t as l}from"./AudioEmitter-Cdm9ofcT.js";export{l as AudioEmitter,a as audioBufferCache,s as getCachedAudioBuffer,e as getEffectiveSoundRate,r as getSoundGeneration,t as playOneShotSound,o as resolveAudioProfile,c as stopAllTrackedSounds,n as trackSound,i as untrackSound};
|
||||
import{s as e}from"./SettingsProvider-BdqQ2Cm4.js";import{a as t,c as n,i as r,l as i,n as a,o,r as s,s as c,t as l}from"./AudioEmitter-CJMuEzA2.js";export{l as AudioEmitter,a as audioBufferCache,s as getCachedAudioBuffer,e as getEffectiveSoundRate,r as getSoundGeneration,t as playOneShotSound,o as resolveAudioProfile,c as stopAllTrackedSounds,n as trackSound,i as untrackSound};
|
||||
1
docs/assets/AudioEmitter-CJMuEzA2.js
Normal file
1
docs/assets/AudioEmitter-CJMuEzA2.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{U as i}from"./index-BEehCpzM.js";var a=e(n(),1),o=t(),s={InputForm:`_InputForm_18kom_1`,Input:`_Input_18kom_1`},c=r();function l(){let e=(0,o.c)(8),[t,n]=(0,a.useState)(``),r;e[0]===t?r=e[1]:(r=e=>{e.preventDefault();let r=t.trim();r&&(i.getState().sendCommand(`messageSent`,r),n(``))},e[0]=t,e[1]=r);let l=r,f;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(f=e=>n(e.target.value),e[2]=f):f=e[2];let p;e[3]===t?p=e[4]:(p=(0,c.jsx)(`input`,{className:s.Input,type:`text`,placeholder:`Say something…`,value:t,onChange:f,onKeyDown:d,onKeyUp:u,maxLength:255}),e[3]=t,e[4]=p);let m;return e[5]!==l||e[6]!==p?(m=(0,c.jsx)(`form`,{className:s.InputForm,onSubmit:l,children:p}),e[5]=l,e[6]=p,e[7]=m):m=e[7],m}function u(e){return e.stopPropagation()}function d(e){return e.stopPropagation()}export{l as ChatInput};
|
||||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{k as i}from"./index-D4aiQcCU.js";var a=e(n(),1),o=t(),s={InputForm:`_InputForm_18kom_1`,Input:`_Input_18kom_1`},c=r();function l(){let e=(0,o.c)(8),[t,n]=(0,a.useState)(``),r;e[0]===t?r=e[1]:(r=e=>{e.preventDefault();let r=t.trim();r&&(i.getState().sendCommand(`messageSent`,r),n(``))},e[0]=t,e[1]=r);let l=r,f;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(f=e=>n(e.target.value),e[2]=f):f=e[2];let p;e[3]===t?p=e[4]:(p=(0,c.jsx)(`input`,{className:s.Input,type:`text`,placeholder:`Say something…`,value:t,onChange:f,onKeyDown:d,onKeyUp:u,maxLength:255}),e[3]=t,e[4]=p);let m;return e[5]!==l||e[6]!==p?(m=(0,c.jsx)(`form`,{className:s.InputForm,onSubmit:l,children:p}),e[5]=l,e[6]=p,e[7]=m):m=e[7],m}function u(e){return e.stopPropagation()}function d(e){return e.stopPropagation()}export{l as ChatInput};
|
||||
1
docs/assets/ChatSoundPlayer-BuKG-RWU.js
Normal file
1
docs/assets/ChatSoundPlayer-BuKG-RWU.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t}from"./jsx-runtime-BpGWiA-R.js";import{a as n,s as r}from"./SettingsProvider-BdqQ2Cm4.js";import{c as i}from"./three.module-DKAirPAO.js";import{r as a}from"./loaders-B4T775qz.js";import{i as o}from"./engineStore-B1KAgiiF.js";import{c as s,d as c,i as l,l as u,r as d}from"./AudioEmitter-CJMuEzA2.js";var f=e(t(),1);function p(){let{audioLoader:e,audioListener:t}=c(),{audioEnabled:p}=n(),m=o(e=>e.playback.streamSnapshot?.chatMessages),h=o(e=>e.playback.streamSnapshot?.timeSec),g=(0,f.useRef)(new WeakSet),_=(0,f.useRef)(new Map);return(0,f.useEffect)(()=>{if(!p||!e||!t||!m?.length||h==null)return;let n=g.current,o=_.current;for(let c of m)if(!n.has(c)&&(n.add(c),c.soundPath&&!(Math.abs(h-c.timeSec)>2)))try{let n=a(c.soundPath),f=c.soundPitch??1,p=c.sender,m=l();d(n,e,e=>{if(m!==l())return;if(p){let e=o.get(p);if(e){try{e.stop()}catch{}u(e);try{e.disconnect()}catch{}o.delete(p)}}let n=new i(t);n.setBuffer(e),n.setPlaybackRate(r(f)),s(n,f),p&&o.set(p,n),n.play(),n.source.onended=()=>{u(n);try{n.disconnect()}catch{}p&&o.get(p)===n&&o.delete(p)}})}catch{}},[p,e,t,m,h]),null}export{p as ChatSoundPlayer};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t}from"./jsx-runtime-BpGWiA-R.js";import{a as n,s as r}from"./SettingsProvider-BeB5OnG9.js";import{i}from"./engineStore-DXFfg1NG.js";import{c as a}from"./three.module-DeDv86YO.js";import{r as o}from"./index-BEehCpzM.js";import{c as s,i as c,l,p as u,r as d}from"./AudioEmitter-Cdm9ofcT.js";var f=e(t(),1);function p(){let{audioLoader:e,audioListener:t}=u(),{audioEnabled:p}=n(),m=i(e=>e.playback.streamSnapshot?.chatMessages),h=i(e=>e.playback.streamSnapshot?.timeSec),g=(0,f.useRef)(new WeakSet),_=(0,f.useRef)(new Map);return(0,f.useEffect)(()=>{if(!p||!e||!t||!m?.length||h==null)return;let n=g.current,i=_.current;for(let u of m)if(!n.has(u)&&(n.add(u),u.soundPath&&!(Math.abs(h-u.timeSec)>2)))try{let n=o(u.soundPath),f=u.soundPitch??1,p=u.sender,m=c();d(n,e,e=>{if(m!==c())return;if(p){let e=i.get(p);if(e){try{e.stop()}catch{}l(e);try{e.disconnect()}catch{}i.delete(p)}}let n=new a(t);n.setBuffer(e),n.setPlaybackRate(r(f)),s(n,f),p&&i.set(p,n),n.play(),n.source.onended=()=>{l(n);try{n.disconnect()}catch{}p&&i.get(p)===n&&i.delete(p)}})}catch{}},[p,e,t,m,h]),null}export{p as ChatSoundPlayer};
|
||||
|
|
@ -1 +1 @@
|
|||
import{n as e,t}from"./jsx-runtime-BpGWiA-R.js";import{E as n,Ft as r,p as i}from"./three.module-DeDv86YO.js";var a=e(),o=t(),s=(0,o.jsx)(`lineBasicMaterial`,{color:`#ff0000`,depthTest:!1,depthWrite:!1,fog:!1,transparent:!0});function c(e){let t=(0,a.c)(6),{size:r}=e,c;t[0]!==r[0]||t[1]!==r[1]||t[2]!==r[2]?(c=new n(new i(r[0],r[1],r[2])),t[0]=r[0],t[1]=r[1],t[2]=r[2],t[3]=c):c=t[3];let l=c,u;return t[4]===l?u=t[5]:(u=(0,o.jsx)(`lineSegments`,{geometry:l,renderOrder:9999,children:s}),t[4]=l,t[5]=u),u}function l(e){let t=(0,a.c)(4),{radius:i}=e,c=i===void 0?1:i,l;t[0]===c?l=t[1]:(l=new n(new r(c,8,6)),t[0]=c,t[1]=l);let u=l,d;return t[2]===u?d=t[3]:(d=(0,o.jsx)(`lineSegments`,{geometry:u,renderOrder:9999,children:s}),t[2]=u,t[3]=d),d}export{l as n,c as t};
|
||||
import{n as e,t}from"./jsx-runtime-BpGWiA-R.js";import{E as n,Ft as r,p as i}from"./three.module-DKAirPAO.js";var a=e(),o=t(),s=(0,o.jsx)(`lineBasicMaterial`,{color:`#ff0000`,depthTest:!1,depthWrite:!1,fog:!1,transparent:!0});function c(e){let t=(0,a.c)(6),{size:r}=e,c;t[0]!==r[0]||t[1]!==r[1]||t[2]!==r[2]?(c=new n(new i(r[0],r[1],r[2])),t[0]=r[0],t[1]=r[1],t[2]=r[2],t[3]=c):c=t[3];let l=c,u;return t[4]===l?u=t[5]:(u=(0,o.jsx)(`lineSegments`,{geometry:l,renderOrder:9999,children:s}),t[4]=l,t[5]=u),u}function l(e){let t=(0,a.c)(4),{radius:i}=e,c=i===void 0?1:i,l;t[0]===c?l=t[1]:(l=new n(new r(c,8,6)),t[0]=c,t[1]=l);let u=l,d;return t[2]===u?d=t[3]:(d=(0,o.jsx)(`lineSegments`,{geometry:u,renderOrder:9999,children:s}),t[2]=u,t[3]=d),d}export{l as n,c as t};
|
||||
|
|
@ -1 +1 @@
|
|||
import{r as e,t}from"./chunk-DECur_0Z.js";import{n,r,t as i}from"./jsx-runtime-BpGWiA-R.js";import{n as a,r as o}from"./react-three-fiber.esm-B4ybsNEe.js";import{t as s}from"./Html-BMPGAmIZ.js";var c=t(((e,t)=>{(function(n,r){typeof e==`object`&&t!==void 0?t.exports=r():typeof define==`function`&&define.amd?define(r):n.Stats=r()})(e,function(){var e=function(){function t(e){return i.appendChild(e.dom),e}function n(e){for(var t=0;t<i.children.length;t++)i.children[t].style.display=t===e?`block`:`none`;r=e}var r=0,i=document.createElement(`div`);i.style.cssText=`position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000`,i.addEventListener(`click`,function(e){e.preventDefault(),n(++r%i.children.length)},!1);var a=(performance||Date).now(),o=a,s=0,c=t(new e.Panel(`FPS`,`#0ff`,`#002`)),l=t(new e.Panel(`MS`,`#0f0`,`#020`));if(self.performance&&self.performance.memory)var u=t(new e.Panel(`MB`,`#f08`,`#201`));return n(0),{REVISION:16,dom:i,addPanel:t,showPanel:n,begin:function(){a=(performance||Date).now()},end:function(){s++;var e=(performance||Date).now();if(l.update(e-a,200),e>o+1e3&&(c.update(1e3*s/(e-o),100),o=e,s=0,u)){var t=performance.memory;u.update(t.usedJSHeapSize/1048576,t.jsHeapSizeLimit/1048576)}return e},update:function(){a=this.end()},domElement:i,setMode:n}};return e.Panel=function(e,t,n){var r=1/0,i=0,a=Math.round,o=a(window.devicePixelRatio||1),s=80*o,c=48*o,l=3*o,u=2*o,d=3*o,f=15*o,p=74*o,m=30*o,h=document.createElement(`canvas`);h.width=s,h.height=c,h.style.cssText=`width:80px;height:48px`;var g=h.getContext(`2d`);return g.font=`bold `+9*o+`px Helvetica,Arial,sans-serif`,g.textBaseline=`top`,g.fillStyle=n,g.fillRect(0,0,s,c),g.fillStyle=t,g.fillText(e,l,u),g.fillRect(d,f,p,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d,f,p,m),{dom:h,update:function(c,_){r=Math.min(r,c),i=Math.max(i,c),g.fillStyle=n,g.globalAlpha=1,g.fillRect(0,0,s,f),g.fillStyle=t,g.fillText(a(c)+` `+e+` (`+a(r)+`-`+a(i)+`)`,l,u),g.drawImage(h,d+o,f,p-o,m,d,f,p-o,m),g.fillRect(d+p-o,f,o,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d+p-o,f,o,a((1-c/_)*m))}}},e})})),l=e(r());function u(e,t){typeof e==`function`?e(t):e!=null&&(e.current=t)}function d(e,t=[],n){let[r,i]=l.useState();return l.useLayoutEffect(()=>{let t=e();return i(t),u(n,t),()=>u(n,null)},t),r}var f=e(c());function p({showPanel:e=0,className:t,parent:n}){let r=d(()=>new f.default,[]);return l.useEffect(()=>{if(r){let i=n&&n.current||document.body;r.showPanel(e),i?.appendChild(r.dom);let s=(t??``).split(` `).filter(e=>e);s.length&&r.dom.classList.add(...s);let c=o(()=>r.begin()),l=a(()=>r.end());return()=>{s.length&&r.dom.classList.remove(...s),i?.removeChild(r.dom),c(),l()}}},[n,r,t,e]),null}var m=n(),h={StatsPanel:`_StatsPanel_10m5i_1`,AxisLabel:`_AxisLabel_10m5i_8`},g=i();function _(){let e=(0,m.c)(10),t=(0,l.useRef)(null),n;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(n=()=>{let e=t.current;e&&e.setColors(`rgb(153, 255, 0)`,`rgb(0, 153, 255)`,`rgb(255, 153, 0)`)},e[0]=n):n=e[0],(0,l.useEffect)(n);let r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,g.jsx)(p,{className:h.StatsPanel}),e[1]=r):r=e[1];let i;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(i=[70],e[2]=i):i=e[2];let a;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,g.jsx)(`axesHelper`,{ref:t,args:i,renderOrder:999,children:(0,g.jsx)(`lineBasicMaterial`,{depthTest:!1,depthWrite:!1,fog:!1,vertexColors:!0})}),e[3]=a):a=e[3];let o;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(o=[80,0,0],e[4]=o):o=e[4];let c;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,g.jsx)(s,{position:o,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`y`,children:`Y`})}),e[5]=c):c=e[5];let u;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=[0,80,0],e[6]=u):u=e[6];let d;e[7]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,g.jsx)(s,{position:u,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`z`,children:`Z`})}),e[7]=d):d=e[7];let f;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(f=[0,0,80],e[8]=f):f=e[8];let _;return e[9]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,g.jsxs)(g.Fragment,{children:[r,a,c,d,(0,g.jsx)(s,{position:f,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`x`,children:`X`})})]}),e[9]=_):_=e[9],_}export{_ as DebugElements};
|
||||
import{r as e,t}from"./chunk-DECur_0Z.js";import{n,r,t as i}from"./jsx-runtime-BpGWiA-R.js";import{n as a,r as o}from"./react-three-fiber.esm-El6vNTZj.js";import{t as s}from"./Html-CXAi5FD_.js";var c=t(((e,t)=>{(function(n,r){typeof e==`object`&&t!==void 0?t.exports=r():typeof define==`function`&&define.amd?define(r):n.Stats=r()})(e,function(){var e=function(){function t(e){return i.appendChild(e.dom),e}function n(e){for(var t=0;t<i.children.length;t++)i.children[t].style.display=t===e?`block`:`none`;r=e}var r=0,i=document.createElement(`div`);i.style.cssText=`position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000`,i.addEventListener(`click`,function(e){e.preventDefault(),n(++r%i.children.length)},!1);var a=(performance||Date).now(),o=a,s=0,c=t(new e.Panel(`FPS`,`#0ff`,`#002`)),l=t(new e.Panel(`MS`,`#0f0`,`#020`));if(self.performance&&self.performance.memory)var u=t(new e.Panel(`MB`,`#f08`,`#201`));return n(0),{REVISION:16,dom:i,addPanel:t,showPanel:n,begin:function(){a=(performance||Date).now()},end:function(){s++;var e=(performance||Date).now();if(l.update(e-a,200),e>o+1e3&&(c.update(1e3*s/(e-o),100),o=e,s=0,u)){var t=performance.memory;u.update(t.usedJSHeapSize/1048576,t.jsHeapSizeLimit/1048576)}return e},update:function(){a=this.end()},domElement:i,setMode:n}};return e.Panel=function(e,t,n){var r=1/0,i=0,a=Math.round,o=a(window.devicePixelRatio||1),s=80*o,c=48*o,l=3*o,u=2*o,d=3*o,f=15*o,p=74*o,m=30*o,h=document.createElement(`canvas`);h.width=s,h.height=c,h.style.cssText=`width:80px;height:48px`;var g=h.getContext(`2d`);return g.font=`bold `+9*o+`px Helvetica,Arial,sans-serif`,g.textBaseline=`top`,g.fillStyle=n,g.fillRect(0,0,s,c),g.fillStyle=t,g.fillText(e,l,u),g.fillRect(d,f,p,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d,f,p,m),{dom:h,update:function(c,_){r=Math.min(r,c),i=Math.max(i,c),g.fillStyle=n,g.globalAlpha=1,g.fillRect(0,0,s,f),g.fillStyle=t,g.fillText(a(c)+` `+e+` (`+a(r)+`-`+a(i)+`)`,l,u),g.drawImage(h,d+o,f,p-o,m,d,f,p-o,m),g.fillRect(d+p-o,f,o,m),g.fillStyle=n,g.globalAlpha=.9,g.fillRect(d+p-o,f,o,a((1-c/_)*m))}}},e})})),l=e(r());function u(e,t){typeof e==`function`?e(t):e!=null&&(e.current=t)}function d(e,t=[],n){let[r,i]=l.useState();return l.useLayoutEffect(()=>{let t=e();return i(t),u(n,t),()=>u(n,null)},t),r}var f=e(c());function p({showPanel:e=0,className:t,parent:n}){let r=d(()=>new f.default,[]);return l.useEffect(()=>{if(r){let i=n&&n.current||document.body;r.showPanel(e),i?.appendChild(r.dom);let s=(t??``).split(` `).filter(e=>e);s.length&&r.dom.classList.add(...s);let c=o(()=>r.begin()),l=a(()=>r.end());return()=>{s.length&&r.dom.classList.remove(...s),i?.removeChild(r.dom),c(),l()}}},[n,r,t,e]),null}var m=n(),h={StatsPanel:`_StatsPanel_10m5i_1`,AxisLabel:`_AxisLabel_10m5i_8`},g=i();function _(){let e=(0,m.c)(10),t=(0,l.useRef)(null),n;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(n=()=>{let e=t.current;e&&e.setColors(`rgb(153, 255, 0)`,`rgb(0, 153, 255)`,`rgb(255, 153, 0)`)},e[0]=n):n=e[0],(0,l.useEffect)(n);let r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,g.jsx)(p,{className:h.StatsPanel}),e[1]=r):r=e[1];let i;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(i=[70],e[2]=i):i=e[2];let a;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,g.jsx)(`axesHelper`,{ref:t,args:i,renderOrder:999,children:(0,g.jsx)(`lineBasicMaterial`,{depthTest:!1,depthWrite:!1,fog:!1,vertexColors:!0})}),e[3]=a):a=e[3];let o;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(o=[80,0,0],e[4]=o):o=e[4];let c;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,g.jsx)(s,{position:o,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`y`,children:`Y`})}),e[5]=c):c=e[5];let u;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=[0,80,0],e[6]=u):u=e[6];let d;e[7]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,g.jsx)(s,{position:u,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`z`,children:`Z`})}),e[7]=d):d=e[7];let f;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(f=[0,0,80],e[8]=f):f=e[8];let _;return e[9]===Symbol.for(`react.memo_cache_sentinel`)?(_=(0,g.jsxs)(g.Fragment,{children:[r,a,c,d,(0,g.jsx)(s,{position:f,center:!0,children:(0,g.jsx)(`span`,{className:h.AxisLabel,"data-axis":`x`,children:`X`})})]}),e[9]=_):_=e[9],_}export{_ as DebugElements};
|
||||
|
|
@ -1 +1 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{t as i}from"./logger-CySD1nLn.js";var a=t(),o=e(n(),1),s=r(),c=i(`DebugSuspense`);function l(e){let t=(0,a.c)(10),{name:n,fallback:r,children:i}=e,c=r===void 0?null:r,l;t[0]!==c||t[1]!==n?(l=(0,s.jsx)(u,{name:n,children:c}),t[0]=c,t[1]=n,t[2]=l):l=t[2];let f;t[3]===n?f=t[4]:(f=(0,s.jsx)(d,{name:n}),t[3]=n,t[4]=f);let p;return t[5]!==i||t[6]!==n||t[7]!==l||t[8]!==f?(p=(0,s.jsxs)(o.Suspense,{name:n,fallback:l,children:[f,i]}),t[5]=i,t[6]=n,t[7]=l,t[8]=f,t[9]=p):p=t[9],p}function u(e){let t=(0,a.c)(3),{name:n,children:r}=e,i,s;return t[0]===n?(i=t[1],s=t[2]):(i=()=>{c.debug(`🛑 SUSPENDED: %s`,n)},s=[n],t[0]=n,t[1]=i,t[2]=s),(0,o.useEffect)(i,s),r}function d(e){let t=(0,a.c)(3),{name:n}=e,r,i;return t[0]===n?(r=t[1],i=t[2]):(r=()=>{c.debug(`✅ RESOLVED: %s`,n)},i=[n],t[0]=n,t[1]=r,t[2]=i),(0,o.useEffect)(r,i),null}export{l as t};
|
||||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{t as i}from"./logger-B058WGzf.js";var a=t(),o=e(n(),1),s=r(),c=i(`DebugSuspense`);function l(e){let t=(0,a.c)(10),{name:n,fallback:r,children:i}=e,c=r===void 0?null:r,l;t[0]!==c||t[1]!==n?(l=(0,s.jsx)(u,{name:n,children:c}),t[0]=c,t[1]=n,t[2]=l):l=t[2];let f;t[3]===n?f=t[4]:(f=(0,s.jsx)(d,{name:n}),t[3]=n,t[4]=f);let p;return t[5]!==i||t[6]!==n||t[7]!==l||t[8]!==f?(p=(0,s.jsxs)(o.Suspense,{name:n,fallback:l,children:[f,i]}),t[5]=i,t[6]=n,t[7]=l,t[8]=f,t[9]=p):p=t[9],p}function u(e){let t=(0,a.c)(3),{name:n,children:r}=e,i,s;return t[0]===n?(i=t[1],s=t[2]):(i=()=>{c.debug(`🛑 SUSPENDED: %s`,n)},s=[n],t[0]=n,t[1]=i,t[2]=s),(0,o.useEffect)(i,s),r}function d(e){let t=(0,a.c)(3),{name:n}=e,r,i;return t[0]===n?(r=t[1],i=t[2]):(r=()=>{c.debug(`✅ RESOLVED: %s`,n)},i=[n],t[0]=n,t[1]=r,t[2]=i),(0,o.useEffect)(r,i),null}export{l as t};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{B as i,H as a,I as o,L as s,R as c,V as l,w as u,z as d}from"./index-BEehCpzM.js";import{n as f,t as p}from"./gr-CIZJuMcZ.js";var m=e(n(),1),h=t(),g={Root:`_Root_flggk_1`,PlayPause:`_PlayPause_flggk_16 _Button_p0g82_2`,Time:`_Time_flggk_36`,Seek:`_Seek_flggk_54`,Speed:`_Speed_flggk_61`,CameraMode:`_CameraMode_flggk_62`,Field:`_Field_flggk_80`},_=r();function v(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=Math.floor(e%60);return t>0?`${t}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n}:${r.toString().padStart(2,`0`)}`}function y(){let e=(0,h.c)(42),t=l(),n=d(),r=s(),y=c(),x=a(),{play:S,pause:C,seek:w,setSpeed:T}=i(),E,D;e[0]!==n||e[1]!==C||e[2]!==S||e[3]!==t?(E=()=>{if(!t)return;let e=e=>{if(e.code!==`Space`)return;let t=e.target;t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.tagName===`SELECT`||t.tagName===`BUTTON`||t.isContentEditable||(e.preventDefault(),n?C():S())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},D=[t,n,S,C],e[0]=n,e[1]=C,e[2]=S,e[3]=t,e[4]=E,e[5]=D):(E=e[4],D=e[5]),(0,m.useEffect)(E,D);let O;e[6]!==T||e[7]!==x?(O=()=>{let e=o.indexOf(x);e>0&&T(o[e-1])},e[6]=T,e[7]=x,e[8]=O):O=e[8],u(`decreasePlaybackSpeed`,O);let k;e[9]!==T||e[10]!==x?(k=()=>{let e=o.indexOf(x);e<o.length-1&&T(o[e+1])},e[9]=T,e[10]=x,e[11]=k):k=e[11],u(`increasePlaybackSpeed`,k);let A;e[12]===w?A=e[13]:(A=e=>{w(parseFloat(e.target.value))},e[12]=w,e[13]=A);let j=A,M;e[14]===T?M=e[15]:(M=e=>{T(parseFloat(e.target.value))},e[14]=T,e[15]=M);let N=M;if(!t||!Number.isFinite(t.duration))return null;let P=n?C:S,F=n?`Pause`:`Play`,I;e[16]===n?I=e[17]:(I=n?(0,_.jsx)(p,{}):(0,_.jsx)(f,{}),e[16]=n,e[17]=I);let L;e[18]!==P||e[19]!==F||e[20]!==I?(L=(0,_.jsx)(`button`,{className:g.PlayPause,onClick:P,"aria-label":F,autoFocus:!0,children:I}),e[18]=P,e[19]=F,e[20]=I,e[21]=L):L=e[21];let R;e[22]===r?R=e[23]:(R=v(r),e[22]=r,e[23]=R);let z;e[24]===y?z=e[25]:(z=v(y),e[24]=y,e[25]=z);let B=`${R} / ${z}`,V;e[26]===B?V=e[27]:(V=(0,_.jsx)(`span`,{className:g.Time,children:B}),e[26]=B,e[27]=V);let H;e[28]!==r||e[29]!==y||e[30]!==j?(H=(0,_.jsx)(`input`,{className:g.Seek,type:`range`,min:0,max:y,step:.01,value:r,onChange:j}),e[28]=r,e[29]=y,e[30]=j,e[31]=H):H=e[31];let U;e[32]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,_.jsx)(`label`,{htmlFor:`playbackSpeed`,children:`Speed`}),e[32]=U):U=e[32];let W;e[33]===Symbol.for(`react.memo_cache_sentinel`)?(W=o.map(b),e[33]=W):W=e[33];let G;e[34]!==N||e[35]!==x?(G=(0,_.jsxs)(`div`,{className:g.Field,children:[U,(0,_.jsx)(`select`,{id:`playbackSpeed`,className:g.Speed,value:x,onChange:N,children:W})]}),e[34]=N,e[35]=x,e[36]=G):G=e[36];let K;return e[37]!==V||e[38]!==H||e[39]!==G||e[40]!==L?(K=(0,_.jsxs)(`div`,{className:g.Root,children:[L,V,H,G]}),e[37]=V,e[38]=H,e[39]=G,e[40]=L,e[41]=K):K=e[41],K}function b(e){return(0,_.jsxs)(`option`,{value:e,children:[e,`×`]},e)}export{y as DemoPlaybackControls};
|
||||
1
docs/assets/DemoPlaybackControls-DrXShtXN.js
Normal file
1
docs/assets/DemoPlaybackControls-DrXShtXN.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{C as i,D as a,E as o,O as s,S as c,T as l,u,w as d}from"./index-D4aiQcCU.js";import{n as f,t as p}from"./gr-DFj_ScyC.js";var m=e(n(),1),h=t(),g={Root:`_Root_flggk_1`,PlayPause:`_PlayPause_flggk_16 _Button_p0g82_2`,Time:`_Time_flggk_36`,Seek:`_Seek_flggk_54`,Speed:`_Speed_flggk_61`,CameraMode:`_CameraMode_flggk_62`,Field:`_Field_flggk_80`},_=r();function v(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=Math.floor(e%60);return t>0?`${t}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n}:${r.toString().padStart(2,`0`)}`}function y(){let e=(0,h.c)(42),t=a(),n=l(),r=i(),y=d(),x=s(),{play:S,pause:C,seek:w,setSpeed:T}=o(),E,D;e[0]!==n||e[1]!==C||e[2]!==S||e[3]!==t?(E=()=>{if(!t)return;let e=e=>{if(e.code!==`Space`)return;let t=e.target;t.tagName===`INPUT`||t.tagName===`TEXTAREA`||t.tagName===`SELECT`||t.tagName===`BUTTON`||t.isContentEditable||(e.preventDefault(),n?C():S())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},D=[t,n,S,C],e[0]=n,e[1]=C,e[2]=S,e[3]=t,e[4]=E,e[5]=D):(E=e[4],D=e[5]),(0,m.useEffect)(E,D);let O;e[6]!==T||e[7]!==x?(O=()=>{let e=c.indexOf(x);e>0&&T(c[e-1])},e[6]=T,e[7]=x,e[8]=O):O=e[8],u(`decreasePlaybackSpeed`,O);let k;e[9]!==T||e[10]!==x?(k=()=>{let e=c.indexOf(x);e<c.length-1&&T(c[e+1])},e[9]=T,e[10]=x,e[11]=k):k=e[11],u(`increasePlaybackSpeed`,k);let A;e[12]===w?A=e[13]:(A=e=>{w(parseFloat(e.target.value))},e[12]=w,e[13]=A);let j=A,M;e[14]===T?M=e[15]:(M=e=>{T(parseFloat(e.target.value))},e[14]=T,e[15]=M);let N=M;if(!t||!Number.isFinite(t.duration))return null;let P=n?C:S,F=n?`Pause`:`Play`,I;e[16]===n?I=e[17]:(I=n?(0,_.jsx)(p,{}):(0,_.jsx)(f,{}),e[16]=n,e[17]=I);let L;e[18]!==P||e[19]!==F||e[20]!==I?(L=(0,_.jsx)(`button`,{className:g.PlayPause,onClick:P,"aria-label":F,autoFocus:!0,children:I}),e[18]=P,e[19]=F,e[20]=I,e[21]=L):L=e[21];let R;e[22]===r?R=e[23]:(R=v(r),e[22]=r,e[23]=R);let z;e[24]===y?z=e[25]:(z=v(y),e[24]=y,e[25]=z);let B=`${R} / ${z}`,V;e[26]===B?V=e[27]:(V=(0,_.jsx)(`span`,{className:g.Time,children:B}),e[26]=B,e[27]=V);let H;e[28]!==r||e[29]!==y||e[30]!==j?(H=(0,_.jsx)(`input`,{className:g.Seek,type:`range`,min:0,max:y,step:.01,value:r,onChange:j}),e[28]=r,e[29]=y,e[30]=j,e[31]=H):H=e[31];let U;e[32]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,_.jsx)(`label`,{htmlFor:`playbackSpeed`,children:`Speed`}),e[32]=U):U=e[32];let W;e[33]===Symbol.for(`react.memo_cache_sentinel`)?(W=c.map(b),e[33]=W):W=e[33];let G;e[34]!==N||e[35]!==x?(G=(0,_.jsxs)(`div`,{className:g.Field,children:[U,(0,_.jsx)(`select`,{id:`playbackSpeed`,className:g.Speed,value:x,onChange:N,children:W})]}),e[34]=N,e[35]=x,e[36]=G):G=e[36];let K;return e[37]!==V||e[38]!==H||e[39]!==G||e[40]!==L?(K=(0,_.jsxs)(`div`,{className:g.Root,children:[L,V,H,G]}),e[37]=V,e[38]=H,e[39]=G,e[40]=L,e[41]=K):K=e[41],K}function b(e){return(0,_.jsxs)(`option`,{value:e,children:[e,`×`]},e)}export{y as DemoPlaybackControls};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{a as r}from"./react-three-fiber.esm-B4ybsNEe.js";import{n as i,r as a}from"./engineStore-DXFfg1NG.js";import{$ as o,o as s}from"./three.module-DeDv86YO.js";import{i as c,l}from"./GenericShape-Disamruh.js";import{_ as u,a as d,g as f,h as p,l as m}from"./playbackUtils-D5VkIMBR.js";import{t as h}from"./useAnisotropy-D9b509fd.js";import{n as g}from"./streamPlaybackStore-CGokDWAy.js";var _=e(t(),1),v=n();function y(e){let t=e.sizes,n=e.times;if(!Array.isArray(t)||t.length===0)return{times:[0,1],sizes:[[1,1,1],[1,1,1]]};let r=t.map(e=>[e.x/100,e.y/100,e.z/100]);return{times:Array.isArray(n)?n:r.map((e,t)=>t/Math.max(r.length-1,1)),sizes:r}}function b(e,t){let{times:n,sizes:r}=e;if(n.length===0)return[1,1,1];if(t<=n[0])return r[0];if(t>=n[n.length-1])return r[r.length-1];for(let e=0;e<n.length-1;e++)if(t>=n[e]&&t<=n[e+1]){let i=(t-n[e])/(n[e+1]-n[e]);return[r[e][0]+(r[e+1][0]-r[e][0])*i,r[e][1]+(r[e+1][1]-r[e][1])*i,r[e][2]+(r[e+1][2]-r[e][2])*i]}return r[r.length-1]}function x({entity:e}){let t=g.getState().playback,n=c(e.shapeName),x=h(),S=(0,_.useRef)(null),C=(0,_.useRef)(i()),w=(0,_.useRef)(Math.random()*Math.PI*2),T=(0,_.useRef)([]),E=(0,_.useMemo)(()=>{if(e.explosionDataBlockId)return t.getDataBlockData(e.explosionDataBlockId)},[e.explosionDataBlockId,t]),D=(0,_.useMemo)(()=>E?y(E):void 0,[E]),O=(0,_.useMemo)(()=>{let e=E?.explosionScale;return e?[e.x/100,e.y/100,e.z/100]:[1,1,1]},[E]),k=(E?.lifetimeMS??31)*32,A=e.faceViewer!==!1,{scene:j,mixer:M,visNodes:N,iflInfos:P,materials:F}=(0,_.useMemo)(()=>{let t=l(n.scene),r=[];t.traverse(e=>{if(!e.isMesh||!e.material)return;let t=Array.isArray(e.material)?e.material[0]:e.material;if(!t?.userData)return;let n=new Set(t.userData.flag_names??[]),i=t.userData.resource_path;if(n.has(`IflMaterial`)&&i){let t=e.userData;r.push({mesh:e,iflPath:`textures/${i}.ifl`,sequenceName:t?.ifl_sequence?String(t.ifl_sequence).toLowerCase():void 0,duration:t?.ifl_duration?Number(t.ifl_duration):void 0,cyclic:t?.ifl_sequence?!!t.ifl_cyclic:void 0,toolBegin:t?.ifl_tool_begin==null?void 0:Number(t.ifl_tool_begin)})}}),m(t,e.shapeName,{anisotropy:x});let i=[];t.traverse(e=>{if(!e.isMesh)return;let t=e.userData;if(!t)return;let n=t.vis_keyframes,r=t.vis_duration,a=(t.vis_sequence??``).toLowerCase();!a||!Array.isArray(n)||n.length<=1||!r||r<=0||a===`ambient`&&i.push({mesh:e,keyframes:n,duration:r,cyclic:!!t.vis_cyclic})});for(let e of i)e.mesh.visible=!0,e.mesh.material&&!Array.isArray(e.mesh.material)&&(e.mesh.material.transparent=!0,e.mesh.material.depthWrite=!1);for(let e of r)e.mesh.userData?.vis_sequence||(e.mesh.visible=!0);let a=new Map;for(let e of n.animations)a.set(e.name.toLowerCase(),e);let c=a.get(`ambient`),u=null;if(c){u=new s(t);let e=u.clipAction(c);e.setLoop(o,1),e.clampWhenFinished=!0,e.timeScale=(E?.playSpeed??20)/20,e.play()}let d=[];return t.traverse(e=>{e.isMesh&&(Array.isArray(e.material)?d.push(...e.material):e.material&&d.push(e.material))}),t.traverse(e=>{e.frustumCulled=!1}),{scene:t,mixer:u,visNodes:i,iflInfos:r,materials:d}},[n,E,x]);return(0,_.useEffect)(()=>()=>{d(j),M?.uncacheRoot(j)},[j,M]),(0,_.useEffect)(()=>{T.current=[];for(let e of P)f(e.iflPath).then(t=>{let n=Array.isArray(e.mesh.material)?e.mesh.material[0]:e.mesh.material;n&&(n.map=t.texture,n.needsUpdate=!0),T.current.push({atlas:t,info:e})}).catch(()=>{})},[P]),r((e,t)=>{let n=S.current;if(!n)return;let r=a.getState().playback,o=r.status===`playing`?t*r.rate:0,s=i()-C.current,c=Math.min(s/k,1),l=s/1e3;M&&M.update(o);let d=c>.8?1-(c-.8)/.2:1;for(let{mesh:e,keyframes:t,duration:n,cyclic:r}of N){let i=e.material;if(!i||Array.isArray(i))continue;let a=l/n,o=r?a%1:Math.min(a,1),s=t.length,c=o*s,u=Math.floor(c)%s,f=(u+1)%s,p=c-Math.floor(c);i.opacity=(t[u]+(t[f]-t[u])*p)*d}if(d<1)for(let e of F)`opacity`in e&&(e.transparent=!0,e.opacity*=d);for(let{atlas:e,info:t}of T.current){let n;n=t.sequenceName&&t.duration?(t.cyclic?l/t.duration%1:Math.min(l/t.duration,1))*t.duration+(t.toolBegin??0):l,u(e,p(e,n))}if(D){let e=b(D,c);n.scale.set(e[0]*O[0],e[1]*O[1],e[2]*O[2])}A&&(n.lookAt(e.camera.position),n.rotateZ(w.current))}),(0,v.jsx)(`group`,{ref:S,children:(0,v.jsx)(`group`,{rotation:[0,Math.PI,0],children:(0,v.jsx)(`primitive`,{object:j})})})}export{x as ExplosionShape};
|
||||
1
docs/assets/ExplosionShape-Cmot7uAQ.js
Normal file
1
docs/assets/ExplosionShape-Cmot7uAQ.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{a as r}from"./react-three-fiber.esm-El6vNTZj.js";import{$ as i,o as a}from"./three.module-DKAirPAO.js";import{c as o,f as s}from"./PlayerModel-DY4jKfUP.js";import{_ as c,a as l,g as u,h as d,l as f}from"./playbackUtils-DjmjN4tv.js";import{n as p,r as m}from"./engineStore-B1KAgiiF.js";import{t as h}from"./useAnisotropy-D9othEmk.js";import{n as g}from"./streamPlaybackStore-D5ldcfU5.js";var _=e(t(),1),v=n();function y(e){let t=e.sizes,n=e.times;if(!Array.isArray(t)||t.length===0)return{times:[0,1],sizes:[[1,1,1],[1,1,1]]};let r=t.map(e=>[e.x/100,e.y/100,e.z/100]);return{times:Array.isArray(n)?n:r.map((e,t)=>t/Math.max(r.length-1,1)),sizes:r}}function b(e,t){let{times:n,sizes:r}=e;if(n.length===0)return[1,1,1];if(t<=n[0])return r[0];if(t>=n[n.length-1])return r[r.length-1];for(let e=0;e<n.length-1;e++)if(t>=n[e]&&t<=n[e+1]){let i=(t-n[e])/(n[e+1]-n[e]);return[r[e][0]+(r[e+1][0]-r[e][0])*i,r[e][1]+(r[e+1][1]-r[e][1])*i,r[e][2]+(r[e+1][2]-r[e][2])*i]}return r[r.length-1]}function x({entity:e}){let t=g.getState().playback,n=o(e.shapeName),x=h(),S=(0,_.useRef)(null),C=(0,_.useRef)(p()),w=(0,_.useRef)(Math.random()*Math.PI*2),T=(0,_.useRef)([]),E=(0,_.useMemo)(()=>{if(e.explosionDataBlockId)return t.getDataBlockData(e.explosionDataBlockId)},[e.explosionDataBlockId,t]),D=(0,_.useMemo)(()=>E?y(E):void 0,[E]),O=(0,_.useMemo)(()=>{let e=E?.explosionScale;return e?[e.x/100,e.y/100,e.z/100]:[1,1,1]},[E]),k=(E?.lifetimeMS??31)*32,A=e.faceViewer!==!1,{scene:j,mixer:M,visNodes:N,iflInfos:P,materials:F}=(0,_.useMemo)(()=>{let t=s(n.scene),r=[];t.traverse(e=>{if(!e.isMesh||!e.material)return;let t=Array.isArray(e.material)?e.material[0]:e.material;if(!t?.userData)return;let n=new Set(t.userData.flag_names??[]),i=t.userData.resource_path;if(n.has(`IflMaterial`)&&i){let t=e.userData;r.push({mesh:e,iflPath:`textures/${i}.ifl`,sequenceName:t?.ifl_sequence?String(t.ifl_sequence).toLowerCase():void 0,duration:t?.ifl_duration?Number(t.ifl_duration):void 0,cyclic:t?.ifl_sequence?!!t.ifl_cyclic:void 0,toolBegin:t?.ifl_tool_begin==null?void 0:Number(t.ifl_tool_begin)})}}),f(t,e.shapeName,{anisotropy:x});let o=[];t.traverse(e=>{if(!e.isMesh)return;let t=e.userData;if(!t)return;let n=t.vis_keyframes,r=t.vis_duration,i=(t.vis_sequence??``).toLowerCase();!i||!Array.isArray(n)||n.length<=1||!r||r<=0||i===`ambient`&&o.push({mesh:e,keyframes:n,duration:r,cyclic:!!t.vis_cyclic})});for(let e of o)e.mesh.visible=!0,e.mesh.material&&!Array.isArray(e.mesh.material)&&(e.mesh.material.transparent=!0,e.mesh.material.depthWrite=!1);for(let e of r)e.mesh.userData?.vis_sequence||(e.mesh.visible=!0);let c=new Map;for(let e of n.animations)c.set(e.name.toLowerCase(),e);let l=c.get(`ambient`),u=null;if(l){u=new a(t);let e=u.clipAction(l);e.setLoop(i,1),e.clampWhenFinished=!0,e.timeScale=(E?.playSpeed??20)/20,e.play()}let d=[];return t.traverse(e=>{e.isMesh&&(Array.isArray(e.material)?d.push(...e.material):e.material&&d.push(e.material))}),t.traverse(e=>{e.frustumCulled=!1}),{scene:t,mixer:u,visNodes:o,iflInfos:r,materials:d}},[n,E,x]);return(0,_.useEffect)(()=>()=>{l(j),M?.uncacheRoot(j)},[j,M]),(0,_.useEffect)(()=>{T.current=[];for(let e of P)u(e.iflPath).then(t=>{let n=Array.isArray(e.mesh.material)?e.mesh.material[0]:e.mesh.material;n&&(n.map=t.texture,n.needsUpdate=!0),T.current.push({atlas:t,info:e})}).catch(()=>{})},[P]),r((e,t)=>{let n=S.current;if(!n)return;let r=m.getState().playback,i=r.status===`playing`?t*r.rate:0,a=p()-C.current,o=Math.min(a/k,1),s=a/1e3;M&&M.update(i);let l=o>.8?1-(o-.8)/.2:1;for(let{mesh:e,keyframes:t,duration:n,cyclic:r}of N){let i=e.material;if(!i||Array.isArray(i))continue;let a=s/n,o=r?a%1:Math.min(a,1),c=t.length,u=o*c,d=Math.floor(u)%c,f=(d+1)%c,p=u-Math.floor(u);i.opacity=(t[d]+(t[f]-t[d])*p)*l}if(l<1)for(let e of F)`opacity`in e&&(e.transparent=!0,e.opacity*=l);for(let{atlas:e,info:t}of T.current){let n;n=t.sequenceName&&t.duration?(t.cyclic?s/t.duration%1:Math.min(s/t.duration,1))*t.duration+(t.toolBegin??0):s,c(e,d(e,n))}if(D){let e=b(D,o);n.scale.set(e[0]*O[0],e[1]*O[1],e[2]*O[2])}A&&(n.lookAt(e.camera.position),n.rotateZ(w.current))}),(0,v.jsx)(`group`,{ref:S,children:(0,v.jsx)(`group`,{rotation:[0,Math.PI,0],children:(0,v.jsx)(`primitive`,{object:j})})})}export{x as ExplosionShape};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{a as i}from"./react-three-fiber.esm-B4ybsNEe.js";import{a}from"./SettingsProvider-BeB5OnG9.js";import{r as o}from"./cameraTourStore-CfKPrs02.js";import{Ot as s,Ut as c,b as l,jt as u,p as d}from"./three.module-DeDv86YO.js";import{t as f}from"./Texture-DuIJU_zO.js";import{p}from"./index-BEehCpzM.js";import{t as m}from"./DebugBounds-DUxS5ppE.js";import{t as h}from"./DebugSuspense-DmIsfY-y.js";var g=e(n(),1),_=t(),v=`
|
||||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{a as i}from"./react-three-fiber.esm-El6vNTZj.js";import{a}from"./SettingsProvider-BdqQ2Cm4.js";import{Ot as o,Ut as s,b as c,jt as l,p as u}from"./three.module-DKAirPAO.js";import{p as d}from"./loaders-B4T775qz.js";import{t as f}from"./Texture-BYh0PjzP.js";import{r as p}from"./cameraTourStore-CtH3IrnD.js";import{t as m}from"./DebugBounds-CZKrvsAw.js";import{t as h}from"./DebugSuspense-ChOWTvws.js";var g=e(n(),1),_=t(),v=`
|
||||
#include <fog_pars_vertex>
|
||||
|
||||
varying vec2 vUv;
|
||||
|
|
@ -72,4 +72,4 @@ void main() {
|
|||
gl_FragColor.a *= 1.0 - fogFactor;
|
||||
#endif
|
||||
}
|
||||
`;function b({textures:e,scale:t,umapping:n,vmapping:r,color:i,baseTranslucency:a}){let o=[...t].sort((e,t)=>t-e),s=new c(o[0]*n,o[1]*r),d=e[0];return new u({uniforms:{frame0:{value:d},frame1:{value:e[1]??d},frame2:{value:e[2]??d},frame3:{value:e[3]??d},frame4:{value:e[4]??d},currentFrame:{value:0},vScroll:{value:0},uvScale:{value:s},tintColor:{value:new l(...i)},opacity:{value:a},opacityFactor:{value:1},fogColor:{value:new l},fogNear:{value:1},fogFar:{value:2e3}},vertexShader:v,fragmentShader:y,transparent:!0,blending:2,side:2,depthWrite:!1,fog:!0})}var x=r();function S(e){e.wrapS=e.wrapT=s,e.colorSpace=``,e.flipY=!1,e.needsUpdate=!0}function C(e){let t=(0,_.c)(7),[n,r,i]=e,a;t[0]!==n||t[1]!==r||t[2]!==i?(a=new d(n,r,i),a.translate(n/2,r/2,i/2),t[0]=n,t[1]=r,t[2]=i,t[3]=a):a=t[3];let o=a,s,c;return t[4]===o?(s=t[5],c=t[6]):(s=()=>()=>o.dispose(),c=[o],t[4]=o,t[5]=s,t[6]=c),(0,g.useEffect)(s,c),o}function w(e){let t=(0,_.c)(10),{scale:n,color:r,baseTranslucency:i}=e,a=C(n),o;t[0]!==r[0]||t[1]!==r[1]||t[2]!==r[2]?(o=new l(r[0],r[1],r[2]),t[0]=r[0],t[1]=r[1],t[2]=r[2],t[3]=o):o=t[3];let s=o,c=i*1,u;t[4]!==s||t[5]!==c?(u=(0,x.jsx)(`meshBasicMaterial`,{color:s,transparent:!0,opacity:c,blending:2,side:2,depthWrite:!1,fog:!1}),t[4]=s,t[5]=c,t[6]=u):u=t[6];let d;return t[7]!==a||t[8]!==u?(d=(0,x.jsx)(`mesh`,{geometry:a,renderOrder:1,children:u}),t[7]=a,t[8]=u,t[9]=d):d=t[9],d}function T({scale:e,data:t}){let{animationEnabled:n}=a(),r=C(e),o=f((0,g.useMemo)(()=>t.textures.map(e=>p(e)),[t.textures]),e=>{e.forEach(e=>S(e))}),s=(0,g.useMemo)(()=>b({textures:o,scale:e,umapping:t.umapping,vmapping:t.vmapping,color:t.color,baseTranslucency:t.baseTranslucency}),[o,e,t]);(0,g.useEffect)(()=>()=>s.dispose(),[s]);let c=(0,g.useRef)(0);return i((e,r)=>{if(!n){c.current=0,s.uniforms.currentFrame.value=0,s.uniforms.vScroll.value=0;return}c.current+=r,s.uniforms.currentFrame.value=Math.floor(c.current*t.framesPerSec)%t.numFrames,s.uniforms.vScroll.value=c.current*t.scrollSpeed}),(0,x.jsx)(`mesh`,{geometry:r,material:s,renderOrder:1})}function E(e){let t=(0,_.c)(20),{entity:n}=e,r=n.forceFieldData,i=r.dimensions,a=o(n.id);if(r.textures.map(D).length===0){let e;return t[0]!==r.baseTranslucency||t[1]!==r.color||t[2]!==i?(e=(0,x.jsx)(w,{scale:i,color:r.color,baseTranslucency:r.baseTranslucency}),t[0]=r.baseTranslucency,t[1]=r.color,t[2]=i,t[3]=e):e=t[3],e}let s;t[4]!==r.baseTranslucency||t[5]!==r.color||t[6]!==i?(s=(0,x.jsx)(w,{scale:i,color:r.color,baseTranslucency:r.baseTranslucency}),t[4]=r.baseTranslucency,t[5]=r.color,t[6]=i,t[7]=s):s=t[7];let c;t[8]!==r||t[9]!==i?(c=(0,x.jsx)(T,{scale:i,data:r}),t[8]=r,t[9]=i,t[10]=c):c=t[10];let l;t[11]!==s||t[12]!==c?(l=(0,x.jsx)(h,{name:`ForceField`,fallback:s,children:c}),t[11]=s,t[12]=c,t[13]=l):l=t[13];let u;t[14]!==a||t[15]!==i?(u=a&&i&&(0,x.jsx)(m,{size:i}),t[14]=a,t[15]=i,t[16]=u):u=t[16];let d;return t[17]!==l||t[18]!==u?(d=(0,x.jsxs)(x.Fragment,{children:[l,u]}),t[17]=l,t[18]=u,t[19]=d):d=t[19],d}function D(e){return p(e)}export{E as ForceFieldBare};
|
||||
`;function b({textures:e,scale:t,umapping:n,vmapping:r,color:i,baseTranslucency:a}){let o=[...t].sort((e,t)=>t-e),u=new s(o[0]*n,o[1]*r),d=e[0];return new l({uniforms:{frame0:{value:d},frame1:{value:e[1]??d},frame2:{value:e[2]??d},frame3:{value:e[3]??d},frame4:{value:e[4]??d},currentFrame:{value:0},vScroll:{value:0},uvScale:{value:u},tintColor:{value:new c(...i)},opacity:{value:a},opacityFactor:{value:1},fogColor:{value:new c},fogNear:{value:1},fogFar:{value:2e3}},vertexShader:v,fragmentShader:y,transparent:!0,blending:2,side:2,depthWrite:!1,fog:!0})}var x=r();function S(e){e.wrapS=e.wrapT=o,e.colorSpace=``,e.flipY=!1,e.needsUpdate=!0}function C(e){let t=(0,_.c)(7),[n,r,i]=e,a;t[0]!==n||t[1]!==r||t[2]!==i?(a=new u(n,r,i),a.translate(n/2,r/2,i/2),t[0]=n,t[1]=r,t[2]=i,t[3]=a):a=t[3];let o=a,s,c;return t[4]===o?(s=t[5],c=t[6]):(s=()=>()=>o.dispose(),c=[o],t[4]=o,t[5]=s,t[6]=c),(0,g.useEffect)(s,c),o}function w(e){let t=(0,_.c)(10),{scale:n,color:r,baseTranslucency:i}=e,a=C(n),o;t[0]!==r[0]||t[1]!==r[1]||t[2]!==r[2]?(o=new c(r[0],r[1],r[2]),t[0]=r[0],t[1]=r[1],t[2]=r[2],t[3]=o):o=t[3];let s=o,l=i*1,u;t[4]!==s||t[5]!==l?(u=(0,x.jsx)(`meshBasicMaterial`,{color:s,transparent:!0,opacity:l,blending:2,side:2,depthWrite:!1,fog:!1}),t[4]=s,t[5]=l,t[6]=u):u=t[6];let d;return t[7]!==a||t[8]!==u?(d=(0,x.jsx)(`mesh`,{geometry:a,renderOrder:1,children:u}),t[7]=a,t[8]=u,t[9]=d):d=t[9],d}function T({scale:e,data:t}){let{animationEnabled:n}=a(),r=C(e),o=f((0,g.useMemo)(()=>t.textures.map(e=>d(e)),[t.textures]),e=>{e.forEach(e=>S(e))}),s=(0,g.useMemo)(()=>b({textures:o,scale:e,umapping:t.umapping,vmapping:t.vmapping,color:t.color,baseTranslucency:t.baseTranslucency}),[o,e,t]);(0,g.useEffect)(()=>()=>s.dispose(),[s]);let c=(0,g.useRef)(0);return i((e,r)=>{if(!n){c.current=0,s.uniforms.currentFrame.value=0,s.uniforms.vScroll.value=0;return}c.current+=r,s.uniforms.currentFrame.value=Math.floor(c.current*t.framesPerSec)%t.numFrames,s.uniforms.vScroll.value=c.current*t.scrollSpeed}),(0,x.jsx)(`mesh`,{geometry:r,material:s,renderOrder:1})}function E(e){let t=(0,_.c)(20),{entity:n}=e,r=n.forceFieldData,i=r.dimensions,a=p(n.id);if(r.textures.map(D).length===0){let e;return t[0]!==r.baseTranslucency||t[1]!==r.color||t[2]!==i?(e=(0,x.jsx)(w,{scale:i,color:r.color,baseTranslucency:r.baseTranslucency}),t[0]=r.baseTranslucency,t[1]=r.color,t[2]=i,t[3]=e):e=t[3],e}let o;t[4]!==r.baseTranslucency||t[5]!==r.color||t[6]!==i?(o=(0,x.jsx)(w,{scale:i,color:r.color,baseTranslucency:r.baseTranslucency}),t[4]=r.baseTranslucency,t[5]=r.color,t[6]=i,t[7]=o):o=t[7];let s;t[8]!==r||t[9]!==i?(s=(0,x.jsx)(T,{scale:i,data:r}),t[8]=r,t[9]=i,t[10]=s):s=t[10];let c;t[11]!==o||t[12]!==s?(c=(0,x.jsx)(h,{name:`ForceField`,fallback:o,children:s}),t[11]=o,t[12]=s,t[13]=c):c=t[13];let l;t[14]!==a||t[15]!==i?(l=a&&i&&(0,x.jsx)(m,{size:i}),t[14]=a,t[15]=i,t[16]=l):l=t[16];let u;return t[17]!==c||t[18]!==l?(u=(0,x.jsxs)(x.Fragment,{children:[c,l]}),t[17]=c,t[18]=l,t[19]=u):u=t[19],u}function D(e){return d(e)}export{E as ForceFieldBare};
|
||||
519
docs/assets/GameView-BMPs220K.js
Normal file
519
docs/assets/GameView-BMPs220K.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
46
docs/assets/Html-CXAi5FD_.js
Normal file
46
docs/assets/Html-CXAi5FD_.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/assets/KeyboardOverlay-C6kCnbeh.js
Normal file
1
docs/assets/KeyboardOverlay-C6kCnbeh.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,5 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{t as i}from"./useQuery-C-bcqv6a.js";import{c as a}from"./manifest-DDCwpSLV.js";import{i as o,it as s,l as c,n as l,rt as u}from"./index-BEehCpzM.js";var d=e(n(),1),f=t(),p={GuiMarkup:`_GuiMarkup_jg4va_1`,Bullet:`_Bullet_jg4va_12`},m=r(),h=new Set([`spop`,`spush`,`lmargin`,`font`,`color`,`bitmap`,`a`,`/a`]);function g(e){return e.split(/<([^><]+)>/g).map((e,t)=>{if(t%2==0)return e?{type:`text`,value:e}:null;{let[t,...n]=e.split(`:`);return h.has(t.toLowerCase())?{type:`tag`,name:t,args:n}:{type:`text`,value:`<${e}>`}}}).filter(e=>e!=null)}function _(e){let[t,n]=e;return{fontDescription:t,fontSize:n?Math.max(11,Math.min(parseInt(n.trim(),10),16)):void 0}}function v(e){let t=g(e),n={type:`span`,source:`root`,style:{},children:[]},r=n,i=[r],a=e=>e.children!=null&&e.children.some(e=>typeof e==`string`||a(e));for(let e of t)switch(e.type){case`text`:r.children.push(e.value);break;case`tag`:switch(e.name){case`spush`:{let e={type:`span`,source:`spush`,style:{},children:[]};r.children.push(e),r=e,i.push(r);break}case`spop`:if(r.source!==`root`){let e=i.pop();for(;e.source!==`spush`;)e=i.pop();r=i[i.length-1]}break;case`lmargin`:break;case`font`:{let t=_(e.args).fontSize;if(!a(r))r.style.fontSize=t;else{let e={type:`span`,source:`spush`,style:{fontSize:t},children:[]};r.children.push(e),r=e,i.push(r)}break}case`color`:if(!a(r))r.style.color=`#${e.args[0].trim()}`;else{let t={type:`span`,source:`spush`,style:{color:`#${e.args[0].trim()}`},children:[]};r.children.push(t),r=t,i.push(r)}break;case`bitmap`:{let t={type:`bitmap`,value:e.args[0]};r.children.push(t);break}case`a`:{let t=e.args[0].trim().split(` `),n={type:`a`,source:`a`,value:`http://${t.length===2&&t[0]===`wwwlink`?t[1]:t[0]}`,style:{},children:[]};r.children.push(n),r=n,i.push(r);break}case`/a`:{let e=i.pop();for(;e.source!==`a`;)e=i.pop();r=i[i.length-1];break}}}return y(n)}function y(e){switch(e.type){case`span`:return d.createElement(`span`,{style:Object.keys(e.style).length===0?void 0:e.style},...e.children.map(e=>typeof e==`string`?e:y(e)));case`a`:return d.createElement(`a`,{href:e.value,style:Object.keys(e.style).length===0?void 0:e.style,rel:`noopener noreferrer`,target:`_blank`},...e.children.map(e=>typeof e==`string`?e:y(e)));case`bitmap`:return(0,m.jsx)(S,{name:e.value})}}var b=new Map;function x(e){if(b.has(e))return b.get(e);let t;try{t=o(a(`textures/gui/${e}`))}catch{t=null}return b.set(e,t),t}function S(e){let t=(0,f.c)(5),{name:n}=e,r;t[0]===n?r=t[1]:(r=x(n),t[0]=n,t[1]=r);let i=r;if(i){let e;return t[2]===i?e=t[3]:(e=(0,m.jsx)(`img`,{src:i,alt:``,className:p.Bitmap}),t[2]=i,t[3]=e),e}if(/bullet/i.test(n)){let e;return t[4]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,m.jsx)(`span`,{className:p.Bullet,children:`•`}),t[4]=e):e=t[4],e}return null}var C=/<(?:font|color|bitmap|just|lmargin|a):/i;function w(e){return C.test(e)}function T(e,t){let n=t.toUpperCase();return e.split(`
|
||||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{t as i}from"./useQuery-6REtM5HO.js";import{i as a,l as o,n as s}from"./loaders-B4T775qz.js";import{c}from"./manifest-BIDT_vSa.js";import{U as l,W as u}from"./index-D4aiQcCU.js";var d=e(n(),1),f=t(),p={GuiMarkup:`_GuiMarkup_jg4va_1`,Bullet:`_Bullet_jg4va_12`},m=r(),h=new Set([`spop`,`spush`,`lmargin`,`font`,`color`,`bitmap`,`a`,`/a`]);function g(e){return e.split(/<([^><]+)>/g).map((e,t)=>{if(t%2==0)return e?{type:`text`,value:e}:null;{let[t,...n]=e.split(`:`);return h.has(t.toLowerCase())?{type:`tag`,name:t,args:n}:{type:`text`,value:`<${e}>`}}}).filter(e=>e!=null)}function _(e){let[t,n]=e;return{fontDescription:t,fontSize:n?Math.max(11,Math.min(parseInt(n.trim(),10),16)):void 0}}function v(e){let t=g(e),n={type:`span`,source:`root`,style:{},children:[]},r=n,i=[r],a=e=>e.children!=null&&e.children.some(e=>typeof e==`string`||a(e));for(let e of t)switch(e.type){case`text`:r.children.push(e.value);break;case`tag`:switch(e.name){case`spush`:{let e={type:`span`,source:`spush`,style:{},children:[]};r.children.push(e),r=e,i.push(r);break}case`spop`:if(r.source!==`root`){let e=i.pop();for(;e.source!==`spush`;)e=i.pop();r=i[i.length-1]}break;case`lmargin`:break;case`font`:{let t=_(e.args).fontSize;if(!a(r))r.style.fontSize=t;else{let e={type:`span`,source:`spush`,style:{fontSize:t},children:[]};r.children.push(e),r=e,i.push(r)}break}case`color`:if(!a(r))r.style.color=`#${e.args[0].trim()}`;else{let t={type:`span`,source:`spush`,style:{color:`#${e.args[0].trim()}`},children:[]};r.children.push(t),r=t,i.push(r)}break;case`bitmap`:{let t={type:`bitmap`,value:e.args[0]};r.children.push(t);break}case`a`:{let t=e.args[0].trim().split(` `),n={type:`a`,source:`a`,value:`http://${t.length===2&&t[0]===`wwwlink`?t[1]:t[0]}`,style:{},children:[]};r.children.push(n),r=n,i.push(r);break}case`/a`:{let e=i.pop();for(;e.source!==`a`;)e=i.pop();r=i[i.length-1];break}}}return y(n)}function y(e){switch(e.type){case`span`:return d.createElement(`span`,{style:Object.keys(e.style).length===0?void 0:e.style},...e.children.map(e=>typeof e==`string`?e:y(e)));case`a`:return d.createElement(`a`,{href:e.value,style:Object.keys(e.style).length===0?void 0:e.style,rel:`noopener noreferrer`,target:`_blank`},...e.children.map(e=>typeof e==`string`?e:y(e)));case`bitmap`:return(0,m.jsx)(S,{name:e.value})}}var b=new Map;function x(e){if(b.has(e))return b.get(e);let t;try{t=a(c(`textures/gui/${e}`))}catch{t=null}return b.set(e,t),t}function S(e){let t=(0,f.c)(5),{name:n}=e,r;t[0]===n?r=t[1]:(r=x(n),t[0]=n,t[1]=r);let i=r;if(i){let e;return t[2]===i?e=t[3]:(e=(0,m.jsx)(`img`,{src:i,alt:``,className:p.Bitmap}),t[2]=i,t[3]=e),e}if(/bullet/i.test(n)){let e;return t[4]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,m.jsx)(`span`,{className:p.Bullet,children:`•`}),t[4]=e):e=t[4],e}return null}var C=/<(?:font|color|bitmap|just|lmargin|a):/i;function w(e){return C.test(e)}function T(e,t){let n=t.toUpperCase();return e.split(`
|
||||
`).flatMap(e=>{let t=e.match(/^\[([^\]]+)\]/);return t&&!t[1].toUpperCase().split(/\s+/).includes(n)?[]:[e.replace(/^\[[^\]]+\]/,``)]}).join(`
|
||||
`)}function E(e){let t=(0,f.c)(4),{markup:n}=e,r;t[0]===n?r=t[1]:(r=v(n),t[0]=n,t[1]=r);let i=r,a;return t[2]===i?a=t[3]:(a=(0,m.jsx)(`div`,{className:p.GuiMarkup,children:i}),t[2]=i,t[3]=a),a}var D={Dialog:`_Dialog_tbn5d_1 _Dialog_1t9wa_1`,Overlay:`_Overlay_tbn5d_10 _Overlay_1t9wa_22`,Body:`_Body_tbn5d_14`,Left:`_Left_tbn5d_22`,PreviewImage:`_PreviewImage_tbn5d_29`,PreviewImageFloating:`_PreviewImageFloating_tbn5d_35`,Title:`_Title_tbn5d_45`,MapMeta:`_MapMeta_tbn5d_53`,MapPlanet:`_MapPlanet_tbn5d_63`,MapQuote:`_MapQuote_tbn5d_67`,MapBlurb:`_MapBlurb_tbn5d_86`,Section:`_Section_tbn5d_91`,SectionTitle:`_SectionTitle_tbn5d_95`,MusicTrack:`_MusicTrack_tbn5d_105`,MusicButton:`_MusicButton_tbn5d_119`,Footer:`_Footer_tbn5d_146`,CloseButton:`_CloseButton_tbn5d_158 _DialogButton_1t9wa_33`,Hint:`_Hint_tbn5d_162`,MusicTrackName:`_MusicTrackName_tbn5d_168`};function ee(e){let t=(0,f.c)(2),n;return t[0]===e?n=t[1]:(n={queryKey:[`parsedMission`,e],queryFn:()=>c(e)},t[0]=e,t[1]=n),i(n)}function te(e){for(let t of e.body){if(t.type!==`ObjectDeclaration`)continue;let{instanceName:e,body:n}=t;if(e&&e.type===`Identifier`&&e.name.toLowerCase()===`missiongroup`){let e={};for(let t of n){if(t.type!==`Assignment`)continue;let{target:n,value:r}=t;n.type===`Identifier`&&r.type===`StringLiteral`&&(e[n.name.toLowerCase()]=r.value)}return e}}return{}}function ne(e,t){if(e)try{return o(a(`textures/gui/${e}`))}catch{}try{return o(a(`textures/gui/Load_${t}`))}catch{}return null}function re(e){let t=(0,f.c)(7),{src:n,alt:r,className:i}=e,a=i===void 0?D.PreviewImage:i,[o,s]=(0,d.useState)(null),c,l;if(t[0]===n?(c=t[1],l=t[2]):(c=()=>{let e=!1,t;return fetch(n).then(j).then(A).then(k).then(n=>{e||!n||(t=URL.createObjectURL(n),s(t))}).catch(O),()=>{e=!0,t&&URL.revokeObjectURL(t)}},l=[n],t[0]=n,t[1]=c,t[2]=l),(0,d.useEffect)(c,l),!o)return null;let u;return t[3]!==r||t[4]!==a||t[5]!==o?(u=(0,m.jsx)(`img`,{src:o,alt:r,className:a}),t[3]=r,t[4]=a,t[5]=o,t[6]=u):u=t[6],u}function O(){}function k(e){return new Promise(t=>{let n=document.createElement(`canvas`);n.width=e.width,n.height=e.height,n.getContext(`2d`)?.drawImage(e,0,0),e.close(),n.toBlob(t)})}function A(e){return createImageBitmap(e,{colorSpaceConversion:`none`})}function j(e){return e.blob()}function ie(e){let t=(0,f.c)(22),{track:n}=e,[r,i]=(0,d.useState)(!1),[a,o]=(0,d.useState)(!0),c=(0,d.useRef)(null),p;t[0]===n?p=t[1]:(p=n.toLowerCase(),t[0]=n,t[1]=p);let h=`${l}music/${p}.mp3`,g,_;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(g=()=>{let e=c.current;if(e)return()=>{e.pause()}},_=[],t[2]=g,t[3]=_):(g=t[2],_=t[3]),(0,d.useEffect)(g,_);let v;t[4]===r?v=t[5]:(v=()=>{let e=c.current;e&&(r?e.pause():e.play().catch(()=>o(!1)))},t[4]=r,t[5]=v);let y=v,b,x,S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(b=()=>i(!0),x=()=>i(!1),S=()=>o(!1),t[6]=b,t[7]=x,t[8]=S):(b=t[6],x=t[7],S=t[8]);let C;t[9]===h?C=t[10]:(C=(0,m.jsx)(`audio`,{ref:c,src:h,loop:!0,onPlay:b,onPause:x,onError:S}),t[9]=h,t[10]=C);let w;t[11]===n?w=t[12]:(w=(0,m.jsx)(`span`,{className:D.MusicTrackName,children:n}),t[11]=n,t[12]=w);let T;t[13]!==a||t[14]!==r||t[15]!==y?(T=a&&(0,m.jsx)(`button`,{className:D.MusicButton,onClick:y,"aria-label":r?`Pause music`:`Play music`,children:r?(0,m.jsx)(s,{}):(0,m.jsx)(u,{})}),t[13]=a,t[14]=r,t[15]=y,t[16]=T):T=t[16];let E;return t[17]!==r||t[18]!==T||t[19]!==C||t[20]!==w?(E=(0,m.jsxs)(`div`,{className:D.MusicTrack,"data-playing":r,children:[C,w,T]}),t[17]=r,t[18]=T,t[19]=C,t[20]=w,t[21]=E):E=t[21],E}function M(e){let t=(0,f.c)(100),{onClose:n,missionName:r,missionType:i}=e,{data:a}=ee(r),o=(0,d.useRef)(null),s,c;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(s=()=>{o.current?.focus();try{document.exitPointerLock()}catch{}},c=[],t[0]=s,t[1]=c):(s=t[0],c=t[1]),(0,d.useEffect)(s,c);let l,u;t[2]===n?(l=t[3],u=t[4]):(l=()=>{let e=e=>{if(e.key===`Escape`)n();else if(e.key===`k`&&(e.metaKey||e.ctrlKey)){n();return}e.stopImmediatePropagation()},t=se;return window.addEventListener(`keydown`,e,{capture:!0}),window.addEventListener(`keyup`,t,{capture:!0}),()=>{window.removeEventListener(`keydown`,e,{capture:!0}),window.removeEventListener(`keyup`,t,{capture:!0})}},u=[n],t[2]=n,t[3]=l,t[4]=u),(0,d.useEffect)(l,u);let p;t[5]===a?p=t[6]:(p=a?te(a.ast):{},t[5]=a,t[6]=p);let h=p,g;t[7]!==r||t[8]!==a?(g=a?ne(a.bitmap,r):null,t[7]=r,t[8]=a,t[9]=g):g=t[9];let _=g,v=a?.displayName??r,y;t[10]===i?y=t[11]:(y=i.toLowerCase(),t[10]=i,t[11]=y);let b=y===`singleplayer`,x=h.musictrack,S,C,O,k,A,j,M,N,P,F,I,L,R,z,B,V,H,U;if(t[12]!==_||t[13]!==v||t[14]!==b||t[15]!==i||t[16]!==n||t[17]!==a){let e=a?.missionString?T(a.missionString,i):null,r,s,c,l;if(t[36]!==a?.missionQuote){if(l=a?.missionQuote?.trim()??``,s=w(l),c=``,r=``,!s)for(let e of l.split(`
|
||||
`)}function E(e){let t=(0,f.c)(4),{markup:n}=e,r;t[0]===n?r=t[1]:(r=v(n),t[0]=n,t[1]=r);let i=r,a;return t[2]===i?a=t[3]:(a=(0,m.jsx)(`div`,{className:p.GuiMarkup,children:i}),t[2]=i,t[3]=a),a}var D={Dialog:`_Dialog_tbn5d_1 _Dialog_1t9wa_1`,Overlay:`_Overlay_tbn5d_10 _Overlay_1t9wa_22`,Body:`_Body_tbn5d_14`,Left:`_Left_tbn5d_22`,PreviewImage:`_PreviewImage_tbn5d_29`,PreviewImageFloating:`_PreviewImageFloating_tbn5d_35`,Title:`_Title_tbn5d_45`,MapMeta:`_MapMeta_tbn5d_53`,MapPlanet:`_MapPlanet_tbn5d_63`,MapQuote:`_MapQuote_tbn5d_67`,MapBlurb:`_MapBlurb_tbn5d_86`,Section:`_Section_tbn5d_91`,SectionTitle:`_SectionTitle_tbn5d_95`,MusicTrack:`_MusicTrack_tbn5d_105`,MusicButton:`_MusicButton_tbn5d_119`,Footer:`_Footer_tbn5d_146`,CloseButton:`_CloseButton_tbn5d_158 _DialogButton_1t9wa_33`,Hint:`_Hint_tbn5d_162`,MusicTrackName:`_MusicTrackName_tbn5d_168`};function ee(e){let t=(0,f.c)(2),n;return t[0]===e?n=t[1]:(n={queryKey:[`parsedMission`,e],queryFn:()=>o(e)},t[0]=e,t[1]=n),i(n)}function te(e){for(let t of e.body){if(t.type!==`ObjectDeclaration`)continue;let{instanceName:e,body:n}=t;if(e&&e.type===`Identifier`&&e.name.toLowerCase()===`missiongroup`){let e={};for(let t of n){if(t.type!==`Assignment`)continue;let{target:n,value:r}=t;n.type===`Identifier`&&r.type===`StringLiteral`&&(e[n.name.toLowerCase()]=r.value)}return e}}return{}}function ne(e,t){if(e)try{return a(c(`textures/gui/${e}`))}catch{}try{return a(c(`textures/gui/Load_${t}`))}catch{}return null}function re(e){let t=(0,f.c)(7),{src:n,alt:r,className:i}=e,a=i===void 0?D.PreviewImage:i,[o,s]=(0,d.useState)(null),c,l;if(t[0]===n?(c=t[1],l=t[2]):(c=()=>{let e=!1,t;return fetch(n).then(j).then(A).then(k).then(n=>{e||!n||(t=URL.createObjectURL(n),s(t))}).catch(O),()=>{e=!0,t&&URL.revokeObjectURL(t)}},l=[n],t[0]=n,t[1]=c,t[2]=l),(0,d.useEffect)(c,l),!o)return null;let u;return t[3]!==r||t[4]!==a||t[5]!==o?(u=(0,m.jsx)(`img`,{src:o,alt:r,className:a}),t[3]=r,t[4]=a,t[5]=o,t[6]=u):u=t[6],u}function O(){}function k(e){return new Promise(t=>{let n=document.createElement(`canvas`);n.width=e.width,n.height=e.height,n.getContext(`2d`)?.drawImage(e,0,0),e.close(),n.toBlob(t)})}function A(e){return createImageBitmap(e,{colorSpaceConversion:`none`})}function j(e){return e.blob()}function ie(e){let t=(0,f.c)(22),{track:n}=e,[r,i]=(0,d.useState)(!1),[a,o]=(0,d.useState)(!0),c=(0,d.useRef)(null),p;t[0]===n?p=t[1]:(p=n.toLowerCase(),t[0]=n,t[1]=p);let h=`${s}music/${p}.mp3`,g,_;t[2]===Symbol.for(`react.memo_cache_sentinel`)?(g=()=>{let e=c.current;if(e)return()=>{e.pause()}},_=[],t[2]=g,t[3]=_):(g=t[2],_=t[3]),(0,d.useEffect)(g,_);let v;t[4]===r?v=t[5]:(v=()=>{let e=c.current;e&&(r?e.pause():e.play().catch(()=>o(!1)))},t[4]=r,t[5]=v);let y=v,b,x,S;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(b=()=>i(!0),x=()=>i(!1),S=()=>o(!1),t[6]=b,t[7]=x,t[8]=S):(b=t[6],x=t[7],S=t[8]);let C;t[9]===h?C=t[10]:(C=(0,m.jsx)(`audio`,{ref:c,src:h,loop:!0,onPlay:b,onPause:x,onError:S}),t[9]=h,t[10]=C);let w;t[11]===n?w=t[12]:(w=(0,m.jsx)(`span`,{className:D.MusicTrackName,children:n}),t[11]=n,t[12]=w);let T;t[13]!==a||t[14]!==r||t[15]!==y?(T=a&&(0,m.jsx)(`button`,{className:D.MusicButton,onClick:y,"aria-label":r?`Pause music`:`Play music`,children:r?(0,m.jsx)(u,{}):(0,m.jsx)(l,{})}),t[13]=a,t[14]=r,t[15]=y,t[16]=T):T=t[16];let E;return t[17]!==r||t[18]!==T||t[19]!==C||t[20]!==w?(E=(0,m.jsxs)(`div`,{className:D.MusicTrack,"data-playing":r,children:[C,w,T]}),t[17]=r,t[18]=T,t[19]=C,t[20]=w,t[21]=E):E=t[21],E}function M(e){let t=(0,f.c)(100),{onClose:n,missionName:r,missionType:i}=e,{data:a}=ee(r),o=(0,d.useRef)(null),s,c;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(s=()=>{o.current?.focus();try{document.exitPointerLock()}catch{}},c=[],t[0]=s,t[1]=c):(s=t[0],c=t[1]),(0,d.useEffect)(s,c);let l,u;t[2]===n?(l=t[3],u=t[4]):(l=()=>{let e=e=>{if(e.key===`Escape`)n();else if(e.key===`k`&&(e.metaKey||e.ctrlKey)){n();return}e.stopImmediatePropagation()},t=se;return window.addEventListener(`keydown`,e,{capture:!0}),window.addEventListener(`keyup`,t,{capture:!0}),()=>{window.removeEventListener(`keydown`,e,{capture:!0}),window.removeEventListener(`keyup`,t,{capture:!0})}},u=[n],t[2]=n,t[3]=l,t[4]=u),(0,d.useEffect)(l,u);let p;t[5]===a?p=t[6]:(p=a?te(a.ast):{},t[5]=a,t[6]=p);let h=p,g;t[7]!==r||t[8]!==a?(g=a?ne(a.bitmap,r):null,t[7]=r,t[8]=a,t[9]=g):g=t[9];let _=g,v=a?.displayName??r,y;t[10]===i?y=t[11]:(y=i.toLowerCase(),t[10]=i,t[11]=y);let b=y===`singleplayer`,x=h.musictrack,S,C,O,k,A,j,M,N,P,F,I,L,R,z,B,V,H,U;if(t[12]!==_||t[13]!==v||t[14]!==b||t[15]!==i||t[16]!==n||t[17]!==a){let e=a?.missionString?T(a.missionString,i):null,r,s,c,l;if(t[36]!==a?.missionQuote){if(l=a?.missionQuote?.trim()??``,s=w(l),c=``,r=``,!s)for(let e of l.split(`
|
||||
`)){let t=e.trim();t.match(/^--[^-]/)?r=t.replace(/^-+\s*/,``).trim():t&&(c+=(c?`
|
||||
`:``)+t)}t[36]=a?.missionQuote,t[37]=r,t[38]=s,t[39]=c,t[40]=l}else r=t[37],s=t[38],c=t[39],l=t[40];B=D.Overlay,V=n,M=o,N=D.Dialog,P=oe,F=ae,I=`dialog`,L=`true`,R=`Map Information`,z=-1,j=D.Body,H=D.Left,t[41]!==_||t[42]!==v||t[43]!==b?(U=_&&b&&(0,m.jsx)(re,{className:D.PreviewImageFloating,src:_,alt:`${v} preview`},_),t[41]=_,t[42]=v,t[43]=b,t[44]=U):U=t[44],t[45]===v?S=t[46]:(S=(0,m.jsx)(`h1`,{className:D.Title,children:v}),t[45]=v,t[46]=S);let u;t[47]===a?u=t[48]:(u=a?.planetName&&(0,m.jsx)(`span`,{className:D.MapPlanet,children:a.planetName}),t[47]=a,t[48]=u),t[49]===u?C=t[50]:(C=(0,m.jsx)(`div`,{className:D.MapMeta,children:u}),t[49]=u,t[50]=C),t[51]!==r||t[52]!==s||t[53]!==c||t[54]!==l?(O=s?(0,m.jsx)(`blockquote`,{className:D.MapQuote,children:(0,m.jsx)(E,{markup:l})}):c?(0,m.jsxs)(`blockquote`,{className:D.MapQuote,children:[(0,m.jsx)(`p`,{children:c}),r&&(0,m.jsxs)(`cite`,{children:[`— `,r]})]}):null,t[51]=r,t[52]=s,t[53]=c,t[54]=l,t[55]=O):O=t[55],t[56]===a?k=t[57]:(k=a?.missionBlurb&&(0,m.jsx)(`div`,{className:D.MapBlurb,children:w(a.missionBlurb)?(0,m.jsx)(E,{markup:a.missionBlurb.trim()}):a.missionBlurb.trim()}),t[56]=a,t[57]=k),A=e&&e.trim()&&(0,m.jsx)(`div`,{className:D.Section,children:(0,m.jsx)(E,{markup:e})}),t[12]=_,t[13]=v,t[14]=b,t[15]=i,t[16]=n,t[17]=a,t[18]=S,t[19]=C,t[20]=O,t[21]=k,t[22]=A,t[23]=j,t[24]=M,t[25]=N,t[26]=P,t[27]=F,t[28]=I,t[29]=L,t[30]=R,t[31]=z,t[32]=B,t[33]=V,t[34]=H,t[35]=U}else S=t[18],C=t[19],O=t[20],k=t[21],A=t[22],j=t[23],M=t[24],N=t[25],P=t[26],F=t[27],I=t[28],L=t[29],R=t[30],z=t[31],B=t[32],V=t[33],H=t[34],U=t[35];let W;t[58]===a?W=t[59]:(W=a?.missionBriefing&&(0,m.jsxs)(`div`,{className:D.Section,children:[(0,m.jsx)(`h2`,{className:D.SectionTitle,children:`Mission Briefing`}),(0,m.jsx)(E,{markup:a.missionBriefing})]}),t[58]=a,t[59]=W);let G;t[60]===x?G=t[61]:(G=x&&(0,m.jsx)(ie,{track:x}),t[60]=x,t[61]=G);let K;t[62]!==S||t[63]!==C||t[64]!==O||t[65]!==k||t[66]!==A||t[67]!==W||t[68]!==G||t[69]!==H||t[70]!==U?(K=(0,m.jsxs)(`div`,{className:H,children:[U,S,C,O,k,A,W,G]}),t[62]=S,t[63]=C,t[64]=O,t[65]=k,t[66]=A,t[67]=W,t[68]=G,t[69]=H,t[70]=U,t[71]=K):K=t[71];let q;t[72]!==_||t[73]!==v||t[74]!==b?(q=_&&!b&&(0,m.jsx)(re,{src:_,alt:`${v} preview`},_),t[72]=_,t[73]=v,t[74]=b,t[75]=q):q=t[75];let J;t[76]!==j||t[77]!==K||t[78]!==q?(J=(0,m.jsxs)(`div`,{className:j,children:[K,q]}),t[76]=j,t[77]=K,t[78]=q,t[79]=J):J=t[79];let Y;t[80]===n?Y=t[81]:(Y=(0,m.jsx)(`button`,{className:D.CloseButton,onClick:n,children:`Close`}),t[80]=n,t[81]=Y);let X;t[82]===Symbol.for(`react.memo_cache_sentinel`)?(X=(0,m.jsx)(`span`,{className:D.Hint,children:`Esc to close`}),t[82]=X):X=t[82];let Z;t[83]===Y?Z=t[84]:(Z=(0,m.jsxs)(`div`,{className:D.Footer,children:[Y,X]}),t[83]=Y,t[84]=Z);let Q;t[85]!==M||t[86]!==N||t[87]!==P||t[88]!==F||t[89]!==I||t[90]!==L||t[91]!==R||t[92]!==z||t[93]!==J||t[94]!==Z?(Q=(0,m.jsxs)(`div`,{ref:M,className:N,onClick:P,onKeyDown:F,role:I,"aria-modal":L,"aria-label":R,tabIndex:z,children:[J,Z]}),t[85]=M,t[86]=N,t[87]=P,t[88]=F,t[89]=I,t[90]=L,t[91]=R,t[92]=z,t[93]=J,t[94]=Z,t[95]=Q):Q=t[95];let $;return t[96]!==B||t[97]!==V||t[98]!==Q?($=(0,m.jsx)(`div`,{className:B,onClick:V,children:Q}),t[96]=B,t[97]=V,t[98]=Q,t[99]=$):$=t[99],$}function ae(e){return e.stopPropagation()}function oe(e){return e.stopPropagation()}function se(e){e.stopImmediatePropagation()}export{M as MapInfoDialog};
|
||||
File diff suppressed because one or more lines are too long
1
docs/assets/Mission-BEL-ZcOh.js
Normal file
1
docs/assets/Mission-BEL-ZcOh.js
Normal file
File diff suppressed because one or more lines are too long
2
docs/assets/PlayerHUD-CVj7JVJO.js
Normal file
2
docs/assets/PlayerHUD-CVj7JVJO.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
docs/assets/PlayerModel-CsbVaSkV.js
Normal file
1
docs/assets/PlayerModel-CsbVaSkV.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{i as e,n as t,r as n,t as r}from"./PlayerModel-DY4jKfUP.js";export{r as PlayerModel,t as fetchSkinManifest,n as playerEyePositions,e as skinManifestQueryKey};
|
||||
File diff suppressed because one or more lines are too long
2
docs/assets/PlayerModel-DY4jKfUP.js
Normal file
2
docs/assets/PlayerModel-DY4jKfUP.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{a as i}from"./react-three-fiber.esm-B4ybsNEe.js";import{Ct as a,Wt as o,b as s,kt as c}from"./three.module-DeDv86YO.js";import{t as l}from"./Texture-DuIJU_zO.js";import{p as u}from"./index-BEehCpzM.js";import{d,f,m as p}from"./playbackUtils-D5VkIMBR.js";var m=t(),h=e(n(),1),g=r(),_=new o,v=new o,y=new o,b=new o,x=new o,S=new o,C=new o(0,1,0);function w(e){let t=(0,m.c)(14),{entity:n}=e,{visual:r}=n,i;t[0]===r.texture?i=t[1]:(i=u(r.texture),t[0]=r.texture,t[1]=i);let a=l(i,T),o=Array.isArray(a)?a[0]:a,d;t[2]!==r.color.b||t[3]!==r.color.g||t[4]!==r.color.r?(d=new s().setRGB(r.color.r,r.color.g,r.color.b,c),t[2]=r.color.b,t[3]=r.color.g,t[4]=r.color.r,t[5]=d):d=t[5];let f=d,p;t[6]===r.size?p=t[7]:(p=[r.size,r.size,1],t[6]=r.size,t[7]=p);let h;t[8]!==f||t[9]!==o?(h=(0,g.jsx)(`spriteMaterial`,{map:o,color:f,transparent:!0,blending:2,depthWrite:!1,toneMapped:!1}),t[8]=f,t[9]=o,t[10]=h):h=t[10];let _;return t[11]!==p||t[12]!==h?(_=(0,g.jsx)(`sprite`,{scale:p,children:h}),t[11]=p,t[12]=h,t[13]=_):_=t[13],_}function T(e){f(Array.isArray(e)?e[0]:e)}function E(e){let t=(0,m.c)(29),{entity:n}=e,{visual:r}=n,o=(0,h.useRef)(null),s=(0,h.useRef)(null),c=(0,h.useRef)(null),f;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(f=new a,t[0]=f):f=t[0];let w=(0,h.useRef)(f),T;t[1]===r.texture?T=t[2]:(T=u(r.texture),t[1]=r.texture,t[2]=T);let E=r.crossTexture??r.texture,O;t[3]===E?O=t[4]:(O=u(E),t[3]=E,t[4]=O);let k;t[5]!==T||t[6]!==O?(k=[T,O],t[5]=T,t[6]=O,t[7]=k):k=t[7];let A=l(k,D),j;t[8]===A?j=t[9]:(j=Array.isArray(A)?A:[A,A],t[8]=A,t[9]=j);let[M,N]=j,P;t[10]!==n.direction||t[11]!==n.keyframes?.[0]||t[12]!==r.crossSize||t[13]!==r.crossViewAng||t[14]!==r.renderCross||t[15]!==r.tracerLength||t[16]!==r.tracerWidth?(P=e=>{let{camera:t}=e,i=o.current,a=s.current;if(!i||!a)return;let l=n.keyframes?.[0],u=l?.position,f=n.direction??l?.velocity;if(!u||!f){i.visible=!1,c.current&&(c.current.visible=!1);return}if(p(f,_),_.lengthSq()<1e-8){i.visible=!1,c.current&&(c.current.visible=!1);return}_.normalize(),i.visible=!0,p(u,S),v.copy(S).sub(t.position),y.crossVectors(v,_),y.lengthSq()<1e-8&&(y.crossVectors(C,_),y.lengthSq()<1e-8&&y.set(1,0,0)),y.normalize().multiplyScalar(r.tracerWidth);let m=r.tracerLength*.5;b.copy(_).multiplyScalar(-m),x.copy(_).multiplyScalar(m);let h=a.array;h[0]=b.x+y.x,h[1]=b.y+y.y,h[2]=b.z+y.z,h[3]=b.x-y.x,h[4]=b.y-y.y,h[5]=b.z-y.z,h[6]=x.x-y.x,h[7]=x.y-y.y,h[8]=x.z-y.z,h[9]=x.x+y.x,h[10]=x.y+y.y,h[11]=x.z+y.z,a.needsUpdate=!0;let g=c.current;if(!g)return;if(!r.renderCross){g.visible=!1;return}v.normalize();let T=_.dot(v);if(T>-r.crossViewAng&&T<r.crossViewAng){g.visible=!1;return}g.visible=!0,d(_,w.current),g.quaternion.copy(w.current),g.scale.setScalar(r.crossSize)},t[10]=n.direction,t[11]=n.keyframes?.[0],t[12]=r.crossSize,t[13]=r.crossViewAng,t[14]=r.renderCross,t[15]=r.tracerLength,t[16]=r.tracerWidth,t[17]=P):P=t[17],i(P);let F;t[18]===Symbol.for(`react.memo_cache_sentinel`)?(F=(0,g.jsx)(`bufferAttribute`,{ref:s,attach:`attributes-position`,args:[new Float32Array(12),3]}),t[18]=F):F=t[18];let I;t[19]===Symbol.for(`react.memo_cache_sentinel`)?(I=(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),t[19]=I):I=t[19];let L;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,g.jsxs)(`bufferGeometry`,{children:[F,I,(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),t[20]=L):L=t[20];let R;t[21]===M?R=t[22]:(R=(0,g.jsxs)(`mesh`,{ref:o,children:[L,(0,g.jsx)(`meshBasicMaterial`,{map:M,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}),t[21]=M,t[22]=R);let z;t[23]!==N||t[24]!==r.renderCross?(z=r.renderCross?(0,g.jsxs)(`mesh`,{ref:c,children:[(0,g.jsxs)(`bufferGeometry`,{children:[(0,g.jsx)(`bufferAttribute`,{attach:`attributes-position`,args:[new Float32Array([-.5,0,-.5,.5,0,-.5,.5,0,.5,-.5,0,.5]),3]}),(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),(0,g.jsx)(`meshBasicMaterial`,{map:N,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}):null,t[23]=N,t[24]=r.renderCross,t[25]=z):z=t[25];let B;return t[26]!==R||t[27]!==z?(B=(0,g.jsxs)(g.Fragment,{children:[R,z]}),t[26]=R,t[27]=z,t[28]=B):B=t[28],B}function D(e){let t=Array.isArray(e)?e:[e];for(let e of t)f(e)}export{w as SpriteProjectile,E as TracerProjectile};
|
||||
1
docs/assets/Projectiles-D417zqjU.js
Normal file
1
docs/assets/Projectiles-D417zqjU.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{n as t,r as n,t as r}from"./jsx-runtime-BpGWiA-R.js";import{a as i}from"./react-three-fiber.esm-El6vNTZj.js";import{Ct as a,Wt as o,b as s,kt as c}from"./three.module-DKAirPAO.js";import{d as l,f as u,m as d}from"./playbackUtils-DjmjN4tv.js";import{p as f}from"./loaders-B4T775qz.js";import{t as p}from"./Texture-BYh0PjzP.js";var m=t(),h=e(n(),1),g=r(),_=new o,v=new o,y=new o,b=new o,x=new o,S=new o,C=new o(0,1,0);function w(e){let t=(0,m.c)(14),{entity:n}=e,{visual:r}=n,i;t[0]===r.texture?i=t[1]:(i=f(r.texture),t[0]=r.texture,t[1]=i);let a=p(i,T),o=Array.isArray(a)?a[0]:a,l;t[2]!==r.color.b||t[3]!==r.color.g||t[4]!==r.color.r?(l=new s().setRGB(r.color.r,r.color.g,r.color.b,c),t[2]=r.color.b,t[3]=r.color.g,t[4]=r.color.r,t[5]=l):l=t[5];let u=l,d;t[6]===r.size?d=t[7]:(d=[r.size,r.size,1],t[6]=r.size,t[7]=d);let h;t[8]!==u||t[9]!==o?(h=(0,g.jsx)(`spriteMaterial`,{map:o,color:u,transparent:!0,blending:2,depthWrite:!1,toneMapped:!1}),t[8]=u,t[9]=o,t[10]=h):h=t[10];let _;return t[11]!==d||t[12]!==h?(_=(0,g.jsx)(`sprite`,{scale:d,children:h}),t[11]=d,t[12]=h,t[13]=_):_=t[13],_}function T(e){u(Array.isArray(e)?e[0]:e)}function E(e){let t=(0,m.c)(29),{entity:n}=e,{visual:r}=n,o=(0,h.useRef)(null),s=(0,h.useRef)(null),c=(0,h.useRef)(null),u;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(u=new a,t[0]=u):u=t[0];let w=(0,h.useRef)(u),T;t[1]===r.texture?T=t[2]:(T=f(r.texture),t[1]=r.texture,t[2]=T);let E=r.crossTexture??r.texture,O;t[3]===E?O=t[4]:(O=f(E),t[3]=E,t[4]=O);let k;t[5]!==T||t[6]!==O?(k=[T,O],t[5]=T,t[6]=O,t[7]=k):k=t[7];let A=p(k,D),j;t[8]===A?j=t[9]:(j=Array.isArray(A)?A:[A,A],t[8]=A,t[9]=j);let[M,N]=j,P;t[10]!==n.direction||t[11]!==n.keyframes?.[0]||t[12]!==r.crossSize||t[13]!==r.crossViewAng||t[14]!==r.renderCross||t[15]!==r.tracerLength||t[16]!==r.tracerWidth?(P=e=>{let{camera:t}=e,i=o.current,a=s.current;if(!i||!a)return;let u=n.keyframes?.[0],f=u?.position,p=n.direction??u?.velocity;if(!f||!p){i.visible=!1,c.current&&(c.current.visible=!1);return}if(d(p,_),_.lengthSq()<1e-8){i.visible=!1,c.current&&(c.current.visible=!1);return}_.normalize(),i.visible=!0,d(f,S),v.copy(S).sub(t.position),y.crossVectors(v,_),y.lengthSq()<1e-8&&(y.crossVectors(C,_),y.lengthSq()<1e-8&&y.set(1,0,0)),y.normalize().multiplyScalar(r.tracerWidth);let m=r.tracerLength*.5;b.copy(_).multiplyScalar(-m),x.copy(_).multiplyScalar(m);let h=a.array;h[0]=b.x+y.x,h[1]=b.y+y.y,h[2]=b.z+y.z,h[3]=b.x-y.x,h[4]=b.y-y.y,h[5]=b.z-y.z,h[6]=x.x-y.x,h[7]=x.y-y.y,h[8]=x.z-y.z,h[9]=x.x+y.x,h[10]=x.y+y.y,h[11]=x.z+y.z,a.needsUpdate=!0;let g=c.current;if(!g)return;if(!r.renderCross){g.visible=!1;return}v.normalize();let T=_.dot(v);if(T>-r.crossViewAng&&T<r.crossViewAng){g.visible=!1;return}g.visible=!0,l(_,w.current),g.quaternion.copy(w.current),g.scale.setScalar(r.crossSize)},t[10]=n.direction,t[11]=n.keyframes?.[0],t[12]=r.crossSize,t[13]=r.crossViewAng,t[14]=r.renderCross,t[15]=r.tracerLength,t[16]=r.tracerWidth,t[17]=P):P=t[17],i(P);let F;t[18]===Symbol.for(`react.memo_cache_sentinel`)?(F=(0,g.jsx)(`bufferAttribute`,{ref:s,attach:`attributes-position`,args:[new Float32Array(12),3]}),t[18]=F):F=t[18];let I;t[19]===Symbol.for(`react.memo_cache_sentinel`)?(I=(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),t[19]=I):I=t[19];let L;t[20]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,g.jsxs)(`bufferGeometry`,{children:[F,I,(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),t[20]=L):L=t[20];let R;t[21]===M?R=t[22]:(R=(0,g.jsxs)(`mesh`,{ref:o,children:[L,(0,g.jsx)(`meshBasicMaterial`,{map:M,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}),t[21]=M,t[22]=R);let z;t[23]!==N||t[24]!==r.renderCross?(z=r.renderCross?(0,g.jsxs)(`mesh`,{ref:c,children:[(0,g.jsxs)(`bufferGeometry`,{children:[(0,g.jsx)(`bufferAttribute`,{attach:`attributes-position`,args:[new Float32Array([-.5,0,-.5,.5,0,-.5,.5,0,.5,-.5,0,.5]),3]}),(0,g.jsx)(`bufferAttribute`,{attach:`attributes-uv`,args:[new Float32Array([0,0,0,1,1,1,1,0]),2]}),(0,g.jsx)(`bufferAttribute`,{attach:`index`,args:[new Uint16Array([0,1,2,0,2,3]),1]})]}),(0,g.jsx)(`meshBasicMaterial`,{map:N,transparent:!0,blending:2,side:2,depthWrite:!1,toneMapped:!1})]}):null,t[23]=N,t[24]=r.renderCross,t[25]=z):z=t[25];let B;return t[26]!==R||t[27]!==z?(B=(0,g.jsxs)(g.Fragment,{children:[R,z]}),t[26]=R,t[27]=z,t[28]=B):B=t[28],B}function D(e){let t=Array.isArray(e)?e:[e];for(let e of t)u(e)}export{w as SpriteProjectile,E as TracerProjectile};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t}from"./jsx-runtime-BpGWiA-R.js";import{t as n}from"./logger-CySD1nLn.js";var r=e(t(),1),i=n(`ShapeErrorBoundary`),a=class extends r.Component{state={hasError:!1};static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e,t){i.error(`Shape load failed: %s %s`,e.message,t.componentStack)}render(){return this.state.hasError?this.props.fallback:this.props.children}};export{a as t};
|
||||
89
docs/assets/StreamingController-D56a4f6m.js
Normal file
89
docs/assets/StreamingController-D56a4f6m.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t}from"./jsx-runtime-BpGWiA-R.js";import{o as n,s as r}from"./react-three-fiber.esm-B4ybsNEe.js";import{Bt as i,zt as a}from"./three.module-DeDv86YO.js";var o=e(t()),s=e=>e===Object(e)&&!Array.isArray(e)&&typeof e!=`function`;function c(e,t){let c=r(e=>e.gl),l=n(i,s(e)?Object.values(e):e);return(0,o.useLayoutEffect)(()=>{t?.(l)},[t]),(0,o.useEffect)(()=>{if(`initTexture`in c){let e=[];Array.isArray(l)?e=l:l instanceof a?e=[l]:s(l)&&(e=Object.values(l)),e.forEach(e=>{e instanceof a&&c.initTexture(e)})}},[c,l]),(0,o.useMemo)(()=>{if(s(e)){let t={},n=0;for(let r in e)t[r]=l[n++];return t}else return l},[e,l])}c.preload=e=>n.preload(i,e),c.clear=e=>n.clear(i,e);export{c as t};
|
||||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t}from"./jsx-runtime-BpGWiA-R.js";import{o as n,s as r}from"./react-three-fiber.esm-El6vNTZj.js";import{Bt as i,zt as a}from"./three.module-DKAirPAO.js";var o=e(t()),s=e=>e===Object(e)&&!Array.isArray(e)&&typeof e!=`function`;function c(e,t){let c=r(e=>e.gl),l=n(i,s(e)?Object.values(e):e);return(0,o.useLayoutEffect)(()=>{t?.(l)},[t]),(0,o.useEffect)(()=>{if(`initTexture`in c){let e=[];Array.isArray(l)?e=l:l instanceof a?e=[l]:s(l)&&(e=Object.values(l)),e.forEach(e=>{e instanceof a&&c.initTexture(e)})}},[c,l]),(0,o.useMemo)(()=>{if(s(e)){let t={},n=0;for(let r in e)t[r]=l[n++];return t}else return l},[e,l])}c.preload=e=>n.preload(i,e),c.clear=e=>n.clear(i,e);export{c as t};
|
||||
|
|
@ -1 +1 @@
|
|||
import{n as e}from"./jsx-runtime-BpGWiA-R.js";import{a as t}from"./react-three-fiber.esm-B4ybsNEe.js";import{r as n}from"./SettingsProvider-BeB5OnG9.js";import{n as r}from"./JoystickContext-BKqyiaNN.js";import{E as i,k as a}from"./index-BEehCpzM.js";var o=e(),s=.004,c=2.5,l=.08,u=.15,d=.15;function f(){let e=(0,o.c)(9),{speedMultiplier:f,touchMode:p,invertDrag:m,invertJoystick:h}=n(),{moveState:g,lookState:_}=r(),v=a(),[,y]=i(),b;return e[0]!==y||e[1]!==m||e[2]!==h||e[3]!==_.current||e[4]!==g.current||e[5]!==v||e[6]!==f||e[7]!==p?(b=(e,t)=>{let{force:n,angle:r}=g.current,{force:i,angle:a}=_.current,o=y().touchLook,b=m?1:-1,x=0,S=0;p===`moveLookStick`&&o&&o.dragging&&(x=b*o.deltaX*s,S=b*o.deltaY*s);let C=0,w=0;if(p===`dualStick`){if(i>u){let e=(i-u)/(1-u),n=Math.cos(a),r=Math.sin(a),o=h?1:-1;x-=o*n*e*c*t,S+=o*r*e*c*t}if(n>l){let e=(n-l)/(1-l),t=Math.cos(r),i=Math.sin(r);C=Math.max(-1,Math.min(1,t*e*(.8*f+.05))),w=Math.max(-1,Math.min(1,i*e*(.8*f+.05)))}}else if(p===`moveLookStick`&&n>0&&(w=Math.min(1,.5*f+.05),n>=d)){let e=Math.cos(r),i=Math.sin(r),a=(n-d)/(1-d),o=h?1:-1;x-=o*e*a*c*.5*t,S+=o*i*a*c*.5*t}!(x!==0||S!==0)&&!(C!==0||w!==0)||v({deltaYaw:x,deltaPitch:S,x:C,y:w,z:0,triggers:[],delta:t})},e[0]=y,e[1]=m,e[2]=h,e[3]=_.current,e[4]=g.current,e[5]=v,e[6]=f,e[7]=p,e[8]=b):b=e[8],t(b),null}export{f as TouchHandler};
|
||||
import{n as e}from"./jsx-runtime-BpGWiA-R.js";import{a as t}from"./react-three-fiber.esm-El6vNTZj.js";import{r as n}from"./SettingsProvider-BdqQ2Cm4.js";import{n as r}from"./JoystickContext-B2sO9eYx.js";import{f as i,h as a}from"./index-D4aiQcCU.js";var o=e(),s=.004,c=2.5,l=.08,u=.15,d=.15;function f(){let e=(0,o.c)(9),{speedMultiplier:f,touchMode:p,invertDrag:m,invertJoystick:h}=n(),{moveState:g,lookState:_}=r(),v=a(),[,y]=i(),b;return e[0]!==y||e[1]!==m||e[2]!==h||e[3]!==_.current||e[4]!==g.current||e[5]!==v||e[6]!==f||e[7]!==p?(b=(e,t)=>{let{force:n,angle:r}=g.current,{force:i,angle:a}=_.current,o=y().touchLook,b=m?1:-1,x=0,S=0;p===`moveLookStick`&&o&&o.dragging&&(x=b*o.deltaX*s,S=b*o.deltaY*s);let C=0,w=0;if(p===`dualStick`){if(i>u){let e=(i-u)/(1-u),n=Math.cos(a),r=Math.sin(a),o=h?1:-1;x-=o*n*e*c*t,S+=o*r*e*c*t}if(n>l){let e=(n-l)/(1-l),t=Math.cos(r),i=Math.sin(r);C=Math.max(-1,Math.min(1,t*e*(.8*f+.05))),w=Math.max(-1,Math.min(1,i*e*(.8*f+.05)))}}else if(p===`moveLookStick`&&n>0&&(w=Math.min(1,.5*f+.05),n>=d)){let e=Math.cos(r),i=Math.sin(r),a=(n-d)/(1-d),o=h?1:-1;x-=o*e*a*c*.5*t,S+=o*i*a*c*.5*t}!(x!==0||S!==0)&&!(C!==0||w!==0)||v({deltaYaw:x,deltaPitch:S,x:C,y:w,z:0,triggers:[],delta:t})},e[0]=y,e[1]=m,e[2]=h,e[3]=_.current,e[4]=g.current,e[5]=v,e[6]=f,e[7]=p,e[8]=b):b=e[8],t(b),null}export{f as TouchHandler};
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/nipplejs-DYp3oo-D.js","assets/chunk-DECur_0Z.js"])))=>i.map(i=>d[i]);
|
||||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{r}from"./SettingsProvider-BeB5OnG9.js";import{t as i}from"./preload-helper-CnJ98jGT.js";import{n as a}from"./JoystickContext-BKqyiaNN.js";var o=e(t(),1),s={Joystick:`_Joystick_155b9_1`,Left:`_Left_155b9_11 _Joystick_155b9_1`,Right:`_Right_155b9_17 _Joystick_155b9_1`},c=n();function l(e){let t=e.querySelector(`.back`);t&&(t.style.background=`rgba(3, 79, 76, 0.6)`,t.style.border=`1px solid rgba(0, 219, 223, 0.5)`,t.style.boxShadow=`inset 0 0 10px rgba(0, 0, 0, 0.7)`);let n=e.querySelector(`.front`);n&&(n.style.background=`radial-gradient(circle at 50% 50%, rgba(23, 247, 198, 0.9) 0%, rgba(9, 184, 170, 0.95) 100%)`,n.style.border=`2px solid rgba(255, 255, 255, 0.4)`,n.style.boxShadow=`0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 -1px 2px rgba(0, 0, 0, 0.3)`)}function u(){let{touchMode:t}=r(),[n,u]=(0,o.useState)(null),[d,f]=(0,o.useState)(null),{moveState:p,lookState:m,setMoveState:h,setLookState:g}=a();(0,o.useEffect)(()=>{if(!n)return;let t=null,r=!1;return i(()=>import(`./nipplejs-DYp3oo-D.js`).then(t=>e(t.default,1)).then(e=>{r||(t=e.default.create({zone:n,mode:`static`,position:{left:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(n),t.on(`move`,(e,t)=>{h({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{h({force:0})}))}),__vite__mapDeps([0,1])),()=>{r=!0,t?.destroy()}},[p,n,h]),(0,o.useEffect)(()=>{if(!d)return;let t=null,n=!1;return i(()=>import(`./nipplejs-DYp3oo-D.js`).then(t=>e(t.default,1)).then(e=>{n||(t=e.default.create({zone:d,mode:`static`,position:{right:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(d),t.on(`move`,(e,t)=>{g({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{g({force:0})}))}),__vite__mapDeps([0,1])),()=>{n=!0,t?.destroy()}},[m,d,g]);let _=()=>{document.activeElement instanceof HTMLElement&&document.activeElement.blur()};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(`div`,{ref:u,className:t===`dualStick`?s.Left:s.Joystick,onContextMenu:e=>e.preventDefault(),onTouchStart:_},t),t===`dualStick`?(0,c.jsx)(`div`,{ref:f,className:s.Right,onContextMenu:e=>e.preventDefault(),onTouchStart:_}):null]})}export{u as TouchJoystick};
|
||||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/nipplejs-C1uh2Feh.js","assets/chunk-DECur_0Z.js"])))=>i.map(i=>d[i]);
|
||||
import{r as e}from"./chunk-DECur_0Z.js";import{r as t,t as n}from"./jsx-runtime-BpGWiA-R.js";import{r}from"./SettingsProvider-BdqQ2Cm4.js";import{t as i}from"./preload-helper-BPkniflS.js";import{n as a}from"./JoystickContext-B2sO9eYx.js";var o=e(t(),1),s={Joystick:`_Joystick_155b9_1`,Left:`_Left_155b9_11 _Joystick_155b9_1`,Right:`_Right_155b9_17 _Joystick_155b9_1`},c=n();function l(e){let t=e.querySelector(`.back`);t&&(t.style.background=`rgba(3, 79, 76, 0.6)`,t.style.border=`1px solid rgba(0, 219, 223, 0.5)`,t.style.boxShadow=`inset 0 0 10px rgba(0, 0, 0, 0.7)`);let n=e.querySelector(`.front`);n&&(n.style.background=`radial-gradient(circle at 50% 50%, rgba(23, 247, 198, 0.9) 0%, rgba(9, 184, 170, 0.95) 100%)`,n.style.border=`2px solid rgba(255, 255, 255, 0.4)`,n.style.boxShadow=`0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15), inset 0 -1px 2px rgba(0, 0, 0, 0.3)`)}function u(){let{touchMode:t}=r(),[n,u]=(0,o.useState)(null),[d,f]=(0,o.useState)(null),{moveState:p,lookState:m,setMoveState:h,setLookState:g}=a();(0,o.useEffect)(()=>{if(!n)return;let t=null,r=!1;return i(()=>import(`./nipplejs-C1uh2Feh.js`).then(t=>e(t.default,1)).then(e=>{r||(t=e.default.create({zone:n,mode:`static`,position:{left:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(n),t.on(`move`,(e,t)=>{h({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{h({force:0})}))}),__vite__mapDeps([0,1])),()=>{r=!0,t?.destroy()}},[p,n,h]),(0,o.useEffect)(()=>{if(!d)return;let t=null,n=!1;return i(()=>import(`./nipplejs-C1uh2Feh.js`).then(t=>e(t.default,1)).then(e=>{n||(t=e.default.create({zone:d,mode:`static`,position:{right:`70px`,bottom:`70px`},size:120,restOpacity:.9,dynamicPage:!0}),l(d),t.on(`move`,(e,t)=>{g({angle:t.angle.radian,force:Math.min(1,t.force)})}),t.on(`end`,()=>{g({force:0})}))}),__vite__mapDeps([0,1])),()=>{n=!0,t?.destroy()}},[m,d,g]);let _=()=>{document.activeElement instanceof HTMLElement&&document.activeElement.blur()};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(`div`,{ref:u,className:t===`dualStick`?s.Left:s.Joystick,onContextMenu:e=>e.preventDefault(),onTouchStart:_},t),t===`dualStick`?(0,c.jsx)(`div`,{ref:f,className:s.Right,onContextMenu:e=>e.preventDefault(),onTouchStart:_}):null]})}export{u as TouchJoystick};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
import{n as e}from"./jsx-runtime-BpGWiA-R.js";import{i as t,n}from"./traditional-DPdbI9gv.js";var r=e();function i(e,t=null,n=`feature`){return{targets:e,categoryName:t,tourType:n,currentIndex:0,phase:`traveling`,elapsed:0,phaseDuration:0,curve:null,startPos:null,startQuat:null,orbitCenter:null,orbitRadius:null,orbitStartAngle:0}}var a=t(e=>({animation:null,flyTo(t,n=`feature`){e({animation:i([t],null,n)})},startTour(t,n,r=`feature`){t.length!==0&&e({animation:i(t,n,r)})},advanceTarget(){e(e=>e.animation?{animation:{...e.animation,currentIndex:e.animation.currentIndex+1,phase:`traveling`,elapsed:0,curve:null,startPos:null,startQuat:null,orbitCenter:null,orbitRadius:null,orbitStartAngle:0}}:e)},cancel(){e({animation:null})}}));function o(e,t){return n(a,e,t)}function s(e){let t=(0,r.c)(2),n;return t[0]===e?n=t[1]:(n=t=>{let n=t.animation;return!n||n.tourType!==`debug`?!1:n.targets[n.currentIndex]?.entityId===e},t[0]=e,t[1]=n),o(n)}export{o as n,s as r,a as t};
|
||||
1
docs/assets/cameraTourStore-CtH3IrnD.js
Normal file
1
docs/assets/cameraTourStore-CtH3IrnD.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{n as e}from"./jsx-runtime-BpGWiA-R.js";import{n as t,r as n}from"./traditional-CCqNJZlI.js";var r=e();function i(e,t=null,n=`feature`){return{targets:e,categoryName:t,tourType:n,currentIndex:0,phase:`traveling`,elapsed:0,phaseDuration:0,curve:null,startPos:null,startQuat:null,orbitCenter:null,orbitRadius:null,orbitStartAngle:0}}var a=n(e=>({animation:null,flyTo(t,n=`feature`){e({animation:i([t],null,n)})},startTour(t,n,r=`feature`){t.length!==0&&e({animation:i(t,n,r)})},advanceTarget(){e(e=>e.animation?{animation:{...e.animation,currentIndex:e.animation.currentIndex+1,phase:`traveling`,elapsed:0,curve:null,startPos:null,startQuat:null,orbitCenter:null,orbitRadius:null,orbitStartAngle:0}}:e)},cancel(){e({animation:null})}}));function o(e,n){return t(a,e,n)}function s(e){let t=(0,r.c)(2),n;return t[0]===e?n=t[1]:(n=t=>{let n=t.animation;return!n||n.tourType!==`debug`?!1:n.targets[n.currentIndex]?.entityId===e},t[0]=e,t[1]=n),o(n)}export{o as n,s as r,a as t};
|
||||
File diff suppressed because one or more lines are too long
1
docs/assets/demoTimelineScanner-BbHg_3A9.js
Normal file
1
docs/assets/demoTimelineScanner-BbHg_3A9.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
docs/assets/engineStore-B1KAgiiF.js
Normal file
1
docs/assets/engineStore-B1KAgiiF.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{n as e}from"./jsx-runtime-BpGWiA-R.js";import{n as t,r as n}from"./traditional-CCqNJZlI.js";function r(e){let t=new Map;for(let n of e.state.datablocks.values()){if(n._class!==`tsshapeconstructor`)continue;let e=n.baseshape;if(typeof e!=`string`)continue;let r=e.toLowerCase(),i=r.replace(/\.dts$/i,``)+`_`,a=new Map;for(let e=0;e<=127;e++){let t=n[`sequence${e}`];if(typeof t!=`string`)continue;let r=t.indexOf(` `);if(r===-1)continue;let o=t.slice(0,r).toLowerCase(),s=t.slice(r+1).trim().toLowerCase();if(!s||!o.startsWith(i)||!o.endsWith(`.dsq`))continue;let c=o.slice(i.length,-4);c&&a.set(s,c)}a.size>0&&t.set(r,a)}return t}function i(e,t,n){let r=new Map;for(let n of e){let e=t.clipAction(n);r.set(n.name.toLowerCase(),e)}if(n)for(let[e,t]of n){let n=r.get(t);n&&!r.has(e)&&r.set(e,n)}return r}var a=e=>(t,n,r)=>{let i=r.subscribe;return r.subscribe=((e,t,n)=>{let a=e;if(t){let i=n?.equalityFn||Object.is,o=e(r.getState());a=n=>{let r=e(n);if(!i(o,r)){let e=o;t(o=r,e)}},n?.fireImmediately&&t(o,o)}return i(a)}),e(t,n,r)};e();function o(e){return e.toLowerCase()}function s(e){let t=o(e.trim());return t.startsWith(`$`)?t.slice(1):t}function c(e,t,n){return e<t?t:e>n?n:e}function l(e){let t={},n={},r={},i={};for(let n of e.state.objectsById.values())t[n._id]=0,n._name&&(r[o(n._name)]=n._id,n._isDatablock&&(i[o(n._name)]=n._id));for(let t of e.state.globals.keys())n[s(t)]=0;return{objectVersionById:t,globalVersionByName:n,objectIdsByName:r,datablockIdsByName:i}}var u={runtime:{runtime:null,sequenceAliases:new Map,objectVersionById:{},globalVersionByName:{},objectIdsByName:{},datablockIdsByName:{},lastRuntimeTick:0},playback:{recording:null,status:`stopped`,seekTime:0,rate:1,durationMs:0,streamSnapshot:null}},d=n()(a(e=>({...u,setRuntime(t){let n=l(t),i=r(t);e(e=>({...e,runtime:{runtime:t,sequenceAliases:i,objectVersionById:n.objectVersionById,globalVersionByName:n.globalVersionByName,objectIdsByName:n.objectIdsByName,datablockIdsByName:n.datablockIdsByName,lastRuntimeTick:0}}))},clearRuntime(){e(e=>({...e,runtime:{runtime:null,sequenceAliases:new Map,objectVersionById:{},globalVersionByName:{},objectIdsByName:{},datablockIdsByName:{},lastRuntimeTick:0}}))},applyRuntimeBatch(t,n){t.length!==0&&e(e=>{let r={...e.runtime.objectVersionById},i={...e.runtime.globalVersionByName},a={...e.runtime.objectIdsByName},c={...e.runtime.datablockIdsByName},l=e=>{e!=null&&(r[e]=(r[e]??0)+1)};for(let e of t){if(e.type===`object.created`){let t=e.object;if(l(e.objectId),t._name){let n=o(t._name);a[n]=e.objectId,t._isDatablock&&(c[n]=e.objectId)}l(t._parent?._id);continue}if(e.type===`object.deleted`){let t=e.object;if(delete r[e.objectId],t?._name){let e=o(t._name);delete a[e],t._isDatablock&&delete c[e]}l(t?._parent?._id);continue}if(e.type===`field.changed`){l(e.objectId);continue}if(e.type===`global.changed`){let t=s(e.name);i[t]=(i[t]??0)+1;continue}}let u=n?.tick??(e.runtime.lastRuntimeTick>0?e.runtime.lastRuntimeTick+1:1);return{...e,runtime:{...e.runtime,objectVersionById:r,globalVersionByName:i,objectIdsByName:a,datablockIdsByName:c,lastRuntimeTick:u}}})},setRecording(t){let n=Math.max(0,(t?.duration??0)*1e3);e(e=>({...e,playback:{recording:t,status:t?`stopped`:e.playback.status,seekTime:t?0:e.playback.seekTime,rate:t?1:e.playback.rate,durationMs:n,streamSnapshot:t?null:e.playback.streamSnapshot}}))},seekPlayback(t){e(e=>{let n=c(t,0,e.playback.durationMs/1e3);return{...e,playback:{...e.playback,seekTime:n}}})},setPlaybackStatus(t){e(e=>({...e,playback:{...e.playback,status:t}}))},setPlaybackRate(t){let n=Number.isFinite(t)?c(t,.01,16):1;e(e=>({...e,playback:{...e.playback,rate:n}}))},setPlaybackStreamSnapshot(t){e(e=>({...e,playback:{...e.playback,streamSnapshot:t}}))}}))),f=0;function p(){return f}function m(e,t){f+=e*t*1e3}function h(){f=0}d.subscribe(e=>e.playback.status,e=>{e===`stopped`&&h()});function g(){return d}function _(e,n){return t(d,e,n)}export{g as a,_ as i,p as n,a as o,d as r,i as s,m as t};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{n as e}from"./jsx-runtime-BpGWiA-R.js";import{i as t,n}from"./traditional-DPdbI9gv.js";var r=e=>(t,n,r)=>{let i=r.subscribe;return r.subscribe=((e,t,n)=>{let a=e;if(t){let i=n?.equalityFn||Object.is,o=e(r.getState());a=n=>{let r=e(n);if(!i(o,r)){let e=o;t(o=r,e)}},n?.fireImmediately&&t(o,o)}return i(a)}),e(t,n,r)};function i(e){let t=new Map;for(let n of e.state.datablocks.values()){if(n._class!==`tsshapeconstructor`)continue;let e=n.baseshape;if(typeof e!=`string`)continue;let r=e.toLowerCase(),i=r.replace(/\.dts$/i,``)+`_`,a=new Map;for(let e=0;e<=127;e++){let t=n[`sequence${e}`];if(typeof t!=`string`)continue;let r=t.indexOf(` `);if(r===-1)continue;let o=t.slice(0,r).toLowerCase(),s=t.slice(r+1).trim().toLowerCase();if(!s||!o.startsWith(i)||!o.endsWith(`.dsq`))continue;let c=o.slice(i.length,-4);c&&a.set(s,c)}a.size>0&&t.set(r,a)}return t}function a(e,t,n){let r=new Map;for(let n of e){let e=t.clipAction(n);r.set(n.name.toLowerCase(),e)}if(n)for(let[e,t]of n){let n=r.get(t);n&&!r.has(e)&&r.set(e,n)}return r}e();function o(e){return e.toLowerCase()}function s(e){let t=o(e.trim());return t.startsWith(`$`)?t.slice(1):t}function c(e,t,n){return e<t?t:e>n?n:e}function l(e){let t={},n={},r={},i={};for(let n of e.state.objectsById.values())t[n._id]=0,n._name&&(r[o(n._name)]=n._id,n._isDatablock&&(i[o(n._name)]=n._id));for(let t of e.state.globals.keys())n[s(t)]=0;return{objectVersionById:t,globalVersionByName:n,objectIdsByName:r,datablockIdsByName:i}}var u={runtime:{runtime:null,sequenceAliases:new Map,objectVersionById:{},globalVersionByName:{},objectIdsByName:{},datablockIdsByName:{},lastRuntimeTick:0},playback:{recording:null,status:`stopped`,timeMs:0,rate:1,durationMs:0,streamSnapshot:null}},d=t()(r(e=>({...u,setRuntime(t){let n=l(t),r=i(t);e(e=>({...e,runtime:{runtime:t,sequenceAliases:r,objectVersionById:n.objectVersionById,globalVersionByName:n.globalVersionByName,objectIdsByName:n.objectIdsByName,datablockIdsByName:n.datablockIdsByName,lastRuntimeTick:0}}))},clearRuntime(){e(e=>({...e,runtime:{runtime:null,sequenceAliases:new Map,objectVersionById:{},globalVersionByName:{},objectIdsByName:{},datablockIdsByName:{},lastRuntimeTick:0}}))},applyRuntimeBatch(t,n){t.length!==0&&e(e=>{let r={...e.runtime.objectVersionById},i={...e.runtime.globalVersionByName},a={...e.runtime.objectIdsByName},c={...e.runtime.datablockIdsByName},l=e=>{e!=null&&(r[e]=(r[e]??0)+1)};for(let e of t){if(e.type===`object.created`){let t=e.object;if(l(e.objectId),t._name){let n=o(t._name);a[n]=e.objectId,t._isDatablock&&(c[n]=e.objectId)}l(t._parent?._id);continue}if(e.type===`object.deleted`){let t=e.object;if(delete r[e.objectId],t?._name){let e=o(t._name);delete a[e],t._isDatablock&&delete c[e]}l(t?._parent?._id);continue}if(e.type===`field.changed`){l(e.objectId);continue}if(e.type===`global.changed`){let t=s(e.name);i[t]=(i[t]??0)+1;continue}}let u=n?.tick??(e.runtime.lastRuntimeTick>0?e.runtime.lastRuntimeTick+1:1);return{...e,runtime:{...e.runtime,objectVersionById:r,globalVersionByName:i,objectIdsByName:a,datablockIdsByName:c,lastRuntimeTick:u}}})},setRecording(t){let n=Math.max(0,(t?.duration??0)*1e3);e(e=>({...e,playback:{recording:t,status:t?`stopped`:e.playback.status,timeMs:t?0:e.playback.timeMs,rate:t?1:e.playback.rate,durationMs:n,streamSnapshot:t?null:e.playback.streamSnapshot}}))},setPlaybackTime(t){e(e=>{let n=c(t,0,e.playback.durationMs);return{...e,playback:{...e.playback,timeMs:n}}})},setPlaybackStatus(t){e(e=>({...e,playback:{...e.playback,status:t}}))},setPlaybackRate(t){let n=Number.isFinite(t)?c(t,.01,16):1;e(e=>({...e,playback:{...e.playback,rate:n}}))},setPlaybackStreamSnapshot(t){e(e=>({...e,playback:{...e.playback,streamSnapshot:t}}))}}))),f=0;function p(){return f}function m(e,t){f+=e*t*1e3}function h(){f=0}d.subscribe(e=>e.playback.status,e=>{e===`stopped`&&h()});function g(){return d}function _(e,t){return n(d,e,t)}export{g as a,_ as i,p as n,a as o,d as r,r as s,m as t};
|
||||
|
|
@ -1 +1 @@
|
|||
import{t as e}from"./iconBase-DjT_EJem.js";function t(t){return e({tag:`svg`,attr:{viewBox:`0 0 24 24`},child:[{tag:`path`,attr:{fill:`none`,strokeWidth:`2`,d:`M3,22.0000002 L21,12 L3,2 L3,22.0000002 Z M5,19 L17.5999998,11.9999999 L5,5 L5,19 Z M7,16 L14.1999999,12 L7,8 L7,16 Z M9,13 L10.8,12 L9,11 L9,13 Z`},child:[]}]})(t)}function n(t){return e({tag:`svg`,attr:{viewBox:`0 0 24 24`},child:[{tag:`path`,attr:{fill:`none`,strokeWidth:`2`,d:`M3,21 L9,21 L9,3 L3,3 L3,21 Z M4,19 L8,19 L8,5 L4,5 L4,19 Z M5,17 L7,17 L7,7 L5,7 L5,17 Z M15,21 L21,21 L21,3 L15,3 L15,21 Z M16,19 L20,19 L20,5 L16,5 L16,19 Z M17,17 L19,17 L19,7 L17,7 L17,17 Z`},child:[]}]})(t)}export{t as n,n as t};
|
||||
import{t as e}from"./iconBase-DZ3jidsI.js";function t(t){return e({tag:`svg`,attr:{viewBox:`0 0 24 24`},child:[{tag:`path`,attr:{fill:`none`,strokeWidth:`2`,d:`M3,22.0000002 L21,12 L3,2 L3,22.0000002 Z M5,19 L17.5999998,11.9999999 L5,5 L5,19 Z M7,16 L14.1999999,12 L7,8 L7,16 Z M9,13 L10.8,12 L9,11 L9,13 Z`},child:[]}]})(t)}function n(t){return e({tag:`svg`,attr:{viewBox:`0 0 24 24`},child:[{tag:`path`,attr:{fill:`none`,strokeWidth:`2`,d:`M3,21 L9,21 L9,3 L3,3 L3,21 Z M4,19 L8,19 L8,5 L4,5 L4,19 Z M5,17 L7,17 L7,7 L5,7 L5,17 Z M15,21 L21,21 L21,3 L15,3 L15,21 Z M16,19 L20,19 L20,5 L16,5 L16,19 Z M17,17 L19,17 L19,7 L17,7 L17,17 Z`},child:[]}]})(t)}export{t as n,n as t};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
docs/assets/index-CiZqoesx.css
Normal file
1
docs/assets/index-CiZqoesx.css
Normal file
File diff suppressed because one or more lines are too long
4
docs/assets/index-D4aiQcCU.js
Normal file
4
docs/assets/index-D4aiQcCU.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/assets/loaders-B4T775qz.js
Normal file
1
docs/assets/loaders-B4T775qz.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{t as e}from"./logger-B058WGzf.js";import{c as t,n,s as r,t as i}from"./manifest-BIDT_vSa.js";import{a}from"./stringUtils-1MyeFdQ_.js";import{a as o}from"./mission-yeigCtfF.js";function s(e){return e.split(/(?:\r\n|\r|\n)/g).map(e=>e.trim()).filter(Boolean).filter(e=>!e.startsWith(`;`)).map(e=>{let t=e.match(/^(.+)\s(\d+)$/);if(t){let e=parseInt(t[2],10);return{name:t[1],frameCount:e}}else return{name:e,frameCount:1}})}var c=256;function l(e){let t=new DataView(e),n=0,r=t.getUint8(n++),i=new Uint16Array(c*c),a=[],o=e=>{let r=``;for(let i=0;i<e;i++){let e=t.getUint8(n+i);if(e===0)break;r+=String.fromCharCode(e)}return n+=e,r};for(let e=0;e<c*c;e++){let r=t.getUint16(n,!0);n+=2,i[e]=r}n+=256*256;let s=i;for(let e=0;e<8;e++){let r=t.getUint8(n++),i=o(r);e<6&&r>0&&a.push(i)}let l=[];for(let e of a){let e=new Uint8Array(c*c);for(let r=0;r<c*c;r++)e[r]=t.getUint8(n++);l.push(e)}return{version:r,textureNames:a,heightMap:s,alphaMaps:l}}var u=e(`loaders`),d=`/t2-mapper`,f=`${d}/base/`,p=`${d}/white.png`;function m(e,t){let n;try{n=i(e)}catch(n){if(t)return u.warn(`Resource "%s" not found — rendering fallback`,e),t;throw n}let[a,o]=r(n);return a?`${f}@vl2/${a}/${o}`:`${f}${o}`}function h(e){return m(`interiors/${e}`).replace(/\.dif$/i,`.glb`)}function g(e){return m(`shapes/${e}`).replace(/\.dts$/i,`.glb`)}function _(e){return e=e.replace(/^terrain\./,``),m(t(`textures/terrain/${e}`),p)}function v(e,n){let r=a(n).split(`/`);return m(t(`${r.length>1?r.slice(0,-1).join(`/`)+`/`:``}${e}`),p)}function y(e,n=p){return m(t(`textures/${e}`),n??void 0)}function b(e){return m(`audio/${/\.\w+$/.test(e)?e:`${e}.wav`}`).replace(/\.wav$/i,`.m4a`)}async function x(e){let t=m(`textures/${e}`);return(await(await fetch(t)).text()).split(/(?:\r\n|\r|\n)/).map(e=>{if(e=e.trim(),!e.startsWith(`;`))return e}).filter(Boolean)}async function S(e){let t=n(e),r=await(await fetch(m(t.resourcePath))).arrayBuffer(),i;try{i=new TextDecoder(`utf-8`,{fatal:!0}).decode(r)}catch{i=new TextDecoder(`windows-1252`).decode(r)}return i=i.replaceAll(`<EFBFBD>`,`'`),o(i)}async function C(e){let t=m(`terrains/${e}`);u.debug(`Fetching terrain: %s`,t);let n=await fetch(t);if(!n.ok)throw Error(`[loadTerrain] Failed to fetch ${t}: ${n.status} ${n.statusText}`);let r=await n.arrayBuffer();return u.debug(`Loaded terrain %s: %d bytes`,e,r.byteLength),l(r)}async function w(e){let t=m(e);return s(await(await fetch(t)).text())}export{v as a,w as c,g as d,_ as f,m as i,S as l,f as n,h as o,y as p,b as r,x as s,p as t,C as u};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
import{r as e,t}from"./chunk-DECur_0Z.js";import{t as n}from"./logger-CySD1nLn.js";function r(e){let t=e.indexOf(`::`);return t===-1?null:{namespace:e.slice(0,t),method:e.slice(t+2)}}var i={"+":`$.add`,"-":`$.sub`,"*":`$.mul`,"/":`$.div`,"<":`$.lt`,"<=":`$.le`,">":`$.gt`,">=":`$.ge`,"==":`$.eq`,"!=":`$.ne`,"%":`$.mod`,"&":`$.bitand`,"|":`$.bitor`,"^":`$.bitxor`,"<<":`$.shl`,">>":`$.shr`},a=class{indent;runtime;functions;globals;locals;indentLevel=0;currentClass=null;currentFunction=null;constructor(e={}){this.indent=e.indent??` `,this.runtime=e.runtime??`$`,this.functions=e.functions??`$f`,this.globals=e.globals??`$g`,this.locals=e.locals??`$l`}getAccessInfo(e){if(e.type===`Variable`){let t=JSON.stringify(e.name),n=e.scope===`global`?this.globals:this.locals;return{getter:`${n}.get(${t})`,setter:e=>`${n}.set(${t}, ${e})`,postIncHelper:`${n}.postInc(${t})`,postDecHelper:`${n}.postDec(${t})`}}if(e.type===`MemberExpression`){let t=this.expression(e.object),n=e.property.type===`Identifier`?JSON.stringify(e.property.name):this.expression(e.property);return{getter:`${this.runtime}.prop(${t}, ${n})`,setter:e=>`${this.runtime}.setProp(${t}, ${n}, ${e})`,postIncHelper:`${this.runtime}.propPostInc(${t}, ${n})`,postDecHelper:`${this.runtime}.propPostDec(${t}, ${n})`}}if(e.type===`IndexExpression`){let t=Array.isArray(e.index)?e.index.map(e=>this.expression(e)):[this.expression(e.index)];if(e.object.type===`Variable`){let n=JSON.stringify(e.object.name),r=e.object.scope===`global`?this.globals:this.locals,i=t.join(`, `);return{getter:`${r}.get(${n}, ${i})`,setter:e=>`${r}.set(${n}, ${i}, ${e})`,postIncHelper:`${r}.postInc(${n}, ${i})`,postDecHelper:`${r}.postDec(${n}, ${i})`}}if(e.object.type===`MemberExpression`){let n=e.object,r=this.expression(n.object),i=n.property.type===`Identifier`?JSON.stringify(n.property.name):this.expression(n.property),a=`${this.runtime}.key(${i}, ${t.join(`, `)})`;return{getter:`${this.runtime}.prop(${r}, ${a})`,setter:e=>`${this.runtime}.setProp(${r}, ${a}, ${e})`,postIncHelper:`${this.runtime}.propPostInc(${r}, ${a})`,postDecHelper:`${this.runtime}.propPostDec(${r}, ${a})`}}let n=this.expression(e.object),r=t.length===1?t[0]:`${this.runtime}.key(${t.join(`, `)})`;return{getter:`${this.runtime}.getIndex(${n}, ${r})`,setter:e=>`${this.runtime}.setIndex(${n}, ${r}, ${e})`,postIncHelper:`${this.runtime}.indexPostInc(${n}, ${r})`,postDecHelper:`${this.runtime}.indexPostDec(${n}, ${r})`}}return null}generate(e){let t=[];for(let n of e.body){let e=this.statement(n);e&&t.push(e)}return t.join(`
|
||||
import{r as e,t}from"./chunk-DECur_0Z.js";import{t as n}from"./logger-B058WGzf.js";function r(e){let t=e.indexOf(`::`);return t===-1?null:{namespace:e.slice(0,t),method:e.slice(t+2)}}var i={"+":`$.add`,"-":`$.sub`,"*":`$.mul`,"/":`$.div`,"<":`$.lt`,"<=":`$.le`,">":`$.gt`,">=":`$.ge`,"==":`$.eq`,"!=":`$.ne`,"%":`$.mod`,"&":`$.bitand`,"|":`$.bitor`,"^":`$.bitxor`,"<<":`$.shl`,">>":`$.shr`},a=class{indent;runtime;functions;globals;locals;indentLevel=0;currentClass=null;currentFunction=null;constructor(e={}){this.indent=e.indent??` `,this.runtime=e.runtime??`$`,this.functions=e.functions??`$f`,this.globals=e.globals??`$g`,this.locals=e.locals??`$l`}getAccessInfo(e){if(e.type===`Variable`){let t=JSON.stringify(e.name),n=e.scope===`global`?this.globals:this.locals;return{getter:`${n}.get(${t})`,setter:e=>`${n}.set(${t}, ${e})`,postIncHelper:`${n}.postInc(${t})`,postDecHelper:`${n}.postDec(${t})`}}if(e.type===`MemberExpression`){let t=this.expression(e.object),n=e.property.type===`Identifier`?JSON.stringify(e.property.name):this.expression(e.property);return{getter:`${this.runtime}.prop(${t}, ${n})`,setter:e=>`${this.runtime}.setProp(${t}, ${n}, ${e})`,postIncHelper:`${this.runtime}.propPostInc(${t}, ${n})`,postDecHelper:`${this.runtime}.propPostDec(${t}, ${n})`}}if(e.type===`IndexExpression`){let t=Array.isArray(e.index)?e.index.map(e=>this.expression(e)):[this.expression(e.index)];if(e.object.type===`Variable`){let n=JSON.stringify(e.object.name),r=e.object.scope===`global`?this.globals:this.locals,i=t.join(`, `);return{getter:`${r}.get(${n}, ${i})`,setter:e=>`${r}.set(${n}, ${i}, ${e})`,postIncHelper:`${r}.postInc(${n}, ${i})`,postDecHelper:`${r}.postDec(${n}, ${i})`}}if(e.object.type===`MemberExpression`){let n=e.object,r=this.expression(n.object),i=n.property.type===`Identifier`?JSON.stringify(n.property.name):this.expression(n.property),a=`${this.runtime}.key(${i}, ${t.join(`, `)})`;return{getter:`${this.runtime}.prop(${r}, ${a})`,setter:e=>`${this.runtime}.setProp(${r}, ${a}, ${e})`,postIncHelper:`${this.runtime}.propPostInc(${r}, ${a})`,postDecHelper:`${this.runtime}.propPostDec(${r}, ${a})`}}let n=this.expression(e.object),r=t.length===1?t[0]:`${this.runtime}.key(${t.join(`, `)})`;return{getter:`${this.runtime}.getIndex(${n}, ${r})`,setter:e=>`${this.runtime}.setIndex(${n}, ${r}, ${e})`,postIncHelper:`${this.runtime}.indexPostInc(${n}, ${r})`,postDecHelper:`${this.runtime}.indexPostDec(${n}, ${r})`}}return null}generate(e){let t=[];for(let n of e.body){let e=this.statement(n);e&&t.push(e)}return t.join(`
|
||||
|
||||
`)}statement(e){switch(e.type){case`Comment`:return``;case`ExpressionStatement`:return this.line(`${this.expression(e.expression)};`);case`FunctionDeclaration`:return this.functionDeclaration(e);case`PackageDeclaration`:return this.packageDeclaration(e);case`DatablockDeclaration`:return this.datablockDeclaration(e);case`ObjectDeclaration`:return this.line(`${this.objectDeclaration(e)};`);case`IfStatement`:return this.ifStatement(e);case`ForStatement`:return this.forStatement(e);case`WhileStatement`:return this.whileStatement(e);case`DoWhileStatement`:return this.doWhileStatement(e);case`SwitchStatement`:return this.switchStatement(e);case`ReturnStatement`:return this.returnStatement(e);case`BreakStatement`:return this.line(`break;`);case`ContinueStatement`:return this.line(`continue;`);case`BlockStatement`:return this.blockStatement(e);default:throw Error(`Unknown statement type: ${e.type}`)}}functionDeclaration(e){let t=r(e.name.name);if(t){let n=t.namespace,r=t.method;this.currentClass=n.toLowerCase(),this.currentFunction=r.toLowerCase();let i=this.functionBody(e.body,e.params);return this.currentClass=null,this.currentFunction=null,`${this.line(`${this.runtime}.registerMethod(${JSON.stringify(n)}, ${JSON.stringify(r)}, function() {`)}\n${i}\n${this.line(`});`)}`}else{let t=e.name.name;this.currentFunction=t.toLowerCase();let n=this.functionBody(e.body,e.params);return this.currentFunction=null,`${this.line(`${this.runtime}.registerFunction(${JSON.stringify(t)}, function() {`)}\n${n}\n${this.line(`});`)}`}}functionBody(e,t){this.indentLevel++;let n=[];n.push(this.line(`const ${this.locals} = ${this.runtime}.locals();`));for(let e=0;e<t.length;e++)n.push(this.line(`${this.locals}.set(${JSON.stringify(t[e].name)}, arguments[${e}]);`));for(let t of e.body)n.push(this.statement(t));return this.indentLevel--,n.join(`
|
||||
`)}packageDeclaration(e){let t=JSON.stringify(e.name.name);this.indentLevel++;let n=e.body.map(e=>this.statement(e)).join(`
|
||||
File diff suppressed because one or more lines are too long
47
docs/assets/playbackUtils-DjmjN4tv.js
Normal file
47
docs/assets/playbackUtils-DjmjN4tv.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
12
docs/assets/react-three-fiber.esm-El6vNTZj.js
Normal file
12
docs/assets/react-three-fiber.esm-El6vNTZj.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/assets/scene-C20n9V3Y.js
Normal file
1
docs/assets/scene-C20n9V3Y.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{Ct as e,rt as t}from"./three.module-DKAirPAO.js";import{t as n}from"./logger-B058WGzf.js";var r=n(`ghostToScene`),i={x:0,y:0,z:0},a={x:1,y:1,z:1};function o(e,t){return e??t}function s(e,t){return e??t}function c(e){if(!e)return{elements:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],position:i};if(`elements`in e)return e;let{position:t,rotation:n}=e,r=n.x*n.x,a=n.y*n.y,o=n.z*n.z,s=n.x*n.y,c=n.x*n.z,l=n.y*n.z,u=n.w*n.x,d=n.w*n.y,f=n.w*n.z;return{elements:[1-2*(a+o),2*(s+f),2*(c-d),0,2*(s-f),1-2*(r+o),2*(l+u),0,2*(c+d),2*(l-u),1-2*(r+a),0,t.x,t.y,t.z,1],position:{x:t.x,y:t.y,z:t.z}}}function l(e,t){return{className:`TerrainBlock`,ghostIndex:e,terrFileName:t.terrFileName??``,detailTextureName:t.detailTextureName??``,squareSize:t.squareSize??8,emptySquareRuns:t.emptySquareRuns}}function u(e,t){return{className:`InteriorInstance`,ghostIndex:e,interiorFile:t.interiorFile??``,transform:c(t.transform),scale:t.scale??a,showTerrainInside:t.showTerrainInside??!1,skinBase:t.skinBase??``,alarmState:t.alarmState??!1}}function d(e,t){return{className:`TSStatic`,ghostIndex:e,shapeName:t.shapeName??``,transform:c(t.transform),scale:t.scale??a}}function f(e,t){let n=t.fogVolumes?t.fogVolumes.map(e=>({visibleDistance:e.visibleDistance??0,minHeight:e.minHeight??0,maxHeight:e.maxHeight??0,color:o(e.color,{r:0,g:0,b:0})})):[],r=t.cloudLayers?t.cloudLayers.map(e=>({texture:e.texture??``,heightPercent:e.heightPercent??0,speed:e.speed??0})):[];return{className:`Sky`,ghostIndex:e,materialList:t.materialList??``,fogColor:o(t.fogColor,{r:0,g:0,b:0}),visibleDistance:t.visibleDistance??1e3,fogDistance:t.fogDistance??0,skySolidColor:o(t.skySolidColor,{r:0,g:0,b:0}),useSkyTextures:t.useSkyTextures??!0,fogVolumes:n,cloudLayers:r,windVelocity:t.windVelocity??i}}function p(e,t){return{className:`Sun`,ghostIndex:e,direction:t.direction??{x:.57735,y:.57735,z:-.57735},color:s(t.color,{r:.7,g:.7,b:.7,a:1}),ambient:s(t.ambient,{r:.5,g:.5,b:.5,a:1}),textures:t.textures}}function m(e,t){return{className:`MissionArea`,ghostIndex:e,area:t.area??{x:-512,y:-512,w:1024,h:1024},flightCeiling:t.flightCeiling??2e3,flightCeilingRange:t.flightCeilingRange??50}}function h(e,t){return{className:`WaterBlock`,ghostIndex:e,transform:c(t.transform),scale:t.scale??a,surfaceName:t.surfaceName??``,envMapName:t.envMapName??``,surfaceOpacity:t.surfaceOpacity??.75,waveMagnitude:t.waveMagnitude??1,envMapIntensity:t.envMapIntensity??1}}function g(e,t,n){switch(e){case`TerrainBlock`:{let e=l(t,n);return r.debug(`TerrainBlock #%d: terrFileName=%s`,t,e.terrFileName),e}case`InteriorInstance`:{let e=u(t,n);return r.debug(`InteriorInstance #%d: interiorFile=%s`,t,e.interiorFile),e}case`TSStatic`:return d(t,n);case`Sky`:{let e=f(t,n);return r.debug(`Sky #%d: materialList=%s fogColor=(%s, %s, %s) visibleDist=%d fogDist=%d useSkyTextures=%s`,t,e.materialList,e.fogColor.r.toFixed(3),e.fogColor.g.toFixed(3),e.fogColor.b.toFixed(3),e.visibleDistance,e.fogDistance,e.useSkyTextures),e}case`Sun`:{let e=p(t,n);return r.debug(`Sun #%d: dir=(%s, %s, %s) color=(%s, %s, %s) ambient=(%s, %s, %s)`,t,e.direction.x.toFixed(3),e.direction.y.toFixed(3),e.direction.z.toFixed(3),e.color.r.toFixed(3),e.color.g.toFixed(3),e.color.b.toFixed(3),e.ambient.r.toFixed(3),e.ambient.g.toFixed(3),e.ambient.b.toFixed(3)),e}case`MissionArea`:return m(t,n);case`WaterBlock`:return h(t,n);default:return null}}function _(e){return[e.y,e.z,e.x]}function v(e){return[e.y,e.z,e.x]}function y(n){let r=n.elements,i=new t,a=i.elements;a[0]=r[5],a[1]=r[6],a[2]=r[4],a[3]=0,a[4]=r[9],a[5]=r[10],a[6]=r[8],a[7]=0,a[8]=r[1],a[9]=r[2],a[10]=r[0],a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1;let o=new e;return o.setFromRotationMatrix(i),o.conjugate(),o}export{g as i,v as n,_ as r,y as t};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{t as e}from"./logger-CySD1nLn.js";import{Ct as t,rt as n}from"./three.module-DeDv86YO.js";var r=e(`ghostToScene`);function i(e,t={x:0,y:0,z:0}){return e&&typeof e==`object`&&`x`in e?e:t}function a(e,t={r:0,g:0,b:0}){return e&&typeof e==`object`&&`r`in e?e:t}function o(e,t={r:.5,g:.5,b:.5,a:1}){return e&&typeof e==`object`&&`r`in e?e:t}function s(e){if(e&&typeof e==`object`&&`elements`in e&&Array.isArray(e.elements))return e;if(e&&typeof e==`object`&&`position`in e&&`rotation`in e){let{position:t,rotation:n}=e,r=n.x*n.x,i=n.y*n.y,a=n.z*n.z,o=n.x*n.y,s=n.x*n.z,c=n.y*n.z,l=n.w*n.x,u=n.w*n.y,d=n.w*n.z;return{elements:[1-2*(i+a),2*(o+d),2*(s-u),0,2*(o-d),1-2*(r+a),2*(c+l),0,2*(s+u),2*(c-l),1-2*(r+i),0,t.x,t.y,t.z,1],position:{x:t.x,y:t.y,z:t.z}}}return{elements:[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],position:{x:0,y:0,z:0}}}function c(e,t){return{className:`TerrainBlock`,ghostIndex:e,terrFileName:t.terrFileName??``,detailTextureName:t.detailTextureName??``,squareSize:t.squareSize??8,emptySquareRuns:t.emptySquareRuns}}function l(e,t){return{className:`InteriorInstance`,ghostIndex:e,interiorFile:t.interiorFile??``,transform:s(t.transform),scale:i(t.scale,{x:1,y:1,z:1}),showTerrainInside:t.showTerrainInside??!1,skinBase:t.skinBase??``,alarmState:t.alarmState??!1}}function u(e,t){return{className:`TSStatic`,ghostIndex:e,shapeName:t.shapeName??``,transform:s(t.transform),scale:i(t.scale,{x:1,y:1,z:1})}}function d(e,t){let n=Array.isArray(t.fogVolumes)?t.fogVolumes.map(e=>({visibleDistance:e.visibleDistance??0,minHeight:e.minHeight??0,maxHeight:e.maxHeight??0,color:a(e.color)})):[],r=Array.isArray(t.cloudLayers)?t.cloudLayers.map(e=>({texture:e.texture??``,heightPercent:e.heightPercent??0,speed:e.speed??0})):[];return{className:`Sky`,ghostIndex:e,materialList:t.materialList??``,fogColor:a(t.fogColor),visibleDistance:t.visibleDistance??1e3,fogDistance:t.fogDistance??0,skySolidColor:a(t.skySolidColor),useSkyTextures:t.useSkyTextures??!0,fogVolumes:n,cloudLayers:r,windVelocity:i(t.windVelocity)}}function f(e,t){return{className:`Sun`,ghostIndex:e,direction:i(t.direction,{x:.57735,y:.57735,z:-.57735}),color:o(t.color,{r:.7,g:.7,b:.7,a:1}),ambient:o(t.ambient,{r:.5,g:.5,b:.5,a:1}),textures:Array.isArray(t.textures)?t.textures:void 0}}function p(e,t){return{className:`MissionArea`,ghostIndex:e,area:t.area??{x:-512,y:-512,w:1024,h:1024},flightCeiling:t.flightCeiling??2e3,flightCeilingRange:t.flightCeilingRange??50}}function m(e,t){return{className:`WaterBlock`,ghostIndex:e,transform:s(t.transform),scale:i(t.scale,{x:1,y:1,z:1}),surfaceName:t.surfaceName??``,envMapName:t.envMapName??``,surfaceOpacity:t.surfaceOpacity??.75,waveMagnitude:t.waveMagnitude??1,envMapIntensity:t.envMapIntensity??1}}function h(e,t,n){let i;switch(e){case`TerrainBlock`:return i=c(t,n),r.debug(`TerrainBlock #%d: terrFileName=%s`,t,i.terrFileName),i;case`InteriorInstance`:return i=l(t,n),r.debug(`InteriorInstance #%d: interiorFile=%s`,t,i.interiorFile),i;case`TSStatic`:return u(t,n);case`Sky`:{i=d(t,n);let e=i;return r.debug(`Sky #%d: materialList=%s fogColor=(%s, %s, %s) visibleDist=%d fogDist=%d useSkyTextures=%s`,t,e.materialList,e.fogColor.r.toFixed(3),e.fogColor.g.toFixed(3),e.fogColor.b.toFixed(3),e.visibleDistance,e.fogDistance,e.useSkyTextures),i}case`Sun`:{i=f(t,n);let e=i;return r.debug(`Sun #%d: dir=(%s, %s, %s) color=(%s, %s, %s) ambient=(%s, %s, %s)`,t,e.direction.x.toFixed(3),e.direction.y.toFixed(3),e.direction.z.toFixed(3),e.color.r.toFixed(3),e.color.g.toFixed(3),e.color.b.toFixed(3),e.ambient.r.toFixed(3),e.ambient.g.toFixed(3),e.ambient.b.toFixed(3)),i}case`MissionArea`:return p(t,n);case`WaterBlock`:return m(t,n);default:return null}}function g(e){return[e.y,e.z,e.x]}function _(e){return[e.y,e.z,e.x]}function v(e){let r=e.elements,i=new n,a=i.elements;a[0]=r[5],a[1]=r[6],a[2]=r[4],a[3]=0,a[4]=r[9],a[5]=r[10],a[6]=r[8],a[7]=0,a[8]=r[1],a[9]=r[2],a[10]=r[0],a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1;let o=new t;return o.setFromRotationMatrix(i),o.conjugate(),o}export{h as i,_ as n,g as r,v as t};
|
||||
1
docs/assets/streamHelpers-CYLk-lCT.js
Normal file
1
docs/assets/streamHelpers-CYLk-lCT.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{i as e}from"./traditional-DPdbI9gv.js";var t=e()(()=>({time:0,playback:null,root:null,cameraMode:`original`,orbitOverrideYaw:0,orbitOverridePitch:0}));function n(){t.setState({time:0,playback:null,cameraMode:`original`,orbitOverrideYaw:0,orbitOverridePitch:0})}export{t as n,n as t};
|
||||
import{r as e}from"./traditional-CCqNJZlI.js";var t=e()(()=>({time:0,playback:null,root:null,cameraMode:`original`,orbitOverrideYaw:0,orbitOverridePitch:0}));function n(){t.setState({time:0,playback:null,cameraMode:`original`,orbitOverrideYaw:0,orbitOverridePitch:0})}export{t as n,n as t};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import{C as e,Dt as t,Ht as n,J as r,Ot as i,P as a,kt as o,q as s,t as c,zt as l}from"./three.module-DeDv86YO.js";var u=`
|
||||
import{C as e,Ht as t,J as n,Ot as r,P as i,Tt as a,kt as o,q as s,t as c,zt as l}from"./three.module-DKAirPAO.js";var u=`
|
||||
#ifdef USE_FOG
|
||||
// Check fog enabled uniform - allows toggling without shader recompilation
|
||||
#ifdef USE_VOLUMETRIC_FOG
|
||||
|
|
@ -191,4 +191,4 @@ import{C as e,Dt as t,Ht as n,J as r,Ot as i,P as a,kt as o,q as s,t as c,zt as
|
|||
uniform bool fogEnabled;
|
||||
#define USE_FOG_WORLD_POSITION
|
||||
varying vec3 vFogWorldPosition;
|
||||
#endif`),e.fragmentShader=e.fragmentShader.replace(`#include <fog_fragment>`,u)}var m=3,h=4,g={fogVolumeData:{value:new Float32Array(m*h)},cameraHeight:{value:0},fogEnabled:{value:!0},fogDistanceScale:{value:1}};function _(e,t,n=!0){g.cameraHeight.value=e,g.fogVolumeData.value.set(t),g.fogEnabled.value=n}function v(){g.cameraHeight.value=0,g.fogVolumeData.value.fill(0),g.fogEnabled.value=!0,g.fogDistanceScale.value=1}function y(e){let t=new Float32Array(m*h);for(let n=0;n<m;n++){let r=n*h,i=e[n];i&&(t[r+0]=i.visibleDistance,t[r+1]=i.minHeight,t[r+2]=i.maxHeight,t[r+3]=i.percentage)}return t}var b=new a;b.setOptions({premultiplyAlpha:`none`});var x=new Map;function S(e,t,n){let r=x.get(e);if(r)return t&&r.image&&t(r),r;let i=new l;return i.flipY=!1,x.set(e,i),b.load(e,e=>{i.image=e,i.needsUpdate=!0,t?.(i)},void 0,()=>{x.delete(e),n?.(e)}),i}function C(e){let t=x.get(e);return t?t.image?Promise.resolve(t):new Promise(e=>{let n=()=>{t.image?e(t):setTimeout(n,16)};n()}):new Promise((t,n)=>{let r=new l;r.flipY=!1,x.set(e,r),b.load(e,e=>{r.image=e,r.needsUpdate=!0,t(r)},void 0,n)})}function w(e,t={}){let{repeat:n=[1,1],disableMipmaps:a=!1,anisotropy:c,noColorSpace:l=!1}=t;return e.wrapS=e.wrapT=i,l||(e.colorSpace=o),e.repeat.set(...n),e.flipY=!1,e.anisotropy=c??1,a?(e.generateMipmaps=!1,e.minFilter=s):(e.generateMipmaps=!0,e.minFilter=r),e.magFilter=s,e.needsUpdate=!0,e}function T(r){let a=new e(r,256,256,t,n);return a.colorSpace=``,a.wrapS=a.wrapT=i,a.generateMipmaps=!1,a.minFilter=s,a.magFilter=s,a.needsUpdate=!0,a}export{g as a,_ as c,d,w as i,u as l,C as n,y as o,T as r,v as s,S as t,p as u};
|
||||
#endif`),e.fragmentShader=e.fragmentShader.replace(`#include <fog_fragment>`,u)}var m=3,h=4,g={fogVolumeData:{value:new Float32Array(m*h)},cameraHeight:{value:0},fogEnabled:{value:!0},fogDistanceScale:{value:1}};function _(e,t,n=!0){g.cameraHeight.value=e,g.fogVolumeData.value.set(t),g.fogEnabled.value=n}function v(){g.cameraHeight.value=0,g.fogVolumeData.value.fill(0),g.fogEnabled.value=!0,g.fogDistanceScale.value=1}function y(e){let t=new Float32Array(m*h);for(let n=0;n<m;n++){let r=n*h,i=e[n];i&&(t[r+0]=i.visibleDistance,t[r+1]=i.minHeight,t[r+2]=i.maxHeight,t[r+3]=i.percentage)}return t}var b=new i;b.setOptions({premultiplyAlpha:`none`});var x=new Map;function S(e,t,n){let r=x.get(e);if(r)return t&&r.image&&t(r),r;let i=new l;return i.flipY=!1,x.set(e,i),b.load(e,e=>{i.image=e,i.needsUpdate=!0,t?.(i)},void 0,()=>{x.delete(e),n?.(e)}),i}function C(e){let t=x.get(e);return t?t.image?Promise.resolve(t):new Promise(e=>{let n=()=>{t.image?e(t):setTimeout(n,16)};n()}):new Promise((t,n)=>{let r=new l;r.flipY=!1,x.set(e,r),b.load(e,e=>{r.image=e,r.needsUpdate=!0,t(r)},void 0,n)})}function w(e,t={}){let{repeat:i=[1,1],disableMipmaps:a=!1,anisotropy:c,noColorSpace:l=!1}=t;return e.wrapS=e.wrapT=r,l||(e.colorSpace=o),e.repeat.set(...i),e.flipY=!1,e.anisotropy=c??1,a?(e.generateMipmaps=!1,e.minFilter=s):(e.generateMipmaps=!0,e.minFilter=n),e.magFilter=s,e.image&&(e.needsUpdate=!0),e}function T(n,i=256){let o=[];for(let c=0;c<n.length;c+=3){let l=n[c],u=n[c+1],d=n[c+2],f=i*i,p=new Uint8Array(f*4);for(let e=0;e<f;e++)p[e*4]=l[e],p[e*4+1]=u?u[e]:0,p[e*4+2]=d?d[e]:0,p[e*4+3]=255;let m=new e(p,i,i,a,t);m.colorSpace=``,m.wrapS=m.wrapT=r,m.generateMipmaps=!1,m.minFilter=s,m.magFilter=s,m.needsUpdate=!0,o.push(m)}return o}export{g as a,_ as c,d,w as i,u as l,C as n,y as o,T as r,v as s,S as t,p as u};
|
||||
1
docs/assets/traditional-CCqNJZlI.js
Normal file
1
docs/assets/traditional-CCqNJZlI.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{r as e,t}from"./chunk-DECur_0Z.js";import{r as n}from"./jsx-runtime-BpGWiA-R.js";var r=t((e=>{var t=n();function r(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var i=typeof Object.is==`function`?Object.is:r,a=t.useState,o=t.useEffect,s=t.useLayoutEffect,c=t.useDebugValue;function l(e,t){var n=t(),r=a({inst:{value:n,getSnapshot:t}}),i=r[0].inst,l=r[1];return s(function(){i.value=n,i.getSnapshot=t,u(i)&&l({inst:i})},[e,n,t]),o(function(){return u(i)&&l({inst:i}),e(function(){u(i)&&l({inst:i})})},[e]),c(n),n}function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!i(e,n)}catch{return!0}}function d(e,t){return t()}var f=typeof window>`u`||window.document===void 0||window.document.createElement===void 0?d:l;e.useSyncExternalStore=t.useSyncExternalStore===void 0?f:t.useSyncExternalStore})),i=t(((e,t)=>{t.exports=r()})),a=t((e=>{var t=n(),r=i();function a(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var o=typeof Object.is==`function`?Object.is:a,s=r.useSyncExternalStore,c=t.useRef,l=t.useEffect,u=t.useMemo,d=t.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var a=c(null);if(a.current===null){var f={hasValue:!1,value:null};a.current=f}else f=a.current;a=u(function(){function e(e){if(!a){if(a=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,o(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var a=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,a[0],a[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),o=t(((e,t)=>{t.exports=a()})),s=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},c=(e=>e?s(e):s),l=e(n(),1),{useSyncExternalStoreWithSelector:u}=e(o(),1).default,d=e=>e;function f(e,t=d,n){let r=u(e.subscribe,e.getState,e.getInitialState,t,n);return l.useDebugValue(r),r}var p=(e,t)=>{let n=c(e),r=(e,r=t)=>f(n,e,r);return Object.assign(r,n),r},m=((e,t)=>e?p(e,t):p);export{i,f as n,c as r,m as t};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{r as e,t}from"./chunk-DECur_0Z.js";import{r as n}from"./jsx-runtime-BpGWiA-R.js";var r=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},i=(e=>e?r(e):r),a=t((e=>{var t=n();function r(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var i=typeof Object.is==`function`?Object.is:r,a=t.useState,o=t.useEffect,s=t.useLayoutEffect,c=t.useDebugValue;function l(e,t){var n=t(),r=a({inst:{value:n,getSnapshot:t}}),i=r[0].inst,l=r[1];return s(function(){i.value=n,i.getSnapshot=t,u(i)&&l({inst:i})},[e,n,t]),o(function(){return u(i)&&l({inst:i}),e(function(){u(i)&&l({inst:i})})},[e]),c(n),n}function u(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!i(e,n)}catch{return!0}}function d(e,t){return t()}var f=typeof window>`u`||window.document===void 0||window.document.createElement===void 0?d:l;e.useSyncExternalStore=t.useSyncExternalStore===void 0?f:t.useSyncExternalStore})),o=t(((e,t)=>{t.exports=a()})),s=t((e=>{var t=n(),r=o();function i(e,t){return e===t&&(e!==0||1/e==1/t)||e!==e&&t!==t}var a=typeof Object.is==`function`?Object.is:i,s=r.useSyncExternalStore,c=t.useRef,l=t.useEffect,u=t.useMemo,d=t.useDebugValue;e.useSyncExternalStoreWithSelector=function(e,t,n,r,i){var o=c(null);if(o.current===null){var f={hasValue:!1,value:null};o.current=f}else f=o.current;o=u(function(){function e(e){if(!o){if(o=!0,s=e,e=r(e),i!==void 0&&f.hasValue){var t=f.value;if(i(t,e))return c=t}return c=e}if(t=c,a(s,e))return t;var n=r(e);return i!==void 0&&i(t,n)?(s=e,t):(s=e,c=n)}var o=!1,s,c,l=n===void 0?null:n;return[function(){return e(t())},l===null?void 0:function(){return e(l())}]},[t,n,r,i]);var p=s(e,o[0],o[1]);return l(function(){f.hasValue=!0,f.value=p},[p]),d(p),p}})),c=t(((e,t)=>{t.exports=s()})),l=e(n(),1),{useSyncExternalStoreWithSelector:u}=e(c(),1).default,d=e=>e;function f(e,t=d,n){let r=u(e.subscribe,e.getState,e.getInitialState,t,n);return l.useDebugValue(r),r}var p=(e,t)=>{let n=i(e),r=(e,r=t)=>f(n,e,r);return Object.assign(r,n),r},m=((e,t)=>e?p(e,t):p);export{i,f as n,o as r,m as t};
|
||||
|
|
@ -1 +1 @@
|
|||
import{s as e}from"./react-three-fiber.esm-B4ybsNEe.js";function t(){return e(n)}function n(e){return e.gl.capabilities.getMaxAnisotropy()}export{t};
|
||||
import{s as e}from"./react-three-fiber.esm-El6vNTZj.js";function t(){return e(n)}function n(e){return e.gl.capabilities.getMaxAnisotropy()}export{t};
|
||||
1
docs/assets/useQuery-6REtM5HO.js
Normal file
1
docs/assets/useQuery-6REtM5HO.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -19,25 +19,39 @@
|
|||
<link rel="apple-touch-icon" href="/t2-mapper/icon-512.png" />
|
||||
<meta name="theme-color" content="#067272" />
|
||||
<link rel="preconnect" href="https://www.gstatic.com" crossorigin />
|
||||
<script type="module" crossorigin src="/t2-mapper/assets/index-BEehCpzM.js"></script>
|
||||
<script type="module" crossorigin src="/t2-mapper/assets/index-D4aiQcCU.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/chunk-DECur_0Z.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/preload-helper-CnJ98jGT.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/logger-CySD1nLn.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/mission-yBcX4xit.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/preload-helper-BPkniflS.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/logger-B058WGzf.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/mission-yeigCtfF.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/extends-lXRikpl0.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/jsx-runtime-BpGWiA-R.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/three.module-DeDv86YO.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/traditional-DPdbI9gv.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/react-three-fiber.esm-B4ybsNEe.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/streamHelpers-DZp0O0LI.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/engineStore-DXFfg1NG.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/stringUtils-Bvtx11IK.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/manifest-DDCwpSLV.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/SettingsProvider-BeB5OnG9.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/iconBase-DjT_EJem.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/JoystickContext-BKqyiaNN.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/scene-KKwVL-xq.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/cameraTourStore-CfKPrs02.js">
|
||||
<link rel="stylesheet" crossorigin href="/t2-mapper/assets/index-BONY_dmA.css">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/three.module-DKAirPAO.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/traditional-CCqNJZlI.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/react-three-fiber.esm-El6vNTZj.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/Html-CXAi5FD_.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/useQuery-6REtM5HO.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/engineStore-B1KAgiiF.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/stringUtils-1MyeFdQ_.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/manifest-BIDT_vSa.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/SettingsProvider-BdqQ2Cm4.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/DebugBounds-CZKrvsAw.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/loaders-B4T775qz.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/cameraTourStore-CtH3IrnD.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/AudioEmitter-CJMuEzA2.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/DebugSuspense-ChOWTvws.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/textureUtils-Bk_jPZib.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/playbackUtils-DjmjN4tv.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/useAnisotropy-D9othEmk.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/streamPlaybackStore-D5ldcfU5.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/PlayerModel-DY4jKfUP.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/streamHelpers-CYLk-lCT.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/iconBase-DZ3jidsI.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/JoystickContext-B2sO9eYx.js">
|
||||
<link rel="modulepreload" crossorigin href="/t2-mapper/assets/scene-C20n9V3Y.js">
|
||||
<link rel="stylesheet" crossorigin href="/t2-mapper/assets/AudioEmitter-DAQByNim.css">
|
||||
<link rel="stylesheet" crossorigin href="/t2-mapper/assets/PlayerModel-Bi7C0zGW.css">
|
||||
<link rel="stylesheet" crossorigin href="/t2-mapper/assets/index-CiZqoesx.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
"serve:static": "tsx scripts/serve-static.ts",
|
||||
"server-list": "node --env-file-if-exists=.env.development.local --import=tsx/esm scripts/t2-server-list.ts",
|
||||
"start:both": "concurrently npm:start npm:relay:dev",
|
||||
"start": "vite --host",
|
||||
"start": "vite dev --host --force",
|
||||
"test-connect": "node --env-file-if-exists=.env.development.local --import=tsx/esm scripts/test-connect.ts",
|
||||
"test:watch": "vitest",
|
||||
"test": "vitest run",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
import { Suspense } from "react";
|
||||
import { NuqsAdapter } from "nuqs/adapters/react";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import {
|
||||
skinManifestQueryKey,
|
||||
fetchSkinManifest,
|
||||
} from "@/src/components/PlayerModel";
|
||||
import { FeaturesProvider } from "@/src/components/FeaturesProvider";
|
||||
import { MapInspector } from "@/src/components/MapInspector";
|
||||
import { SettingsProvider } from "@/src/components/SettingsProvider";
|
||||
|
|
@ -15,6 +19,16 @@ const queryClient = new QueryClient({
|
|||
},
|
||||
});
|
||||
|
||||
// Prefetch the custom skins manifest at startup so it's in the cache before
|
||||
// any PlayerModel renders. This avoids a race where useQuery inside PlayerModel
|
||||
// can't trigger a re-render during streaming (store mutations starve React's
|
||||
// concurrent rendering).
|
||||
queryClient.prefetchQuery({
|
||||
queryKey: skinManifestQueryKey,
|
||||
queryFn: fetchSkinManifest,
|
||||
staleTime: Infinity,
|
||||
});
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<Suspense>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
.Container {
|
||||
.Container[data-filtered] {
|
||||
min-height: 100dvh;
|
||||
}
|
||||
|
||||
.Title {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 16px 10px 8px 10px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.Header {
|
||||
font-size: 12px;
|
||||
opacity: 0.6;
|
||||
padding: 2px 0;
|
||||
padding: 18px 4px 4px 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.Group {
|
||||
|
|
@ -18,10 +22,13 @@
|
|||
}
|
||||
|
||||
.GroupHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
padding: 6px 8px;
|
||||
padding: 6px 8px 6px 0;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
list-style: none;
|
||||
|
|
@ -31,14 +38,24 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.GroupHeader::before {
|
||||
content: "[+] ";
|
||||
font-family: monospace;
|
||||
color: rgba(255, 255, 255, 0.4);
|
||||
.OpenedIcon {
|
||||
display: none;
|
||||
font-size: 15px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.Group[open] > .GroupHeader::before {
|
||||
content: "[-] ";
|
||||
.ClosedIcon {
|
||||
display: inline-block;
|
||||
font-size: 15px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.Group[open] .OpenedIcon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.Group[open] .ClosedIcon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.GroupCount {
|
||||
|
|
@ -146,10 +163,20 @@
|
|||
color: rgba(255, 255, 255, 0.35);
|
||||
}
|
||||
|
||||
.Detail dt::after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
.Detail dd {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.FilterInput {
|
||||
font-family: inherit;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
color: #fff;
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.FilterInput:focus {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { memo, useMemo, useCallback } from "react";
|
||||
import { memo, useMemo, useCallback, useState, useDeferredValue } from "react";
|
||||
import { FaLocationArrow } from "react-icons/fa6";
|
||||
import { matchSorter } from "match-sorter";
|
||||
import { useGameEntities } from "../state/gameEntityStore";
|
||||
import { cameraTourStore } from "../state/cameraTourStore";
|
||||
import type { GameEntity } from "../state/gameEntityTypes";
|
||||
|
|
@ -7,6 +8,7 @@ import { torqueToThree } from "../scene/coordinates";
|
|||
import { gameEntityStore, useDebugHidden } from "../state/gameEntityStore";
|
||||
import { useSettings } from "./SettingsProvider";
|
||||
import styles from "./DebugEntityList.module.css";
|
||||
import { FaRegMinusSquare, FaRegPlusSquare } from "react-icons/fa";
|
||||
|
||||
function getEntityLabel(entity: GameEntity): string {
|
||||
if (entity.renderType === "Player" && "playerName" in entity) {
|
||||
|
|
@ -116,7 +118,7 @@ function EntityRow({ entity }: { entity: GameEntity }) {
|
|||
<dl className={styles.Detail}>
|
||||
{Object.entries(detail).map(([key, value]) => (
|
||||
<div key={key}>
|
||||
<dt>{key}</dt>
|
||||
<dt>{key}:</dt>
|
||||
<dd>{value}</dd>
|
||||
</div>
|
||||
))}
|
||||
|
|
@ -138,15 +140,45 @@ function EntityRow({ entity }: { entity: GameEntity }) {
|
|||
);
|
||||
}
|
||||
|
||||
const ENTITY_MATCH_KEYS = [
|
||||
"id",
|
||||
"className",
|
||||
"label",
|
||||
"playerName",
|
||||
"skinPrefName",
|
||||
"shapeName",
|
||||
"dataBlock",
|
||||
"audioFileName",
|
||||
"interiorData.interiorFile",
|
||||
"terrainData.terrFileName",
|
||||
"waterData.surfaceName",
|
||||
];
|
||||
|
||||
export const DebugEntityList = memo(function DebugEntityList() {
|
||||
const [filterText, setFilterText] = useState("");
|
||||
const activeFilterText = useDeferredValue(filterText.trim());
|
||||
|
||||
const entities = useGameEntities();
|
||||
// useGameEntities re-renders on version bump, but the Map reference is
|
||||
// stable (mutated in place). Use version as a useMemo dep to recompute.
|
||||
const version = gameEntityStore.getState().version;
|
||||
|
||||
const filteredEntities = useMemo(() => {
|
||||
const allEntities = Array.from(entities.values());
|
||||
|
||||
return activeFilterText
|
||||
? matchSorter(allEntities, activeFilterText, {
|
||||
keys: ENTITY_MATCH_KEYS,
|
||||
})
|
||||
: allEntities;
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [activeFilterText, entities, version]);
|
||||
|
||||
const grouped = useMemo(() => {
|
||||
const groups = new Map<string, GameEntity[]>();
|
||||
for (const entity of entities.values()) {
|
||||
|
||||
for (const entity of filteredEntities) {
|
||||
if (
|
||||
entity.renderType === "Sky" ||
|
||||
entity.renderType === "Sun" ||
|
||||
|
|
@ -168,16 +200,33 @@ export const DebugEntityList = memo(function DebugEntityList() {
|
|||
list.sort((a, b) => a.id.localeCompare(b.id));
|
||||
}
|
||||
return sorted;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [entities, version]);
|
||||
}, [filteredEntities]);
|
||||
|
||||
return (
|
||||
<div className={styles.Container}>
|
||||
<h4 className={styles.Title}>Entity list</h4>
|
||||
<section
|
||||
className={styles.Container}
|
||||
data-filtered={activeFilterText ? true : undefined}
|
||||
>
|
||||
<header className={styles.Header}>
|
||||
<h4 className={styles.Title}>Entity list</h4>
|
||||
<input
|
||||
type="search"
|
||||
value={filterText}
|
||||
onChange={(e) => setFilterText(e.target.value)}
|
||||
size={16}
|
||||
placeholder="Filter"
|
||||
className={styles.FilterInput}
|
||||
/>
|
||||
</header>
|
||||
{grouped.map(([className, list]) => (
|
||||
<details key={className} className={styles.Group}>
|
||||
<details
|
||||
key={className}
|
||||
className={styles.Group}
|
||||
open={activeFilterText ? true : undefined}
|
||||
>
|
||||
<summary className={styles.GroupHeader}>
|
||||
{className}{" "}
|
||||
<FaRegPlusSquare className={styles.ClosedIcon} />
|
||||
<FaRegMinusSquare className={styles.OpenedIcon} /> {className}{" "}
|
||||
<span className={styles.GroupCount}>({list.length})</span>
|
||||
</summary>
|
||||
<ul className={styles.List}>
|
||||
|
|
@ -189,6 +238,6 @@ export const DebugEntityList = memo(function DebugEntityList() {
|
|||
</ul>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -93,11 +93,8 @@ function renderEventDescription(event: TimelineEvent): React.ReactNode {
|
|||
</>
|
||||
);
|
||||
}
|
||||
if (event.type === "match-start") {
|
||||
return "Match started";
|
||||
}
|
||||
if (event.type === "match-end") {
|
||||
return "Match ended";
|
||||
if (event.type === "match-start" || event.type === "match-end") {
|
||||
return event.description;
|
||||
}
|
||||
return event.description;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,12 +73,15 @@ const WaterBlock = createLazy("WaterBlock", () => import("./WaterBlock"));
|
|||
*/
|
||||
export const EntityRenderer = memo(function EntityRenderer({
|
||||
entity,
|
||||
objectMounts,
|
||||
}: {
|
||||
entity: GameEntity;
|
||||
/** Object-mounted entities (players in vehicles, turrets on vehicles). */
|
||||
objectMounts?: Record<number, React.ReactNode>;
|
||||
}) {
|
||||
switch (entity.renderType) {
|
||||
case "Shape":
|
||||
return <ShapeEntity entity={entity} />;
|
||||
return <ShapeEntity entity={entity} objectMounts={objectMounts} />;
|
||||
case "ForceFieldBare":
|
||||
return <ForceFieldBare entity={entity} />;
|
||||
case "Player":
|
||||
|
|
@ -119,7 +122,13 @@ export const EntityRenderer = memo(function EntityRenderer({
|
|||
}
|
||||
});
|
||||
|
||||
function ShapeEntity({ entity }: { entity: ShapeEntityType }) {
|
||||
function ShapeEntity({
|
||||
entity,
|
||||
objectMounts,
|
||||
}: {
|
||||
entity: ShapeEntityType;
|
||||
objectMounts?: Record<number, React.ReactNode>;
|
||||
}) {
|
||||
const dataSource = useDataSource();
|
||||
const isStreaming = dataSource === "demo" || dataSource === "live";
|
||||
const groupRef = useRef<Group>(null);
|
||||
|
|
@ -153,6 +162,30 @@ function ShapeEntity({ entity }: { entity: ShapeEntityType }) {
|
|||
? "#00ff88"
|
||||
: "yellow";
|
||||
|
||||
// Merge image mounts (all 8 slots) with object mounts (players in vehicles).
|
||||
// Both use the same Mount bones. Each image slot's mount bone comes from
|
||||
// dataBlock->mountPoint (binary-verified), not from the slot index.
|
||||
// Object mounts take priority over image mounts at the same bone.
|
||||
const allMounts = useMemo(() => {
|
||||
const m: Record<number, React.ReactNode> = { ...objectMounts };
|
||||
const slots = entity.imageSlots;
|
||||
if (slots) {
|
||||
for (let i = 0; i < slots.length; i++) {
|
||||
const slot = slots[i];
|
||||
if (!slot?.shapeName || slot.mountPoint in m) continue;
|
||||
m[slot.mountPoint] = (
|
||||
<MountedShapeContent
|
||||
shapeName={slot.shapeName}
|
||||
imageDataBlockId={slot.dataBlockId}
|
||||
entityId={entity.id}
|
||||
skinName={slot.skinName}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
return Object.keys(m).length > 0 ? m : undefined;
|
||||
}, [objectMounts, entity.imageSlots, entity.id]);
|
||||
|
||||
return (
|
||||
<ShapeInfoProvider
|
||||
object={entity.runtimeObject as TorqueObject | undefined}
|
||||
|
|
@ -166,19 +199,7 @@ function ShapeEntity({ entity }: { entity: ShapeEntityType }) {
|
|||
emap={emap}
|
||||
entityId={entity.id}
|
||||
skinName={entity.skinName}
|
||||
mounted={
|
||||
entity.weaponShape
|
||||
? {
|
||||
0: (
|
||||
<MountedShapeContent
|
||||
shapeName={entity.weaponShape}
|
||||
imageDataBlockId={entity.imageDataBlockIds?.[0]}
|
||||
entityId={entity.id}
|
||||
/>
|
||||
),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
mounted={allMounts}
|
||||
>
|
||||
{flagLabel ? (
|
||||
<FloatingLabel opacity={0.6}>{flagLabel}</FloatingLabel>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
import { memo, useCallback, useRef, useState, useMemo } from "react";
|
||||
import React, {
|
||||
memo,
|
||||
Suspense,
|
||||
useCallback,
|
||||
useRef,
|
||||
useState,
|
||||
useMemo,
|
||||
} from "react";
|
||||
import { Quaternion } from "three";
|
||||
import type { Group } from "three";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
|
|
@ -55,13 +62,37 @@ const EntityLayer = memo(function EntityLayer() {
|
|||
}
|
||||
}
|
||||
|
||||
// Build object mount relationships: which entities are mounted on which.
|
||||
// Mounted entities render inside their target's mount bone (via createPortal
|
||||
// in ShapeRenderer), NOT as top-level positioned entities.
|
||||
const mountedIds = new Set<string>();
|
||||
const mountChildren = new Map<string, Map<number, GameEntity>>();
|
||||
for (const entity of cache.values()) {
|
||||
const mountId = entity.mountObjectId;
|
||||
if (mountId && cache.has(mountId)) {
|
||||
mountedIds.add(entity.id);
|
||||
let children = mountChildren.get(mountId);
|
||||
if (!children) {
|
||||
children = new Map();
|
||||
mountChildren.set(mountId, children);
|
||||
}
|
||||
children.set(entity.mountNode ?? 0, entity);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{
|
||||
// eslint-disable-next-line react-hooks/refs
|
||||
[...cache.values()].map((entity) => (
|
||||
<EntityWrapper key={entity.id} entity={entity} />
|
||||
))
|
||||
[...cache.values()]
|
||||
.filter((entity) => !mountedIds.has(entity.id))
|
||||
.map((entity) => (
|
||||
<EntityWrapper
|
||||
key={entity.id}
|
||||
entity={entity}
|
||||
mountChildren={mountChildren.get(entity.id)}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</>
|
||||
);
|
||||
|
|
@ -69,8 +100,10 @@ const EntityLayer = memo(function EntityLayer() {
|
|||
|
||||
const EntityWrapper = memo(function EntityWrapper({
|
||||
entity,
|
||||
mountChildren,
|
||||
}: {
|
||||
entity: GameEntity;
|
||||
mountChildren?: Map<number, GameEntity>;
|
||||
}) {
|
||||
if (entity.debugHidden) return null;
|
||||
|
||||
|
|
@ -87,7 +120,9 @@ const EntityWrapper = memo(function EntityWrapper({
|
|||
if (entity.renderType === "None") return null;
|
||||
|
||||
// From here, entity is a PositionedEntity
|
||||
return <PositionedEntityWrapper entity={entity} />;
|
||||
return (
|
||||
<PositionedEntityWrapper entity={entity} mountChildren={mountChildren} />
|
||||
);
|
||||
});
|
||||
|
||||
/** Imperatively tracks targetRenderFlags bit 0x2 on a game entity and
|
||||
|
|
@ -121,7 +156,13 @@ function FlagMarkerSlot({ entity }: { entity: GameEntity }) {
|
|||
return <FlagMarker entity={entity} />;
|
||||
}
|
||||
|
||||
function PositionedEntityWrapper({ entity }: { entity: PositionedEntity }) {
|
||||
function PositionedEntityWrapper({
|
||||
entity,
|
||||
mountChildren,
|
||||
}: {
|
||||
entity: PositionedEntity;
|
||||
mountChildren?: Map<number, GameEntity>;
|
||||
}) {
|
||||
const position = entity.position;
|
||||
const scale = entity.scale;
|
||||
const quaternion = useMemo(() => {
|
||||
|
|
@ -161,6 +202,22 @@ function PositionedEntityWrapper({ entity }: { entity: PositionedEntity }) {
|
|||
</mesh>
|
||||
);
|
||||
|
||||
// Build object mount content for entities mounted on this one (e.g. players
|
||||
// sitting in a vehicle). Each mounted entity renders via EntityRenderer
|
||||
// inside the target's mount bone (portaled by ShapeRenderer).
|
||||
const objectMounts = useMemo(() => {
|
||||
if (!mountChildren || mountChildren.size === 0) return undefined;
|
||||
const mounts: Record<number, React.ReactNode> = {};
|
||||
for (const [node, child] of mountChildren) {
|
||||
mounts[node] = (
|
||||
<Suspense key={child.id}>
|
||||
<EntityRenderer entity={child} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
return mounts;
|
||||
}, [mountChildren]);
|
||||
|
||||
return (
|
||||
<group
|
||||
name={entity.id}
|
||||
|
|
@ -170,7 +227,7 @@ function PositionedEntityWrapper({ entity }: { entity: PositionedEntity }) {
|
|||
>
|
||||
<group name="model">
|
||||
<ShapeErrorBoundary fallback={fallback}>
|
||||
<EntityRenderer entity={entity} />
|
||||
<EntityRenderer entity={entity} objectMounts={objectMounts} />
|
||||
</ShapeErrorBoundary>
|
||||
<FlagMarkerSlot entity={entity} />
|
||||
</group>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { Fragment, memo, Suspense, useEffect, useMemo, useRef } from "react";
|
||||
import type { ReactNode } from "react";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
import type { AnimationAction } from "three";
|
||||
import type { AnimationAction, Object3D } from "three";
|
||||
import { useGLTF } from "@react-three/drei";
|
||||
import { createPortal, useFrame } from "@react-three/fiber";
|
||||
import { createLogger } from "../logger";
|
||||
import { shapeToUrl } from "../loaders";
|
||||
import { shapeToUrl, textureToUrl } from "../loaders";
|
||||
import {
|
||||
MeshStandardMaterial,
|
||||
AdditiveAnimationBlendMode,
|
||||
|
|
@ -14,9 +14,12 @@ import {
|
|||
AnimationUtils,
|
||||
LoopOnce,
|
||||
LoopRepeat,
|
||||
NormalBlending,
|
||||
Group,
|
||||
Box3,
|
||||
Vector3,
|
||||
RepeatWrapping,
|
||||
NoColorSpace,
|
||||
} from "three";
|
||||
import * as SkeletonUtils from "three/examples/jsm/utils/SkeletonUtils.js";
|
||||
import { useAnisotropy } from "./useAnisotropy";
|
||||
|
|
@ -46,7 +49,49 @@ import {
|
|||
getPosedNodeTransform,
|
||||
} from "../stream/playbackUtils";
|
||||
import { resolveEmapFromImageSlot } from "./resolveEmap";
|
||||
import { playerEyePositions } from "./PlayerModel";
|
||||
import type { ThreadState as StreamThreadState } from "../stream/types";
|
||||
import { loadTexture } from "../textureUtils";
|
||||
|
||||
// ── Cloak texture (binary-verified: special/cloakTexture with UV scrolling) ──
|
||||
// Lazy-loaded on first use since cloaking is rare.
|
||||
|
||||
import type { Texture } from "three";
|
||||
|
||||
let _cloakTexture: Texture | null = null;
|
||||
function getCloakTexture(): Texture {
|
||||
if (!_cloakTexture) {
|
||||
_cloakTexture = loadTexture(textureToUrl("special/cloakTexture"));
|
||||
_cloakTexture.wrapS = RepeatWrapping;
|
||||
_cloakTexture.wrapT = RepeatWrapping;
|
||||
_cloakTexture.colorSpace = NoColorSpace;
|
||||
}
|
||||
return _cloakTexture;
|
||||
}
|
||||
|
||||
// Global UV offset matching engine's static shiftX/shiftY with different moduli
|
||||
// to create a non-repeating shimmer pattern.
|
||||
let _cloakShiftX = 0;
|
||||
let _cloakShiftY = 0;
|
||||
let _cloakLastFrame = -1;
|
||||
function advanceCloakUV(frameId: number): void {
|
||||
if (frameId === _cloakLastFrame) return;
|
||||
_cloakLastFrame = frameId;
|
||||
_cloakShiftX = (_cloakShiftX + 1) % 128;
|
||||
_cloakShiftY = (_cloakShiftY + 1) % 127;
|
||||
getCloakTexture().offset.set(_cloakShiftX / 127, _cloakShiftY / 126);
|
||||
}
|
||||
|
||||
// Counter-rotate for object-mounted content (players in vehicles).
|
||||
// The mount bone is inside the vehicle's R90 Y group (DTS Z-up → Three.js
|
||||
// Y-up). The mounted PlayerModel applies its own R90 Y. We need to undo the
|
||||
// player's R90 and rotate from GLB Y-up back to DTS Z-up so the player
|
||||
// stands upright relative to the vehicle's DTS bone coordinate system.
|
||||
const MOUNT_COUNTER_ROTATION: [x: number, y: number, z: number] = [
|
||||
Math.PI / 2,
|
||||
-Math.PI / 2,
|
||||
0,
|
||||
];
|
||||
|
||||
const STANDARD_90_ROTATION: [x: number, y: number, z: number] = [
|
||||
0,
|
||||
|
|
@ -68,6 +113,8 @@ interface StreamShapeEntity {
|
|||
frozen?: boolean;
|
||||
maxSteeringAngle?: number;
|
||||
soundSlots?: Array<{ index: number; playing: boolean; profileId?: number }>;
|
||||
fadeVal?: number;
|
||||
cloakLevel?: number;
|
||||
dataBlockId?: number;
|
||||
}
|
||||
|
||||
|
|
@ -250,6 +297,7 @@ interface ThreadState {
|
|||
action?: AnimationAction;
|
||||
visNodes?: VisNode[];
|
||||
startTime: number;
|
||||
forward: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -556,7 +604,13 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
}
|
||||
}
|
||||
|
||||
function handlePlayThread(slot: number, sequenceName: string) {
|
||||
// Match binary's updateThread (FUN_005ebf00): direction is implemented
|
||||
// via timeScale (+1 forward, -1 backward). State 0=Play, 1=Stop, 2=Pause.
|
||||
function handlePlayThread(
|
||||
slot: number,
|
||||
sequenceName: string,
|
||||
forward = true,
|
||||
) {
|
||||
const seqLower = sequenceName.toLowerCase();
|
||||
handleStopThread(slot);
|
||||
|
||||
|
|
@ -565,6 +619,7 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
const thread: ThreadState = {
|
||||
sequence: seqLower,
|
||||
startTime: shapeNowSec(),
|
||||
forward,
|
||||
};
|
||||
|
||||
if (clip && mixer) {
|
||||
|
|
@ -582,7 +637,13 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
if (seqBlendByName.has(seqLower)) {
|
||||
action.blendMode = AdditiveAnimationBlendMode;
|
||||
}
|
||||
action.reset().play();
|
||||
action.timeScale = forward ? 1 : -1;
|
||||
action.reset();
|
||||
// For backward playback, start at the end of the clip.
|
||||
if (!forward) {
|
||||
action.time = clip.duration;
|
||||
}
|
||||
action.play();
|
||||
thread.action = action;
|
||||
}
|
||||
|
||||
|
|
@ -598,11 +659,12 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
const thread = threads.get(slot);
|
||||
if (!thread) return;
|
||||
if (thread.action) thread.action.stop();
|
||||
// Binary Stop: reset position to 0.0, freeze. Vis nodes go to frame 0.
|
||||
if (thread.visNodes) {
|
||||
for (const v of thread.visNodes) {
|
||||
v.mesh.visible = false;
|
||||
if (v.mesh.material && !Array.isArray(v.mesh.material)) {
|
||||
v.mesh.material.opacity = v.keyframes[0];
|
||||
v.mesh.visible = v.keyframes[0] > 0.01;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -795,51 +857,70 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
!prev ||
|
||||
prev.sequence !== t.sequence ||
|
||||
prev.state !== t.state ||
|
||||
prev.forward !== t.forward ||
|
||||
prev.atEnd !== t.atEnd;
|
||||
if (!changed) continue;
|
||||
|
||||
// When only atEnd changed (false→true) on a playing thread with
|
||||
// the same sequence, the animation has finished on the server.
|
||||
// Don't restart it — snap to the end pose so one-shot animations
|
||||
// like "deploy" stay clamped instead of collapsing back.
|
||||
const onlyAtEndChanged =
|
||||
prev &&
|
||||
prev.sequence === t.sequence &&
|
||||
prev.state === t.state &&
|
||||
t.state === 0 &&
|
||||
!prev.atEnd &&
|
||||
t.atEnd;
|
||||
if (onlyAtEndChanged) {
|
||||
const thread = threads.get(slot);
|
||||
if (thread?.action) {
|
||||
const clip = thread.action.getClip();
|
||||
thread.action.time = t.forward ? clip.duration : 0;
|
||||
thread.action.setLoop(LoopOnce, 1);
|
||||
thread.action.clampWhenFinished = true;
|
||||
thread.action.paused = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const seqName = seqIndexToName[t.sequence];
|
||||
if (!seqName) continue;
|
||||
if (t.state === 0) {
|
||||
playThread(slot, seqName);
|
||||
// If the animation is already finished (atEnd=true on first
|
||||
// appearance — e.g. a deployed MPB entering scope), snap to
|
||||
// the end pose immediately instead of replaying it.
|
||||
|
||||
// Match binary updateThread (FUN_005ebf00):
|
||||
// State 0=Play, 1=Stop, 2=Pause
|
||||
if (t.state === 1) {
|
||||
// Stop: reset to start, freeze.
|
||||
stopThread(slot);
|
||||
} else if (t.state === 2) {
|
||||
// Pause: freeze at current position.
|
||||
const thread = threads.get(slot);
|
||||
if (thread?.action) {
|
||||
thread.action.paused = true;
|
||||
}
|
||||
} else {
|
||||
// Play (state === 0)
|
||||
if (t.atEnd) {
|
||||
const thread = threads.get(slot);
|
||||
// Already finished: snap to end pose, freeze.
|
||||
// Check if we need to start the thread first.
|
||||
let thread = threads.get(slot);
|
||||
if (!thread || thread.sequence !== seqName) {
|
||||
playThread(slot, seqName, t.forward);
|
||||
thread = threads.get(slot);
|
||||
}
|
||||
if (thread?.action) {
|
||||
const clip = thread.action.getClip();
|
||||
thread.action.time = t.forward ? clip.duration : 0;
|
||||
thread.action.timeScale = 1;
|
||||
thread.action.setLoop(LoopOnce, 1);
|
||||
thread.action.clampWhenFinished = true;
|
||||
thread.action.paused = true;
|
||||
}
|
||||
// Snap vis nodes to end pose.
|
||||
if (thread?.visNodes) {
|
||||
for (const v of thread.visNodes) {
|
||||
const mat = v.mesh.material;
|
||||
if (!mat || Array.isArray(mat)) continue;
|
||||
const endIdx = t.forward
|
||||
? v.keyframes.length - 1
|
||||
: 0;
|
||||
mat.opacity = v.keyframes[endIdx];
|
||||
v.mesh.visible = mat.opacity > 0.01;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Actively playing: (re)start with correct direction.
|
||||
// Only restart if sequence or direction changed.
|
||||
const thread = threads.get(slot);
|
||||
const needRestart =
|
||||
!thread ||
|
||||
thread.sequence !== seqName ||
|
||||
thread.forward !== t.forward;
|
||||
if (needRestart) {
|
||||
playThread(slot, seqName, t.forward);
|
||||
} else if (thread?.action?.paused) {
|
||||
// Resume from pause with correct direction.
|
||||
thread.action.paused = false;
|
||||
thread.action.timeScale = t.forward ? 1 : -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stopThread(slot);
|
||||
}
|
||||
} else if (prev) {
|
||||
// Thread disappeared — stop it.
|
||||
|
|
@ -854,7 +935,8 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
}
|
||||
|
||||
// Drive vis opacity animations for active threads.
|
||||
for (const [, thread] of threads) {
|
||||
// Direction is handled by computing position forward or backward.
|
||||
for (const [slot, thread] of threads) {
|
||||
if (!thread.visNodes) continue;
|
||||
|
||||
for (const { mesh, keyframes, duration, cyclic } of thread.visNodes) {
|
||||
|
|
@ -863,20 +945,29 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
|
||||
if (!animationEnabled) {
|
||||
mat.opacity = keyframes[0];
|
||||
mesh.visible = mat.opacity > 0.01;
|
||||
continue;
|
||||
}
|
||||
|
||||
const elapsed = shapeNowSec() - thread.startTime;
|
||||
const t = cyclic
|
||||
? (elapsed % duration) / duration
|
||||
: Math.min(elapsed / duration, 1);
|
||||
let t: number;
|
||||
if (cyclic) {
|
||||
// Cyclic: wrap position, ignoring direction (cyclic always advances).
|
||||
t = ((elapsed % duration) + duration) % duration / duration;
|
||||
} else if (thread.forward) {
|
||||
t = Math.min(elapsed / duration, 1);
|
||||
} else {
|
||||
// Backward: start at 1.0 and move toward 0.0.
|
||||
t = Math.max(1 - elapsed / duration, 0);
|
||||
}
|
||||
|
||||
const n = keyframes.length;
|
||||
const pos = t * n;
|
||||
const lo = Math.floor(pos) % n;
|
||||
const hi = (lo + 1) % n;
|
||||
const frac = pos - Math.floor(pos);
|
||||
const pos = t * (n - 1);
|
||||
const lo = Math.min(Math.floor(pos), n - 1);
|
||||
const hi = Math.min(lo + 1, n - 1);
|
||||
const frac = pos - lo;
|
||||
mat.opacity = keyframes[lo] + (keyframes[hi] - keyframes[lo]) * frac;
|
||||
mesh.visible = mat.opacity > 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -989,6 +1080,82 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
}
|
||||
});
|
||||
|
||||
// ShapeBase fade opacity and cloak texture effect.
|
||||
// Fade (mFadeVal): opacity-only, used by startFade().
|
||||
// Cloak (mCloakLevel): replaces textures with cloakTexture + UV scrolling,
|
||||
// alpha = 0.125 + (1 - cloakLevel) * 0.875. Binary-verified rendering path.
|
||||
const lastFadeValRef = useRef(1);
|
||||
const lastCloakLevelRef = useRef(0);
|
||||
useFrame((state) => {
|
||||
const entity = streamEntityRef.current;
|
||||
const fadeVal = entity?.fadeVal ?? 1;
|
||||
const cloakLevel = entity?.cloakLevel ?? 0;
|
||||
const isCloak = cloakLevel > 0;
|
||||
|
||||
// Advance global cloak UV offset once per frame (all cloaked shapes share it).
|
||||
if (isCloak)
|
||||
advanceCloakUV(
|
||||
state.frameloop === "never" ? 0 : (state.clock.elapsedTime * 60) | 0,
|
||||
);
|
||||
|
||||
if (
|
||||
fadeVal === lastFadeValRef.current &&
|
||||
cloakLevel === lastCloakLevelRef.current
|
||||
)
|
||||
return;
|
||||
lastFadeValRef.current = fadeVal;
|
||||
lastCloakLevelRef.current = cloakLevel;
|
||||
|
||||
// Cloak alpha OVERRIDES fade (binary-verified: TSMesh uses else-if —
|
||||
// alwaysAlpha takes precedence over overrideFade when both are set).
|
||||
const combinedAlpha = isCloak ? 0.125 + (1 - cloakLevel) * 0.875 : fadeVal;
|
||||
const cloakTex = isCloak ? getCloakTexture() : _cloakTexture;
|
||||
|
||||
clonedScene.traverse((node: any) => {
|
||||
if (!node.isMesh || !node.material || Array.isArray(node.material))
|
||||
return;
|
||||
const mat = node.material;
|
||||
const ud = (mat.userData ??= {});
|
||||
|
||||
// Save originals on first encounter.
|
||||
if (ud._baseFadeOpacity == null) {
|
||||
ud._baseFadeOpacity = mat.opacity ?? 1;
|
||||
ud._baseFadeTransparent = mat.transparent ?? false;
|
||||
ud._originalMap = mat.map;
|
||||
// Originally-translucent materials keep their own texture during cloak.
|
||||
// Detect via alphaTest (organic/Translucent cutout) or non-normal blending
|
||||
// (Additive). These match how createMaterialFromFlags sets up materials.
|
||||
ud._isOriginallyTranslucent =
|
||||
(ud._baseFadeTransparent as boolean) ||
|
||||
mat.alphaTest > 0 ||
|
||||
mat.blending !== NormalBlending;
|
||||
}
|
||||
|
||||
const baseOpacity = ud._baseFadeOpacity as number;
|
||||
|
||||
// Cloak texture replacement (non-translucent materials only).
|
||||
if (isCloak && !ud._isOriginallyTranslucent) {
|
||||
if (mat.map !== cloakTex) {
|
||||
mat.map = cloakTex;
|
||||
mat.needsUpdate = true;
|
||||
}
|
||||
} else if (
|
||||
!isCloak &&
|
||||
ud._originalMap !== undefined &&
|
||||
mat.map === cloakTex
|
||||
) {
|
||||
mat.map = ud._originalMap;
|
||||
mat.needsUpdate = true;
|
||||
}
|
||||
|
||||
mat.opacity = combinedAlpha * baseOpacity;
|
||||
mat.transparent =
|
||||
combinedAlpha < 1 || (ud._baseFadeTransparent as boolean);
|
||||
mat.depthWrite =
|
||||
combinedAlpha >= 1 && !(ud._baseFadeTransparent as boolean);
|
||||
});
|
||||
});
|
||||
|
||||
// ShapeBase sound slots — managed as PositionalAudio, not entities.
|
||||
useEntitySoundSlots(streamEntityRef, clonedScene);
|
||||
|
||||
|
|
@ -1006,19 +1173,53 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
};
|
||||
}, [isTarget, gltf.scene]);
|
||||
|
||||
// Find mount point bones in the cloned scene for portal rendering.
|
||||
// Find mount point bones in the cloned scene for portal rendering
|
||||
// and for vehicle mount position tracking.
|
||||
const mountBones = useMemo(() => {
|
||||
if (!mounted) return null;
|
||||
const bones: Record<number, Group> = {};
|
||||
for (const slot of Object.keys(mounted)) {
|
||||
const index = Number(slot);
|
||||
const nodeName = `Mount${index}`;
|
||||
clonedScene.traverse((node: any) => {
|
||||
if (node.name === nodeName) bones[index] = node;
|
||||
});
|
||||
}
|
||||
// Always look for Mount0 (pilot seat for vehicles).
|
||||
clonedScene.traverse((node: any) => {
|
||||
const match = node.name.match(/^Mount(\d+)$/);
|
||||
if (match) bones[Number(match[1])] = node;
|
||||
});
|
||||
return Object.keys(bones).length > 0 ? bones : null;
|
||||
}, [clonedScene, mounted]);
|
||||
}, [clonedScene]);
|
||||
|
||||
// Find Eye node for vehicle camera positioning. Vehicles have an Eye node
|
||||
// in their DTS shape that defines the cockpit viewpoint.
|
||||
const eyeBone = useMemo((): Object3D | null => {
|
||||
let found: Object3D | null = null;
|
||||
clonedScene.traverse((node: any) => {
|
||||
if (node.name === "Eye") found = node;
|
||||
});
|
||||
return found;
|
||||
}, [clonedScene]);
|
||||
|
||||
// Write animated Eye node position to the shared eye position map so the
|
||||
// camera system can use it (same map as PlayerModel's eye bone).
|
||||
useEffect(() => {
|
||||
if (!eyeBone || !entityId) return;
|
||||
return () => {
|
||||
playerEyePositions.delete(entityId);
|
||||
};
|
||||
}, [eyeBone, entityId]);
|
||||
|
||||
useFrame(() => {
|
||||
if (!eyeBone || !entityId) return;
|
||||
let eyePos = playerEyePositions.get(entityId);
|
||||
if (!eyePos) {
|
||||
eyePos = new Vector3();
|
||||
playerEyePositions.set(entityId, eyePos);
|
||||
}
|
||||
eyeBone.getWorldPosition(eyePos);
|
||||
clonedScene.worldToLocal(eyePos);
|
||||
// Convert GLB (x,y,z) → entity-local Three.js space via R90
|
||||
// (same swizzle as PlayerModel's eye extraction).
|
||||
const gx = eyePos.x;
|
||||
const gy = eyePos.y;
|
||||
const gz = eyePos.z;
|
||||
eyePos.set(gz, gy, -gx);
|
||||
});
|
||||
|
||||
return (
|
||||
<group rotation={noRotation ? undefined : STANDARD_90_ROTATION}>
|
||||
|
|
@ -1040,7 +1241,10 @@ export const ShapeModel = memo(function ShapeModel({
|
|||
const bone = mountBones[Number(slot)];
|
||||
return bone ? (
|
||||
<Fragment key={slot}>
|
||||
{createPortal(<group>{content}</group>, bone)}
|
||||
{createPortal(
|
||||
<group rotation={MOUNT_COUNTER_ROTATION}>{content}</group>,
|
||||
bone,
|
||||
)}
|
||||
</Fragment>
|
||||
) : null;
|
||||
})}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
Activity,
|
||||
Fragment,
|
||||
startTransition,
|
||||
useDeferredValue,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
|
|
@ -173,7 +173,8 @@ export function MissionSelect({
|
|||
autoFocus?: boolean;
|
||||
onCancel: () => void;
|
||||
}) {
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const [latestSearchValue, setSearchValue] = useState("");
|
||||
const searchValue = useDeferredValue(latestSearchValue);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const missionTypeRef = useRef<string | null>(missionType);
|
||||
|
||||
|
|
@ -203,7 +204,7 @@ export function MissionSelect({
|
|||
}
|
||||
},
|
||||
setValue: (value) => {
|
||||
startTransition(() => setSearchValue(value));
|
||||
setSearchValue(value);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@ function Reticle() {
|
|||
if (!snap || snap.camera?.mode !== "first-person") return undefined;
|
||||
const ctrl = snap.controlPlayerGhostId;
|
||||
if (!ctrl) return undefined;
|
||||
return snap.entities.find((e: StreamEntity) => e.id === ctrl)?.weaponShape;
|
||||
return snap.entities.find((e: StreamEntity) => e.id === ctrl)
|
||||
?.imageSlots?.[0]?.shapeName;
|
||||
});
|
||||
if (weaponShape === undefined) return null;
|
||||
const weapon = normalizeWeaponName(weaponShape);
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ import {
|
|||
} from "../stream/playbackUtils";
|
||||
import { pickMoveAnimation } from "../stream/playerAnimation";
|
||||
import { WeaponImageStateMachine } from "../stream/weaponStateMachine";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import type { WeaponAnimState } from "../stream/weaponStateMachine";
|
||||
import { getAliasedActions } from "../torqueScript/shapeConstructor";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
useStaticShape,
|
||||
ShapePlaceholder,
|
||||
|
|
@ -89,23 +89,25 @@ const SKIN_SUFFIXES: Record<string, string> = {
|
|||
/** Processed custom skin manifest: suffix → Set of available skin names. */
|
||||
type SkinLookup = Record<string, Set<string>>;
|
||||
|
||||
/** Fetch the remote custom skins manifest (once, cached forever).
|
||||
* Returns a lookup of suffix → Set<skinName> for O(1) has() checks. */
|
||||
/** Skin manifest query key and fetcher, shared with App.tsx prefetch. */
|
||||
export const skinManifestQueryKey = ["customSkinManifest"] as const;
|
||||
export async function fetchSkinManifest(): Promise<SkinLookup> {
|
||||
const res = await fetch(SKIN_MANIFEST_URL);
|
||||
if (!res.ok) throw new Error(`${res.status}`);
|
||||
const raw: { customSkins?: Record<string, string[]> } = await res.json();
|
||||
const lookup: SkinLookup = {};
|
||||
if (raw.customSkins) {
|
||||
for (const [suffix, names] of Object.entries(raw.customSkins)) {
|
||||
lookup[suffix] = new Set(names);
|
||||
}
|
||||
}
|
||||
return lookup;
|
||||
}
|
||||
|
||||
function useCustomSkinManifest() {
|
||||
return useQuery<SkinLookup>({
|
||||
queryKey: ["customSkinManifest"],
|
||||
queryFn: async () => {
|
||||
const res = await fetch(SKIN_MANIFEST_URL);
|
||||
if (!res.ok) throw new Error(`${res.status}`);
|
||||
const raw: { customSkins?: Record<string, string[]> } = await res.json();
|
||||
const lookup: SkinLookup = {};
|
||||
if (raw.customSkins) {
|
||||
for (const [suffix, names] of Object.entries(raw.customSkins)) {
|
||||
lookup[suffix] = new Set(names);
|
||||
}
|
||||
}
|
||||
return lookup;
|
||||
},
|
||||
queryKey: skinManifestQueryKey,
|
||||
queryFn: fetchSkinManifest,
|
||||
staleTime: Infinity,
|
||||
retry: 1,
|
||||
});
|
||||
|
|
@ -286,6 +288,9 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
|
|||
);
|
||||
|
||||
// Resolve skin texture URL: local manifest first, then remote manifest.
|
||||
// The manifest is prefetched at app startup (see App.tsx) so it's
|
||||
// available synchronously here — no async wait that could be starved
|
||||
// by store mutations during streaming playback.
|
||||
const { data: skinManifest } = useCustomSkinManifest();
|
||||
|
||||
const skinUrl = useMemo(() => {
|
||||
|
|
@ -335,10 +340,16 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
|
|||
|
||||
// Use front-face-only rendering so the camera can see out from inside the
|
||||
// model in first-person (backface culling hides interior faces).
|
||||
// Disable frustum culling — when portaled into a vehicle mount bone, the
|
||||
// bounding sphere is in local space but the world transform comes from the
|
||||
// bone chain, causing incorrect culling.
|
||||
scene.traverse((n: any) => {
|
||||
if (n.isMesh && n.material) {
|
||||
const mats = Array.isArray(n.material) ? n.material : [n.material];
|
||||
for (const m of mats) m.side = FrontSide;
|
||||
if (n.isMesh) {
|
||||
n.frustumCulled = false;
|
||||
if (n.material) {
|
||||
const mats = Array.isArray(n.material) ? n.material : [n.material];
|
||||
for (const m of mats) m.side = FrontSide;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -590,14 +601,14 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
|
|||
|
||||
// Track weaponShape changes. The entity is mutated in-place by the
|
||||
// streaming layer (no React re-render), so we sync it in useFrame.
|
||||
const weaponShapeRef = useRef(entity.weaponShape);
|
||||
const [currentWeaponShape, setCurrentWeaponShape] = useState(
|
||||
entity.weaponShape,
|
||||
);
|
||||
const packShapeRef = useRef(entity.packShape);
|
||||
const [currentPackShape, setCurrentPackShape] = useState(entity.packShape);
|
||||
const flagShapeRef = useRef(entity.flagShape);
|
||||
const [currentFlagShape, setCurrentFlagShape] = useState(entity.flagShape);
|
||||
// Derive weapon/pack/flag from imageSlots.
|
||||
const getSlotShape = (slot: number) => entity.imageSlots?.[slot]?.shapeName;
|
||||
const weaponShapeRef = useRef(getSlotShape(0));
|
||||
const [currentWeaponShape, setCurrentWeaponShape] = useState(getSlotShape(0));
|
||||
const packShapeRef = useRef(getSlotShape(2));
|
||||
const [currentPackShape, setCurrentPackShape] = useState(getSlotShape(2));
|
||||
const flagShapeRef = useRef(getSlotShape(3));
|
||||
const [currentFlagShape, setCurrentFlagShape] = useState(getSlotShape(3));
|
||||
|
||||
// ShapeBase sound slots (weapon switch sounds, etc.) — managed by shared hook.
|
||||
const entityRef = useRef(entity);
|
||||
|
|
@ -663,17 +674,20 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
|
|||
|
||||
// Per-frame animation selection and mixer update.
|
||||
useFrame((_, delta) => {
|
||||
if (entity.weaponShape !== weaponShapeRef.current) {
|
||||
weaponShapeRef.current = entity.weaponShape;
|
||||
setCurrentWeaponShape(entity.weaponShape);
|
||||
const curWeapon = getSlotShape(0);
|
||||
if (curWeapon !== weaponShapeRef.current) {
|
||||
weaponShapeRef.current = curWeapon;
|
||||
setCurrentWeaponShape(curWeapon);
|
||||
}
|
||||
if (entity.packShape !== packShapeRef.current) {
|
||||
packShapeRef.current = entity.packShape;
|
||||
setCurrentPackShape(entity.packShape);
|
||||
const curPack = getSlotShape(2);
|
||||
if (curPack !== packShapeRef.current) {
|
||||
packShapeRef.current = curPack;
|
||||
setCurrentPackShape(curPack);
|
||||
}
|
||||
if (entity.flagShape !== flagShapeRef.current) {
|
||||
flagShapeRef.current = entity.flagShape;
|
||||
setCurrentFlagShape(entity.flagShape);
|
||||
const curFlag = getSlotShape(3);
|
||||
if (curFlag !== flagShapeRef.current) {
|
||||
flagShapeRef.current = curFlag;
|
||||
setCurrentFlagShape(curFlag);
|
||||
}
|
||||
const playback = engineStore.getState().playback;
|
||||
const isPlaying = playback.status === "playing";
|
||||
|
|
@ -929,7 +943,6 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
|
|||
// from the animated skeleton (rotation is discarded — head rotation
|
||||
// is constructed from mHead pitch/yaw instead).
|
||||
if (eyeBone) {
|
||||
clonedScene.updateWorldMatrix(false, true);
|
||||
let eyePos = playerEyePositions.get(entity.id);
|
||||
if (!eyePos) {
|
||||
eyePos = new Vector3();
|
||||
|
|
@ -981,7 +994,7 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
|
|||
<Suspense>
|
||||
<MountedShapeContent
|
||||
shapeName={currentPackShape}
|
||||
imageDataBlockId={entity.imageDataBlockIds?.[2]}
|
||||
imageDataBlockId={entity.imageSlots?.[2]?.dataBlockId}
|
||||
entityId={entity.id}
|
||||
/>
|
||||
</Suspense>,
|
||||
|
|
@ -993,9 +1006,9 @@ export function PlayerModel({ entity }: { entity: PlayerEntity }) {
|
|||
<Suspense>
|
||||
<MountedShapeContent
|
||||
shapeName={currentFlagShape}
|
||||
imageDataBlockId={entity.imageDataBlockIds?.[3]}
|
||||
imageDataBlockId={entity.imageSlots?.[3]?.dataBlockId}
|
||||
entityId={entity.id}
|
||||
skinName={entity.imageSkinNames?.[3]}
|
||||
skinName={entity.imageSlots?.[3]?.skinName}
|
||||
/>
|
||||
</Suspense>,
|
||||
mount2,
|
||||
|
|
@ -1075,8 +1088,8 @@ function WeaponModel({
|
|||
const engineStore = useEngineStoreApi();
|
||||
const weaponGltf = useStaticShape(weaponShape);
|
||||
const emap = useMemo(
|
||||
() => resolveEmapFromImageSlot(entity.imageDataBlockIds?.[0]),
|
||||
[entity.imageDataBlockIds],
|
||||
() => resolveEmapFromImageSlot(entity.imageSlots?.[0]?.dataBlockId),
|
||||
[entity.imageSlots],
|
||||
);
|
||||
const anisotropy = useAnisotropy();
|
||||
|
||||
|
|
|
|||
|
|
@ -42,14 +42,16 @@ function mutateRenderFields(
|
|||
renderEntity: GameEntity,
|
||||
stream: StreamEntity,
|
||||
): void {
|
||||
// Fields common to all positioned entities.
|
||||
const e = renderEntity as unknown as Record<string, unknown>;
|
||||
e.mountObjectId = stream.mountObjectId;
|
||||
e.mountNode = stream.mountNode;
|
||||
e.imageSlots = stream.imageSlots;
|
||||
|
||||
switch (renderEntity.renderType) {
|
||||
case "Player": {
|
||||
const e = renderEntity as unknown as Record<string, unknown>;
|
||||
e.threads = stream.threads;
|
||||
e.weaponShape = stream.weaponShape;
|
||||
e.armAction = stream.armAction;
|
||||
e.packShape = stream.packShape;
|
||||
e.flagShape = stream.flagShape;
|
||||
e.falling = stream.falling;
|
||||
e.jetting = stream.jetting;
|
||||
e.weaponImageState = stream.weaponImageState;
|
||||
|
|
@ -63,10 +65,11 @@ function mutateRenderFields(
|
|||
break;
|
||||
}
|
||||
case "Shape": {
|
||||
const e = renderEntity as unknown as Record<string, unknown>;
|
||||
e.threads = stream.threads;
|
||||
e.damageState = stream.damageState;
|
||||
e.weaponShape = stream.weaponShape;
|
||||
e.fadeVal = stream.fadeVal;
|
||||
e.cloakLevel = stream.cloakLevel;
|
||||
e.armAction = stream.armAction;
|
||||
e.targetRenderFlags = stream.targetRenderFlags;
|
||||
e.iffColor = stream.iffColor;
|
||||
e.soundSlots = stream.soundSlots;
|
||||
|
|
@ -146,6 +149,7 @@ export function StreamingController({
|
|||
const engineStore = useEngineStoreApi();
|
||||
const { fov: userFov } = useSettings();
|
||||
const playbackClockRef = useRef(0);
|
||||
const lastSeekTimeRef = useRef(0);
|
||||
const prevTickSnapshotRef = useRef<StreamSnapshot | null>(null);
|
||||
const currentTickSnapshotRef = useRef<StreamSnapshot | null>(null);
|
||||
const streamRef = useRef<StreamingPlayback | null>(
|
||||
|
|
@ -187,7 +191,7 @@ export function StreamingController({
|
|||
getField(renderEntity, "shapeName") !== entity.dataBlock) ||
|
||||
(renderEntity.renderType !== "Player" &&
|
||||
hasShapeName &&
|
||||
getField(renderEntity, "weaponShape") !== entity.weaponShape);
|
||||
getField(renderEntity, "imageSlots") !== entity.imageSlots);
|
||||
|
||||
if (needsNewIdentity) {
|
||||
const prevHidden = renderEntity?.debugHidden;
|
||||
|
|
@ -196,7 +200,13 @@ export function StreamingController({
|
|||
map.set(entity.id, renderEntity);
|
||||
structuralChange = true;
|
||||
} else {
|
||||
// Detect mount state changes — EntityScene needs a store re-render
|
||||
// to re-evaluate mount relationships (portal rendering).
|
||||
const prevMount = renderEntity!.mountObjectId;
|
||||
mutateRenderFields(renderEntity!, entity);
|
||||
if (renderEntity!.mountObjectId !== prevMount) {
|
||||
structuralChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Keyframe update (mutable — position, rotation, velocity, etc.).
|
||||
|
|
@ -260,6 +270,7 @@ export function StreamingController({
|
|||
publishedSnapshotRef.current = null;
|
||||
resetStreamPlayback();
|
||||
playbackClockRef.current = 0;
|
||||
lastSeekTimeRef.current = 0;
|
||||
prevTickSnapshotRef.current = null;
|
||||
currentTickSnapshotRef.current = null;
|
||||
|
||||
|
|
@ -345,17 +356,10 @@ export function StreamingController({
|
|||
const storeState = engineStore.getState();
|
||||
const playback = storeState.playback;
|
||||
const isPlaying = playback.status === "playing";
|
||||
const requestedTimeSec = playback.timeMs / 1000;
|
||||
const externalSeekWhilePaused =
|
||||
!isPlaying &&
|
||||
Math.abs(requestedTimeSec - playbackClockRef.current) > 0.0005;
|
||||
const externalSeekWhilePlaying =
|
||||
isPlaying &&
|
||||
Math.abs(requestedTimeSec - streamPlaybackStore.getState().time) > 0.05;
|
||||
const isSeeking = externalSeekWhilePaused || externalSeekWhilePlaying;
|
||||
const isSeeking = playback.seekTime !== lastSeekTimeRef.current;
|
||||
if (isSeeking) {
|
||||
// Sync stream cursor to UI/programmatic seek.
|
||||
playbackClockRef.current = requestedTimeSec;
|
||||
lastSeekTimeRef.current = playback.seekTime;
|
||||
playbackClockRef.current = playback.seekTime;
|
||||
}
|
||||
|
||||
// Advance the shared effect clock so all effect timers (particles,
|
||||
|
|
@ -522,7 +526,7 @@ export function StreamingController({
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (!entity?.position || entity.hidden) {
|
||||
if (!entity?.position || (entity.fadeVal === 0 && !entity.cloakLevel)) {
|
||||
child.visible = false;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -591,7 +595,11 @@ export function StreamingController({
|
|||
_orbitTarget.copy(targetGroup.position);
|
||||
// Torque orbits the target's render world-box center; player positions
|
||||
// in our stream are feet-level, so lift to an approximate center.
|
||||
if (orbitEntity?.type === "Player") {
|
||||
// For vehicles, use the datablock's cameraOffset (vertical Z offset
|
||||
// in Torque space = Y in Three.js).
|
||||
if (currentCamera.orbitOffset) {
|
||||
_orbitTarget.y += currentCamera.orbitOffset;
|
||||
} else if (orbitEntity?.type === "Player") {
|
||||
_orbitTarget.y += 1.0;
|
||||
}
|
||||
|
||||
|
|
@ -683,11 +691,6 @@ export function StreamingController({
|
|||
if (isPlaying && snapshot.exhausted) {
|
||||
storeState.setPlaybackStatus("paused");
|
||||
}
|
||||
|
||||
const timeMs = playbackClockRef.current * 1000;
|
||||
if (Math.abs(timeMs - playback.timeMs) > 0.5) {
|
||||
storeState.setPlaybackTime(timeMs);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ const log = createLogger("TerrainBlock");
|
|||
import { useSceneSky, useSceneSun } from "../state/gameEntityStore";
|
||||
import { loadTerrain } from "../loaders";
|
||||
import { uint16ToFloat32 } from "../arrayUtils";
|
||||
import { setupMask } from "../textureUtils";
|
||||
import { packMasksRGB } from "../textureUtils";
|
||||
import { TerrainTile, TerrainMaterial } from "./TerrainTile";
|
||||
import {
|
||||
createTerrainHeightSampler,
|
||||
|
|
@ -565,10 +565,11 @@ export const TerrainBlock = memo(function TerrainBlock({
|
|||
// Visibility mask for pooled tiles - all visible (no empty squares)
|
||||
// This is a stable reference shared by all pooled tiles
|
||||
const pooledVisibilityMask = useMemo(() => createVisibilityMask([]), []);
|
||||
// Shared alpha textures from terrain alphaMaps - created once for all tiles
|
||||
const sharedAlphaTextures = useMemo(() => {
|
||||
// Pack alpha masks into RGB textures (3 masks per texture) to reduce
|
||||
// sampler count. 6 layers → 2 RGB textures instead of 6 R textures.
|
||||
const packedAlphaTextures = useMemo(() => {
|
||||
if (!terrain) return null;
|
||||
return terrain.alphaMaps.map((data) => setupMask(data));
|
||||
return packMasksRGB(terrain.alphaMaps);
|
||||
}, [terrain]);
|
||||
// Calculate the maximum number of tiles that can be visible at once.
|
||||
const poolSize = useMemo(() => {
|
||||
|
|
@ -636,14 +637,14 @@ export const TerrainBlock = memo(function TerrainBlock({
|
|||
!terrain ||
|
||||
!sharedGeometry ||
|
||||
!sharedDisplacementMap ||
|
||||
!sharedAlphaTextures
|
||||
!packedAlphaTextures
|
||||
) {
|
||||
log.debug(
|
||||
"Not ready: terrain=%s geometry=%s displacement=%s alpha=%s",
|
||||
!!terrain,
|
||||
!!sharedGeometry,
|
||||
!!sharedDisplacementMap,
|
||||
!!sharedAlphaTextures,
|
||||
!!packedAlphaTextures,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
|
@ -659,7 +660,7 @@ export const TerrainBlock = memo(function TerrainBlock({
|
|||
geometry={sharedGeometry}
|
||||
displacementMap={sharedDisplacementMap}
|
||||
visibilityMask={primaryVisibilityMask}
|
||||
alphaTextures={sharedAlphaTextures}
|
||||
alphaTextures={packedAlphaTextures}
|
||||
detailTextureName={detailTexture}
|
||||
lightmap={terrainLightmap ?? undefined}
|
||||
/>
|
||||
|
|
@ -677,7 +678,7 @@ export const TerrainBlock = memo(function TerrainBlock({
|
|||
displacementMap={sharedDisplacementMap}
|
||||
visibilityMask={pooledVisibilityMask}
|
||||
textureNames={terrain.textureNames}
|
||||
alphaTextures={sharedAlphaTextures}
|
||||
alphaTextures={packedAlphaTextures}
|
||||
detailTextureName={detailTexture}
|
||||
lightmap={terrainLightmap ?? undefined}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -147,14 +147,13 @@ const BlendedTerrainTextures = memo(function BlendedTerrainTextures({
|
|||
// Key for shader structure changes (detail texture, lightmap)
|
||||
const materialKey = `${detailTextureUrl ? "detail" : "nodetail"}-${lightmap ? "lightmap" : "nolightmap"}`;
|
||||
|
||||
// Displacement is done on CPU, so no displacementMap needed
|
||||
// We keep 'map' to provide UV coordinates for shader (vMapUv)
|
||||
// Use MeshLambertMaterial for compatibility with shadow maps
|
||||
// Displacement is done on CPU — no displacementMap or map needed.
|
||||
// UVs are provided by vTerrainUv (injected in the vertex shader),
|
||||
// avoiding an unused `map` sampler that would waste a texture unit.
|
||||
return (
|
||||
<meshLambertMaterial
|
||||
ref={materialRef}
|
||||
key={materialKey}
|
||||
map={displacementMap}
|
||||
depthWrite
|
||||
side={FrontSide}
|
||||
defines={{ DEBUG_MODE: debugMode ? 1 : 0 }}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,9 @@ function createSwapAtlas(
|
|||
tex.wrapS = tex.wrapT = RepeatWrapping;
|
||||
tex.colorSpace = SRGBColorSpace;
|
||||
tex.flipY = false;
|
||||
tex.needsUpdate = true;
|
||||
if (tex.image) {
|
||||
tex.needsUpdate = true;
|
||||
}
|
||||
}
|
||||
return {
|
||||
texture: uniqueTextures[0],
|
||||
|
|
|
|||
|
|
@ -12,8 +12,15 @@ export function useIsPlaying(): boolean {
|
|||
return useEngineSelector((state) => state.playback.status === "playing");
|
||||
}
|
||||
|
||||
/** Playback time for UI display, floored to whole seconds. The selector
|
||||
* evaluates on every store mutation but only triggers a re-render when
|
||||
* the displayed second changes (~1/s). */
|
||||
export function useCurrentTime(): number {
|
||||
return useEngineSelector((state) => state.playback.timeMs / 1000);
|
||||
return useEngineSelector((state) =>
|
||||
Math.floor(
|
||||
state.playback.streamSnapshot?.timeSec ?? state.playback.seekTime,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function useDuration(): number {
|
||||
|
|
@ -30,7 +37,7 @@ export function usePlaybackActions() {
|
|||
const setPlaybackStatus = useEngineSelector(
|
||||
(state) => state.setPlaybackStatus,
|
||||
);
|
||||
const setPlaybackTime = useEngineSelector((state) => state.setPlaybackTime);
|
||||
const seekPlayback = useEngineSelector((state) => state.seekPlayback);
|
||||
const setPlaybackRate = useEngineSelector((state) => state.setPlaybackRate);
|
||||
|
||||
const setRec = useCallback(
|
||||
|
|
@ -50,10 +57,10 @@ export function usePlaybackActions() {
|
|||
}, [setPlaybackStatus]);
|
||||
|
||||
const seek = useCallback(
|
||||
(time: number) => {
|
||||
setPlaybackTime(time * 1000);
|
||||
(timeSec: number) => {
|
||||
seekPlayback(timeSec);
|
||||
},
|
||||
[setPlaybackTime],
|
||||
[seekPlayback],
|
||||
);
|
||||
|
||||
const setSpeed = useCallback(
|
||||
|
|
|
|||
|
|
@ -29164,10 +29164,6 @@
|
|||
"missions/TrueGrit.mis",
|
||||
["z_mappacks/TWL_T2arenaOfficialMaps.vl2"]
|
||||
],
|
||||
"missions/tst_spheremap.mis": [
|
||||
"missions/TST_SphereMap.mis",
|
||||
["z_mappacks/zDMP-4.7.3DX.vl2"]
|
||||
],
|
||||
"missions/tusklt.mis": [
|
||||
"missions/TuskLT.mis",
|
||||
["z_mappacks/z_DMP2-V0.6.vl2"]
|
||||
|
|
@ -30843,7 +30839,6 @@
|
|||
["z_mappacks/z_DMP2-V0.6.vl2"]
|
||||
],
|
||||
"shapes/chaingun_shot.dts": ["shapes/chaingun_shot.dts", ["shapes.vl2"]],
|
||||
"shapes/chrometest.dts": ["shapes/chromeTest.dts", ["shapes.vl2"]],
|
||||
"shapes/debris_generic.dts": ["shapes/debris_generic.dts", ["shapes.vl2"]],
|
||||
"shapes/debris_generic_small.dts": [
|
||||
"shapes/debris_generic_small.dts",
|
||||
|
|
@ -61282,11 +61277,6 @@
|
|||
"displayName": "True Grit",
|
||||
"missionTypes": ["Arena"]
|
||||
},
|
||||
"TST_SphereMap": {
|
||||
"resourcePath": "missions/tst_spheremap.mis",
|
||||
"displayName": "TST-SphereMap",
|
||||
"missionTypes": ["CTF"]
|
||||
},
|
||||
"TuskLT": {
|
||||
"resourcePath": "missions/tusklt.mis",
|
||||
"displayName": "DMP2-Tusk LT",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,15 @@
|
|||
import type {
|
||||
TerrainBlockGhostData,
|
||||
InteriorInstanceGhostData,
|
||||
TSStaticGhostData,
|
||||
SkyGhostData,
|
||||
SunGhostData,
|
||||
MissionAreaGhostData,
|
||||
WaterBlockGhostData,
|
||||
ParsedData,
|
||||
AffineTransform,
|
||||
MatrixF as ParserMatrixF,
|
||||
} from "t2-demo-parser";
|
||||
import type {
|
||||
SceneTerrainBlock,
|
||||
SceneInteriorInstance,
|
||||
|
|
@ -16,147 +28,121 @@ import { createLogger } from "../logger";
|
|||
|
||||
const log = createLogger("ghostToScene");
|
||||
|
||||
type GhostData = Record<string, unknown>;
|
||||
const DEFAULT_VEC3: Vec3 = { x: 0, y: 0, z: 0 };
|
||||
const UNIT_SCALE: Vec3 = { x: 1, y: 1, z: 1 };
|
||||
|
||||
function vec3(v: unknown, fallback: Vec3 = { x: 0, y: 0, z: 0 }): Vec3 {
|
||||
if (v && typeof v === "object" && "x" in v) return v as Vec3;
|
||||
return fallback;
|
||||
function color3Or(v: Color3 | undefined, fallback: Color3): Color3 {
|
||||
return v ?? fallback;
|
||||
}
|
||||
|
||||
function color3(v: unknown, fallback: Color3 = { r: 0, g: 0, b: 0 }): Color3 {
|
||||
if (v && typeof v === "object" && "r" in v) return v as Color3;
|
||||
return fallback;
|
||||
function color4Or(v: Color4 | undefined, fallback: Color4): Color4 {
|
||||
return v ?? fallback;
|
||||
}
|
||||
|
||||
function color4(
|
||||
v: unknown,
|
||||
fallback: Color4 = { r: 0.5, g: 0.5, b: 0.5, a: 1 },
|
||||
): Color4 {
|
||||
if (v && typeof v === "object" && "r" in v) return v as Color4;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
function matrixF(v: unknown): MatrixF {
|
||||
if (
|
||||
v &&
|
||||
typeof v === "object" &&
|
||||
"elements" in v &&
|
||||
Array.isArray((v as any).elements)
|
||||
) {
|
||||
return v as MatrixF;
|
||||
}
|
||||
// readAffineTransform() returns {position, rotation} — convert to MatrixF.
|
||||
if (v && typeof v === "object" && "position" in v && "rotation" in v) {
|
||||
const { position: pos, rotation: q } = v as {
|
||||
position: { x: number; y: number; z: number };
|
||||
rotation: { x: number; y: number; z: number; w: number };
|
||||
};
|
||||
// Quaternion to column-major 4×4 matrix (idx = row + col*4).
|
||||
const xx = q.x * q.x,
|
||||
yy = q.y * q.y,
|
||||
zz = q.z * q.z;
|
||||
const xy = q.x * q.y,
|
||||
xz = q.x * q.z,
|
||||
yz = q.y * q.z;
|
||||
const wx = q.w * q.x,
|
||||
wy = q.w * q.y,
|
||||
wz = q.w * q.z;
|
||||
/**
|
||||
* Convert a parser transform (MatrixF or AffineTransform) to the scene's
|
||||
* MatrixF format. The parser may emit either depending on the ghost class.
|
||||
*/
|
||||
function toMatrixF(v: ParserMatrixF | AffineTransform | undefined): MatrixF {
|
||||
if (!v) {
|
||||
return {
|
||||
elements: [
|
||||
1 - 2 * (yy + zz),
|
||||
2 * (xy + wz),
|
||||
2 * (xz - wy),
|
||||
0,
|
||||
2 * (xy - wz),
|
||||
1 - 2 * (xx + zz),
|
||||
2 * (yz + wx),
|
||||
0,
|
||||
2 * (xz + wy),
|
||||
2 * (yz - wx),
|
||||
1 - 2 * (xx + yy),
|
||||
0,
|
||||
pos.x,
|
||||
pos.y,
|
||||
pos.z,
|
||||
1,
|
||||
],
|
||||
position: { x: pos.x, y: pos.y, z: pos.z },
|
||||
elements: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||
position: DEFAULT_VEC3,
|
||||
};
|
||||
}
|
||||
// MatrixF: has elements array
|
||||
if ("elements" in v) {
|
||||
return v;
|
||||
}
|
||||
// AffineTransform: has position + rotation quaternion
|
||||
const { position: pos, rotation: q } = v;
|
||||
const xx = q.x * q.x,
|
||||
yy = q.y * q.y,
|
||||
zz = q.z * q.z;
|
||||
const xy = q.x * q.y,
|
||||
xz = q.x * q.z,
|
||||
yz = q.y * q.z;
|
||||
const wx = q.w * q.x,
|
||||
wy = q.w * q.y,
|
||||
wz = q.w * q.z;
|
||||
return {
|
||||
elements: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
elements: [
|
||||
1 - 2 * (yy + zz),
|
||||
2 * (xy + wz),
|
||||
2 * (xz - wy),
|
||||
0,
|
||||
2 * (xy - wz),
|
||||
1 - 2 * (xx + zz),
|
||||
2 * (yz + wx),
|
||||
0,
|
||||
2 * (xz + wy),
|
||||
2 * (yz - wx),
|
||||
1 - 2 * (xx + yy),
|
||||
0,
|
||||
pos.x,
|
||||
pos.y,
|
||||
pos.z,
|
||||
1,
|
||||
],
|
||||
position: { x: pos.x, y: pos.y, z: pos.z },
|
||||
};
|
||||
}
|
||||
|
||||
export function terrainFromGhost(
|
||||
ghostIndex: number,
|
||||
data: GhostData,
|
||||
data: TerrainBlockGhostData,
|
||||
): SceneTerrainBlock {
|
||||
return {
|
||||
className: "TerrainBlock",
|
||||
ghostIndex,
|
||||
terrFileName: (data.terrFileName as string) ?? "",
|
||||
detailTextureName: (data.detailTextureName as string) ?? "",
|
||||
squareSize: (data.squareSize as number) ?? 8,
|
||||
emptySquareRuns: data.emptySquareRuns as number[] | undefined,
|
||||
terrFileName: data.terrFileName ?? "",
|
||||
detailTextureName: data.detailTextureName ?? "",
|
||||
squareSize: data.squareSize ?? 8,
|
||||
emptySquareRuns: data.emptySquareRuns,
|
||||
};
|
||||
}
|
||||
|
||||
export function interiorFromGhost(
|
||||
ghostIndex: number,
|
||||
data: GhostData,
|
||||
data: InteriorInstanceGhostData,
|
||||
): SceneInteriorInstance {
|
||||
return {
|
||||
className: "InteriorInstance",
|
||||
ghostIndex,
|
||||
interiorFile: (data.interiorFile as string) ?? "",
|
||||
transform: matrixF(data.transform),
|
||||
scale: vec3(data.scale, { x: 1, y: 1, z: 1 }),
|
||||
showTerrainInside: (data.showTerrainInside as boolean) ?? false,
|
||||
skinBase: (data.skinBase as string) ?? "",
|
||||
alarmState: (data.alarmState as boolean) ?? false,
|
||||
interiorFile: data.interiorFile ?? "",
|
||||
transform: toMatrixF(data.transform),
|
||||
scale: data.scale ?? UNIT_SCALE,
|
||||
showTerrainInside: data.showTerrainInside ?? false,
|
||||
skinBase: data.skinBase ?? "",
|
||||
alarmState: data.alarmState ?? false,
|
||||
};
|
||||
}
|
||||
|
||||
export function tsStaticFromGhost(
|
||||
ghostIndex: number,
|
||||
data: GhostData,
|
||||
data: TSStaticGhostData,
|
||||
): SceneTSStatic {
|
||||
return {
|
||||
className: "TSStatic",
|
||||
ghostIndex,
|
||||
shapeName: (data.shapeName as string) ?? "",
|
||||
transform: matrixF(data.transform),
|
||||
scale: vec3(data.scale, { x: 1, y: 1, z: 1 }),
|
||||
shapeName: data.shapeName ?? "",
|
||||
transform: toMatrixF(data.transform),
|
||||
scale: data.scale ?? UNIT_SCALE,
|
||||
};
|
||||
}
|
||||
|
||||
export function skyFromGhost(ghostIndex: number, data: GhostData): SceneSky {
|
||||
const fogVolumes = Array.isArray(data.fogVolumes)
|
||||
? (
|
||||
data.fogVolumes as Array<{
|
||||
visibleDistance?: number;
|
||||
minHeight?: number;
|
||||
maxHeight?: number;
|
||||
color?: Color3;
|
||||
}>
|
||||
).map((v) => ({
|
||||
export function skyFromGhost(ghostIndex: number, data: SkyGhostData): SceneSky {
|
||||
const fogVolumes = data.fogVolumes
|
||||
? data.fogVolumes.map((v) => ({
|
||||
visibleDistance: v.visibleDistance ?? 0,
|
||||
minHeight: v.minHeight ?? 0,
|
||||
maxHeight: v.maxHeight ?? 0,
|
||||
color: color3(v.color),
|
||||
color: color3Or(v.color, { r: 0, g: 0, b: 0 }),
|
||||
}))
|
||||
: [];
|
||||
|
||||
const cloudLayers = Array.isArray(data.cloudLayers)
|
||||
? (
|
||||
data.cloudLayers as Array<{
|
||||
texture?: string;
|
||||
heightPercent?: number;
|
||||
speed?: number;
|
||||
}>
|
||||
).map((c) => ({
|
||||
const cloudLayers = data.cloudLayers
|
||||
? data.cloudLayers.map((c) => ({
|
||||
texture: c.texture ?? "",
|
||||
heightPercent: c.heightPercent ?? 0,
|
||||
speed: c.speed ?? 0,
|
||||
|
|
@ -166,61 +152,56 @@ export function skyFromGhost(ghostIndex: number, data: GhostData): SceneSky {
|
|||
return {
|
||||
className: "Sky",
|
||||
ghostIndex,
|
||||
materialList: (data.materialList as string) ?? "",
|
||||
fogColor: color3(data.fogColor),
|
||||
visibleDistance: (data.visibleDistance as number) ?? 1000,
|
||||
fogDistance: (data.fogDistance as number) ?? 0,
|
||||
skySolidColor: color3(data.skySolidColor),
|
||||
useSkyTextures: (data.useSkyTextures as boolean) ?? true,
|
||||
materialList: data.materialList ?? "",
|
||||
fogColor: color3Or(data.fogColor, { r: 0, g: 0, b: 0 }),
|
||||
visibleDistance: data.visibleDistance ?? 1000,
|
||||
fogDistance: data.fogDistance ?? 0,
|
||||
skySolidColor: color3Or(data.skySolidColor, { r: 0, g: 0, b: 0 }),
|
||||
useSkyTextures: data.useSkyTextures ?? true,
|
||||
fogVolumes,
|
||||
cloudLayers,
|
||||
windVelocity: vec3(data.windVelocity),
|
||||
windVelocity: data.windVelocity ?? DEFAULT_VEC3,
|
||||
};
|
||||
}
|
||||
|
||||
export function sunFromGhost(ghostIndex: number, data: GhostData): SceneSun {
|
||||
export function sunFromGhost(ghostIndex: number, data: SunGhostData): SceneSun {
|
||||
return {
|
||||
className: "Sun",
|
||||
ghostIndex,
|
||||
direction: vec3(data.direction, { x: 0.57735, y: 0.57735, z: -0.57735 }),
|
||||
color: color4(data.color, { r: 0.7, g: 0.7, b: 0.7, a: 1 }),
|
||||
ambient: color4(data.ambient, { r: 0.5, g: 0.5, b: 0.5, a: 1 }),
|
||||
textures: Array.isArray(data.textures)
|
||||
? (data.textures as string[])
|
||||
: undefined,
|
||||
direction: data.direction ?? { x: 0.57735, y: 0.57735, z: -0.57735 },
|
||||
color: color4Or(data.color, { r: 0.7, g: 0.7, b: 0.7, a: 1 }),
|
||||
ambient: color4Or(data.ambient, { r: 0.5, g: 0.5, b: 0.5, a: 1 }),
|
||||
textures: data.textures,
|
||||
};
|
||||
}
|
||||
|
||||
export function missionAreaFromGhost(
|
||||
ghostIndex: number,
|
||||
data: GhostData,
|
||||
data: MissionAreaGhostData,
|
||||
): SceneMissionArea {
|
||||
const area = data.area as
|
||||
| { x: number; y: number; w: number; h: number }
|
||||
| undefined;
|
||||
return {
|
||||
className: "MissionArea",
|
||||
ghostIndex,
|
||||
area: area ?? { x: -512, y: -512, w: 1024, h: 1024 },
|
||||
flightCeiling: (data.flightCeiling as number) ?? 2000,
|
||||
flightCeilingRange: (data.flightCeilingRange as number) ?? 50,
|
||||
area: data.area ?? { x: -512, y: -512, w: 1024, h: 1024 },
|
||||
flightCeiling: data.flightCeiling ?? 2000,
|
||||
flightCeilingRange: data.flightCeilingRange ?? 50,
|
||||
};
|
||||
}
|
||||
|
||||
export function waterBlockFromGhost(
|
||||
ghostIndex: number,
|
||||
data: GhostData,
|
||||
data: WaterBlockGhostData,
|
||||
): SceneWaterBlock {
|
||||
return {
|
||||
className: "WaterBlock",
|
||||
ghostIndex,
|
||||
transform: matrixF(data.transform),
|
||||
scale: vec3(data.scale, { x: 1, y: 1, z: 1 }),
|
||||
surfaceName: (data.surfaceName as string) ?? "",
|
||||
envMapName: (data.envMapName as string) ?? "",
|
||||
surfaceOpacity: (data.surfaceOpacity as number) ?? 0.75,
|
||||
waveMagnitude: (data.waveMagnitude as number) ?? 1.0,
|
||||
envMapIntensity: (data.envMapIntensity as number) ?? 1.0,
|
||||
transform: toMatrixF(data.transform),
|
||||
scale: data.scale ?? UNIT_SCALE,
|
||||
surfaceName: data.surfaceName ?? "",
|
||||
envMapName: data.envMapName ?? "",
|
||||
surfaceOpacity: data.surfaceOpacity ?? 0.75,
|
||||
waveMagnitude: data.waveMagnitude ?? 1.0,
|
||||
envMapIntensity: data.envMapIntensity ?? 1.0,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -228,66 +209,71 @@ export function waterBlockFromGhost(
|
|||
export function ghostToSceneObject(
|
||||
className: string,
|
||||
ghostIndex: number,
|
||||
data: GhostData,
|
||||
data: ParsedData,
|
||||
): SceneObject | null {
|
||||
let result: SceneObject | null;
|
||||
switch (className) {
|
||||
case "TerrainBlock":
|
||||
result = terrainFromGhost(ghostIndex, data);
|
||||
case "TerrainBlock": {
|
||||
const result = terrainFromGhost(
|
||||
ghostIndex,
|
||||
data as TerrainBlockGhostData,
|
||||
);
|
||||
log.debug(
|
||||
"TerrainBlock #%d: terrFileName=%s",
|
||||
ghostIndex,
|
||||
(result as SceneTerrainBlock).terrFileName,
|
||||
result.terrFileName,
|
||||
);
|
||||
return result;
|
||||
case "InteriorInstance":
|
||||
result = interiorFromGhost(ghostIndex, data);
|
||||
}
|
||||
case "InteriorInstance": {
|
||||
const result = interiorFromGhost(
|
||||
ghostIndex,
|
||||
data as InteriorInstanceGhostData,
|
||||
);
|
||||
log.debug(
|
||||
"InteriorInstance #%d: interiorFile=%s",
|
||||
ghostIndex,
|
||||
(result as SceneInteriorInstance).interiorFile,
|
||||
result.interiorFile,
|
||||
);
|
||||
return result;
|
||||
}
|
||||
case "TSStatic":
|
||||
return tsStaticFromGhost(ghostIndex, data);
|
||||
return tsStaticFromGhost(ghostIndex, data as TSStaticGhostData);
|
||||
case "Sky": {
|
||||
result = skyFromGhost(ghostIndex, data);
|
||||
const sky = result as SceneSky;
|
||||
const result = skyFromGhost(ghostIndex, data as SkyGhostData);
|
||||
log.debug(
|
||||
"Sky #%d: materialList=%s fogColor=(%s, %s, %s) visibleDist=%d fogDist=%d useSkyTextures=%s",
|
||||
ghostIndex,
|
||||
sky.materialList,
|
||||
sky.fogColor.r.toFixed(3),
|
||||
sky.fogColor.g.toFixed(3),
|
||||
sky.fogColor.b.toFixed(3),
|
||||
sky.visibleDistance,
|
||||
sky.fogDistance,
|
||||
sky.useSkyTextures,
|
||||
result.materialList,
|
||||
result.fogColor.r.toFixed(3),
|
||||
result.fogColor.g.toFixed(3),
|
||||
result.fogColor.b.toFixed(3),
|
||||
result.visibleDistance,
|
||||
result.fogDistance,
|
||||
result.useSkyTextures,
|
||||
);
|
||||
return result;
|
||||
}
|
||||
case "Sun": {
|
||||
result = sunFromGhost(ghostIndex, data);
|
||||
const sun = result as SceneSun;
|
||||
const result = sunFromGhost(ghostIndex, data as SunGhostData);
|
||||
log.debug(
|
||||
"Sun #%d: dir=(%s, %s, %s) color=(%s, %s, %s) ambient=(%s, %s, %s)",
|
||||
ghostIndex,
|
||||
sun.direction.x.toFixed(3),
|
||||
sun.direction.y.toFixed(3),
|
||||
sun.direction.z.toFixed(3),
|
||||
sun.color.r.toFixed(3),
|
||||
sun.color.g.toFixed(3),
|
||||
sun.color.b.toFixed(3),
|
||||
sun.ambient.r.toFixed(3),
|
||||
sun.ambient.g.toFixed(3),
|
||||
sun.ambient.b.toFixed(3),
|
||||
result.direction.x.toFixed(3),
|
||||
result.direction.y.toFixed(3),
|
||||
result.direction.z.toFixed(3),
|
||||
result.color.r.toFixed(3),
|
||||
result.color.g.toFixed(3),
|
||||
result.color.b.toFixed(3),
|
||||
result.ambient.r.toFixed(3),
|
||||
result.ambient.g.toFixed(3),
|
||||
result.ambient.b.toFixed(3),
|
||||
);
|
||||
return result;
|
||||
}
|
||||
case "MissionArea":
|
||||
return missionAreaFromGhost(ghostIndex, data);
|
||||
return missionAreaFromGhost(ghostIndex, data as MissionAreaGhostData);
|
||||
case "WaterBlock":
|
||||
return waterBlockFromGhost(ghostIndex, data);
|
||||
return waterBlockFromGhost(ghostIndex, data as WaterBlockGhostData);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue