├── .commitlintrc.json ├── .eslintrc ├── .gitignore ├── .husky ├── commit-msg ├── common.sh └── pre-commit ├── .npmrc ├── .prettierrc ├── .yarn ├── plugins │ └── @yarnpkg │ │ ├── plugin-interactive-tools.cjs │ │ └── plugin-typescript.cjs └── releases │ └── yarn-berry.cjs ├── README.md ├── blender ├── constraintExporter.py ├── gltfjsxify.sh ├── infty.blend ├── nameExporter.py └── objectExporter.py ├── next-env.d.ts ├── next.config.js ├── package.json ├── public ├── Arch.glb ├── ArchLeft.glb ├── ArchRight.glb ├── BendWall.glb ├── BendWallOuter.glb ├── BendWallOuterLower.glb ├── BendWallOuterTop.glb ├── BendWallTop.glb ├── Connector.glb ├── Corner.glb ├── CornerFull.glb ├── CornerFullHalfLower.glb ├── CornerHalfLower.glb ├── DoubleSided.glb ├── Edge.glb ├── EdgeHalfLower.glb ├── FlatStairWithWallLeftLowerUper.glb ├── FlatStairWithWallRightUper.glb ├── FlatStairsFreeUper.glb ├── Loop.glb ├── LoopHalfLower.glb ├── StairWithWallLeft.glb ├── StairWithWallRight.glb ├── Stairs.glb ├── StairsLeft.glb ├── StairsRight.glb ├── Wall.glb ├── android-chrome-192x192.png ├── android-chrome-384x384.png ├── apple-touch-icon.png ├── browserconfig.xml ├── environmentMap.hdr ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── fonts │ ├── Redaction_35-Bold.woff2 │ ├── Redaction_35-Regular.woff2 │ ├── Redaction_50-Bold.woff2 │ └── Redaction_50-Regular.woff2 ├── mstile-150x150.png ├── safari-pinned-tab.svg ├── site.webmanifest └── wfc.wasm ├── src ├── components │ ├── body │ │ └── body.tsx │ ├── camera │ │ └── camera.tsx │ ├── constraintsSampler │ │ └── constraintsSampler.tsx │ ├── displayer │ │ └── displayer.tsx │ ├── environment │ │ └── environment.tsx │ ├── generator │ │ ├── fullGenerator.tsx │ │ ├── generator.tsx │ │ ├── loader.tsx │ │ └── stepGenerator.tsx │ ├── header │ │ └── header.tsx │ ├── modelObject │ │ └── modelObject.tsx │ ├── postprocessing │ │ └── postprocessing.tsx │ └── scenes │ │ └── scene.tsx ├── models │ ├── Arch.tsx │ ├── ArchLeft.tsx │ ├── ArchRight.tsx │ ├── BendWall.tsx │ ├── BendWallOuter.tsx │ ├── BendWallOuterLower.tsx │ ├── BendWallOuterTop.tsx │ ├── BendWallTop.tsx │ ├── Connector.tsx │ ├── Corner.tsx │ ├── CornerFull.tsx │ ├── CornerFullHalfLower.tsx │ ├── CornerHalfLower.tsx │ ├── DoubleSided.tsx │ ├── Edge.tsx │ ├── EdgeHalfLower.tsx │ ├── FlatStairWithWallLeftLowerUper.tsx │ ├── FlatStairWithWallRightUper.tsx │ ├── FlatStairsFreeUper.tsx │ ├── Loop.tsx │ ├── LoopHalfLower.tsx │ ├── StairWithWallLeft.tsx │ ├── StairWithWallRight.tsx │ ├── Stairs.tsx │ ├── StairsLeft.tsx │ ├── StairsRight.tsx │ ├── Wall.tsx │ └── constraints.json ├── pages │ ├── _app.tsx │ └── index.tsx ├── stores │ └── generationStore.tsx ├── styles │ └── globals.css ├── utils │ ├── mapNumbers.ts │ ├── useInterval.ts │ └── wfc.ts └── wfc │ └── wfc.js ├── tsconfig.json └── yarn.lock /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-conventional"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier"], 3 | "extends": ["next", "next/core-web-vitals", "prettier"], 4 | "rules": { 5 | "prettier/prettier": "off", 6 | "camelcase": "off", 7 | "import/prefer-default-export": "off", 8 | "react/jsx-filename-extension": "off", 9 | "react/jsx-props-no-spreading": "off", 10 | "react/no-unused-prop-types": "off", 11 | "react/require-default-props": "off", 12 | "import/extensions": [ 13 | "error", 14 | "ignorePackages", 15 | { 16 | "ts": "never", 17 | "tsx": "never", 18 | "js": "never", 19 | "jsx": "never" 20 | } 21 | ], 22 | "quotes": "off", 23 | "jsx-a11y/anchor-is-valid": [ 24 | "error", 25 | { 26 | "components": ["Link"], 27 | "specialLink": ["hrefLeft", "hrefRight"], 28 | "aspects": ["invalidHref", "preferButton"] 29 | } 30 | ] 31 | }, 32 | "overrides": [ 33 | { 34 | "files": "**/*.+(ts|tsx)", 35 | "parser": "@typescript-eslint/parser", 36 | "plugins": ["@typescript-eslint/eslint-plugin"], 37 | "extends": ["plugin:@typescript-eslint/recommended", "prettier"], 38 | "rules": { 39 | "@typescript-eslint/explicit-function-return-type": "off", 40 | "@typescript-eslint/explicit-module-boundary-types": "off", 41 | "@typescript-eslint/ban-ts-comment": "off", 42 | "no-use-before-define": [0], 43 | "@typescript-eslint/no-use-before-define": [1], 44 | "@typescript-eslint/no-explicit-any": "off", 45 | "@typescript-eslint/no-var-requires": "off", 46 | "@typescript-eslint/no-unused-vars": "off", 47 | "@typescript-eslint/quotes": "off", 48 | "@typescript-eslint/no-empty-interface": "off", 49 | "@typescript-eslint/no-inferrable-types": "off", 50 | "react/display-name": "off", 51 | "no-var": "off", 52 | "@typescript-eslint/ban-types": "off", 53 | "@typescript-eslint/no-this-alias": "off" 54 | } 55 | } 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | .yarn/* 37 | !.yarn/patches 38 | !.yarn/plugins 39 | !.yarn/releases 40 | !.yarn/sdks 41 | !.yarn/versions 42 | .pnp.* 43 | 44 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | . "$(dirname "$0")/common.sh" 4 | 5 | yarn commitlint --edit $1 6 | -------------------------------------------------------------------------------- /.husky/common.sh: -------------------------------------------------------------------------------- 1 | command_exists () { 2 | command -v "$1" >/dev/null 2>&1 3 | } 4 | 5 | # Workaround for Windows 10, Git Bash and Yarn 6 | if command_exists winpty && test -t 1; then 7 | exec < /dev/tty 8 | fi 9 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | . "$(dirname "$0")/common.sh" 4 | 5 | yarn lint-staged 6 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | save-exact = true 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "semi": false, 4 | "printWidth": 120 5 | } 6 | -------------------------------------------------------------------------------- /.yarn/plugins/@yarnpkg/plugin-typescript.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | //prettier-ignore 3 | module.exports = { 4 | name: "@yarnpkg/plugin-typescript", 5 | factory: function (require) { 6 | var plugin=(()=>{var Ft=Object.create,H=Object.defineProperty,Bt=Object.defineProperties,Kt=Object.getOwnPropertyDescriptor,zt=Object.getOwnPropertyDescriptors,Gt=Object.getOwnPropertyNames,Q=Object.getOwnPropertySymbols,$t=Object.getPrototypeOf,ne=Object.prototype.hasOwnProperty,De=Object.prototype.propertyIsEnumerable;var Re=(e,t,r)=>t in e?H(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,u=(e,t)=>{for(var r in t||(t={}))ne.call(t,r)&&Re(e,r,t[r]);if(Q)for(var r of Q(t))De.call(t,r)&&Re(e,r,t[r]);return e},g=(e,t)=>Bt(e,zt(t)),Lt=e=>H(e,"__esModule",{value:!0});var R=(e,t)=>{var r={};for(var s in e)ne.call(e,s)&&t.indexOf(s)<0&&(r[s]=e[s]);if(e!=null&&Q)for(var s of Q(e))t.indexOf(s)<0&&De.call(e,s)&&(r[s]=e[s]);return r};var I=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Vt=(e,t)=>{for(var r in t)H(e,r,{get:t[r],enumerable:!0})},Qt=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Gt(t))!ne.call(e,s)&&s!=="default"&&H(e,s,{get:()=>t[s],enumerable:!(r=Kt(t,s))||r.enumerable});return e},C=e=>Qt(Lt(H(e!=null?Ft($t(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var xe=I(J=>{"use strict";Object.defineProperty(J,"__esModule",{value:!0});function _(e){let t=[...e.caches],r=t.shift();return r===void 0?ve():{get(s,n,a={miss:()=>Promise.resolve()}){return r.get(s,n,a).catch(()=>_({caches:t}).get(s,n,a))},set(s,n){return r.set(s,n).catch(()=>_({caches:t}).set(s,n))},delete(s){return r.delete(s).catch(()=>_({caches:t}).delete(s))},clear(){return r.clear().catch(()=>_({caches:t}).clear())}}}function ve(){return{get(e,t,r={miss:()=>Promise.resolve()}){return t().then(n=>Promise.all([n,r.miss(n)])).then(([n])=>n)},set(e,t){return Promise.resolve(t)},delete(e){return Promise.resolve()},clear(){return Promise.resolve()}}}J.createFallbackableCache=_;J.createNullCache=ve});var Ee=I(($s,qe)=>{qe.exports=xe()});var Te=I(ae=>{"use strict";Object.defineProperty(ae,"__esModule",{value:!0});function Jt(e={serializable:!0}){let t={};return{get(r,s,n={miss:()=>Promise.resolve()}){let a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);let o=s(),d=n&&n.miss||(()=>Promise.resolve());return o.then(y=>d(y)).then(()=>o)},set(r,s){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(s):s,Promise.resolve(s)},delete(r){return delete t[JSON.stringify(r)],Promise.resolve()},clear(){return t={},Promise.resolve()}}}ae.createInMemoryCache=Jt});var we=I((Vs,Me)=>{Me.exports=Te()});var Ce=I(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});function Xt(e,t,r){let s={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers(){return e===oe.WithinHeaders?s:{}},queryParameters(){return e===oe.WithinQueryParameters?s:{}}}}function Yt(e){let t=0,r=()=>(t++,new Promise(s=>{setTimeout(()=>{s(e(r))},Math.min(100*t,1e3))}));return e(r)}function ke(e,t=(r,s)=>Promise.resolve()){return Object.assign(e,{wait(r){return ke(e.then(s=>Promise.all([t(s,r),s])).then(s=>s[1]))}})}function Zt(e){let t=e.length-1;for(t;t>0;t--){let r=Math.floor(Math.random()*(t+1)),s=e[t];e[t]=e[r],e[r]=s}return e}function er(e,t){return Object.keys(t!==void 0?t:{}).forEach(r=>{e[r]=t[r](e)}),e}function tr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}var rr="4.2.0",sr=e=>()=>e.transporter.requester.destroy(),oe={WithinQueryParameters:0,WithinHeaders:1};M.AuthMode=oe;M.addMethods=er;M.createAuth=Xt;M.createRetryablePromise=Yt;M.createWaitablePromise=ke;M.destroy=sr;M.encode=tr;M.shuffle=Zt;M.version=rr});var F=I((Js,Ue)=>{Ue.exports=Ce()});var Ne=I(ie=>{"use strict";Object.defineProperty(ie,"__esModule",{value:!0});var nr={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};ie.MethodEnum=nr});var B=I((Ys,We)=>{We.exports=Ne()});var Ze=I(A=>{"use strict";Object.defineProperty(A,"__esModule",{value:!0});var He=B();function ce(e,t){let r=e||{},s=r.data||{};return Object.keys(r).forEach(n=>{["timeout","headers","queryParameters","data","cacheable"].indexOf(n)===-1&&(s[n]=r[n])}),{data:Object.entries(s).length>0?s:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var X={Read:1,Write:2,Any:3},U={Up:1,Down:2,Timeouted:3},_e=2*60*1e3;function ue(e,t=U.Up){return g(u({},e),{status:t,lastUpdate:Date.now()})}function Fe(e){return e.status===U.Up||Date.now()-e.lastUpdate>_e}function Be(e){return e.status===U.Timeouted&&Date.now()-e.lastUpdate<=_e}function le(e){return{protocol:e.protocol||"https",url:e.url,accept:e.accept||X.Any}}function ar(e,t){return Promise.all(t.map(r=>e.get(r,()=>Promise.resolve(ue(r))))).then(r=>{let s=r.filter(d=>Fe(d)),n=r.filter(d=>Be(d)),a=[...s,...n],o=a.length>0?a.map(d=>le(d)):t;return{getTimeout(d,y){return(n.length===0&&d===0?1:n.length+3+d)*y},statelessHosts:o}})}var or=({isTimedOut:e,status:t})=>!e&&~~t==0,ir=e=>{let t=e.status;return e.isTimedOut||or(e)||~~(t/100)!=2&&~~(t/100)!=4},cr=({status:e})=>~~(e/100)==2,ur=(e,t)=>ir(e)?t.onRetry(e):cr(e)?t.onSucess(e):t.onFail(e);function Qe(e,t,r,s){let n=[],a=$e(r,s),o=Le(e,s),d=r.method,y=r.method!==He.MethodEnum.Get?{}:u(u({},r.data),s.data),b=u(u(u({"x-algolia-agent":e.userAgent.value},e.queryParameters),y),s.queryParameters),f=0,p=(h,S)=>{let O=h.pop();if(O===void 0)throw Ve(de(n));let P={data:a,headers:o,method:d,url:Ge(O,r.path,b),connectTimeout:S(f,e.timeouts.connect),responseTimeout:S(f,s.timeout)},x=j=>{let T={request:P,response:j,host:O,triesLeft:h.length};return n.push(T),T},v={onSucess:j=>Ke(j),onRetry(j){let T=x(j);return j.isTimedOut&&f++,Promise.all([e.logger.info("Retryable failure",pe(T)),e.hostsCache.set(O,ue(O,j.isTimedOut?U.Timeouted:U.Down))]).then(()=>p(h,S))},onFail(j){throw x(j),ze(j,de(n))}};return e.requester.send(P).then(j=>ur(j,v))};return ar(e.hostsCache,t).then(h=>p([...h.statelessHosts].reverse(),h.getTimeout))}function lr(e){let{hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,hosts:y,queryParameters:b,headers:f}=e,p={hostsCache:t,logger:r,requester:s,requestsCache:n,responsesCache:a,timeouts:o,userAgent:d,headers:f,queryParameters:b,hosts:y.map(h=>le(h)),read(h,S){let O=ce(S,p.timeouts.read),P=()=>Qe(p,p.hosts.filter(j=>(j.accept&X.Read)!=0),h,O);if((O.cacheable!==void 0?O.cacheable:h.cacheable)!==!0)return P();let v={request:h,mappedRequestOptions:O,transporter:{queryParameters:p.queryParameters,headers:p.headers}};return p.responsesCache.get(v,()=>p.requestsCache.get(v,()=>p.requestsCache.set(v,P()).then(j=>Promise.all([p.requestsCache.delete(v),j]),j=>Promise.all([p.requestsCache.delete(v),Promise.reject(j)])).then(([j,T])=>T)),{miss:j=>p.responsesCache.set(v,j)})},write(h,S){return Qe(p,p.hosts.filter(O=>(O.accept&X.Write)!=0),h,ce(S,p.timeouts.write))}};return p}function dr(e){let t={value:`Algolia for JavaScript (${e})`,add(r){let s=`; ${r.segment}${r.version!==void 0?` (${r.version})`:""}`;return t.value.indexOf(s)===-1&&(t.value=`${t.value}${s}`),t}};return t}function Ke(e){try{return JSON.parse(e.content)}catch(t){throw Je(t.message,e)}}function ze({content:e,status:t},r){let s=e;try{s=JSON.parse(e).message}catch(n){}return Xe(s,t,r)}function pr(e,...t){let r=0;return e.replace(/%s/g,()=>encodeURIComponent(t[r++]))}function Ge(e,t,r){let s=Ye(r),n=`${e.protocol}://${e.url}/${t.charAt(0)==="/"?t.substr(1):t}`;return s.length&&(n+=`?${s}`),n}function Ye(e){let t=r=>Object.prototype.toString.call(r)==="[object Object]"||Object.prototype.toString.call(r)==="[object Array]";return Object.keys(e).map(r=>pr("%s=%s",r,t(e[r])?JSON.stringify(e[r]):e[r])).join("&")}function $e(e,t){if(e.method===He.MethodEnum.Get||e.data===void 0&&t.data===void 0)return;let r=Array.isArray(e.data)?e.data:u(u({},e.data),t.data);return JSON.stringify(r)}function Le(e,t){let r=u(u({},e.headers),t.headers),s={};return Object.keys(r).forEach(n=>{let a=r[n];s[n.toLowerCase()]=a}),s}function de(e){return e.map(t=>pe(t))}function pe(e){let t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return g(u({},e),{request:g(u({},e.request),{headers:u(u({},e.request.headers),t)})})}function Xe(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}function Je(e,t){return{name:"DeserializationError",message:e,response:t}}function Ve(e){return{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:e}}A.CallEnum=X;A.HostStatusEnum=U;A.createApiError=Xe;A.createDeserializationError=Je;A.createMappedRequestOptions=ce;A.createRetryError=Ve;A.createStatefulHost=ue;A.createStatelessHost=le;A.createTransporter=lr;A.createUserAgent=dr;A.deserializeFailure=ze;A.deserializeSuccess=Ke;A.isStatefulHostTimeouted=Be;A.isStatefulHostUp=Fe;A.serializeData=$e;A.serializeHeaders=Le;A.serializeQueryParameters=Ye;A.serializeUrl=Ge;A.stackFrameWithoutCredentials=pe;A.stackTraceWithoutCredentials=de});var K=I((en,et)=>{et.exports=Ze()});var tt=I(w=>{"use strict";Object.defineProperty(w,"__esModule",{value:!0});var N=F(),mr=K(),z=B(),hr=e=>{let t=e.region||"us",r=N.createAuth(N.AuthMode.WithinHeaders,e.appId,e.apiKey),s=mr.createTransporter(g(u({hosts:[{url:`analytics.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n=e.appId;return N.addMethods({appId:n,transporter:s},e.methods)},yr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:"2/abtests",data:t},r),gr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Delete,path:N.encode("2/abtests/%s",t)},r),fr=e=>(t,r)=>e.transporter.read({method:z.MethodEnum.Get,path:N.encode("2/abtests/%s",t)},r),br=e=>t=>e.transporter.read({method:z.MethodEnum.Get,path:"2/abtests"},t),Pr=e=>(t,r)=>e.transporter.write({method:z.MethodEnum.Post,path:N.encode("2/abtests/%s/stop",t)},r);w.addABTest=yr;w.createAnalyticsClient=hr;w.deleteABTest=gr;w.getABTest=fr;w.getABTests=br;w.stopABTest=Pr});var st=I((rn,rt)=>{rt.exports=tt()});var at=I(G=>{"use strict";Object.defineProperty(G,"__esModule",{value:!0});var me=F(),jr=K(),nt=B(),Or=e=>{let t=e.region||"us",r=me.createAuth(me.AuthMode.WithinHeaders,e.appId,e.apiKey),s=jr.createTransporter(g(u({hosts:[{url:`recommendation.${t}.algolia.com`}]},e),{headers:u(g(u({},r.headers()),{"content-type":"application/json"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)}));return me.addMethods({appId:e.appId,transporter:s},e.methods)},Ir=e=>t=>e.transporter.read({method:nt.MethodEnum.Get,path:"1/strategies/personalization"},t),Ar=e=>(t,r)=>e.transporter.write({method:nt.MethodEnum.Post,path:"1/strategies/personalization",data:t},r);G.createRecommendationClient=Or;G.getPersonalizationStrategy=Ir;G.setPersonalizationStrategy=Ar});var it=I((nn,ot)=>{ot.exports=at()});var jt=I(i=>{"use strict";Object.defineProperty(i,"__esModule",{value:!0});var l=F(),q=K(),m=B(),Sr=require("crypto");function Y(e){let t=r=>e.request(r).then(s=>{if(e.batch!==void 0&&e.batch(s.hits),!e.shouldStop(s))return s.cursor?t({cursor:s.cursor}):t({page:(r.page||0)+1})});return t({})}var Dr=e=>{let t=e.appId,r=l.createAuth(e.authMode!==void 0?e.authMode:l.AuthMode.WithinHeaders,t,e.apiKey),s=q.createTransporter(g(u({hosts:[{url:`${t}-dsn.algolia.net`,accept:q.CallEnum.Read},{url:`${t}.algolia.net`,accept:q.CallEnum.Write}].concat(l.shuffle([{url:`${t}-1.algolianet.com`},{url:`${t}-2.algolianet.com`},{url:`${t}-3.algolianet.com`}]))},e),{headers:u(g(u({},r.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:u(u({},r.queryParameters()),e.queryParameters)})),n={transporter:s,appId:t,addAlgoliaAgent(a,o){s.userAgent.add({segment:a,version:o})},clearCache(){return Promise.all([s.requestsCache.clear(),s.responsesCache.clear()]).then(()=>{})}};return l.addMethods(n,e.methods)};function ct(){return{name:"MissingObjectIDError",message:"All objects must have an unique objectID (like a primary key) to be valid. Algolia is also able to generate objectIDs automatically but *it's not recommended*. To do it, use the `{'autoGenerateObjectIDIfNotExist': true}` option."}}function ut(){return{name:"ObjectNotFoundError",message:"Object not found."}}function lt(){return{name:"ValidUntilNotFoundError",message:"ValidUntil not found in given secured api key."}}var Rr=e=>(t,r)=>{let d=r||{},{queryParameters:s}=d,n=R(d,["queryParameters"]),a=u({acl:t},s!==void 0?{queryParameters:s}:{}),o=(y,b)=>l.createRetryablePromise(f=>$(e)(y.key,b).catch(p=>{if(p.status!==404)throw p;return f()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/keys",data:a},n),o)},vr=e=>(t,r,s)=>{let n=q.createMappedRequestOptions(s);return n.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping",data:{cluster:r}},n)},xr=e=>(t,r,s)=>e.transporter.write({method:m.MethodEnum.Post,path:"1/clusters/mapping/batch",data:{users:t,cluster:r}},s),Z=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"copy",destination:r}},s),n)},qr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Rules]})),Er=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Settings]})),Tr=e=>(t,r,s)=>Z(e)(t,r,g(u({},s),{scope:[ee.Synonyms]})),Mr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).then(o).catch(d=>{if(d.status!==404)throw d}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/keys/%s",t)},r),s)},wr=()=>(e,t)=>{let r=q.serializeQueryParameters(t),s=Sr.createHmac("sha256",e).update(r).digest("hex");return Buffer.from(s+r).toString("base64")},$=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/keys/%s",t)},r),kr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/logs"},t),Cr=()=>e=>{let t=Buffer.from(e,"base64").toString("ascii"),r=/validUntil=(\d+)/,s=t.match(r);if(s===null)throw lt();return parseInt(s[1],10)-Math.round(new Date().getTime()/1e3)},Ur=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/top"},t),Nr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/clusters/mapping/%s",t)},r),Wr=e=>t=>{let n=t||{},{retrieveMappings:r}=n,s=R(n,["retrieveMappings"]);return r===!0&&(s.getClusters=!0),e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping/pending"},s)},L=e=>(t,r={})=>{let s={transporter:e.transporter,appId:e.appId,indexName:t};return l.addMethods(s,r.methods)},Hr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/keys"},t),_r=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters"},t),Fr=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/indexes"},t),Br=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:"1/clusters/mapping"},t),Kr=e=>(t,r,s)=>{let n=(a,o)=>L(e)(t,{methods:{waitTask:D}}).waitTask(a.taskID,o);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",t),data:{operation:"move",destination:r}},s),n)},zr=e=>(t,r)=>{let s=(n,a)=>Promise.all(Object.keys(n.taskID).map(o=>L(e)(o,{methods:{waitTask:D}}).waitTask(n.taskID[o],a)));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:"1/indexes/*/batch",data:{requests:t}},r),s)},Gr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:t}},r),$r=e=>(t,r)=>{let s=t.map(n=>g(u({},n),{params:q.serializeQueryParameters(n.params||{})}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/queries",data:{requests:s},cacheable:!0},r)},Lr=e=>(t,r)=>Promise.all(t.map(s=>{let d=s.params,{facetName:n,facetQuery:a}=d,o=R(d,["facetName","facetQuery"]);return L(e)(s.indexName,{methods:{searchForFacetValues:dt}}).searchForFacetValues(n,a,u(u({},r),o))})),Vr=e=>(t,r)=>{let s=q.createMappedRequestOptions(r);return s.queryParameters["X-Algolia-User-ID"]=t,e.transporter.write({method:m.MethodEnum.Delete,path:"1/clusters/mapping"},s)},Qr=e=>(t,r)=>{let s=(n,a)=>l.createRetryablePromise(o=>$(e)(t,a).catch(d=>{if(d.status!==404)throw d;return o()}));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/keys/%s/restore",t)},r),s)},Jr=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:"1/clusters/mapping/search",data:{query:t}},r),Xr=e=>(t,r)=>{let s=Object.assign({},r),f=r||{},{queryParameters:n}=f,a=R(f,["queryParameters"]),o=n?{queryParameters:n}:{},d=["acl","indexes","referers","restrictSources","queryParameters","description","maxQueriesPerIPPerHour","maxHitsPerQuery"],y=p=>Object.keys(s).filter(h=>d.indexOf(h)!==-1).every(h=>p[h]===s[h]),b=(p,h)=>l.createRetryablePromise(S=>$(e)(t,h).then(O=>y(O)?Promise.resolve():S()));return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/keys/%s",t),data:o},a),b)},pt=e=>(t,r)=>{let s=(n,a)=>D(e)(n.taskID,a);return l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/batch",e.indexName),data:{requests:t}},r),s)},Yr=e=>t=>Y(g(u({},t),{shouldStop:r=>r.cursor===void 0,request:r=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/browse",e.indexName),data:r},t)})),Zr=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},es=e=>t=>{let r=u({hitsPerPage:1e3},t);return Y(g(u({},r),{shouldStop:s=>s.hits.lengthg(u({},n),{hits:n.hits.map(a=>(delete a._highlightResult,a))}))}}))},te=e=>(t,r,s)=>{let y=s||{},{batchSize:n}=y,a=R(y,["batchSize"]),o={taskIDs:[],objectIDs:[]},d=(b=0)=>{let f=[],p;for(p=b;p({action:r,body:h})),a).then(h=>(o.objectIDs=o.objectIDs.concat(h.objectIDs),o.taskIDs.push(h.taskID),p++,d(p)))};return l.createWaitablePromise(d(),(b,f)=>Promise.all(b.taskIDs.map(p=>D(e)(p,f))))},ts=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/clear",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),rs=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ss=e=>t=>{let a=t||{},{forwardToReplicas:r}=a,s=R(a,["forwardToReplicas"]),n=q.createMappedRequestOptions(s);return r&&(n.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/clear",e.indexName)},n),(o,d)=>D(e)(o.taskID,d))},ns=e=>(t,r)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/deleteByQuery",e.indexName),data:t},r),(s,n)=>D(e)(s.taskID,n)),as=e=>t=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s",e.indexName)},t),(r,s)=>D(e)(r.taskID,s)),os=e=>(t,r)=>l.createWaitablePromise(yt(e)([t],r).then(s=>({taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),yt=e=>(t,r)=>{let s=t.map(n=>({objectID:n}));return te(e)(s,k.DeleteObject,r)},is=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},cs=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Delete,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},a),(d,y)=>D(e)(d.taskID,y))},us=e=>t=>gt(e)(t).then(()=>!0).catch(r=>{if(r.status!==404)throw r;return!1}),ls=e=>(t,r)=>{let y=r||{},{query:s,paginate:n}=y,a=R(y,["query","paginate"]),o=0,d=()=>ft(e)(s||"",g(u({},a),{page:o})).then(b=>{for(let[f,p]of Object.entries(b.hits))if(t(p))return{object:p,position:parseInt(f,10),page:o};if(o++,n===!1||o>=b.nbPages)throw ut();return d()});return d()},ds=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/%s",e.indexName,t)},r),ps=()=>(e,t)=>{for(let[r,s]of Object.entries(e.hits))if(s.objectID===t)return parseInt(r,10);return-1},ms=e=>(t,r)=>{let o=r||{},{attributesToRetrieve:s}=o,n=R(o,["attributesToRetrieve"]),a=t.map(d=>u({indexName:e.indexName,objectID:d},s?{attributesToRetrieve:s}:{}));return e.transporter.read({method:m.MethodEnum.Post,path:"1/indexes/*/objects",data:{requests:a}},n)},hs=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/rules/%s",e.indexName,t)},r),gt=e=>t=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/settings",e.indexName),data:{getVersion:2}},t),ys=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/synonyms/%s",e.indexName,t)},r),bt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Get,path:l.encode("1/indexes/%s/task/%s",e.indexName,t.toString())},r),gs=e=>(t,r)=>l.createWaitablePromise(Pt(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),Pt=e=>(t,r)=>{let o=r||{},{createIfNotExists:s}=o,n=R(o,["createIfNotExists"]),a=s?k.PartialUpdateObject:k.PartialUpdateObjectNoCreate;return te(e)(t,a,n)},fs=e=>(t,r)=>{let O=r||{},{safe:s,autoGenerateObjectIDIfNotExist:n,batchSize:a}=O,o=R(O,["safe","autoGenerateObjectIDIfNotExist","batchSize"]),d=(P,x,v,j)=>l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/operation",P),data:{operation:v,destination:x}},j),(T,V)=>D(e)(T.taskID,V)),y=Math.random().toString(36).substring(7),b=`${e.indexName}_tmp_${y}`,f=he({appId:e.appId,transporter:e.transporter,indexName:b}),p=[],h=d(e.indexName,b,"copy",g(u({},o),{scope:["settings","synonyms","rules"]}));p.push(h);let S=(s?h.wait(o):h).then(()=>{let P=f(t,g(u({},o),{autoGenerateObjectIDIfNotExist:n,batchSize:a}));return p.push(P),s?P.wait(o):P}).then(()=>{let P=d(b,e.indexName,"move",o);return p.push(P),s?P.wait(o):P}).then(()=>Promise.all(p)).then(([P,x,v])=>({objectIDs:x.objectIDs,taskIDs:[P.taskID,...x.taskIDs,v.taskID]}));return l.createWaitablePromise(S,(P,x)=>Promise.all(p.map(v=>v.wait(x))))},bs=e=>(t,r)=>ye(e)(t,g(u({},r),{clearExistingRules:!0})),Ps=e=>(t,r)=>ge(e)(t,g(u({},r),{replaceExistingSynonyms:!0})),js=e=>(t,r)=>l.createWaitablePromise(he(e)([t],r).then(s=>({objectID:s.objectIDs[0],taskID:s.taskIDs[0]})),(s,n)=>D(e)(s.taskID,n)),he=e=>(t,r)=>{let o=r||{},{autoGenerateObjectIDIfNotExist:s}=o,n=R(o,["autoGenerateObjectIDIfNotExist"]),a=s?k.AddObject:k.UpdateObject;if(a===k.UpdateObject){for(let d of t)if(d.objectID===void 0)return l.createWaitablePromise(Promise.reject(ct()))}return te(e)(t,a,n)},Os=e=>(t,r)=>ye(e)([t],r),ye=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,clearExistingRules:n}=d,a=R(d,["forwardToReplicas","clearExistingRules"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.clearExistingRules=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},Is=e=>(t,r)=>ge(e)([t],r),ge=e=>(t,r)=>{let d=r||{},{forwardToReplicas:s,replaceExistingSynonyms:n}=d,a=R(d,["forwardToReplicas","replaceExistingSynonyms"]),o=q.createMappedRequestOptions(a);return s&&(o.queryParameters.forwardToReplicas=1),n&&(o.queryParameters.replaceExistingSynonyms=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/batch",e.indexName),data:t},o),(y,b)=>D(e)(y.taskID,b))},ft=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r),dt=e=>(t,r,s)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},s),mt=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/rules/search",e.indexName),data:{query:t}},r),ht=e=>(t,r)=>e.transporter.read({method:m.MethodEnum.Post,path:l.encode("1/indexes/%s/synonyms/search",e.indexName),data:{query:t}},r),As=e=>(t,r)=>{let o=r||{},{forwardToReplicas:s}=o,n=R(o,["forwardToReplicas"]),a=q.createMappedRequestOptions(n);return s&&(a.queryParameters.forwardToReplicas=1),l.createWaitablePromise(e.transporter.write({method:m.MethodEnum.Put,path:l.encode("1/indexes/%s/settings",e.indexName),data:t},a),(d,y)=>D(e)(d.taskID,y))},D=e=>(t,r)=>l.createRetryablePromise(s=>bt(e)(t,r).then(n=>n.status!=="published"?s():void 0)),Ss={AddObject:"addObject",Analytics:"analytics",Browser:"browse",DeleteIndex:"deleteIndex",DeleteObject:"deleteObject",EditSettings:"editSettings",ListIndexes:"listIndexes",Logs:"logs",Recommendation:"recommendation",Search:"search",SeeUnretrievableAttributes:"seeUnretrievableAttributes",Settings:"settings",Usage:"usage"},k={AddObject:"addObject",UpdateObject:"updateObject",PartialUpdateObject:"partialUpdateObject",PartialUpdateObjectNoCreate:"partialUpdateObjectNoCreate",DeleteObject:"deleteObject"},ee={Settings:"settings",Synonyms:"synonyms",Rules:"rules"},Ds={None:"none",StopIfEnoughMatches:"stopIfEnoughMatches"},Rs={Synonym:"synonym",OneWaySynonym:"oneWaySynonym",AltCorrection1:"altCorrection1",AltCorrection2:"altCorrection2",Placeholder:"placeholder"};i.ApiKeyACLEnum=Ss;i.BatchActionEnum=k;i.ScopeEnum=ee;i.StrategyEnum=Ds;i.SynonymEnum=Rs;i.addApiKey=Rr;i.assignUserID=vr;i.assignUserIDs=xr;i.batch=pt;i.browseObjects=Yr;i.browseRules=Zr;i.browseSynonyms=es;i.chunkedBatch=te;i.clearObjects=ts;i.clearRules=rs;i.clearSynonyms=ss;i.copyIndex=Z;i.copyRules=qr;i.copySettings=Er;i.copySynonyms=Tr;i.createBrowsablePromise=Y;i.createMissingObjectIDError=ct;i.createObjectNotFoundError=ut;i.createSearchClient=Dr;i.createValidUntilNotFoundError=lt;i.deleteApiKey=Mr;i.deleteBy=ns;i.deleteIndex=as;i.deleteObject=os;i.deleteObjects=yt;i.deleteRule=is;i.deleteSynonym=cs;i.exists=us;i.findObject=ls;i.generateSecuredApiKey=wr;i.getApiKey=$;i.getLogs=kr;i.getObject=ds;i.getObjectPosition=ps;i.getObjects=ms;i.getRule=hs;i.getSecuredApiKeyRemainingValidity=Cr;i.getSettings=gt;i.getSynonym=ys;i.getTask=bt;i.getTopUserIDs=Ur;i.getUserID=Nr;i.hasPendingMappings=Wr;i.initIndex=L;i.listApiKeys=Hr;i.listClusters=_r;i.listIndices=Fr;i.listUserIDs=Br;i.moveIndex=Kr;i.multipleBatch=zr;i.multipleGetObjects=Gr;i.multipleQueries=$r;i.multipleSearchForFacetValues=Lr;i.partialUpdateObject=gs;i.partialUpdateObjects=Pt;i.removeUserID=Vr;i.replaceAllObjects=fs;i.replaceAllRules=bs;i.replaceAllSynonyms=Ps;i.restoreApiKey=Qr;i.saveObject=js;i.saveObjects=he;i.saveRule=Os;i.saveRules=ye;i.saveSynonym=Is;i.saveSynonyms=ge;i.search=ft;i.searchForFacetValues=dt;i.searchRules=mt;i.searchSynonyms=ht;i.searchUserIDs=Jr;i.setSettings=As;i.updateApiKey=Xr;i.waitTask=D});var It=I((on,Ot)=>{Ot.exports=jt()});var At=I(re=>{"use strict";Object.defineProperty(re,"__esModule",{value:!0});function vs(){return{debug(e,t){return Promise.resolve()},info(e,t){return Promise.resolve()},error(e,t){return Promise.resolve()}}}var xs={Debug:1,Info:2,Error:3};re.LogLevelEnum=xs;re.createNullLogger=vs});var Dt=I((un,St)=>{St.exports=At()});var xt=I(fe=>{"use strict";Object.defineProperty(fe,"__esModule",{value:!0});var Rt=require("http"),vt=require("https"),qs=require("url");function Es(){let e={keepAlive:!0},t=new Rt.Agent(e),r=new vt.Agent(e);return{send(s){return new Promise(n=>{let a=qs.parse(s.url),o=a.query===null?a.pathname:`${a.pathname}?${a.query}`,d=u({agent:a.protocol==="https:"?r:t,hostname:a.hostname,path:o,method:s.method,headers:s.headers},a.port!==void 0?{port:a.port||""}:{}),y=(a.protocol==="https:"?vt:Rt).request(d,h=>{let S="";h.on("data",O=>S+=O),h.on("end",()=>{clearTimeout(f),clearTimeout(p),n({status:h.statusCode||0,content:S,isTimedOut:!1})})}),b=(h,S)=>setTimeout(()=>{y.abort(),n({status:0,content:S,isTimedOut:!0})},h*1e3),f=b(s.connectTimeout,"Connection timeout"),p;y.on("error",h=>{clearTimeout(f),clearTimeout(p),n({status:0,content:h.message,isTimedOut:!1})}),y.once("response",()=>{clearTimeout(f),p=b(s.responseTimeout,"Socket timeout")}),s.data!==void 0&&y.write(s.data),y.end()})},destroy(){return t.destroy(),r.destroy(),Promise.resolve()}}}fe.createNodeHttpRequester=Es});var Et=I((dn,qt)=>{qt.exports=xt()});var kt=I((pn,Tt)=>{"use strict";var Mt=Ee(),Ts=we(),W=st(),be=F(),Pe=it(),c=It(),Ms=Dt(),ws=Et(),ks=K();function wt(e,t,r){let s={appId:e,apiKey:t,timeouts:{connect:2,read:5,write:30},requester:ws.createNodeHttpRequester(),logger:Ms.createNullLogger(),responsesCache:Mt.createNullCache(),requestsCache:Mt.createNullCache(),hostsCache:Ts.createInMemoryCache(),userAgent:ks.createUserAgent(be.version).add({segment:"Node.js",version:process.versions.node})};return c.createSearchClient(g(u(u({},s),r),{methods:{search:c.multipleQueries,searchForFacetValues:c.multipleSearchForFacetValues,multipleBatch:c.multipleBatch,multipleGetObjects:c.multipleGetObjects,multipleQueries:c.multipleQueries,copyIndex:c.copyIndex,copySettings:c.copySettings,copyRules:c.copyRules,copySynonyms:c.copySynonyms,moveIndex:c.moveIndex,listIndices:c.listIndices,getLogs:c.getLogs,listClusters:c.listClusters,multipleSearchForFacetValues:c.multipleSearchForFacetValues,getApiKey:c.getApiKey,addApiKey:c.addApiKey,listApiKeys:c.listApiKeys,updateApiKey:c.updateApiKey,deleteApiKey:c.deleteApiKey,restoreApiKey:c.restoreApiKey,assignUserID:c.assignUserID,assignUserIDs:c.assignUserIDs,getUserID:c.getUserID,searchUserIDs:c.searchUserIDs,listUserIDs:c.listUserIDs,getTopUserIDs:c.getTopUserIDs,removeUserID:c.removeUserID,hasPendingMappings:c.hasPendingMappings,generateSecuredApiKey:c.generateSecuredApiKey,getSecuredApiKeyRemainingValidity:c.getSecuredApiKeyRemainingValidity,destroy:be.destroy,initIndex:n=>a=>c.initIndex(n)(a,{methods:{batch:c.batch,delete:c.deleteIndex,getObject:c.getObject,getObjects:c.getObjects,saveObject:c.saveObject,saveObjects:c.saveObjects,search:c.search,searchForFacetValues:c.searchForFacetValues,waitTask:c.waitTask,setSettings:c.setSettings,getSettings:c.getSettings,partialUpdateObject:c.partialUpdateObject,partialUpdateObjects:c.partialUpdateObjects,deleteObject:c.deleteObject,deleteObjects:c.deleteObjects,deleteBy:c.deleteBy,clearObjects:c.clearObjects,browseObjects:c.browseObjects,getObjectPosition:c.getObjectPosition,findObject:c.findObject,exists:c.exists,saveSynonym:c.saveSynonym,saveSynonyms:c.saveSynonyms,getSynonym:c.getSynonym,searchSynonyms:c.searchSynonyms,browseSynonyms:c.browseSynonyms,deleteSynonym:c.deleteSynonym,clearSynonyms:c.clearSynonyms,replaceAllObjects:c.replaceAllObjects,replaceAllSynonyms:c.replaceAllSynonyms,searchRules:c.searchRules,getRule:c.getRule,deleteRule:c.deleteRule,saveRule:c.saveRule,saveRules:c.saveRules,replaceAllRules:c.replaceAllRules,browseRules:c.browseRules,clearRules:c.clearRules}}),initAnalytics:()=>n=>W.createAnalyticsClient(g(u(u({},s),n),{methods:{addABTest:W.addABTest,getABTest:W.getABTest,getABTests:W.getABTests,stopABTest:W.stopABTest,deleteABTest:W.deleteABTest}})),initRecommendation:()=>n=>Pe.createRecommendationClient(g(u(u({},s),n),{methods:{getPersonalizationStrategy:Pe.getPersonalizationStrategy,setPersonalizationStrategy:Pe.setPersonalizationStrategy}}))}}))}wt.version=be.version;Tt.exports=wt});var Ut=I((mn,je)=>{var Ct=kt();je.exports=Ct;je.exports.default=Ct});var Ws={};Vt(Ws,{default:()=>Ks});var Oe=C(require("@yarnpkg/core")),E=C(require("@yarnpkg/core")),Ie=C(require("@yarnpkg/plugin-essentials")),Ht=C(require("semver"));var se=C(require("@yarnpkg/core")),Nt=C(Ut()),Cs="e8e1bd300d860104bb8c58453ffa1eb4",Us="OFCNCOG2CU",Wt=async(e,t)=>{var a;let r=se.structUtils.stringifyIdent(e),n=Ns(t).initIndex("npm-search");try{return((a=(await n.getObject(r,{attributesToRetrieve:["types"]})).types)==null?void 0:a.ts)==="definitely-typed"}catch(o){return!1}},Ns=e=>(0,Nt.default)(Us,Cs,{requester:{async send(r){try{let s=await se.httpUtils.request(r.url,r.data||null,{configuration:e,headers:r.headers});return{content:s.body,isTimedOut:!1,status:s.statusCode}}catch(s){return{content:s.response.body,isTimedOut:!1,status:s.response.statusCode}}}}});var _t=e=>e.scope?`${e.scope}__${e.name}`:`${e.name}`,Hs=async(e,t,r,s)=>{if(r.scope==="types")return;let{project:n}=e,{configuration:a}=n,o=a.makeResolver(),d={project:n,resolver:o,report:new E.ThrowReport};if(!await Wt(r,a))return;let b=_t(r),f=E.structUtils.parseRange(r.range).selector;if(!E.semverUtils.validRange(f)){let P=await o.getCandidates(r,new Map,d);f=E.structUtils.parseRange(P[0].reference).selector}let p=Ht.default.coerce(f);if(p===null)return;let h=`${Ie.suggestUtils.Modifier.CARET}${p.major}`,S=E.structUtils.makeDescriptor(E.structUtils.makeIdent("types",b),h),O=E.miscUtils.mapAndFind(n.workspaces,P=>{var T,V;let x=(T=P.manifest.dependencies.get(r.identHash))==null?void 0:T.descriptorHash,v=(V=P.manifest.devDependencies.get(r.identHash))==null?void 0:V.descriptorHash;if(x!==r.descriptorHash&&v!==r.descriptorHash)return E.miscUtils.mapAndFind.skip;let j=[];for(let Ae of Oe.Manifest.allDependencies){let Se=P.manifest[Ae].get(S.identHash);typeof Se!="undefined"&&j.push([Ae,Se])}return j.length===0?E.miscUtils.mapAndFind.skip:j});if(typeof O!="undefined")for(let[P,x]of O)e.manifest[P].set(x.identHash,x);else{try{if((await o.getCandidates(S,new Map,d)).length===0)return}catch{return}e.manifest[Ie.suggestUtils.Target.DEVELOPMENT].set(S.identHash,S)}},_s=async(e,t,r)=>{if(r.scope==="types")return;let s=_t(r),n=E.structUtils.makeIdent("types",s);for(let a of Oe.Manifest.allDependencies)typeof e.manifest[a].get(n.identHash)!="undefined"&&e.manifest[a].delete(n.identHash)},Fs=(e,t)=>{t.publishConfig&&t.publishConfig.typings&&(t.typings=t.publishConfig.typings),t.publishConfig&&t.publishConfig.types&&(t.types=t.publishConfig.types)},Bs={hooks:{afterWorkspaceDependencyAddition:Hs,afterWorkspaceDependencyRemoval:_s,beforeWorkspacePacking:Fs}},Ks=Bs;return Ws;})(); 7 | return plugin; 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Infinite World Generation 2 | 3 | > Demo of the wave form collapse (WFC) algorithm with react three fiber and web assembly (WASM) [Tweet][tweet] 4 | 5 | 6 | https://user-images.githubusercontent.com/9963865/158373612-9377a198-a6fe-454f-8d7d-085650761d01.mov 7 | 8 | 9 | The WFC algorithm is part of the family of procedural algorithms and allows to construct object grids that follow human designed neighbouring rules. 10 | It was first introduced by [Maxim Gumin][original] and apated for 3D by many others such as in the [Stålberg experiments][stahlberg] or [generative cities][city]. 11 | This project provides a baseline of the WFC algorithm in a flexible but still a very performant manner. 12 | We present a pipeline containing three parts the fast flexible WFC WASM implementation, a model and adjancency exporter and a demo that showcases the results and interacts with the WFC WASM. 13 | In this repository one will find the adjancency exporter, the compiled WASM and the demo. 14 | The demo can be tested at https://inftyworld.vercel.app/. 15 | 16 | ## Features 17 | The WFC WASM version features a 32x16x32 3D solver, with a run and a run step mode. 18 | Voxels can be preset to set the floor or pad the walls. 19 | Additionaly a sampling rate of objects can be set to force certain models over others, this is usefull to create for example more sparse results. 20 | The solver features a backtracking step, to avoid getting stuck in unsolvable situations. 21 | For the exporter part of the pipeline we used blender to model the objects. 22 | One is able to export the models and adjacency examples with the provided python scripts. 23 | The results of the compination of the exporter and the WASM can be viewed in the demo, which also has a generate and a step mode. 24 | Models can be exported and smapling rate can be changed. 25 | 26 | ## Contents 27 | In the following you find a short description of the most important files that are in connection with WFC. 28 | Files that are not named here are either config files or supporting structure to render and display the results. 29 | 30 | ``` 31 | . 32 | ├── public 33 | │ ├── ... .glb # All models glb files 34 | │ ├── wfc.wasm # Web assembly wave form collapse 35 | │ └── constraint.json # Adjacency constraints 36 | │ 37 | ├── src 38 | │ ├── components 39 | │ │ ├── generator # Generator files loading and using WFC 40 | │ │ └── displayer # Displayer of generated WFC structures 41 | │ ├── models # All models tsx files 42 | │ └── wfc # Emscripten WFC javascript module 43 | │ 44 | ├── stores 45 | │ └── generationStore.tsx # Config for WFC such as size and samples 46 | │ 47 | └── blender 48 | ├── infty.blend # Blender file with objects and scripts 49 | ├── nameExporter.py # Name exporter to copy paste in javascript 50 | ├── constraintExporter.py # Constraint exporter for adjacency 51 | ├── objectExporter.py # Object exportet for models 52 | └── gltfjsxify.sh # TSX file generator from glb files 53 | ``` 54 | 55 | 56 | ### Misc 57 | 58 | This project was part of the Computer Graphics [internship][praktikum] by the university of Tübingen. 59 | Big thanks to [Martin Donald][martinDonald] for his amazing [tutorial][youtube] as well as [Oskar Stålberg][oskarStahlberg] and [Marian Kleineberg][marian] for their inspiration. 60 | 61 | 62 | 63 | 64 | [stahlberg]: https://www.youtube.com/watch?v=0bcZb-SsnrA 65 | [youtube]: https://www.youtube.com/watch?v=2SuvO4Gi7uY 66 | [martinDonald]: https://twitter.com/bolddunkley 67 | [oskarStahlberg]: https://twitter.com/osksta 68 | [city]: https://marian42.de/article/wfc/ 69 | [marian]: https://twitter.com/marian42_ 70 | [original]: https://github.com/mxgmn/WaveFunctionCollapse 71 | [praktikum]: https://uni-tuebingen.de/fakultaeten/mathematisch-naturwissenschaftliche-fakultaet/fachbereiche/informatik/lehrstuehle/computergrafik/lehrstuhl/lehre/praktikum-computergrafik/ 72 | [tweet]: https://twitter.com/JDihlmann/status/1511717277959442432?s=20&t=UFAo1s9EnVkQ7GC3kXmQfw 73 | -------------------------------------------------------------------------------- /blender/constraintExporter.py: -------------------------------------------------------------------------------- 1 | import os 2 | import bpy 3 | import math 4 | import json 5 | import numpy as np 6 | 7 | 8 | class ConstraintExporter: 9 | 10 | grid = None 11 | bounds = None 12 | constraints = [] 13 | 14 | 15 | def __init__(self, bounds): 16 | self.bounds = bounds 17 | self.cartographRegion() 18 | self.generateConstraints() 19 | 20 | def export(self, path): 21 | with open(path + "constraints.json", "w") as outfile: 22 | json_object = json.dump(self.constraints, outfile, indent = 4) 23 | # print(json_object) 24 | 25 | 26 | 27 | def cartographRegion(self): 28 | """ 29 | Cartographs region of voxels in the blender view by storing 30 | detected object references in a voxel matrix 31 | """ 32 | 33 | # Bound sizes 34 | sizeX = self.bounds["x"][1] - self.bounds["x"][0] 35 | sizeY = self.bounds["y"][1] - self.bounds["y"][0] 36 | sizeZ = self.bounds["z"][1] - self.bounds["z"][0] 37 | 38 | # Create voxel matrix 39 | voxelGrid = np.zeros([sizeX, sizeY, sizeZ]).tolist() 40 | 41 | # Scene Objects 42 | objects = bpy.context.scene.objects 43 | 44 | # Iterate through objects 45 | for collection in bpy.data.collections: 46 | if collection.name == "Constrains": 47 | for obj in collection.all_objects: 48 | 49 | if (obj.name.split(".")[0] != "Connector"): 50 | 51 | # Voxel anchor coords 52 | x = math.floor(obj.location.x) 53 | y = math.floor(obj.location.y) 54 | z = math.floor(obj.location.z) 55 | 56 | if self.isInBounds(x, y, z): 57 | voxelGrid[x][y][z] = obj 58 | 59 | # Iterate through Connector 60 | for collection in bpy.data.collections: 61 | if collection.name == "Constrains": 62 | for obj in collection.all_objects: 63 | 64 | if (obj.name.split(".")[0] == "Connector"): 65 | 66 | # Voxel anchor coords 67 | x = math.floor(obj.location.x) 68 | y = math.floor(obj.location.y) 69 | z = math.floor(obj.location.z) 70 | 71 | if self.isInBounds(x, y, z): 72 | if(voxelGrid[x][y][z] == 0): 73 | voxelGrid[x][y][z] = obj 74 | 75 | self.grid = voxelGrid 76 | 77 | 78 | def generateConstraints(self): 79 | """ 80 | Generates the constraint object for cartographed objects. 81 | """ 82 | 83 | constraints = {} 84 | 85 | # Add empty element 86 | empty = {} 87 | for dx in [-1, 0, 1]: 88 | for dy in [-1, 0, 1]: 89 | for dz in [-1, 0, 1]: 90 | if abs(dx) + abs(dy) + abs(dz) == 1: # Change to != 0 91 | empty[str(dx) + "_" + str(dy) + "_" + str(dz)] = [] 92 | 93 | constraints["Empty"] = empty 94 | 95 | # Add floor elements 96 | floor = {} 97 | for dx in [-1, 0, 1]: 98 | for dy in [-1, 0, 1]: 99 | for dz in [-1, 0, 1]: 100 | if abs(dx) + abs(dy) + abs(dz) == 1: # Change to != 0 101 | if dy == 0: 102 | floor[str(dx) + "_" + str(dy) + "_" + str(dz)] = ["Floor"] 103 | else : 104 | floor[str(dx) + "_" + str(dy) + "_" + str(dz)] = [] 105 | 106 | constraints["Floor"] = floor 107 | 108 | for x in range(0, len(self.grid)): 109 | for y in range(0, len(self.grid[x])): 110 | for z in range(0, len(self.grid[x][y])): 111 | for r in [0, 1, 2, 3]: 112 | parsedObject = self.parseGridObject(x, y, z, r) 113 | adjacency = self.getObjectAdjacency(x, y, z, r) 114 | 115 | 116 | if parsedObject in constraints: 117 | for key in adjacency: 118 | if adjacency[key] != None: 119 | if adjacency[key] not in constraints[parsedObject][key]: 120 | constraints[parsedObject][key].append(adjacency[key]) 121 | 122 | if adjacency[key] == "Floor": 123 | iKey = key.split("_")[0] + "_1_" + key.split("_")[2] 124 | if parsedObject not in constraints["Floor"][iKey]: 125 | constraints["Floor"][iKey].append(parsedObject) 126 | 127 | else: 128 | constraints[parsedObject] = {} 129 | for key in adjacency: 130 | if adjacency[key] != None: 131 | constraints[parsedObject][key] = [adjacency[key]] 132 | if adjacency[key] == "Floor": 133 | iKey = key.split("_")[0] + "_1_" + key.split("_")[2] 134 | if parsedObject not in constraints["Floor"][iKey]: 135 | constraints["Floor"][iKey].append(parsedObject) 136 | else: 137 | constraints[parsedObject][key] = [] 138 | if adjacency[key] == "Floor": 139 | iKey = key.split("_")[0] + "_1_" + key.split("_")[2] 140 | if parsedObject not in constraints["Floor"][iKey]: 141 | constraints["Floor"][iKey].append(parsedObject) 142 | 143 | self.constraints = constraints 144 | 145 | 146 | def getObjectAdjacency(self, x, y, z, r): 147 | """ 148 | Returns the object adjacency for a given voxel 149 | """ 150 | 151 | if(self.grid == None): 152 | return None 153 | 154 | adjacency = {} 155 | 156 | if r == 0: 157 | for dx in [-1, 0, 1]: 158 | for dy in [-1, 0, 1]: 159 | for dz in [-1, 0, 1]: 160 | if abs(dx) + abs(dy) + abs(dz) == 1: # Change to != 0 161 | direction = str(dx) + "_" + str(dy) + "_" + str(dz) 162 | adjacency[direction] = self.parseGridObject(x + dx, y - dz, z + dy, r) 163 | 164 | if r == 1: 165 | for dx in [-1, 0, 1]: 166 | for dy in [-1, 0, 1]: 167 | for dz in [-1, 0, 1]: 168 | if abs(dx) + abs(dy) + abs(dz) == 1: # Change to != 0 169 | direction = str(dx) + "_" + str(dy) + "_" + str(dz) 170 | adjacency[direction] = self.parseGridObject(x - dz, y - dx, z + dy, r) 171 | 172 | 173 | if r == 2: 174 | for dx in [-1, 0, 1]: 175 | for dy in [-1, 0, 1]: 176 | for dz in [-1, 0, 1]: 177 | if abs(dx) + abs(dy) + abs(dz) == 1: # Change to != 0 178 | direction = str(dx) + "_" + str(dy) + "_" + str(dz) 179 | adjacency[direction] = self.parseGridObject(x - dx, y + dz, z + dy, r) 180 | 181 | 182 | if r == 3: 183 | for dx in [-1, 0, 1]: 184 | for dy in [-1, 0, 1]: 185 | for dz in [-1, 0, 1]: 186 | if abs(dx) + abs(dy) + abs(dz) == 1: # Change to != 0 187 | direction = str(dx) + "_" + str(dy) + "_" + str(dz) 188 | adjacency[direction] = self.parseGridObject(x + dz, y + dx, z + dy, r) 189 | 190 | return adjacency 191 | 192 | 193 | def isInBounds(self, x, y, z): 194 | """ 195 | Checks if a voxel is within the bounds 196 | """ 197 | 198 | if bounds["x"][0] <= x and x < bounds["x"][1] : 199 | if bounds["y"][0] <= y and y < bounds["y"][1] : 200 | if bounds["z"][0] <= z and z < bounds["z"][1] : 201 | return True 202 | 203 | return False 204 | 205 | 206 | def isInGrid(self, x, y, z): 207 | """ 208 | Checks if a voxel is within the bounds of the grid 209 | """ 210 | 211 | if self.grid == None: 212 | return False 213 | 214 | if 0 <= x and x < len(self.grid) : 215 | if 0 <= y and y < len(self.grid[x]) : 216 | if 0 <= z and z < len(self.grid[x][y]) : 217 | return True 218 | 219 | return False 220 | 221 | def isConnectedToFloor(self, x, y, z): 222 | """ 223 | Checks if a voxel is connected with the floor 224 | """ 225 | 226 | if self.grid == None: 227 | return False 228 | 229 | return z == 0 230 | 231 | 232 | def parseGridObject(self, x, y, z, r): 233 | """ 234 | Parses a grid object to a string representation 235 | """ 236 | 237 | if not self.isInGrid(x, y, z): 238 | if(z < 0): 239 | return "Floor" 240 | else: 241 | return "Empty" 242 | 243 | obj = self.grid[x][y][z] 244 | 245 | if obj == 0: 246 | return "Empty" 247 | 248 | nameIdentity = obj.name.split(".")[0] 249 | 250 | # Euler angles into 90 degree divisor 251 | rotation = obj.rotation_euler 252 | 253 | rotationX = int(divmod(round(math.degrees(rotation[0])) % 360, 90)[0] % 4) 254 | rotationY = int(divmod(round(math.degrees(rotation[1])) % 360, 90)[0] % 4) 255 | rotationZ = int(divmod(round(math.degrees(rotation[2]) + 90 * r) % 360, 90)[0] % 4) 256 | 257 | if nameIdentity == "Connector": 258 | rotationX = 0 259 | rotationY = 0 260 | rotationZ = 0 261 | 262 | return nameIdentity + "_" + str(rotationX) + "_" + str(rotationY) + "_" + str(rotationZ) 263 | 264 | 265 | 266 | bounds = { 267 | "x": (0, 40), 268 | "y": (0, 40), 269 | "z": (0, 40) 270 | } 271 | 272 | constraintExporter = ConstraintExporter(bounds) 273 | constraintExporter.export("/Users/jdihlmann/Desktop/") 274 | -------------------------------------------------------------------------------- /blender/gltfjsxify.sh: -------------------------------------------------------------------------------- 1 | for f in *.glb ; do npx gltfjsx -t $f ; done -------------------------------------------------------------------------------- /blender/infty.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/blender/infty.blend -------------------------------------------------------------------------------- /blender/nameExporter.py: -------------------------------------------------------------------------------- 1 | import bpy 2 | import os 3 | 4 | def export(path): 5 | 6 | # Scene Objects 7 | objects = bpy.context.scene.objects 8 | 9 | # Deselect all in scene 10 | bpy.ops.object.select_all(action='DESELECT') 11 | 12 | for collection in bpy.data.collections: 13 | if collection.name == "Objects": 14 | for obj in collection.all_objects: 15 | print('import ' + obj.name + ' from "@/models/' + obj.name + '"') 16 | 17 | print('#########################################################################################') 18 | 19 | for collection in bpy.data.collections: 20 | if collection.name == "Objects": 21 | for obj in collection.all_objects: 22 | print('case "' + obj.name + '":') 23 | print('return <' + obj.name + ' key={key} position={pos} rotation={obj.rotation} />' ) 24 | 25 | 26 | 27 | export('/Users/jdihlmann/Desktop/Export') -------------------------------------------------------------------------------- /blender/objectExporter.py: -------------------------------------------------------------------------------- 1 | import bpy 2 | import os 3 | 4 | def export(path): 5 | 6 | # Scene Objects 7 | objects = bpy.context.scene.objects 8 | 9 | # Deselect all in scene 10 | bpy.ops.object.select_all(action='DESELECT') 11 | 12 | for collection in bpy.data.collections: 13 | if collection.name == "Objects": 14 | for obj in collection.all_objects: 15 | 16 | outpath = os.path.join(path, obj.name + '.glb') 17 | 18 | old_x = obj.location.x 19 | old_y = obj.location.y 20 | old_z = obj.location.z 21 | 22 | obj.location.x = 0 23 | obj.location.y = 0 24 | obj.location.z = 0 25 | 26 | bpy.context.scene.objects[obj.name].select_set(True) 27 | 28 | bpy.ops.export_scene.gltf( 29 | filepath=outpath, 30 | use_selection=True 31 | ) 32 | 33 | bpy.context.scene.objects[obj.name].select_set(False) 34 | 35 | obj.location.x = old_x 36 | obj.location.y = old_y 37 | obj.location.z = old_z 38 | 39 | 40 | 41 | export('/Users/jdihlmann/Desktop/CG Infty') -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | // NOTE: This file should not be edited 6 | // see https://nextjs.org/docs/basic-features/typescript for more information. 7 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | reactStrictMode: true, 3 | webpack(config) { 4 | config.output.webassemblyModuleFilename = "static/wasm/[modulehash].wasm" 5 | config.experiments = { asyncWebAssembly: true } 6 | return config 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Infty", 3 | "description": "Infinite world generation with wave form collapse", 4 | "version": "1.0.0", 5 | "private": true, 6 | "author": "Jan-Niklas Dihlmann (@jdihlmann)", 7 | "license": "MIT", 8 | "keywords": [ 9 | "nextjs", 10 | "threejs", 11 | "typescript" 12 | ], 13 | "scripts": { 14 | "dev": "next", 15 | "build": "next build", 16 | "start": "next start", 17 | "type-check": "tsc", 18 | "lint": "eslint --ignore-path .gitignore \"src/**/*.+(ts|js|tsx)\"", 19 | "format": "prettier --ignore-path .gitignore \"src/**/*.+(ts|js|tsx)\" --write", 20 | "postinstall": "husky install", 21 | "commit": "cz" 22 | }, 23 | "lint-staged": { 24 | "./src/**/*.{ts,js,jsx,tsx}": [ 25 | "yarn lint --fix", 26 | "yarn format" 27 | ] 28 | }, 29 | "dependencies": { 30 | "@react-three/drei": "7.12.4", 31 | "@react-three/fiber": "7.0.7", 32 | "@react-three/postprocessing": "2.0.5", 33 | "@types/three": "0.131.1", 34 | "immer": "^9.0.5", 35 | "leva": "0.9.23", 36 | "nanoid": "^3.1.28", 37 | "next": "11.1.2", 38 | "react": "17.0.2", 39 | "react-dom": "17.0.2", 40 | "react-responsive": "9.0.0-beta.6", 41 | "three": "0.132.2", 42 | "three-stdlib": "^2.4.2" 43 | }, 44 | "devDependencies": { 45 | "@commitlint/cli": "13.2.1", 46 | "@commitlint/config-conventional": "13.2.0", 47 | "@types/node": "14.17.21", 48 | "@types/react": "17.0.27", 49 | "@types/react-dom": "17.0.9", 50 | "@typescript-eslint/eslint-plugin": "4.33.0", 51 | "@typescript-eslint/parser": "4.33.0", 52 | "commitizen": "4.2.4", 53 | "cz-conventional-changelog": "3.3.0", 54 | "eslint": "7.32.0", 55 | "eslint-config-next": "11.1.2", 56 | "eslint-config-prettier": "8.3.0", 57 | "eslint-import-resolver-typescript": "2.5.0", 58 | "eslint-plugin-prettier": "4.0.0", 59 | "husky": "7.0.2", 60 | "lint-staged": "11.2.3", 61 | "prettier": "2.4.1", 62 | "typescript": "4.4.3" 63 | }, 64 | "config": { 65 | "commitizen": { 66 | "path": "cz-conventional-changelog" 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /public/Arch.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/Arch.glb -------------------------------------------------------------------------------- /public/ArchLeft.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/ArchLeft.glb -------------------------------------------------------------------------------- /public/ArchRight.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/ArchRight.glb -------------------------------------------------------------------------------- /public/BendWall.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/BendWall.glb -------------------------------------------------------------------------------- /public/BendWallOuter.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/BendWallOuter.glb -------------------------------------------------------------------------------- /public/BendWallOuterLower.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/BendWallOuterLower.glb -------------------------------------------------------------------------------- /public/BendWallOuterTop.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/BendWallOuterTop.glb -------------------------------------------------------------------------------- /public/BendWallTop.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/BendWallTop.glb -------------------------------------------------------------------------------- /public/Connector.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/Connector.glb -------------------------------------------------------------------------------- /public/Corner.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/Corner.glb -------------------------------------------------------------------------------- /public/CornerFull.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/CornerFull.glb -------------------------------------------------------------------------------- /public/CornerFullHalfLower.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/CornerFullHalfLower.glb -------------------------------------------------------------------------------- /public/CornerHalfLower.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/CornerHalfLower.glb -------------------------------------------------------------------------------- /public/DoubleSided.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/DoubleSided.glb -------------------------------------------------------------------------------- /public/Edge.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/Edge.glb -------------------------------------------------------------------------------- /public/EdgeHalfLower.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/EdgeHalfLower.glb -------------------------------------------------------------------------------- /public/FlatStairWithWallLeftLowerUper.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/FlatStairWithWallLeftLowerUper.glb -------------------------------------------------------------------------------- /public/FlatStairWithWallRightUper.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/FlatStairWithWallRightUper.glb -------------------------------------------------------------------------------- /public/FlatStairsFreeUper.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/FlatStairsFreeUper.glb -------------------------------------------------------------------------------- /public/Loop.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/Loop.glb -------------------------------------------------------------------------------- /public/LoopHalfLower.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/LoopHalfLower.glb -------------------------------------------------------------------------------- /public/StairWithWallLeft.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/StairWithWallLeft.glb -------------------------------------------------------------------------------- /public/StairWithWallRight.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/StairWithWallRight.glb -------------------------------------------------------------------------------- /public/Stairs.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/Stairs.glb -------------------------------------------------------------------------------- /public/StairsLeft.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/StairsLeft.glb -------------------------------------------------------------------------------- /public/StairsRight.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/StairsRight.glb -------------------------------------------------------------------------------- /public/Wall.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/Wall.glb -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/android-chrome-384x384.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/apple-touch-icon.png -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/environmentMap.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/environmentMap.hdr -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/Redaction_35-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/fonts/Redaction_35-Bold.woff2 -------------------------------------------------------------------------------- /public/fonts/Redaction_35-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/fonts/Redaction_35-Regular.woff2 -------------------------------------------------------------------------------- /public/fonts/Redaction_50-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/fonts/Redaction_50-Bold.woff2 -------------------------------------------------------------------------------- /public/fonts/Redaction_50-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/fonts/Redaction_50-Regular.woff2 -------------------------------------------------------------------------------- /public/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/mstile-150x150.png -------------------------------------------------------------------------------- /public/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.14, written by Peter Selinger 2001-2017 9 | 10 | 12 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /public/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-384x384.png", 12 | "sizes": "384x384", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /public/wfc.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JDihlmann/infty/c6c2f83bda3cbbddcf4c0d7e2147744e6024167a/public/wfc.wasm -------------------------------------------------------------------------------- /src/components/body/body.tsx: -------------------------------------------------------------------------------- 1 | import Header from "@/components/header/header" 2 | import React, { FunctionComponent } from "react" 3 | import { Leva } from "leva" 4 | import ConstraintsSampler from "../constraintsSampler/constraintsSampler" 5 | 6 | interface BodyProps { 7 | className?: string 8 | } 9 | 10 | const Body: FunctionComponent = ({ children, className = undefined }) => { 11 | return ( 12 |
29 |
30 | 31 | 32 |
45 | {children} 46 |
47 |
48 | ) 49 | } 50 | 51 | export default Body 52 | -------------------------------------------------------------------------------- /src/components/camera/camera.tsx: -------------------------------------------------------------------------------- 1 | import { MapControls, PerspectiveCamera } from "@react-three/drei" 2 | import { MathUtils } from "three" 3 | 4 | const Camera = () => { 5 | const angle = MathUtils.degToRad(35) 6 | 7 | return ( 8 | <> 9 | 18 | 19 | 20 | ) 21 | } 22 | 23 | export default Camera 24 | -------------------------------------------------------------------------------- /src/components/constraintsSampler/constraintsSampler.tsx: -------------------------------------------------------------------------------- 1 | import Header from "@/components/header/header" 2 | import React, { FunctionComponent } from "react" 3 | import { useControls } from "leva" 4 | import { useGenerationStore } from "@/stores/generationStore" 5 | 6 | interface ConstraintsSamplerProps {} 7 | 8 | const ConstraintsSampler: FunctionComponent = ({}) => { 9 | const prototypes = useGenerationStore((state) => state.prototypes) 10 | const probabilites = useGenerationStore((state) => state.probabilities) 11 | const setProbalities = useGenerationStore((state) => state.setProbabilities) 12 | 13 | const names: string[] = Object.values(prototypes).map(({ id }) => { 14 | return id.split("_")[0] 15 | }) 16 | 17 | const levaObjects: Record = {} 18 | names.forEach((name) => { 19 | levaObjects[name] = probabilites[name] ? probabilites[name] : 1 20 | }) 21 | 22 | const probabilities = useControls(levaObjects, { collapsed: true }) 23 | setProbalities(probabilities) 24 | 25 | return <> 26 | } 27 | 28 | export default ConstraintsSampler 29 | -------------------------------------------------------------------------------- /src/components/displayer/displayer.tsx: -------------------------------------------------------------------------------- 1 | import { useGenerationStore } from "@/stores/generationStore" 2 | import { Html } from "@react-three/drei" 3 | import { useRef, useEffect } from "react" 4 | import { Group } from "three" 5 | import { GLTFExporter } from "three-stdlib" 6 | import ModelObject from "../modelObject/modelObject" 7 | 8 | const Displayer = () => { 9 | const prototypeObjects = useGenerationStore((state) => state.prototypeObjects) 10 | const size = useGenerationStore((state) => state.size) 11 | const exporting = useGenerationStore((state) => state.exporting) 12 | const setExport = useGenerationStore((state) => state.setExport) 13 | 14 | const ref = useRef() 15 | 16 | useEffect(() => { 17 | if (exporting) { 18 | if (ref && ref.current) { 19 | const exporter = new GLTFExporter() 20 | 21 | exporter.parse( 22 | ref.current, 23 | async function (gltf) { 24 | const output = JSON.stringify(gltf, null, 2) 25 | 26 | const blob = new Blob([output], { type: "text/plain" }) 27 | const filename = "infty.gltf" 28 | 29 | const link = document.createElement("a") 30 | link.href = URL.createObjectURL(blob) 31 | link.download = filename 32 | document.body.appendChild(link) 33 | link.click() 34 | document.body.removeChild(link) 35 | 36 | setExport(false) 37 | }, 38 | {} 39 | ) 40 | } 41 | } 42 | }, [exporting, setExport]) 43 | 44 | return ( 45 | <> 46 | 47 | {prototypeObjects && 48 | prototypeObjects.map((prototype) => ( 49 | 50 | ))} 51 | 52 | 53 | ) 54 | } 55 | 56 | export default Displayer 57 | -------------------------------------------------------------------------------- /src/components/environment/environment.tsx: -------------------------------------------------------------------------------- 1 | import { Environment as EnvironmentLight } from "@react-three/drei" 2 | import { Suspense } from "react" 3 | import Displayer from "../displayer/displayer" 4 | 5 | const Environment = () => { 6 | return ( 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default Environment 18 | -------------------------------------------------------------------------------- /src/components/generator/fullGenerator.tsx: -------------------------------------------------------------------------------- 1 | import { useGenerationStore } from "@/stores/generationStore" 2 | import { memo, useEffect, useState } from "react" 3 | import WFC from "../../wfc/wfc" 4 | 5 | interface FullGeneratorProps { 6 | doneCallback: () => void 7 | } 8 | 9 | const FullGenerator = memo(({ doneCallback }) => { 10 | const size = useGenerationStore((state) => state.size) 11 | const prototypes = useGenerationStore((state) => state.prototypes) 12 | const probabilities = useGenerationStore((state) => state.probabilities) 13 | const setGeneration = useGenerationStore((state) => state.setGeneration) 14 | 15 | const [wfcModule, setWFCModule] = useState(undefined) 16 | const [done, setDone] = useState(false) 17 | 18 | useEffect(() => { 19 | //@ts-ignore 20 | WFC().then((module) => { 21 | setWFCModule(module) 22 | }) 23 | }, []) 24 | 25 | useEffect(() => { 26 | if (wfcModule && !done) { 27 | // @ts-ignore 28 | const processHelper = new wfcModule.ForwardPropagationSolverProcessHelper3D_32_16_32( 29 | prototypes.length, 30 | false, 31 | false 32 | ) 33 | 34 | // Enable Heuristic 35 | processHelper.set_element_type_heuristic(1) 36 | 37 | // Set Probability 38 | prototypes.forEach((prototype, id) => { 39 | const neighbourCells = prototype.neighbourCells 40 | 41 | Object.entries(neighbourCells).forEach(([posId, neighbourIds]) => { 42 | neighbourIds.forEach((neighbourId: number) => { 43 | const x = parseInt(posId.split("_")[0]) 44 | const y = parseInt(posId.split("_")[1]) 45 | const z = parseInt(posId.split("_")[2]) 46 | processHelper.set_rule(id, neighbourId, x, y, z, true) 47 | 48 | const probability = probabilities[prototype.id.split("_")[0]] 49 | if (probability !== undefined) { 50 | processHelper.set_density_probability(id, probability) 51 | } else { 52 | processHelper.set_density_probability(id, 1) 53 | } 54 | }) 55 | }) 56 | }) 57 | 58 | // Pad Walls 59 | for (let x = 0; x < size.x; x++) { 60 | for (let y = 0; y < size.y; y++) { 61 | for (let z = 0; z < size.z; z++) { 62 | if (y === 0) { 63 | processHelper.preset_element(x, y, z, 1) 64 | } else { 65 | if (x <= 0 || x >= size.x - 1 || z <= 0 || z >= size.z - 1 || y == size.y - 1) { 66 | processHelper.preset_element(x, y, z, 0) 67 | } 68 | } 69 | } 70 | } 71 | } 72 | 73 | // Run 74 | try { 75 | processHelper.run() 76 | 77 | // Get Result 78 | const waves = new Array(size.x) 79 | .fill(0) 80 | .map(() => new Array(size.y).fill(0).map(() => new Array(size.z).fill(0))) 81 | for (let x = 0; x < size.x; x++) { 82 | for (let y = 0; y < size.y; y++) { 83 | for (let z = 0; z < size.z; z++) { 84 | //@ts-ignore 85 | waves[x][y][z] = [processHelper.query(x, y, z) - 1] 86 | } 87 | } 88 | } 89 | 90 | // Set Generation 91 | setGeneration(waves) 92 | setDone(true) 93 | doneCallback() 94 | } catch (error) { 95 | console.log("Rerunning") 96 | if (processHelper.had_error()) { 97 | console.log(processHelper.get_last_error()) 98 | } 99 | 100 | //@ts-ignore 101 | WFC().then((module) => { 102 | setWFCModule(module) 103 | }) 104 | } 105 | } 106 | }, [wfcModule, size, prototypes, setGeneration, doneCallback, setDone, done]) 107 | 108 | return <> 109 | }) 110 | 111 | export default FullGenerator 112 | -------------------------------------------------------------------------------- /src/components/generator/generator.tsx: -------------------------------------------------------------------------------- 1 | import { useGenerationStore } from "@/stores/generationStore" 2 | import { useState, useEffect } from "react" 3 | import dynamic from "next/dynamic" 4 | import { useFrame } from "@react-three/fiber" 5 | import FullGenerator from "./fullGenerator" 6 | import StepGenerator from "./stepGenerator" 7 | import { FullGeneratorLoader, StepGeneratorLoader } from "./loader" 8 | 9 | const Generator = () => { 10 | const [generateFull, setGenerateFull] = useState(false) 11 | const [generateFullDone, setGenerateFullDone] = useState(false) 12 | const [generateStep, setGenerateStep] = useState(false) 13 | const [generateStepDone, setGenerateStepDone] = useState(false) 14 | const setExport = useGenerationStore((state) => state.setExport) 15 | 16 | return ( 17 | <> 18 | 57 | {generateFull && ( 58 | { 60 | setGenerateFullDone(true) 61 | }} 62 | /> 63 | )} 64 | 102 | 103 | 115 | 116 | {generateStep && ( 117 | { 119 | setGenerateStepDone(true) 120 | }} 121 | /> 122 | )} 123 | 124 | ) 125 | } 126 | 127 | export default Generator 128 | -------------------------------------------------------------------------------- /src/components/generator/loader.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | //import wfc from "@/utils/wasmLoader" 3 | import dynamic from "next/dynamic" 4 | import { useGenerationStore } from "@/stores/generationStore" 5 | 6 | export const FullGeneratorLoader = dynamic(() => import("./fullGenerator"), { 7 | ssr: false, 8 | }) 9 | 10 | export const StepGeneratorLoader = dynamic(() => import("./stepGenerator"), { 11 | ssr: false, 12 | }) 13 | -------------------------------------------------------------------------------- /src/components/generator/stepGenerator.tsx: -------------------------------------------------------------------------------- 1 | import { useGenerationStore } from "@/stores/generationStore" 2 | import WFC from "@/wfc/wfc" 3 | import useInterval from "@/utils/useInterval" 4 | import { FunctionComponent, useEffect, useState } from "react" 5 | 6 | interface StepGeneratorProps { 7 | doneCallback: () => void 8 | } 9 | 10 | const StepGenerator: FunctionComponent = ({ doneCallback }) => { 11 | const size = useGenerationStore((state) => state.size) 12 | const prototypes = useGenerationStore((state) => state.prototypes) 13 | const probabilities = useGenerationStore((state) => state.probabilities) 14 | const setGeneration = useGenerationStore((state) => state.setGeneration) 15 | 16 | const [wfcModule, setWFCModule] = useState(undefined) 17 | const [done, setDone] = useState(false) 18 | const [completedGeneration, setCompletedGeneration] = useState(false) 19 | 20 | const [processHelper, setProcessHelper] = useState(undefined) 21 | 22 | useEffect(() => { 23 | //@ts-ignore 24 | WFC().then((module) => { 25 | setWFCModule(module) 26 | }) 27 | 28 | return () => { 29 | setGeneration([]) 30 | } 31 | }, [setGeneration]) 32 | 33 | useEffect(() => { 34 | if (wfcModule && !done) { 35 | // @ts-ignore 36 | const processHelper = new wfcModule.ForwardPropagationSolverProcessHelper3D_32_16_32( 37 | prototypes.length, 38 | false, 39 | false 40 | ) 41 | 42 | // Enable Heuristic 43 | processHelper.set_element_type_heuristic(1) 44 | 45 | // Set Probability 46 | prototypes.forEach((prototype, id) => { 47 | const neighbourCells = prototype.neighbourCells 48 | 49 | Object.entries(neighbourCells).forEach(([posId, neighbourIds]) => { 50 | neighbourIds.forEach((neighbourId: number) => { 51 | const x = parseInt(posId.split("_")[0]) 52 | const y = parseInt(posId.split("_")[1]) 53 | const z = parseInt(posId.split("_")[2]) 54 | processHelper.set_rule(id, neighbourId, x, y, z, true) 55 | 56 | const probability = probabilities[prototype.id.split("_")[0]] 57 | if (probability !== undefined) { 58 | processHelper.set_density_probability(id, probability) 59 | } else { 60 | processHelper.set_density_probability(id, 1) 61 | } 62 | }) 63 | }) 64 | }) 65 | 66 | // Pad Walls 67 | for (let x = 0; x < size.x; x++) { 68 | for (let y = 0; y < size.y; y++) { 69 | for (let z = 0; z < size.z; z++) { 70 | if (y === 0) { 71 | processHelper.preset_element(x, y, z, 1) 72 | } else { 73 | if (x <= 0 || x >= size.x - 1 || z <= 0 || z >= size.z - 1 || y == size.y - 1) { 74 | processHelper.preset_element(x, y, z, 0) 75 | } 76 | } 77 | } 78 | } 79 | } 80 | 81 | setDone(true) 82 | doneCallback() 83 | setProcessHelper(processHelper) 84 | } 85 | }, [wfcModule, prototypes, size, doneCallback, done]) 86 | 87 | useInterval(() => { 88 | if (processHelper && !completedGeneration) { 89 | // Run 90 | processHelper.run_step() 91 | 92 | // Log Error 93 | if (processHelper.had_error()) { 94 | console.log(processHelper.get_last_error()) 95 | } 96 | 97 | // Get Result 98 | const waves = new Array(size.x).fill(0).map(() => new Array(size.y).fill(0).map(() => new Array(size.z).fill(0))) 99 | 100 | const entropies = new Array(size.x) 101 | .fill(0) 102 | .map(() => new Array(size.y).fill(0).map(() => new Array(size.z).fill(0))) 103 | 104 | let filledCounter = 0 105 | for (let x = 0; x < size.x; x++) { 106 | for (let y = 0; y < size.y; y++) { 107 | for (let z = 0; z < size.z; z++) { 108 | //@ts-ignore 109 | waves[x][y][z] = [processHelper.query(x, y, z) - 1] 110 | 111 | //@ts-ignore 112 | entropies[x][y][z] = processHelper.num_valid_in_pattern_buffer_coordinates(x, y, z) // only for debugging 113 | if (entropies[x][y][z] == 1) { 114 | filledCounter++ 115 | } 116 | } 117 | } 118 | } 119 | 120 | if (filledCounter === size.x * size.y * size.z) { 121 | setCompletedGeneration(true) 122 | } 123 | 124 | setGeneration(waves) 125 | } 126 | }, 20) 127 | 128 | return <> 129 | } 130 | 131 | export default StepGenerator 132 | -------------------------------------------------------------------------------- /src/components/header/header.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link" 2 | import { useMediaQuery } from "react-responsive" 3 | import { useEffect, useRef, useState } from "react" 4 | 5 | const Header = ({}) => { 6 | return ( 7 |
18 |
27 |
34 | 35 | 48 | Infty 49 | 50 | 51 |
52 | 53 |
61 |
62 |
63 | ) 64 | } 65 | 66 | export default Header 67 | -------------------------------------------------------------------------------- /src/components/modelObject/modelObject.tsx: -------------------------------------------------------------------------------- 1 | import Arch from "@/models/Arch" 2 | import ArchLeft from "@/models/ArchLeft" 3 | import ArchRight from "@/models/ArchRight" 4 | import BendWall from "@/models/BendWall" 5 | import BendWallOuter from "@/models/BendWallOuter" 6 | import BendWallOuterLower from "@/models/BendWallOuterLower" 7 | import BendWallOuterTop from "@/models/BendWallOuterTop" 8 | import BendWallTop from "@/models/BendWallTop" 9 | import Connector from "@/models/Connector" 10 | import Corner from "@/models/Corner" 11 | import CornerFull from "@/models/CornerFull" 12 | import CornerFullHalfLower from "@/models/CornerFullHalfLower" 13 | import CornerHalfLower from "@/models/CornerHalfLower" 14 | import DoubleSided from "@/models/DoubleSided" 15 | import Edge from "@/models/Edge" 16 | import EdgeHalfLower from "@/models/EdgeHalfLower" 17 | import FlatStairsFreeUper from "@/models/FlatStairsFreeUper" 18 | import FlatStairWithWallLeftLowerUper from "@/models/FlatStairWithWallLeftLowerUper" 19 | import FlatStairWithWallRightUper from "@/models/FlatStairWithWallRightUper" 20 | import Loop from "@/models/Loop" 21 | import LoopHalfLower from "@/models/LoopHalfLower" 22 | import Stairs from "@/models/Stairs" 23 | import StairsLeft from "@/models/StairsLeft" 24 | import StairsRight from "@/models/StairsRight" 25 | import StairWithWallLeft from "@/models/StairWithWallLeft" 26 | import StairWithWallRight from "@/models/StairWithWallRight" 27 | import Wall from "@/models/Wall" 28 | import { useGenerationStore } from "@/stores/generationStore" 29 | import { memo } from "react" 30 | import { MathUtils, Object3D, Vector3 } from "three" 31 | 32 | interface ModelObjectProps { 33 | id: string 34 | positionString: string 35 | } 36 | 37 | const ModelObject = memo(({ id, positionString }) => { 38 | const prototypes = useGenerationStore((state) => state.prototypes) 39 | const position = new Vector3( 40 | parseInt(positionString.split("_")[0]), 41 | parseInt(positionString.split("_")[1]), 42 | parseInt(positionString.split("_")[2]) 43 | ) 44 | 45 | const getMeshForId = (id: string, position: Vector3 | undefined) => { 46 | const nameId = id.split("_")[0] 47 | 48 | const obj = new Object3D() 49 | obj.rotateOnWorldAxis(new Vector3(1, 0, 0), MathUtils.degToRad(parseInt(id.split("_")[1]) * 90)) 50 | obj.rotateOnWorldAxis(new Vector3(0, 0, 1), MathUtils.degToRad(-parseInt(id.split("_")[2]) * 90)) 51 | obj.rotateOnWorldAxis(new Vector3(0, 1, 0), MathUtils.degToRad(parseInt(id.split("_")[3]) * 90)) 52 | 53 | const pos = position?.clone().add(new Vector3(0.5, 0.5, 0.5)) 54 | 55 | switch (nameId) { 56 | case "Arch": 57 | return 58 | case "ArchLeft": 59 | return 60 | case "ArchRight": 61 | return 62 | case "BendWall": 63 | return 64 | case "BendWallOuter": 65 | return 66 | case "BendWallOuterLower": 67 | return 68 | case "BendWallOuterTop": 69 | return 70 | case "BendWallTop": 71 | return 72 | case "Connector": 73 | return 74 | case "Corner": 75 | return 76 | case "CornerFull": 77 | return 78 | case "CornerFullHalfLower": 79 | return 80 | case "CornerHalfLower": 81 | return 82 | case "DoubleSided": 83 | return 84 | case "Edge": 85 | return 86 | case "EdgeHalfLower": 87 | return 88 | case "FlatStairsFreeUper": 89 | return 90 | case "FlatStairWithWallLeftLowerUper": 91 | return 92 | case "FlatStairWithWallRightUper": 93 | return 94 | case "Loop": 95 | return 96 | case "LoopHalfLower": 97 | return 98 | case "Stairs": 99 | return 100 | case "StairsLeft": 101 | return 102 | case "StairsRight": 103 | return 104 | case "StairWithWallLeft": 105 | return 106 | case "StairWithWallRight": 107 | return 108 | case "Wall": 109 | return 110 | } 111 | } 112 | 113 | return <>{getMeshForId(id, position)} 114 | }) 115 | 116 | export default ModelObject 117 | -------------------------------------------------------------------------------- /src/components/postprocessing/postprocessing.tsx: -------------------------------------------------------------------------------- 1 | import { EffectComposer, SSAO } from "@react-three/postprocessing" 2 | 3 | const Postprocessing = () => { 4 | return ( 5 | 6 | { 7 | //@ts-ignore 8 | 9 | } 10 | 11 | ) 12 | } 13 | 14 | export default Postprocessing 15 | -------------------------------------------------------------------------------- /src/components/scenes/scene.tsx: -------------------------------------------------------------------------------- 1 | import Camera from "@/components/camera/camera" 2 | import Environment from "@/components/environment/environment" 3 | import { Canvas } from "@react-three/fiber" 4 | import { Grid } from "@react-three/postprocessing" 5 | import React, { FunctionComponent } from "react" 6 | import { NoToneMapping, sRGBEncoding } from "three" 7 | import Postprocessing from "../postprocessing/postprocessing" 8 | 9 | interface SceneProps {} 10 | 11 | const Scene: FunctionComponent = ({}) => { 12 | return ( 13 | { 18 | gl.toneMapping = NoToneMapping 19 | gl.outputEncoding = sRGBEncoding 20 | }} 21 | > 22 | 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | export default Scene 30 | -------------------------------------------------------------------------------- /src/models/Arch.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Arch: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.123"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/Arch.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/Arch.glb") 30 | -------------------------------------------------------------------------------- /src/models/ArchLeft.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | ArchLeft: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.446"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/ArchLeft.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/ArchLeft.glb") 30 | -------------------------------------------------------------------------------- /src/models/ArchRight.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | ArchRight: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.443"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/ArchRight.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/ArchRight.glb") 30 | -------------------------------------------------------------------------------- /src/models/BendWall.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | BendWall: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.430"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/BendWall.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/BendWall.glb") 30 | -------------------------------------------------------------------------------- /src/models/BendWallOuter.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | BendWallOuter: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.438"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/BendWallOuter.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/BendWallOuter.glb") 30 | -------------------------------------------------------------------------------- /src/models/BendWallOuterLower.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | BendWallOuterLower: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.442"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/BendWallOuterLower.glb") as GLTFResult 22 | return ( 23 | 24 | 29 | 30 | ) 31 | } 32 | 33 | useGLTF.preload("/BendWallOuterLower.glb") 34 | -------------------------------------------------------------------------------- /src/models/BendWallOuterTop.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | BendWallOuterTop: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.441"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/BendWallOuterTop.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/BendWallOuterTop.glb") 30 | -------------------------------------------------------------------------------- /src/models/BendWallTop.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | BendWallTop: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.431"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/BendWallTop.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/BendWallTop.glb") 30 | -------------------------------------------------------------------------------- /src/models/Connector.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Connector: THREE.Mesh 13 | } 14 | materials: {} 15 | } 16 | 17 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 18 | const group = useRef() 19 | const { nodes, materials } = useGLTF("/Connector.glb") as GLTFResult 20 | return ( 21 | 22 | 23 | 24 | ) 25 | } 26 | 27 | useGLTF.preload("/Connector.glb") 28 | -------------------------------------------------------------------------------- /src/models/Corner.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Corner: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.104"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/Corner.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/Corner.glb") 30 | -------------------------------------------------------------------------------- /src/models/CornerFull.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | CornerFull: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.119"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/CornerFull.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/CornerFull.glb") 30 | -------------------------------------------------------------------------------- /src/models/CornerFullHalfLower.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | CornerFullHalfLower: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.176"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/CornerFullHalfLower.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/CornerFullHalfLower.glb") 30 | -------------------------------------------------------------------------------- /src/models/CornerHalfLower.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | CornerHalfLower: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.447"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/CornerHalfLower.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/CornerHalfLower.glb") 30 | -------------------------------------------------------------------------------- /src/models/DoubleSided.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | DoubleSided: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.435"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/DoubleSided.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/DoubleSided.glb") 30 | -------------------------------------------------------------------------------- /src/models/Edge.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Edge: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.008"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/Edge.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/Edge.glb") 30 | -------------------------------------------------------------------------------- /src/models/EdgeHalfLower.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | EdgeHalfLower: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.191"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/EdgeHalfLower.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/EdgeHalfLower.glb") 30 | -------------------------------------------------------------------------------- /src/models/FlatStairWithWallLeftLowerUper.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | FlatStairWithWallLeftLowerUper: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.142"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/FlatStairWithWallLeftLowerUper.glb") as GLTFResult 22 | return ( 23 | 24 | 29 | 30 | ) 31 | } 32 | 33 | useGLTF.preload("/FlatStairWithWallLeftLowerUper.glb") 34 | -------------------------------------------------------------------------------- /src/models/FlatStairWithWallRightUper.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | FlatStairWithWallRightUper: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.143"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/FlatStairWithWallRightUper.glb") as GLTFResult 22 | return ( 23 | 24 | 29 | 30 | ) 31 | } 32 | 33 | useGLTF.preload("/FlatStairWithWallRightUper.glb") 34 | -------------------------------------------------------------------------------- /src/models/FlatStairsFreeUper.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | FlatStairsFreeUper: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.146"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/FlatStairsFreeUper.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/FlatStairsFreeUper.glb") 30 | -------------------------------------------------------------------------------- /src/models/Loop.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Loop: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.105"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/Loop.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/Loop.glb") 30 | -------------------------------------------------------------------------------- /src/models/LoopHalfLower.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | LoopHalfLower: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.179"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/LoopHalfLower.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/LoopHalfLower.glb") 30 | -------------------------------------------------------------------------------- /src/models/StairWithWallLeft.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | StairWithWallLeft: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.115"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/StairWithWallLeft.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/StairWithWallLeft.glb") 30 | -------------------------------------------------------------------------------- /src/models/StairWithWallRight.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | StairWithWallRight: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.116"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/StairWithWallRight.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/StairWithWallRight.glb") 30 | -------------------------------------------------------------------------------- /src/models/Stairs.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Cube331: THREE.Mesh 13 | Cube331_1: THREE.Mesh 14 | Cube331_2: THREE.Mesh 15 | } 16 | materials: { 17 | ["Material.433"]: THREE.MeshStandardMaterial 18 | ["Material.434"]: THREE.MeshStandardMaterial 19 | ["Material.432"]: THREE.MeshStandardMaterial 20 | } 21 | } 22 | 23 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 24 | const group = useRef() 25 | const { nodes, materials } = useGLTF("/Stairs.glb") as GLTFResult 26 | return ( 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | ) 35 | } 36 | 37 | useGLTF.preload("/Stairs.glb") 38 | -------------------------------------------------------------------------------- /src/models/StairsLeft.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Cube097: THREE.Mesh 13 | Cube097_1: THREE.Mesh 14 | } 15 | materials: { 16 | ["Material.072"]: THREE.MeshStandardMaterial 17 | ["Material.089"]: THREE.MeshStandardMaterial 18 | } 19 | } 20 | 21 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 22 | const group = useRef() 23 | const { nodes, materials } = useGLTF("/StairsLeft.glb") as GLTFResult 24 | return ( 25 | 26 | 27 | 28 | 29 | 30 | 31 | ) 32 | } 33 | 34 | useGLTF.preload("/StairsLeft.glb") 35 | -------------------------------------------------------------------------------- /src/models/StairsRight.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Cube097: THREE.Mesh 13 | Cube097_1: THREE.Mesh 14 | } 15 | materials: { 16 | ["Material.072"]: THREE.MeshStandardMaterial 17 | ["Material.089"]: THREE.MeshStandardMaterial 18 | } 19 | } 20 | 21 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 22 | const group = useRef() 23 | const { nodes, materials } = useGLTF("/StairsRight.glb") as GLTFResult 24 | return ( 25 | 26 | 27 | 28 | 29 | 30 | 31 | ) 32 | } 33 | 34 | useGLTF.preload("/StairsRight.glb") 35 | -------------------------------------------------------------------------------- /src/models/Wall.tsx: -------------------------------------------------------------------------------- 1 | /* 2 | Auto-generated by: https://github.com/pmndrs/gltfjsx 3 | */ 4 | 5 | import * as THREE from "three" 6 | import React, { useRef } from "react" 7 | import { useGLTF } from "@react-three/drei" 8 | import { GLTF } from "three-stdlib" 9 | 10 | type GLTFResult = GLTF & { 11 | nodes: { 12 | Wall: THREE.Mesh 13 | } 14 | materials: { 15 | ["Material.102"]: THREE.MeshStandardMaterial 16 | } 17 | } 18 | 19 | export default function Model({ ...props }: JSX.IntrinsicElements["group"]) { 20 | const group = useRef() 21 | const { nodes, materials } = useGLTF("/Wall.glb") as GLTFResult 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | useGLTF.preload("/Wall.glb") 30 | -------------------------------------------------------------------------------- /src/models/constraints.json: -------------------------------------------------------------------------------- 1 | { 2 | "Empty": { 3 | "-1_0_0": [ 4 | "Empty", 5 | "Corner_0_0_0", 6 | "Edge_1_0_0", 7 | "Corner_0_3_0", 8 | "Edge_0_0_0", 9 | "Wall_0_0_0", 10 | "Edge_0_3_0", 11 | "Corner_0_0_3", 12 | "Edge_1_0_3", 13 | "Corner_0_3_3", 14 | "BendWallOuterTop_3_0_3", 15 | "BendWallOuter_1_0_2", 16 | "BendWallOuterTop_1_0_2", 17 | "BendWallOuterTop_3_0_2", 18 | "BendWallOuter_1_0_1", 19 | "BendWallOuterTop_1_0_1", 20 | "BendWallOuterLower_3_0_3", 21 | "BendWallOuterLower_3_0_2", 22 | "StairsRight_0_0_2", 23 | "StairsRight_0_0_3", 24 | "StairsLeft_0_0_3", 25 | "StairsLeft_0_0_0", 26 | "StairWithWallLeft_0_0_3", 27 | "StairWithWallRight_0_0_3", 28 | "ArchLeft_0_3_1", 29 | "ArchRight_0_3_3", 30 | "EdgeHalfLower_0_0_0", 31 | "LoopHalfLower_0_0_0", 32 | "ArchLeft_0_3_2", 33 | "ArchRight_0_3_2" 34 | ], 35 | "0_-1_0": [ 36 | "Floor", 37 | "Empty", 38 | "Corner_0_3_2", 39 | "Corner_0_3_3", 40 | "Corner_0_3_0", 41 | "Corner_0_3_1", 42 | "Edge_0_3_2", 43 | "Edge_0_3_3", 44 | "Edge_0_3_0", 45 | "Edge_0_3_1", 46 | "Wall_0_3_0", 47 | "Wall_0_3_1", 48 | "Wall_0_3_2", 49 | "Wall_0_3_3", 50 | "BendWallOuterTop_1_0_0", 51 | "BendWallOuterTop_1_0_1", 52 | "BendWallOuterTop_1_0_2", 53 | "BendWallOuterTop_1_0_3", 54 | "StairsRight_0_0_0", 55 | "StairsRight_0_0_1", 56 | "StairsRight_0_0_2", 57 | "StairsRight_0_0_3", 58 | "StairsLeft_0_0_0", 59 | "StairsLeft_0_0_1", 60 | "StairsLeft_0_0_2", 61 | "StairsLeft_0_0_3", 62 | "StairWithWallLeft_0_0_2", 63 | "StairWithWallLeft_0_0_3", 64 | "StairWithWallLeft_0_0_0", 65 | "StairWithWallLeft_0_0_1", 66 | "StairWithWallRight_0_0_0", 67 | "StairWithWallRight_0_0_1", 68 | "StairWithWallRight_0_0_2", 69 | "StairWithWallRight_0_0_3", 70 | "FlatStairWithWallRightUper_0_0_0", 71 | "FlatStairWithWallRightUper_0_0_1", 72 | "FlatStairWithWallRightUper_0_0_2", 73 | "FlatStairWithWallRightUper_0_0_3", 74 | "EdgeHalfLower_0_0_2", 75 | "EdgeHalfLower_0_0_3", 76 | "EdgeHalfLower_0_0_0", 77 | "EdgeHalfLower_0_0_1", 78 | "LoopHalfLower_0_0_2", 79 | "LoopHalfLower_0_0_3", 80 | "LoopHalfLower_0_0_0", 81 | "LoopHalfLower_0_0_1", 82 | "FlatStairWithWallLeftLowerUper_0_0_2", 83 | "FlatStairWithWallLeftLowerUper_0_0_3", 84 | "FlatStairWithWallLeftLowerUper_0_0_0", 85 | "FlatStairWithWallLeftLowerUper_0_0_1" 86 | ], 87 | "0_0_-1": [ 88 | "Empty", 89 | "Corner_0_0_3", 90 | "Edge_1_0_3", 91 | "Corner_0_3_3", 92 | "Edge_0_0_3", 93 | "Wall_0_0_3", 94 | "Edge_0_3_3", 95 | "Corner_0_0_2", 96 | "Edge_1_0_2", 97 | "Corner_0_3_2", 98 | "BendWallOuterTop_3_0_2", 99 | "BendWallOuter_1_0_1", 100 | "BendWallOuterTop_1_0_1", 101 | "BendWallOuterTop_3_0_1", 102 | "BendWallOuter_1_0_0", 103 | "BendWallOuterTop_1_0_0", 104 | "BendWallOuterLower_3_0_2", 105 | "BendWallOuterLower_3_0_1", 106 | "StairsRight_0_0_1", 107 | "StairsRight_0_0_2", 108 | "StairsLeft_0_0_2", 109 | "StairsLeft_0_0_3", 110 | "StairWithWallLeft_0_0_2", 111 | "StairWithWallRight_0_0_2", 112 | "ArchLeft_0_3_0", 113 | "ArchRight_0_3_2", 114 | "EdgeHalfLower_0_0_3", 115 | "LoopHalfLower_0_0_3", 116 | "ArchLeft_0_3_1", 117 | "ArchRight_0_3_1" 118 | ], 119 | "0_0_1": [ 120 | "Empty", 121 | "Corner_0_0_1", 122 | "Edge_1_0_1", 123 | "Corner_0_3_1", 124 | "Edge_0_0_1", 125 | "Wall_0_0_1", 126 | "Edge_0_3_1", 127 | "Corner_0_0_0", 128 | "Edge_1_0_0", 129 | "Corner_0_3_0", 130 | "BendWallOuterTop_3_0_0", 131 | "BendWallOuter_1_0_3", 132 | "BendWallOuterTop_1_0_3", 133 | "BendWallOuterTop_3_0_3", 134 | "BendWallOuter_1_0_2", 135 | "BendWallOuterTop_1_0_2", 136 | "BendWallOuterLower_3_0_0", 137 | "BendWallOuterLower_3_0_3", 138 | "StairsRight_0_0_3", 139 | "StairsRight_0_0_0", 140 | "StairsLeft_0_0_0", 141 | "StairsLeft_0_0_1", 142 | "StairWithWallLeft_0_0_0", 143 | "StairWithWallRight_0_0_0", 144 | "ArchLeft_0_3_2", 145 | "ArchRight_0_3_0", 146 | "EdgeHalfLower_0_0_1", 147 | "LoopHalfLower_0_0_1", 148 | "ArchLeft_0_3_3", 149 | "ArchRight_0_3_3" 150 | ], 151 | "0_1_0": [ 152 | "Empty", 153 | "ArchLeft_0_3_3", 154 | "ArchLeft_0_3_0", 155 | "ArchLeft_0_3_1", 156 | "ArchLeft_0_3_2", 157 | "ArchRight_0_3_1", 158 | "ArchRight_0_3_2", 159 | "ArchRight_0_3_3", 160 | "ArchRight_0_3_0", 161 | "Arch_0_3_3", 162 | "Arch_0_3_0", 163 | "Arch_0_3_1", 164 | "Arch_0_3_2", 165 | "LoopHalfLower_0_0_2", 166 | "LoopHalfLower_0_0_3", 167 | "LoopHalfLower_0_0_0", 168 | "LoopHalfLower_0_0_1" 169 | ], 170 | "1_0_0": [ 171 | "Empty", 172 | "Corner_0_0_2", 173 | "Edge_1_0_2", 174 | "Corner_0_3_2", 175 | "Edge_0_0_2", 176 | "Wall_0_0_2", 177 | "Edge_0_3_2", 178 | "Corner_0_0_1", 179 | "Edge_1_0_1", 180 | "Corner_0_3_1", 181 | "BendWallOuterTop_3_0_1", 182 | "BendWallOuter_1_0_0", 183 | "BendWallOuterTop_1_0_0", 184 | "BendWallOuterTop_3_0_0", 185 | "BendWallOuter_1_0_3", 186 | "BendWallOuterTop_1_0_3", 187 | "BendWallOuterLower_3_0_1", 188 | "BendWallOuterLower_3_0_0", 189 | "StairsRight_0_0_0", 190 | "StairsRight_0_0_1", 191 | "StairsLeft_0_0_1", 192 | "StairsLeft_0_0_2", 193 | "StairWithWallLeft_0_0_1", 194 | "StairWithWallRight_0_0_1", 195 | "ArchLeft_0_3_3", 196 | "ArchRight_0_3_1", 197 | "EdgeHalfLower_0_0_2", 198 | "LoopHalfLower_0_0_2", 199 | "ArchLeft_0_3_0", 200 | "ArchRight_0_3_0" 201 | ] 202 | }, 203 | "Floor": { 204 | "-1_0_0": [ 205 | "Floor" 206 | ], 207 | "0_-1_0": [], 208 | "0_0_-1": [ 209 | "Floor" 210 | ], 211 | "0_0_1": [ 212 | "Floor" 213 | ], 214 | "0_1_0": [ 215 | "Empty", 216 | "Corner_0_0_2", 217 | "Corner_0_0_3", 218 | "Corner_0_0_0", 219 | "Corner_0_0_1", 220 | "Edge_0_0_2", 221 | "Edge_0_0_3", 222 | "Edge_0_0_0", 223 | "Edge_0_0_1", 224 | "Wall_0_1_0", 225 | "Wall_0_1_1", 226 | "Wall_0_1_2", 227 | "Wall_0_1_3", 228 | "BendWallOuterTop_3_0_1", 229 | "BendWallOuterTop_3_0_2", 230 | "BendWallOuterTop_3_0_3", 231 | "BendWallOuterTop_3_0_0" 232 | ], 233 | "1_0_0": [ 234 | "Floor" 235 | ] 236 | }, 237 | "Corner_0_0_2": { 238 | "-1_0_0": [ 239 | "Empty" 240 | ], 241 | "0_-1_0": [ 242 | "Floor" 243 | ], 244 | "0_0_-1": [ 245 | "Edge_0_0_2", 246 | "Corner_0_0_1" 247 | ], 248 | "0_0_1": [ 249 | "Empty" 250 | ], 251 | "0_1_0": [ 252 | "Edge_1_0_2", 253 | "Corner_0_3_2" 254 | ], 255 | "1_0_0": [ 256 | "Edge_0_0_3", 257 | "Corner_0_0_3" 258 | ] 259 | }, 260 | "Corner_0_0_3": { 261 | "-1_0_0": [ 262 | "Edge_0_0_3", 263 | "Corner_0_0_2" 264 | ], 265 | "0_-1_0": [ 266 | "Floor" 267 | ], 268 | "0_0_-1": [ 269 | "Edge_0_0_0", 270 | "Corner_0_0_0" 271 | ], 272 | "0_0_1": [ 273 | "Empty" 274 | ], 275 | "0_1_0": [ 276 | "Edge_1_0_3", 277 | "Corner_0_3_3" 278 | ], 279 | "1_0_0": [ 280 | "Empty" 281 | ] 282 | }, 283 | "Corner_0_0_0": { 284 | "-1_0_0": [ 285 | "Edge_0_0_1", 286 | "Corner_0_0_1" 287 | ], 288 | "0_-1_0": [ 289 | "Floor" 290 | ], 291 | "0_0_-1": [ 292 | "Empty" 293 | ], 294 | "0_0_1": [ 295 | "Edge_0_0_0", 296 | "Corner_0_0_3" 297 | ], 298 | "0_1_0": [ 299 | "Edge_1_0_0", 300 | "Corner_0_3_0" 301 | ], 302 | "1_0_0": [ 303 | "Empty" 304 | ] 305 | }, 306 | "Corner_0_0_1": { 307 | "-1_0_0": [ 308 | "Empty" 309 | ], 310 | "0_-1_0": [ 311 | "Floor" 312 | ], 313 | "0_0_-1": [ 314 | "Empty" 315 | ], 316 | "0_0_1": [ 317 | "Edge_0_0_2", 318 | "Corner_0_0_2" 319 | ], 320 | "0_1_0": [ 321 | "Edge_1_0_1", 322 | "Corner_0_3_1" 323 | ], 324 | "1_0_0": [ 325 | "Edge_0_0_1", 326 | "Corner_0_0_0" 327 | ] 328 | }, 329 | "Edge_1_0_2": { 330 | "-1_0_0": [ 331 | "Empty", 332 | "ArchLeft_0_3_0" 333 | ], 334 | "0_-1_0": [ 335 | "Corner_0_0_2", 336 | "Edge_1_0_2", 337 | "Connector_0_0_0" 338 | ], 339 | "0_0_-1": [ 340 | "Wall_0_0_2", 341 | "Connector_0_0_0", 342 | "Edge_1_0_1" 343 | ], 344 | "0_0_1": [ 345 | "Empty", 346 | "ArchRight_0_3_1" 347 | ], 348 | "0_1_0": [ 349 | "Edge_1_0_2", 350 | "Corner_0_3_2", 351 | "Edge_0_3_3", 352 | "Wall_0_0_2", 353 | "Edge_0_3_2", 354 | "Wall_0_0_3" 355 | ], 356 | "1_0_0": [ 357 | "Wall_0_0_3", 358 | "Connector_0_0_0", 359 | "Edge_1_0_3" 360 | ] 361 | }, 362 | "Edge_1_0_3": { 363 | "-1_0_0": [ 364 | "Wall_0_0_3", 365 | "Connector_0_0_0", 366 | "Edge_1_0_2" 367 | ], 368 | "0_-1_0": [ 369 | "Corner_0_0_3", 370 | "Edge_1_0_3", 371 | "Connector_0_0_0" 372 | ], 373 | "0_0_-1": [ 374 | "Wall_0_0_0", 375 | "Connector_0_0_0", 376 | "Edge_1_0_0" 377 | ], 378 | "0_0_1": [ 379 | "Empty", 380 | "ArchLeft_0_3_1" 381 | ], 382 | "0_1_0": [ 383 | "Edge_1_0_3", 384 | "Corner_0_3_3", 385 | "Edge_0_3_0", 386 | "Wall_0_0_3", 387 | "Edge_0_3_3", 388 | "Wall_0_0_0" 389 | ], 390 | "1_0_0": [ 391 | "Empty", 392 | "ArchRight_0_3_2" 393 | ] 394 | }, 395 | "Edge_1_0_0": { 396 | "-1_0_0": [ 397 | "Wall_0_0_1", 398 | "Connector_0_0_0", 399 | "Edge_1_0_1" 400 | ], 401 | "0_-1_0": [ 402 | "Corner_0_0_0", 403 | "Edge_1_0_0", 404 | "Connector_0_0_0" 405 | ], 406 | "0_0_-1": [ 407 | "Empty", 408 | "ArchRight_0_3_3" 409 | ], 410 | "0_0_1": [ 411 | "Wall_0_0_0", 412 | "Connector_0_0_0", 413 | "Edge_1_0_3" 414 | ], 415 | "0_1_0": [ 416 | "Edge_1_0_0", 417 | "Corner_0_3_0", 418 | "Edge_0_3_1", 419 | "Wall_0_0_0", 420 | "Edge_0_3_0", 421 | "Wall_0_0_1" 422 | ], 423 | "1_0_0": [ 424 | "Empty", 425 | "ArchLeft_0_3_2" 426 | ] 427 | }, 428 | "Edge_1_0_1": { 429 | "-1_0_0": [ 430 | "Empty", 431 | "ArchRight_0_3_0" 432 | ], 433 | "0_-1_0": [ 434 | "Corner_0_0_1", 435 | "Edge_1_0_1", 436 | "Connector_0_0_0" 437 | ], 438 | "0_0_-1": [ 439 | "Empty", 440 | "ArchLeft_0_3_3" 441 | ], 442 | "0_0_1": [ 443 | "Wall_0_0_2", 444 | "Connector_0_0_0", 445 | "Edge_1_0_2" 446 | ], 447 | "0_1_0": [ 448 | "Edge_1_0_1", 449 | "Corner_0_3_1", 450 | "Edge_0_3_2", 451 | "Wall_0_0_1", 452 | "Edge_0_3_1", 453 | "Wall_0_0_2" 454 | ], 455 | "1_0_0": [ 456 | "Wall_0_0_1", 457 | "Connector_0_0_0", 458 | "Edge_1_0_0" 459 | ] 460 | }, 461 | "Corner_0_3_2": { 462 | "-1_0_0": [ 463 | "Empty" 464 | ], 465 | "0_-1_0": [ 466 | "Edge_1_0_2", 467 | "Corner_0_0_2", 468 | "Wall_0_0_2", 469 | "Wall_0_0_3" 470 | ], 471 | "0_0_-1": [ 472 | "Edge_0_3_2", 473 | "Wall_0_0_2", 474 | "StairWithWallRight_0_0_1", 475 | "FlatStairWithWallRightUper_0_0_1" 476 | ], 477 | "0_0_1": [ 478 | "Empty" 479 | ], 480 | "0_1_0": [ 481 | "Empty" 482 | ], 483 | "1_0_0": [ 484 | "Edge_0_3_3", 485 | "StairWithWallLeft_0_0_2", 486 | "Wall_0_0_3", 487 | "FlatStairWithWallLeftLowerUper_0_0_2" 488 | ] 489 | }, 490 | "Corner_0_3_3": { 491 | "-1_0_0": [ 492 | "Edge_0_3_3", 493 | "Wall_0_0_3", 494 | "StairWithWallRight_0_0_2", 495 | "FlatStairWithWallRightUper_0_0_2" 496 | ], 497 | "0_-1_0": [ 498 | "Edge_1_0_3", 499 | "Corner_0_0_3", 500 | "Wall_0_0_3", 501 | "Wall_0_0_0" 502 | ], 503 | "0_0_-1": [ 504 | "Edge_0_3_0", 505 | "StairWithWallLeft_0_0_3", 506 | "Wall_0_0_0", 507 | "FlatStairWithWallLeftLowerUper_0_0_3" 508 | ], 509 | "0_0_1": [ 510 | "Empty" 511 | ], 512 | "0_1_0": [ 513 | "Empty" 514 | ], 515 | "1_0_0": [ 516 | "Empty" 517 | ] 518 | }, 519 | "Corner_0_3_0": { 520 | "-1_0_0": [ 521 | "Edge_0_3_1", 522 | "StairWithWallLeft_0_0_0", 523 | "Wall_0_0_1", 524 | "FlatStairWithWallLeftLowerUper_0_0_0" 525 | ], 526 | "0_-1_0": [ 527 | "Edge_1_0_0", 528 | "Corner_0_0_0", 529 | "Wall_0_0_0", 530 | "Wall_0_0_1" 531 | ], 532 | "0_0_-1": [ 533 | "Empty" 534 | ], 535 | "0_0_1": [ 536 | "Edge_0_3_0", 537 | "Wall_0_0_0", 538 | "StairWithWallRight_0_0_3", 539 | "FlatStairWithWallRightUper_0_0_3" 540 | ], 541 | "0_1_0": [ 542 | "Empty" 543 | ], 544 | "1_0_0": [ 545 | "Empty" 546 | ] 547 | }, 548 | "Corner_0_3_1": { 549 | "-1_0_0": [ 550 | "Empty" 551 | ], 552 | "0_-1_0": [ 553 | "Edge_1_0_1", 554 | "Corner_0_0_1", 555 | "Wall_0_0_1", 556 | "Wall_0_0_2" 557 | ], 558 | "0_0_-1": [ 559 | "Empty" 560 | ], 561 | "0_0_1": [ 562 | "Edge_0_3_2", 563 | "StairWithWallLeft_0_0_1", 564 | "Wall_0_0_2", 565 | "FlatStairWithWallLeftLowerUper_0_0_1" 566 | ], 567 | "0_1_0": [ 568 | "Empty" 569 | ], 570 | "1_0_0": [ 571 | "Edge_0_3_1", 572 | "Wall_0_0_1", 573 | "StairWithWallRight_0_0_0", 574 | "FlatStairWithWallRightUper_0_0_0" 575 | ] 576 | }, 577 | "Edge_0_0_2": { 578 | "-1_0_0": [ 579 | "Empty" 580 | ], 581 | "0_-1_0": [ 582 | "Floor" 583 | ], 584 | "0_0_-1": [ 585 | "Edge_0_0_2", 586 | "Corner_0_0_1", 587 | "BendWallOuterTop_3_0_0" 588 | ], 589 | "0_0_1": [ 590 | "Corner_0_0_2", 591 | "Edge_0_0_2", 592 | "BendWallOuterTop_3_0_1" 593 | ], 594 | "0_1_0": [ 595 | "Wall_0_0_2", 596 | "Edge_0_3_2" 597 | ], 598 | "1_0_0": [ 599 | "Wall_0_1_0", 600 | "Wall_0_1_3", 601 | "Wall_0_1_1", 602 | "Wall_0_1_2", 603 | "Edge_0_0_0" 604 | ] 605 | }, 606 | "Edge_0_0_3": { 607 | "-1_0_0": [ 608 | "Edge_0_0_3", 609 | "Corner_0_0_2", 610 | "BendWallOuterTop_3_0_1" 611 | ], 612 | "0_-1_0": [ 613 | "Floor" 614 | ], 615 | "0_0_-1": [ 616 | "Wall_0_1_1", 617 | "Wall_0_1_0", 618 | "Wall_0_1_2", 619 | "Wall_0_1_3", 620 | "Edge_0_0_1" 621 | ], 622 | "0_0_1": [ 623 | "Empty" 624 | ], 625 | "0_1_0": [ 626 | "Wall_0_0_3", 627 | "Edge_0_3_3" 628 | ], 629 | "1_0_0": [ 630 | "Corner_0_0_3", 631 | "Edge_0_0_3", 632 | "BendWallOuterTop_3_0_2" 633 | ] 634 | }, 635 | "Edge_0_0_0": { 636 | "-1_0_0": [ 637 | "Wall_0_1_2", 638 | "Wall_0_1_1", 639 | "Wall_0_1_3", 640 | "Wall_0_1_0", 641 | "Edge_0_0_2" 642 | ], 643 | "0_-1_0": [ 644 | "Floor" 645 | ], 646 | "0_0_-1": [ 647 | "Corner_0_0_0", 648 | "Edge_0_0_0", 649 | "BendWallOuterTop_3_0_3" 650 | ], 651 | "0_0_1": [ 652 | "Edge_0_0_0", 653 | "Corner_0_0_3", 654 | "BendWallOuterTop_3_0_2" 655 | ], 656 | "0_1_0": [ 657 | "Wall_0_0_0", 658 | "Edge_0_3_0" 659 | ], 660 | "1_0_0": [ 661 | "Empty" 662 | ] 663 | }, 664 | "Edge_0_0_1": { 665 | "-1_0_0": [ 666 | "Corner_0_0_1", 667 | "Edge_0_0_1", 668 | "BendWallOuterTop_3_0_0" 669 | ], 670 | "0_-1_0": [ 671 | "Floor" 672 | ], 673 | "0_0_-1": [ 674 | "Empty" 675 | ], 676 | "0_0_1": [ 677 | "Wall_0_1_3", 678 | "Wall_0_1_2", 679 | "Wall_0_1_0", 680 | "Wall_0_1_1", 681 | "Edge_0_0_3" 682 | ], 683 | "0_1_0": [ 684 | "Wall_0_0_1", 685 | "Edge_0_3_1" 686 | ], 687 | "1_0_0": [ 688 | "Edge_0_0_1", 689 | "Corner_0_0_0", 690 | "BendWallOuterTop_3_0_3" 691 | ] 692 | }, 693 | "Wall_0_0_2": { 694 | "-1_0_0": [ 695 | "Empty", 696 | "Arch_0_3_0" 697 | ], 698 | "0_-1_0": [ 699 | "Edge_0_0_2", 700 | "Wall_0_0_2", 701 | "Connector_0_0_0", 702 | "Edge_1_0_2", 703 | "Edge_1_0_1" 704 | ], 705 | "0_0_-1": [ 706 | "Wall_0_0_2", 707 | "Edge_1_0_1", 708 | "BendWallOuter_1_0_3", 709 | "BendWallOuterLower_3_0_0", 710 | "StairsRight_0_0_0", 711 | "Edge_0_3_2", 712 | "Corner_0_3_1", 713 | "ArchLeft_0_3_3" 714 | ], 715 | "0_0_1": [ 716 | "Edge_1_0_2", 717 | "Wall_0_0_2", 718 | "BendWallOuter_1_0_0", 719 | "BendWallOuterLower_3_0_1", 720 | "StairsLeft_0_0_2", 721 | "Edge_0_3_2", 722 | "Corner_0_3_2", 723 | "ArchRight_0_3_1" 724 | ], 725 | "0_1_0": [ 726 | "Wall_0_0_2", 727 | "Edge_0_3_2", 728 | "StairsRight_0_0_0", 729 | "StairsLeft_0_0_2", 730 | "Corner_0_3_2", 731 | "Corner_0_3_1", 732 | "Wall_0_3_1", 733 | "Connector_0_0_0" 734 | ], 735 | "1_0_0": [ 736 | "Connector_0_0_0", 737 | "Wall_0_0_0" 738 | ] 739 | }, 740 | "Wall_0_0_3": { 741 | "-1_0_0": [ 742 | "Wall_0_0_3", 743 | "Edge_1_0_2", 744 | "BendWallOuter_1_0_0", 745 | "BendWallOuterLower_3_0_1", 746 | "StairsRight_0_0_1", 747 | "Edge_0_3_3", 748 | "Corner_0_3_2", 749 | "ArchLeft_0_3_0" 750 | ], 751 | "0_-1_0": [ 752 | "Edge_0_0_3", 753 | "Wall_0_0_3", 754 | "Connector_0_0_0", 755 | "Edge_1_0_3", 756 | "Edge_1_0_2" 757 | ], 758 | "0_0_-1": [ 759 | "Connector_0_0_0", 760 | "Wall_0_0_1" 761 | ], 762 | "0_0_1": [ 763 | "Empty", 764 | "Arch_0_3_1" 765 | ], 766 | "0_1_0": [ 767 | "Wall_0_0_3", 768 | "Edge_0_3_3", 769 | "StairsRight_0_0_1", 770 | "StairsLeft_0_0_3", 771 | "Corner_0_3_3", 772 | "Corner_0_3_2", 773 | "Wall_0_3_2", 774 | "Connector_0_0_0" 775 | ], 776 | "1_0_0": [ 777 | "Edge_1_0_3", 778 | "Wall_0_0_3", 779 | "BendWallOuter_1_0_1", 780 | "BendWallOuterLower_3_0_2", 781 | "StairsLeft_0_0_3", 782 | "Edge_0_3_3", 783 | "Corner_0_3_3", 784 | "ArchRight_0_3_2" 785 | ] 786 | }, 787 | "Wall_0_0_0": { 788 | "-1_0_0": [ 789 | "Connector_0_0_0", 790 | "Wall_0_0_2" 791 | ], 792 | "0_-1_0": [ 793 | "Edge_0_0_0", 794 | "Wall_0_0_0", 795 | "Connector_0_0_0", 796 | "Edge_1_0_0", 797 | "Edge_1_0_3" 798 | ], 799 | "0_0_-1": [ 800 | "Edge_1_0_0", 801 | "Wall_0_0_0", 802 | "BendWallOuter_1_0_2", 803 | "BendWallOuterLower_3_0_3", 804 | "StairsLeft_0_0_0", 805 | "Edge_0_3_0", 806 | "Corner_0_3_0", 807 | "ArchRight_0_3_3" 808 | ], 809 | "0_0_1": [ 810 | "Wall_0_0_0", 811 | "Edge_1_0_3", 812 | "BendWallOuter_1_0_1", 813 | "BendWallOuterLower_3_0_2", 814 | "StairsRight_0_0_2", 815 | "Edge_0_3_0", 816 | "Corner_0_3_3", 817 | "ArchLeft_0_3_1" 818 | ], 819 | "0_1_0": [ 820 | "Wall_0_0_0", 821 | "Edge_0_3_0", 822 | "StairsRight_0_0_2", 823 | "StairsLeft_0_0_0", 824 | "Corner_0_3_0", 825 | "Corner_0_3_3", 826 | "Wall_0_3_3", 827 | "Connector_0_0_0" 828 | ], 829 | "1_0_0": [ 830 | "Empty", 831 | "Arch_0_3_2" 832 | ] 833 | }, 834 | "Wall_0_0_1": { 835 | "-1_0_0": [ 836 | "Edge_1_0_1", 837 | "Wall_0_0_1", 838 | "BendWallOuter_1_0_3", 839 | "BendWallOuterLower_3_0_0", 840 | "StairsLeft_0_0_1", 841 | "Edge_0_3_1", 842 | "Corner_0_3_1", 843 | "ArchRight_0_3_0" 844 | ], 845 | "0_-1_0": [ 846 | "Edge_0_0_1", 847 | "Wall_0_0_1", 848 | "Connector_0_0_0", 849 | "Edge_1_0_1", 850 | "Edge_1_0_0" 851 | ], 852 | "0_0_-1": [ 853 | "Empty", 854 | "Arch_0_3_3" 855 | ], 856 | "0_0_1": [ 857 | "Connector_0_0_0", 858 | "Wall_0_0_3" 859 | ], 860 | "0_1_0": [ 861 | "Wall_0_0_1", 862 | "Edge_0_3_1", 863 | "StairsRight_0_0_3", 864 | "StairsLeft_0_0_1", 865 | "Corner_0_3_1", 866 | "Corner_0_3_0", 867 | "Wall_0_3_0", 868 | "Connector_0_0_0" 869 | ], 870 | "1_0_0": [ 871 | "Wall_0_0_1", 872 | "Edge_1_0_0", 873 | "BendWallOuter_1_0_2", 874 | "BendWallOuterLower_3_0_3", 875 | "StairsRight_0_0_3", 876 | "Edge_0_3_1", 877 | "Corner_0_3_0", 878 | "ArchLeft_0_3_2" 879 | ] 880 | }, 881 | "Edge_0_3_2": { 882 | "-1_0_0": [ 883 | "Empty" 884 | ], 885 | "0_-1_0": [ 886 | "Wall_0_0_2", 887 | "Connector_0_0_0", 888 | "Edge_0_0_2", 889 | "Edge_1_0_1", 890 | "ArchLeft_0_3_3", 891 | "ArchRight_0_3_1", 892 | "Edge_1_0_2" 893 | ], 894 | "0_0_-1": [ 895 | "Edge_0_3_2", 896 | "Corner_0_3_1", 897 | "BendWallOuterTop_1_0_3", 898 | "Wall_0_3_2", 899 | "Wall_0_0_2" 900 | ], 901 | "0_0_1": [ 902 | "Corner_0_3_2", 903 | "Edge_0_3_2", 904 | "BendWallOuterTop_1_0_0", 905 | "Wall_0_0_2", 906 | "Wall_0_3_0" 907 | ], 908 | "0_1_0": [ 909 | "Empty" 910 | ], 911 | "1_0_0": [ 912 | "Wall_0_3_0", 913 | "Wall_0_3_3", 914 | "Wall_0_3_1", 915 | "Wall_0_3_2", 916 | "Connector_0_0_0" 917 | ] 918 | }, 919 | "Edge_0_3_3": { 920 | "-1_0_0": [ 921 | "Edge_0_3_3", 922 | "Corner_0_3_2", 923 | "BendWallOuterTop_1_0_0", 924 | "Wall_0_3_3", 925 | "Wall_0_0_3" 926 | ], 927 | "0_-1_0": [ 928 | "Wall_0_0_3", 929 | "Connector_0_0_0", 930 | "Edge_0_0_3", 931 | "Edge_1_0_2", 932 | "ArchLeft_0_3_0", 933 | "ArchRight_0_3_2", 934 | "Edge_1_0_3" 935 | ], 936 | "0_0_-1": [ 937 | "Wall_0_3_1", 938 | "Wall_0_3_0", 939 | "Wall_0_3_2", 940 | "Wall_0_3_3", 941 | "Connector_0_0_0" 942 | ], 943 | "0_0_1": [ 944 | "Empty" 945 | ], 946 | "0_1_0": [ 947 | "Empty" 948 | ], 949 | "1_0_0": [ 950 | "Corner_0_3_3", 951 | "Edge_0_3_3", 952 | "BendWallOuterTop_1_0_1", 953 | "Wall_0_0_3", 954 | "Wall_0_3_1" 955 | ] 956 | }, 957 | "Edge_0_3_0": { 958 | "-1_0_0": [ 959 | "Wall_0_3_2", 960 | "Wall_0_3_1", 961 | "Wall_0_3_3", 962 | "Wall_0_3_0", 963 | "Connector_0_0_0" 964 | ], 965 | "0_-1_0": [ 966 | "Wall_0_0_0", 967 | "Connector_0_0_0", 968 | "Edge_0_0_0", 969 | "Edge_1_0_3", 970 | "ArchLeft_0_3_1", 971 | "ArchRight_0_3_3", 972 | "Edge_1_0_0" 973 | ], 974 | "0_0_-1": [ 975 | "Corner_0_3_0", 976 | "Edge_0_3_0", 977 | "BendWallOuterTop_1_0_2", 978 | "Wall_0_0_0", 979 | "Wall_0_3_2" 980 | ], 981 | "0_0_1": [ 982 | "Edge_0_3_0", 983 | "Corner_0_3_3", 984 | "BendWallOuterTop_1_0_1", 985 | "Wall_0_3_0", 986 | "Wall_0_0_0" 987 | ], 988 | "0_1_0": [ 989 | "Empty" 990 | ], 991 | "1_0_0": [ 992 | "Empty" 993 | ] 994 | }, 995 | "Edge_0_3_1": { 996 | "-1_0_0": [ 997 | "Corner_0_3_1", 998 | "Edge_0_3_1", 999 | "BendWallOuterTop_1_0_3", 1000 | "Wall_0_0_1", 1001 | "Wall_0_3_3" 1002 | ], 1003 | "0_-1_0": [ 1004 | "Wall_0_0_1", 1005 | "Connector_0_0_0", 1006 | "Edge_0_0_1", 1007 | "Edge_1_0_0", 1008 | "ArchLeft_0_3_2", 1009 | "ArchRight_0_3_0", 1010 | "Edge_1_0_1" 1011 | ], 1012 | "0_0_-1": [ 1013 | "Empty" 1014 | ], 1015 | "0_0_1": [ 1016 | "Wall_0_3_3", 1017 | "Wall_0_3_2", 1018 | "Wall_0_3_0", 1019 | "Wall_0_3_1", 1020 | "Connector_0_0_0" 1021 | ], 1022 | "0_1_0": [ 1023 | "Empty" 1024 | ], 1025 | "1_0_0": [ 1026 | "Edge_0_3_1", 1027 | "Corner_0_3_0", 1028 | "BendWallOuterTop_1_0_2", 1029 | "Wall_0_3_1", 1030 | "Wall_0_0_1" 1031 | ] 1032 | }, 1033 | "Wall_0_1_0": { 1034 | "-1_0_0": [ 1035 | "Edge_0_0_2", 1036 | "Wall_0_1_0" 1037 | ], 1038 | "0_-1_0": [ 1039 | "Floor" 1040 | ], 1041 | "0_0_-1": [ 1042 | "Wall_0_1_0", 1043 | "Edge_0_0_1" 1044 | ], 1045 | "0_0_1": [ 1046 | "Edge_0_0_3", 1047 | "Wall_0_1_0" 1048 | ], 1049 | "0_1_0": [ 1050 | "Connector_0_0_0" 1051 | ], 1052 | "1_0_0": [ 1053 | "Wall_0_1_0", 1054 | "Edge_0_0_0" 1055 | ] 1056 | }, 1057 | "Wall_0_1_1": { 1058 | "-1_0_0": [ 1059 | "Wall_0_1_1", 1060 | "Edge_0_0_2" 1061 | ], 1062 | "0_-1_0": [ 1063 | "Floor" 1064 | ], 1065 | "0_0_-1": [ 1066 | "Wall_0_1_1", 1067 | "Edge_0_0_1" 1068 | ], 1069 | "0_0_1": [ 1070 | "Edge_0_0_3", 1071 | "Wall_0_1_1" 1072 | ], 1073 | "0_1_0": [ 1074 | "Connector_0_0_0" 1075 | ], 1076 | "1_0_0": [ 1077 | "Edge_0_0_0", 1078 | "Wall_0_1_1" 1079 | ] 1080 | }, 1081 | "Wall_0_1_2": { 1082 | "-1_0_0": [ 1083 | "Wall_0_1_2", 1084 | "Edge_0_0_2" 1085 | ], 1086 | "0_-1_0": [ 1087 | "Floor" 1088 | ], 1089 | "0_0_-1": [ 1090 | "Edge_0_0_1", 1091 | "Wall_0_1_2" 1092 | ], 1093 | "0_0_1": [ 1094 | "Wall_0_1_2", 1095 | "Edge_0_0_3" 1096 | ], 1097 | "0_1_0": [ 1098 | "Connector_0_0_0" 1099 | ], 1100 | "1_0_0": [ 1101 | "Edge_0_0_0", 1102 | "Wall_0_1_2" 1103 | ] 1104 | }, 1105 | "Wall_0_1_3": { 1106 | "-1_0_0": [ 1107 | "Edge_0_0_2", 1108 | "Wall_0_1_3" 1109 | ], 1110 | "0_-1_0": [ 1111 | "Floor" 1112 | ], 1113 | "0_0_-1": [ 1114 | "Edge_0_0_1", 1115 | "Wall_0_1_3" 1116 | ], 1117 | "0_0_1": [ 1118 | "Wall_0_1_3", 1119 | "Edge_0_0_3" 1120 | ], 1121 | "0_1_0": [ 1122 | "Connector_0_0_0" 1123 | ], 1124 | "1_0_0": [ 1125 | "Wall_0_1_3", 1126 | "Edge_0_0_0" 1127 | ] 1128 | }, 1129 | "Connector_0_0_0": { 1130 | "-1_0_0": [ 1131 | "Wall_0_0_2", 1132 | "Connector_0_0_0", 1133 | "Edge_0_3_2", 1134 | "StairsRight_0_0_0", 1135 | "Edge_1_0_2", 1136 | "Edge_1_0_1", 1137 | "StairsLeft_0_0_2", 1138 | "StairWithWallLeft_0_0_1", 1139 | "Wall_0_3_1", 1140 | "StairWithWallRight_0_0_1", 1141 | "Arch_0_3_0", 1142 | "ArchLeft_0_3_0", 1143 | "BendWallOuter_1_0_0", 1144 | "ArchRight_0_3_0", 1145 | "BendWallOuter_1_0_3" 1146 | ], 1147 | "0_-1_0": [ 1148 | "Wall_0_1_0", 1149 | "Wall_0_1_1", 1150 | "Wall_0_1_2", 1151 | "Wall_0_1_3", 1152 | "Connector_0_0_0", 1153 | "Wall_0_0_3", 1154 | "Wall_0_0_0", 1155 | "Wall_0_0_1", 1156 | "Wall_0_0_2" 1157 | ], 1158 | "0_0_-1": [ 1159 | "Connector_0_0_0", 1160 | "Wall_0_0_1", 1161 | "Edge_0_3_1", 1162 | "Edge_1_0_1", 1163 | "StairsRight_0_0_3", 1164 | "Edge_1_0_0", 1165 | "StairsLeft_0_0_1", 1166 | "StairWithWallLeft_0_0_0", 1167 | "Wall_0_3_0", 1168 | "StairWithWallRight_0_0_0", 1169 | "Arch_0_3_3", 1170 | "ArchLeft_0_3_3", 1171 | "ArchRight_0_3_3", 1172 | "BendWallOuter_1_0_3", 1173 | "BendWallOuter_1_0_2" 1174 | ], 1175 | "0_0_1": [ 1176 | "Wall_0_0_3", 1177 | "Connector_0_0_0", 1178 | "Edge_0_3_3", 1179 | "StairsRight_0_0_1", 1180 | "Edge_1_0_3", 1181 | "Edge_1_0_2", 1182 | "StairsLeft_0_0_3", 1183 | "StairWithWallLeft_0_0_2", 1184 | "Wall_0_3_2", 1185 | "StairWithWallRight_0_0_2", 1186 | "Arch_0_3_1", 1187 | "ArchLeft_0_3_1", 1188 | "ArchRight_0_3_1", 1189 | "BendWallOuter_1_0_1", 1190 | "BendWallOuter_1_0_0" 1191 | ], 1192 | "0_1_0": [ 1193 | "Connector_0_0_0", 1194 | "Wall_0_3_0", 1195 | "Wall_0_3_1", 1196 | "Wall_0_3_2", 1197 | "Wall_0_3_3", 1198 | "BendWallOuterLower_3_0_1", 1199 | "BendWallOuterLower_3_0_2", 1200 | "BendWallOuterLower_3_0_3", 1201 | "BendWallOuterLower_3_0_0", 1202 | "Wall_0_0_2", 1203 | "Wall_0_0_3", 1204 | "Wall_0_0_0", 1205 | "Wall_0_0_1", 1206 | "Edge_0_3_2", 1207 | "Edge_0_3_3", 1208 | "Edge_0_3_0", 1209 | "Edge_0_3_1", 1210 | "Edge_1_0_1", 1211 | "Edge_1_0_2", 1212 | "Edge_1_0_3", 1213 | "Edge_1_0_0", 1214 | "StairWithWallLeft_0_0_2", 1215 | "StairWithWallLeft_0_0_3", 1216 | "StairWithWallLeft_0_0_0", 1217 | "StairWithWallLeft_0_0_1", 1218 | "StairWithWallRight_0_0_0", 1219 | "StairWithWallRight_0_0_1", 1220 | "StairWithWallRight_0_0_2", 1221 | "StairWithWallRight_0_0_3", 1222 | "FlatStairWithWallRightUper_0_0_0", 1223 | "FlatStairWithWallRightUper_0_0_1", 1224 | "FlatStairWithWallRightUper_0_0_2", 1225 | "FlatStairWithWallRightUper_0_0_3", 1226 | "FlatStairWithWallLeftLowerUper_0_0_2", 1227 | "FlatStairWithWallLeftLowerUper_0_0_3", 1228 | "FlatStairWithWallLeftLowerUper_0_0_0", 1229 | "FlatStairWithWallLeftLowerUper_0_0_1" 1230 | ], 1231 | "1_0_0": [ 1232 | "Connector_0_0_0", 1233 | "Wall_0_0_0", 1234 | "Edge_0_3_0", 1235 | "StairsRight_0_0_2", 1236 | "Edge_1_0_0", 1237 | "StairsLeft_0_0_0", 1238 | "Edge_1_0_3", 1239 | "StairWithWallLeft_0_0_3", 1240 | "Wall_0_3_3", 1241 | "StairWithWallRight_0_0_3", 1242 | "Arch_0_3_2", 1243 | "ArchLeft_0_3_2", 1244 | "ArchRight_0_3_2", 1245 | "BendWallOuter_1_0_2", 1246 | "BendWallOuter_1_0_1" 1247 | ] 1248 | }, 1249 | "Wall_0_3_0": { 1250 | "-1_0_0": [ 1251 | "Edge_0_3_2", 1252 | "Wall_0_3_0", 1253 | "StairsRight_0_0_0" 1254 | ], 1255 | "0_-1_0": [ 1256 | "Connector_0_0_0", 1257 | "Wall_0_0_1", 1258 | "Arch_0_3_3", 1259 | "Arch_0_3_1" 1260 | ], 1261 | "0_0_-1": [ 1262 | "Wall_0_3_0", 1263 | "Edge_0_3_1", 1264 | "Edge_0_3_2", 1265 | "Edge_0_3_0", 1266 | "StairWithWallRight_0_0_0", 1267 | "StairWithWallLeft_0_0_0", 1268 | "FlatStairWithWallRightUper_0_0_0", 1269 | "FlatStairWithWallLeftLowerUper_0_0_0" 1270 | ], 1271 | "0_0_1": [ 1272 | "Edge_0_3_3", 1273 | "Wall_0_3_0", 1274 | "StairWithWallLeft_0_0_2", 1275 | "Connector_0_0_0", 1276 | "StairWithWallRight_0_0_2", 1277 | "FlatStairWithWallLeftLowerUper_0_0_2", 1278 | "FlatStairWithWallRightUper_0_0_2" 1279 | ], 1280 | "0_1_0": [ 1281 | "Empty" 1282 | ], 1283 | "1_0_0": [ 1284 | "Wall_0_3_0", 1285 | "Edge_0_3_0", 1286 | "StairsLeft_0_0_0" 1287 | ] 1288 | }, 1289 | "Wall_0_3_1": { 1290 | "-1_0_0": [ 1291 | "Wall_0_3_1", 1292 | "Edge_0_3_2", 1293 | "Edge_0_3_3", 1294 | "Edge_0_3_1", 1295 | "StairWithWallRight_0_0_1", 1296 | "StairWithWallLeft_0_0_1", 1297 | "FlatStairWithWallRightUper_0_0_1", 1298 | "FlatStairWithWallLeftLowerUper_0_0_1" 1299 | ], 1300 | "0_-1_0": [ 1301 | "Connector_0_0_0", 1302 | "Wall_0_0_2", 1303 | "Arch_0_3_0", 1304 | "Arch_0_3_2" 1305 | ], 1306 | "0_0_-1": [ 1307 | "Wall_0_3_1", 1308 | "Edge_0_3_1", 1309 | "StairsLeft_0_0_1" 1310 | ], 1311 | "0_0_1": [ 1312 | "Edge_0_3_3", 1313 | "Wall_0_3_1", 1314 | "StairsRight_0_0_1" 1315 | ], 1316 | "0_1_0": [ 1317 | "Empty" 1318 | ], 1319 | "1_0_0": [ 1320 | "Edge_0_3_0", 1321 | "Wall_0_3_1", 1322 | "StairWithWallLeft_0_0_3", 1323 | "Connector_0_0_0", 1324 | "StairWithWallRight_0_0_3", 1325 | "FlatStairWithWallLeftLowerUper_0_0_3", 1326 | "FlatStairWithWallRightUper_0_0_3" 1327 | ] 1328 | }, 1329 | "Wall_0_3_2": { 1330 | "-1_0_0": [ 1331 | "Wall_0_3_2", 1332 | "Edge_0_3_2", 1333 | "StairsLeft_0_0_2" 1334 | ], 1335 | "0_-1_0": [ 1336 | "Connector_0_0_0", 1337 | "Wall_0_0_3", 1338 | "Arch_0_3_1", 1339 | "Arch_0_3_3" 1340 | ], 1341 | "0_0_-1": [ 1342 | "Edge_0_3_1", 1343 | "Wall_0_3_2", 1344 | "StairWithWallLeft_0_0_0", 1345 | "Connector_0_0_0", 1346 | "StairWithWallRight_0_0_0", 1347 | "FlatStairWithWallLeftLowerUper_0_0_0", 1348 | "FlatStairWithWallRightUper_0_0_0" 1349 | ], 1350 | "0_0_1": [ 1351 | "Wall_0_3_2", 1352 | "Edge_0_3_3", 1353 | "Edge_0_3_0", 1354 | "Edge_0_3_2", 1355 | "StairWithWallRight_0_0_2", 1356 | "StairWithWallLeft_0_0_2", 1357 | "FlatStairWithWallRightUper_0_0_2", 1358 | "FlatStairWithWallLeftLowerUper_0_0_2" 1359 | ], 1360 | "0_1_0": [ 1361 | "Empty" 1362 | ], 1363 | "1_0_0": [ 1364 | "Edge_0_3_0", 1365 | "Wall_0_3_2", 1366 | "StairsRight_0_0_2" 1367 | ] 1368 | }, 1369 | "Wall_0_3_3": { 1370 | "-1_0_0": [ 1371 | "Edge_0_3_2", 1372 | "Wall_0_3_3", 1373 | "StairWithWallLeft_0_0_1", 1374 | "Connector_0_0_0", 1375 | "StairWithWallRight_0_0_1", 1376 | "FlatStairWithWallLeftLowerUper_0_0_1", 1377 | "FlatStairWithWallRightUper_0_0_1" 1378 | ], 1379 | "0_-1_0": [ 1380 | "Connector_0_0_0", 1381 | "Wall_0_0_0", 1382 | "Arch_0_3_2", 1383 | "Arch_0_3_0" 1384 | ], 1385 | "0_0_-1": [ 1386 | "Edge_0_3_1", 1387 | "Wall_0_3_3", 1388 | "StairsRight_0_0_3" 1389 | ], 1390 | "0_0_1": [ 1391 | "Wall_0_3_3", 1392 | "Edge_0_3_3", 1393 | "StairsLeft_0_0_3" 1394 | ], 1395 | "0_1_0": [ 1396 | "Empty" 1397 | ], 1398 | "1_0_0": [ 1399 | "Wall_0_3_3", 1400 | "Edge_0_3_0", 1401 | "Edge_0_3_1", 1402 | "Edge_0_3_3", 1403 | "StairWithWallRight_0_0_3", 1404 | "StairWithWallLeft_0_0_3", 1405 | "FlatStairWithWallRightUper_0_0_3", 1406 | "FlatStairWithWallLeftLowerUper_0_0_3" 1407 | ] 1408 | }, 1409 | "BendWallOuterTop_3_0_1": { 1410 | "-1_0_0": [ 1411 | "Empty" 1412 | ], 1413 | "0_-1_0": [ 1414 | "Floor" 1415 | ], 1416 | "0_0_-1": [ 1417 | "Edge_0_0_2" 1418 | ], 1419 | "0_0_1": [ 1420 | "Empty" 1421 | ], 1422 | "0_1_0": [ 1423 | "BendWallOuter_1_0_0" 1424 | ], 1425 | "1_0_0": [ 1426 | "Edge_0_0_3" 1427 | ] 1428 | }, 1429 | "BendWallOuterTop_3_0_2": { 1430 | "-1_0_0": [ 1431 | "Edge_0_0_3" 1432 | ], 1433 | "0_-1_0": [ 1434 | "Floor" 1435 | ], 1436 | "0_0_-1": [ 1437 | "Edge_0_0_0" 1438 | ], 1439 | "0_0_1": [ 1440 | "Empty" 1441 | ], 1442 | "0_1_0": [ 1443 | "BendWallOuter_1_0_1" 1444 | ], 1445 | "1_0_0": [ 1446 | "Empty" 1447 | ] 1448 | }, 1449 | "BendWallOuterTop_3_0_3": { 1450 | "-1_0_0": [ 1451 | "Edge_0_0_1" 1452 | ], 1453 | "0_-1_0": [ 1454 | "Floor" 1455 | ], 1456 | "0_0_-1": [ 1457 | "Empty" 1458 | ], 1459 | "0_0_1": [ 1460 | "Edge_0_0_0" 1461 | ], 1462 | "0_1_0": [ 1463 | "BendWallOuter_1_0_2" 1464 | ], 1465 | "1_0_0": [ 1466 | "Empty" 1467 | ] 1468 | }, 1469 | "BendWallOuterTop_3_0_0": { 1470 | "-1_0_0": [ 1471 | "Empty" 1472 | ], 1473 | "0_-1_0": [ 1474 | "Floor" 1475 | ], 1476 | "0_0_-1": [ 1477 | "Empty" 1478 | ], 1479 | "0_0_1": [ 1480 | "Edge_0_0_2" 1481 | ], 1482 | "0_1_0": [ 1483 | "BendWallOuter_1_0_3" 1484 | ], 1485 | "1_0_0": [ 1486 | "Edge_0_0_1" 1487 | ] 1488 | }, 1489 | "BendWallOuter_1_0_0": { 1490 | "-1_0_0": [ 1491 | "Empty" 1492 | ], 1493 | "0_-1_0": [ 1494 | "BendWallOuterTop_3_0_1", 1495 | "BendWallOuter_1_0_0", 1496 | "BendWallOuterLower_3_0_1" 1497 | ], 1498 | "0_0_-1": [ 1499 | "Wall_0_0_2", 1500 | "Connector_0_0_0" 1501 | ], 1502 | "0_0_1": [ 1503 | "Empty" 1504 | ], 1505 | "0_1_0": [ 1506 | "BendWallOuter_1_0_0", 1507 | "BendWallOuterTop_1_0_0" 1508 | ], 1509 | "1_0_0": [ 1510 | "Wall_0_0_3", 1511 | "Connector_0_0_0" 1512 | ] 1513 | }, 1514 | "BendWallOuter_1_0_1": { 1515 | "-1_0_0": [ 1516 | "Wall_0_0_3", 1517 | "Connector_0_0_0" 1518 | ], 1519 | "0_-1_0": [ 1520 | "BendWallOuterTop_3_0_2", 1521 | "BendWallOuter_1_0_1", 1522 | "BendWallOuterLower_3_0_2" 1523 | ], 1524 | "0_0_-1": [ 1525 | "Wall_0_0_0", 1526 | "Connector_0_0_0" 1527 | ], 1528 | "0_0_1": [ 1529 | "Empty" 1530 | ], 1531 | "0_1_0": [ 1532 | "BendWallOuter_1_0_1", 1533 | "BendWallOuterTop_1_0_1" 1534 | ], 1535 | "1_0_0": [ 1536 | "Empty" 1537 | ] 1538 | }, 1539 | "BendWallOuter_1_0_2": { 1540 | "-1_0_0": [ 1541 | "Wall_0_0_1", 1542 | "Connector_0_0_0" 1543 | ], 1544 | "0_-1_0": [ 1545 | "BendWallOuterTop_3_0_3", 1546 | "BendWallOuter_1_0_2", 1547 | "BendWallOuterLower_3_0_3" 1548 | ], 1549 | "0_0_-1": [ 1550 | "Empty" 1551 | ], 1552 | "0_0_1": [ 1553 | "Wall_0_0_0", 1554 | "Connector_0_0_0" 1555 | ], 1556 | "0_1_0": [ 1557 | "BendWallOuter_1_0_2", 1558 | "BendWallOuterTop_1_0_2" 1559 | ], 1560 | "1_0_0": [ 1561 | "Empty" 1562 | ] 1563 | }, 1564 | "BendWallOuter_1_0_3": { 1565 | "-1_0_0": [ 1566 | "Empty" 1567 | ], 1568 | "0_-1_0": [ 1569 | "BendWallOuterTop_3_0_0", 1570 | "BendWallOuter_1_0_3", 1571 | "BendWallOuterLower_3_0_0" 1572 | ], 1573 | "0_0_-1": [ 1574 | "Empty" 1575 | ], 1576 | "0_0_1": [ 1577 | "Wall_0_0_2", 1578 | "Connector_0_0_0" 1579 | ], 1580 | "0_1_0": [ 1581 | "BendWallOuter_1_0_3", 1582 | "BendWallOuterTop_1_0_3" 1583 | ], 1584 | "1_0_0": [ 1585 | "Wall_0_0_1", 1586 | "Connector_0_0_0" 1587 | ] 1588 | }, 1589 | "BendWallOuterTop_1_0_0": { 1590 | "-1_0_0": [ 1591 | "Empty" 1592 | ], 1593 | "0_-1_0": [ 1594 | "BendWallOuter_1_0_0" 1595 | ], 1596 | "0_0_-1": [ 1597 | "Edge_0_3_2", 1598 | "StairsRight_0_0_0", 1599 | "FlatStairWithWallRightUper_0_0_1" 1600 | ], 1601 | "0_0_1": [ 1602 | "Empty" 1603 | ], 1604 | "0_1_0": [ 1605 | "Empty" 1606 | ], 1607 | "1_0_0": [ 1608 | "Edge_0_3_3", 1609 | "StairsLeft_0_0_3", 1610 | "FlatStairWithWallLeftLowerUper_0_0_2" 1611 | ] 1612 | }, 1613 | "BendWallOuterTop_1_0_1": { 1614 | "-1_0_0": [ 1615 | "Edge_0_3_3", 1616 | "StairsRight_0_0_1", 1617 | "FlatStairWithWallRightUper_0_0_2" 1618 | ], 1619 | "0_-1_0": [ 1620 | "BendWallOuter_1_0_1" 1621 | ], 1622 | "0_0_-1": [ 1623 | "Edge_0_3_0", 1624 | "StairsLeft_0_0_0", 1625 | "FlatStairWithWallLeftLowerUper_0_0_3" 1626 | ], 1627 | "0_0_1": [ 1628 | "Empty" 1629 | ], 1630 | "0_1_0": [ 1631 | "Empty" 1632 | ], 1633 | "1_0_0": [ 1634 | "Empty" 1635 | ] 1636 | }, 1637 | "BendWallOuterTop_1_0_2": { 1638 | "-1_0_0": [ 1639 | "Edge_0_3_1", 1640 | "StairsLeft_0_0_1", 1641 | "FlatStairWithWallLeftLowerUper_0_0_0" 1642 | ], 1643 | "0_-1_0": [ 1644 | "BendWallOuter_1_0_2" 1645 | ], 1646 | "0_0_-1": [ 1647 | "Empty" 1648 | ], 1649 | "0_0_1": [ 1650 | "Edge_0_3_0", 1651 | "StairsRight_0_0_2", 1652 | "FlatStairWithWallRightUper_0_0_3" 1653 | ], 1654 | "0_1_0": [ 1655 | "Empty" 1656 | ], 1657 | "1_0_0": [ 1658 | "Empty" 1659 | ] 1660 | }, 1661 | "BendWallOuterTop_1_0_3": { 1662 | "-1_0_0": [ 1663 | "Empty" 1664 | ], 1665 | "0_-1_0": [ 1666 | "BendWallOuter_1_0_3" 1667 | ], 1668 | "0_0_-1": [ 1669 | "Empty" 1670 | ], 1671 | "0_0_1": [ 1672 | "Edge_0_3_2", 1673 | "StairsLeft_0_0_2", 1674 | "FlatStairWithWallLeftLowerUper_0_0_1" 1675 | ], 1676 | "0_1_0": [ 1677 | "Empty" 1678 | ], 1679 | "1_0_0": [ 1680 | "Edge_0_3_1", 1681 | "StairsRight_0_0_3", 1682 | "FlatStairWithWallRightUper_0_0_0" 1683 | ] 1684 | }, 1685 | "BendWallOuterLower_3_0_1": { 1686 | "-1_0_0": [ 1687 | "Empty" 1688 | ], 1689 | "0_-1_0": [ 1690 | "Connector_0_0_0" 1691 | ], 1692 | "0_0_-1": [ 1693 | "Wall_0_0_2" 1694 | ], 1695 | "0_0_1": [ 1696 | "Empty" 1697 | ], 1698 | "0_1_0": [ 1699 | "BendWallOuter_1_0_0" 1700 | ], 1701 | "1_0_0": [ 1702 | "Wall_0_0_3" 1703 | ] 1704 | }, 1705 | "BendWallOuterLower_3_0_2": { 1706 | "-1_0_0": [ 1707 | "Wall_0_0_3" 1708 | ], 1709 | "0_-1_0": [ 1710 | "Connector_0_0_0" 1711 | ], 1712 | "0_0_-1": [ 1713 | "Wall_0_0_0" 1714 | ], 1715 | "0_0_1": [ 1716 | "Empty" 1717 | ], 1718 | "0_1_0": [ 1719 | "BendWallOuter_1_0_1" 1720 | ], 1721 | "1_0_0": [ 1722 | "Empty" 1723 | ] 1724 | }, 1725 | "BendWallOuterLower_3_0_3": { 1726 | "-1_0_0": [ 1727 | "Wall_0_0_1" 1728 | ], 1729 | "0_-1_0": [ 1730 | "Connector_0_0_0" 1731 | ], 1732 | "0_0_-1": [ 1733 | "Empty" 1734 | ], 1735 | "0_0_1": [ 1736 | "Wall_0_0_0" 1737 | ], 1738 | "0_1_0": [ 1739 | "BendWallOuter_1_0_2" 1740 | ], 1741 | "1_0_0": [ 1742 | "Empty" 1743 | ] 1744 | }, 1745 | "BendWallOuterLower_3_0_0": { 1746 | "-1_0_0": [ 1747 | "Empty" 1748 | ], 1749 | "0_-1_0": [ 1750 | "Connector_0_0_0" 1751 | ], 1752 | "0_0_-1": [ 1753 | "Empty" 1754 | ], 1755 | "0_0_1": [ 1756 | "Wall_0_0_2" 1757 | ], 1758 | "0_1_0": [ 1759 | "BendWallOuter_1_0_3" 1760 | ], 1761 | "1_0_0": [ 1762 | "Wall_0_0_1" 1763 | ] 1764 | }, 1765 | "StairsRight_0_0_0": { 1766 | "-1_0_0": [ 1767 | "Empty" 1768 | ], 1769 | "0_-1_0": [ 1770 | "Wall_0_0_2" 1771 | ], 1772 | "0_0_-1": [ 1773 | "Empty" 1774 | ], 1775 | "0_0_1": [ 1776 | "BendWallOuterTop_1_0_0", 1777 | "Wall_0_0_2" 1778 | ], 1779 | "0_1_0": [ 1780 | "Empty" 1781 | ], 1782 | "1_0_0": [ 1783 | "Wall_0_3_0", 1784 | "Connector_0_0_0" 1785 | ] 1786 | }, 1787 | "StairsRight_0_0_1": { 1788 | "-1_0_0": [ 1789 | "Empty" 1790 | ], 1791 | "0_-1_0": [ 1792 | "Wall_0_0_3" 1793 | ], 1794 | "0_0_-1": [ 1795 | "Wall_0_3_1", 1796 | "Connector_0_0_0" 1797 | ], 1798 | "0_0_1": [ 1799 | "Empty" 1800 | ], 1801 | "0_1_0": [ 1802 | "Empty" 1803 | ], 1804 | "1_0_0": [ 1805 | "BendWallOuterTop_1_0_1", 1806 | "Wall_0_0_3" 1807 | ] 1808 | }, 1809 | "StairsRight_0_0_2": { 1810 | "-1_0_0": [ 1811 | "Wall_0_3_2", 1812 | "Connector_0_0_0" 1813 | ], 1814 | "0_-1_0": [ 1815 | "Wall_0_0_0" 1816 | ], 1817 | "0_0_-1": [ 1818 | "BendWallOuterTop_1_0_2", 1819 | "Wall_0_0_0" 1820 | ], 1821 | "0_0_1": [ 1822 | "Empty" 1823 | ], 1824 | "0_1_0": [ 1825 | "Empty" 1826 | ], 1827 | "1_0_0": [ 1828 | "Empty" 1829 | ] 1830 | }, 1831 | "StairsRight_0_0_3": { 1832 | "-1_0_0": [ 1833 | "BendWallOuterTop_1_0_3", 1834 | "Wall_0_0_1" 1835 | ], 1836 | "0_-1_0": [ 1837 | "Wall_0_0_1" 1838 | ], 1839 | "0_0_-1": [ 1840 | "Empty" 1841 | ], 1842 | "0_0_1": [ 1843 | "Wall_0_3_3", 1844 | "Connector_0_0_0" 1845 | ], 1846 | "0_1_0": [ 1847 | "Empty" 1848 | ], 1849 | "1_0_0": [ 1850 | "Empty" 1851 | ] 1852 | }, 1853 | "StairsLeft_0_0_0": { 1854 | "-1_0_0": [ 1855 | "Wall_0_3_0", 1856 | "Connector_0_0_0" 1857 | ], 1858 | "0_-1_0": [ 1859 | "Wall_0_0_0" 1860 | ], 1861 | "0_0_-1": [ 1862 | "Empty" 1863 | ], 1864 | "0_0_1": [ 1865 | "BendWallOuterTop_1_0_1", 1866 | "Wall_0_0_0" 1867 | ], 1868 | "0_1_0": [ 1869 | "Empty" 1870 | ], 1871 | "1_0_0": [ 1872 | "Empty" 1873 | ] 1874 | }, 1875 | "StairsLeft_0_0_1": { 1876 | "-1_0_0": [ 1877 | "Empty" 1878 | ], 1879 | "0_-1_0": [ 1880 | "Wall_0_0_1" 1881 | ], 1882 | "0_0_-1": [ 1883 | "Empty" 1884 | ], 1885 | "0_0_1": [ 1886 | "Wall_0_3_1", 1887 | "Connector_0_0_0" 1888 | ], 1889 | "0_1_0": [ 1890 | "Empty" 1891 | ], 1892 | "1_0_0": [ 1893 | "BendWallOuterTop_1_0_2", 1894 | "Wall_0_0_1" 1895 | ] 1896 | }, 1897 | "StairsLeft_0_0_2": { 1898 | "-1_0_0": [ 1899 | "Empty" 1900 | ], 1901 | "0_-1_0": [ 1902 | "Wall_0_0_2" 1903 | ], 1904 | "0_0_-1": [ 1905 | "BendWallOuterTop_1_0_3", 1906 | "Wall_0_0_2" 1907 | ], 1908 | "0_0_1": [ 1909 | "Empty" 1910 | ], 1911 | "0_1_0": [ 1912 | "Empty" 1913 | ], 1914 | "1_0_0": [ 1915 | "Wall_0_3_2", 1916 | "Connector_0_0_0" 1917 | ] 1918 | }, 1919 | "StairsLeft_0_0_3": { 1920 | "-1_0_0": [ 1921 | "BendWallOuterTop_1_0_0", 1922 | "Wall_0_0_3" 1923 | ], 1924 | "0_-1_0": [ 1925 | "Wall_0_0_3" 1926 | ], 1927 | "0_0_-1": [ 1928 | "Wall_0_3_3", 1929 | "Connector_0_0_0" 1930 | ], 1931 | "0_0_1": [ 1932 | "Empty" 1933 | ], 1934 | "0_1_0": [ 1935 | "Empty" 1936 | ], 1937 | "1_0_0": [ 1938 | "Empty" 1939 | ] 1940 | }, 1941 | "StairWithWallLeft_0_0_2": { 1942 | "-1_0_0": [ 1943 | "Corner_0_3_2" 1944 | ], 1945 | "0_-1_0": [ 1946 | "Connector_0_0_0" 1947 | ], 1948 | "0_0_-1": [ 1949 | "Connector_0_0_0", 1950 | "Wall_0_3_0", 1951 | "Wall_0_3_2" 1952 | ], 1953 | "0_0_1": [ 1954 | "Empty" 1955 | ], 1956 | "0_1_0": [ 1957 | "Empty" 1958 | ], 1959 | "1_0_0": [ 1960 | "StairWithWallRight_0_0_2" 1961 | ] 1962 | }, 1963 | "StairWithWallLeft_0_0_3": { 1964 | "-1_0_0": [ 1965 | "Connector_0_0_0", 1966 | "Wall_0_3_1", 1967 | "Wall_0_3_3" 1968 | ], 1969 | "0_-1_0": [ 1970 | "Connector_0_0_0" 1971 | ], 1972 | "0_0_-1": [ 1973 | "StairWithWallRight_0_0_3" 1974 | ], 1975 | "0_0_1": [ 1976 | "Corner_0_3_3" 1977 | ], 1978 | "0_1_0": [ 1979 | "Empty" 1980 | ], 1981 | "1_0_0": [ 1982 | "Empty" 1983 | ] 1984 | }, 1985 | "StairWithWallLeft_0_0_0": { 1986 | "-1_0_0": [ 1987 | "StairWithWallRight_0_0_0" 1988 | ], 1989 | "0_-1_0": [ 1990 | "Connector_0_0_0" 1991 | ], 1992 | "0_0_-1": [ 1993 | "Empty" 1994 | ], 1995 | "0_0_1": [ 1996 | "Connector_0_0_0", 1997 | "Wall_0_3_2", 1998 | "Wall_0_3_0" 1999 | ], 2000 | "0_1_0": [ 2001 | "Empty" 2002 | ], 2003 | "1_0_0": [ 2004 | "Corner_0_3_0" 2005 | ] 2006 | }, 2007 | "StairWithWallLeft_0_0_1": { 2008 | "-1_0_0": [ 2009 | "Empty" 2010 | ], 2011 | "0_-1_0": [ 2012 | "Connector_0_0_0" 2013 | ], 2014 | "0_0_-1": [ 2015 | "Corner_0_3_1" 2016 | ], 2017 | "0_0_1": [ 2018 | "StairWithWallRight_0_0_1" 2019 | ], 2020 | "0_1_0": [ 2021 | "Empty" 2022 | ], 2023 | "1_0_0": [ 2024 | "Connector_0_0_0", 2025 | "Wall_0_3_3", 2026 | "Wall_0_3_1" 2027 | ] 2028 | }, 2029 | "StairWithWallRight_0_0_0": { 2030 | "-1_0_0": [ 2031 | "Corner_0_3_1" 2032 | ], 2033 | "0_-1_0": [ 2034 | "Connector_0_0_0" 2035 | ], 2036 | "0_0_-1": [ 2037 | "Empty" 2038 | ], 2039 | "0_0_1": [ 2040 | "Wall_0_3_0", 2041 | "Connector_0_0_0", 2042 | "Wall_0_3_2" 2043 | ], 2044 | "0_1_0": [ 2045 | "Empty" 2046 | ], 2047 | "1_0_0": [ 2048 | "StairWithWallLeft_0_0_0" 2049 | ] 2050 | }, 2051 | "StairWithWallRight_0_0_1": { 2052 | "-1_0_0": [ 2053 | "Empty" 2054 | ], 2055 | "0_-1_0": [ 2056 | "Connector_0_0_0" 2057 | ], 2058 | "0_0_-1": [ 2059 | "StairWithWallLeft_0_0_1" 2060 | ], 2061 | "0_0_1": [ 2062 | "Corner_0_3_2" 2063 | ], 2064 | "0_1_0": [ 2065 | "Empty" 2066 | ], 2067 | "1_0_0": [ 2068 | "Wall_0_3_1", 2069 | "Connector_0_0_0", 2070 | "Wall_0_3_3" 2071 | ] 2072 | }, 2073 | "StairWithWallRight_0_0_2": { 2074 | "-1_0_0": [ 2075 | "StairWithWallLeft_0_0_2" 2076 | ], 2077 | "0_-1_0": [ 2078 | "Connector_0_0_0" 2079 | ], 2080 | "0_0_-1": [ 2081 | "Wall_0_3_2", 2082 | "Connector_0_0_0", 2083 | "Wall_0_3_0" 2084 | ], 2085 | "0_0_1": [ 2086 | "Empty" 2087 | ], 2088 | "0_1_0": [ 2089 | "Empty" 2090 | ], 2091 | "1_0_0": [ 2092 | "Corner_0_3_3" 2093 | ] 2094 | }, 2095 | "StairWithWallRight_0_0_3": { 2096 | "-1_0_0": [ 2097 | "Wall_0_3_3", 2098 | "Connector_0_0_0", 2099 | "Wall_0_3_1" 2100 | ], 2101 | "0_-1_0": [ 2102 | "Connector_0_0_0" 2103 | ], 2104 | "0_0_-1": [ 2105 | "Corner_0_3_0" 2106 | ], 2107 | "0_0_1": [ 2108 | "StairWithWallLeft_0_0_3" 2109 | ], 2110 | "0_1_0": [ 2111 | "Empty" 2112 | ], 2113 | "1_0_0": [ 2114 | "Empty" 2115 | ] 2116 | }, 2117 | "ArchLeft_0_3_3": { 2118 | "-1_0_0": [ 2119 | "Empty" 2120 | ], 2121 | "0_-1_0": [ 2122 | "Empty" 2123 | ], 2124 | "0_0_-1": [ 2125 | "ArchRight_0_3_1", 2126 | "Empty" 2127 | ], 2128 | "0_0_1": [ 2129 | "Edge_1_0_1", 2130 | "Connector_0_0_0", 2131 | "Wall_0_0_2" 2132 | ], 2133 | "0_1_0": [ 2134 | "Edge_0_3_2", 2135 | "EdgeHalfLower_0_0_2" 2136 | ], 2137 | "1_0_0": [ 2138 | "Arch_0_3_3", 2139 | "ArchRight_0_3_3" 2140 | ] 2141 | }, 2142 | "ArchLeft_0_3_0": { 2143 | "-1_0_0": [ 2144 | "ArchRight_0_3_2", 2145 | "Empty" 2146 | ], 2147 | "0_-1_0": [ 2148 | "Empty" 2149 | ], 2150 | "0_0_-1": [ 2151 | "Arch_0_3_0", 2152 | "ArchRight_0_3_0" 2153 | ], 2154 | "0_0_1": [ 2155 | "Empty" 2156 | ], 2157 | "0_1_0": [ 2158 | "Edge_0_3_3", 2159 | "EdgeHalfLower_0_0_3" 2160 | ], 2161 | "1_0_0": [ 2162 | "Edge_1_0_2", 2163 | "Connector_0_0_0", 2164 | "Wall_0_0_3" 2165 | ] 2166 | }, 2167 | "ArchLeft_0_3_1": { 2168 | "-1_0_0": [ 2169 | "Arch_0_3_1", 2170 | "ArchRight_0_3_1" 2171 | ], 2172 | "0_-1_0": [ 2173 | "Empty" 2174 | ], 2175 | "0_0_-1": [ 2176 | "Edge_1_0_3", 2177 | "Connector_0_0_0", 2178 | "Wall_0_0_0" 2179 | ], 2180 | "0_0_1": [ 2181 | "ArchRight_0_3_3", 2182 | "Empty" 2183 | ], 2184 | "0_1_0": [ 2185 | "Edge_0_3_0", 2186 | "EdgeHalfLower_0_0_0" 2187 | ], 2188 | "1_0_0": [ 2189 | "Empty" 2190 | ] 2191 | }, 2192 | "ArchLeft_0_3_2": { 2193 | "-1_0_0": [ 2194 | "Edge_1_0_0", 2195 | "Connector_0_0_0", 2196 | "Wall_0_0_1" 2197 | ], 2198 | "0_-1_0": [ 2199 | "Empty" 2200 | ], 2201 | "0_0_-1": [ 2202 | "Empty" 2203 | ], 2204 | "0_0_1": [ 2205 | "Arch_0_3_2", 2206 | "ArchRight_0_3_2" 2207 | ], 2208 | "0_1_0": [ 2209 | "Edge_0_3_1", 2210 | "EdgeHalfLower_0_0_1" 2211 | ], 2212 | "1_0_0": [ 2213 | "ArchRight_0_3_0", 2214 | "Empty" 2215 | ] 2216 | }, 2217 | "ArchRight_0_3_1": { 2218 | "-1_0_0": [ 2219 | "Empty" 2220 | ], 2221 | "0_-1_0": [ 2222 | "Empty" 2223 | ], 2224 | "0_0_-1": [ 2225 | "Wall_0_0_2", 2226 | "Connector_0_0_0", 2227 | "Edge_1_0_2" 2228 | ], 2229 | "0_0_1": [ 2230 | "ArchLeft_0_3_3", 2231 | "Empty" 2232 | ], 2233 | "0_1_0": [ 2234 | "Edge_0_3_2", 2235 | "EdgeHalfLower_0_0_2" 2236 | ], 2237 | "1_0_0": [ 2238 | "Arch_0_3_1", 2239 | "ArchLeft_0_3_1" 2240 | ] 2241 | }, 2242 | "ArchRight_0_3_2": { 2243 | "-1_0_0": [ 2244 | "Wall_0_0_3", 2245 | "Connector_0_0_0", 2246 | "Edge_1_0_3" 2247 | ], 2248 | "0_-1_0": [ 2249 | "Empty" 2250 | ], 2251 | "0_0_-1": [ 2252 | "Arch_0_3_2", 2253 | "ArchLeft_0_3_2" 2254 | ], 2255 | "0_0_1": [ 2256 | "Empty" 2257 | ], 2258 | "0_1_0": [ 2259 | "Edge_0_3_3", 2260 | "EdgeHalfLower_0_0_3" 2261 | ], 2262 | "1_0_0": [ 2263 | "ArchLeft_0_3_0", 2264 | "Empty" 2265 | ] 2266 | }, 2267 | "ArchRight_0_3_3": { 2268 | "-1_0_0": [ 2269 | "Arch_0_3_3", 2270 | "ArchLeft_0_3_3" 2271 | ], 2272 | "0_-1_0": [ 2273 | "Empty" 2274 | ], 2275 | "0_0_-1": [ 2276 | "ArchLeft_0_3_1", 2277 | "Empty" 2278 | ], 2279 | "0_0_1": [ 2280 | "Wall_0_0_0", 2281 | "Connector_0_0_0", 2282 | "Edge_1_0_0" 2283 | ], 2284 | "0_1_0": [ 2285 | "Edge_0_3_0", 2286 | "EdgeHalfLower_0_0_0" 2287 | ], 2288 | "1_0_0": [ 2289 | "Empty" 2290 | ] 2291 | }, 2292 | "ArchRight_0_3_0": { 2293 | "-1_0_0": [ 2294 | "ArchLeft_0_3_2", 2295 | "Empty" 2296 | ], 2297 | "0_-1_0": [ 2298 | "Empty" 2299 | ], 2300 | "0_0_-1": [ 2301 | "Empty" 2302 | ], 2303 | "0_0_1": [ 2304 | "Arch_0_3_0", 2305 | "ArchLeft_0_3_0" 2306 | ], 2307 | "0_1_0": [ 2308 | "Edge_0_3_1", 2309 | "EdgeHalfLower_0_0_1" 2310 | ], 2311 | "1_0_0": [ 2312 | "Wall_0_0_1", 2313 | "Connector_0_0_0", 2314 | "Edge_1_0_1" 2315 | ] 2316 | }, 2317 | "Arch_0_3_3": { 2318 | "-1_0_0": [ 2319 | "ArchLeft_0_3_3", 2320 | "Arch_0_3_3" 2321 | ], 2322 | "0_-1_0": [ 2323 | "Empty" 2324 | ], 2325 | "0_0_-1": [ 2326 | "Arch_0_3_1" 2327 | ], 2328 | "0_0_1": [ 2329 | "Wall_0_0_1", 2330 | "Connector_0_0_0" 2331 | ], 2332 | "0_1_0": [ 2333 | "Wall_0_3_0", 2334 | "Wall_0_3_2" 2335 | ], 2336 | "1_0_0": [ 2337 | "Arch_0_3_3", 2338 | "ArchRight_0_3_3" 2339 | ] 2340 | }, 2341 | "Arch_0_3_0": { 2342 | "-1_0_0": [ 2343 | "Arch_0_3_2" 2344 | ], 2345 | "0_-1_0": [ 2346 | "Empty" 2347 | ], 2348 | "0_0_-1": [ 2349 | "Arch_0_3_0", 2350 | "ArchRight_0_3_0" 2351 | ], 2352 | "0_0_1": [ 2353 | "ArchLeft_0_3_0", 2354 | "Arch_0_3_0" 2355 | ], 2356 | "0_1_0": [ 2357 | "Wall_0_3_1", 2358 | "Wall_0_3_3" 2359 | ], 2360 | "1_0_0": [ 2361 | "Wall_0_0_2", 2362 | "Connector_0_0_0" 2363 | ] 2364 | }, 2365 | "Arch_0_3_1": { 2366 | "-1_0_0": [ 2367 | "Arch_0_3_1", 2368 | "ArchRight_0_3_1" 2369 | ], 2370 | "0_-1_0": [ 2371 | "Empty" 2372 | ], 2373 | "0_0_-1": [ 2374 | "Wall_0_0_3", 2375 | "Connector_0_0_0" 2376 | ], 2377 | "0_0_1": [ 2378 | "Arch_0_3_3" 2379 | ], 2380 | "0_1_0": [ 2381 | "Wall_0_3_2", 2382 | "Wall_0_3_0" 2383 | ], 2384 | "1_0_0": [ 2385 | "ArchLeft_0_3_1", 2386 | "Arch_0_3_1" 2387 | ] 2388 | }, 2389 | "Arch_0_3_2": { 2390 | "-1_0_0": [ 2391 | "Wall_0_0_0", 2392 | "Connector_0_0_0" 2393 | ], 2394 | "0_-1_0": [ 2395 | "Empty" 2396 | ], 2397 | "0_0_-1": [ 2398 | "ArchLeft_0_3_2", 2399 | "Arch_0_3_2" 2400 | ], 2401 | "0_0_1": [ 2402 | "Arch_0_3_2", 2403 | "ArchRight_0_3_2" 2404 | ], 2405 | "0_1_0": [ 2406 | "Wall_0_3_3", 2407 | "Wall_0_3_1" 2408 | ], 2409 | "1_0_0": [ 2410 | "Arch_0_3_0" 2411 | ] 2412 | }, 2413 | "FlatStairWithWallRightUper_0_0_0": { 2414 | "-1_0_0": [ 2415 | "Corner_0_3_1", 2416 | "BendWallOuterTop_1_0_3" 2417 | ], 2418 | "0_-1_0": [ 2419 | "Connector_0_0_0" 2420 | ], 2421 | "0_0_-1": [ 2422 | "EdgeHalfLower_0_0_2" 2423 | ], 2424 | "0_0_1": [ 2425 | "Wall_0_3_0", 2426 | "Wall_0_3_2" 2427 | ], 2428 | "0_1_0": [ 2429 | "Empty" 2430 | ], 2431 | "1_0_0": [ 2432 | "FlatStairWithWallLeftLowerUper_0_0_0" 2433 | ] 2434 | }, 2435 | "FlatStairWithWallRightUper_0_0_1": { 2436 | "-1_0_0": [ 2437 | "EdgeHalfLower_0_0_3" 2438 | ], 2439 | "0_-1_0": [ 2440 | "Connector_0_0_0" 2441 | ], 2442 | "0_0_-1": [ 2443 | "FlatStairWithWallLeftLowerUper_0_0_1" 2444 | ], 2445 | "0_0_1": [ 2446 | "Corner_0_3_2", 2447 | "BendWallOuterTop_1_0_0" 2448 | ], 2449 | "0_1_0": [ 2450 | "Empty" 2451 | ], 2452 | "1_0_0": [ 2453 | "Wall_0_3_1", 2454 | "Wall_0_3_3" 2455 | ] 2456 | }, 2457 | "FlatStairWithWallRightUper_0_0_2": { 2458 | "-1_0_0": [ 2459 | "FlatStairWithWallLeftLowerUper_0_0_2" 2460 | ], 2461 | "0_-1_0": [ 2462 | "Connector_0_0_0" 2463 | ], 2464 | "0_0_-1": [ 2465 | "Wall_0_3_2", 2466 | "Wall_0_3_0" 2467 | ], 2468 | "0_0_1": [ 2469 | "EdgeHalfLower_0_0_0" 2470 | ], 2471 | "0_1_0": [ 2472 | "Empty" 2473 | ], 2474 | "1_0_0": [ 2475 | "Corner_0_3_3", 2476 | "BendWallOuterTop_1_0_1" 2477 | ] 2478 | }, 2479 | "FlatStairWithWallRightUper_0_0_3": { 2480 | "-1_0_0": [ 2481 | "Wall_0_3_3", 2482 | "Wall_0_3_1" 2483 | ], 2484 | "0_-1_0": [ 2485 | "Connector_0_0_0" 2486 | ], 2487 | "0_0_-1": [ 2488 | "Corner_0_3_0", 2489 | "BendWallOuterTop_1_0_2" 2490 | ], 2491 | "0_0_1": [ 2492 | "FlatStairWithWallLeftLowerUper_0_0_3" 2493 | ], 2494 | "0_1_0": [ 2495 | "Empty" 2496 | ], 2497 | "1_0_0": [ 2498 | "EdgeHalfLower_0_0_1" 2499 | ] 2500 | }, 2501 | "EdgeHalfLower_0_0_2": { 2502 | "-1_0_0": [ 2503 | "Empty" 2504 | ], 2505 | "0_-1_0": [ 2506 | "ArchLeft_0_3_3", 2507 | "ArchRight_0_3_1" 2508 | ], 2509 | "0_0_-1": [ 2510 | "LoopHalfLower_0_0_2", 2511 | "FlatStairWithWallLeftLowerUper_0_0_2" 2512 | ], 2513 | "0_0_1": [ 2514 | "FlatStairWithWallRightUper_0_0_0", 2515 | "LoopHalfLower_0_0_2" 2516 | ], 2517 | "0_1_0": [ 2518 | "Empty" 2519 | ], 2520 | "1_0_0": [ 2521 | "EdgeHalfLower_0_0_0" 2522 | ] 2523 | }, 2524 | "EdgeHalfLower_0_0_3": { 2525 | "-1_0_0": [ 2526 | "LoopHalfLower_0_0_3", 2527 | "FlatStairWithWallLeftLowerUper_0_0_3" 2528 | ], 2529 | "0_-1_0": [ 2530 | "ArchLeft_0_3_0", 2531 | "ArchRight_0_3_2" 2532 | ], 2533 | "0_0_-1": [ 2534 | "EdgeHalfLower_0_0_1" 2535 | ], 2536 | "0_0_1": [ 2537 | "Empty" 2538 | ], 2539 | "0_1_0": [ 2540 | "Empty" 2541 | ], 2542 | "1_0_0": [ 2543 | "FlatStairWithWallRightUper_0_0_1", 2544 | "LoopHalfLower_0_0_3" 2545 | ] 2546 | }, 2547 | "EdgeHalfLower_0_0_0": { 2548 | "-1_0_0": [ 2549 | "EdgeHalfLower_0_0_2" 2550 | ], 2551 | "0_-1_0": [ 2552 | "ArchLeft_0_3_1", 2553 | "ArchRight_0_3_3" 2554 | ], 2555 | "0_0_-1": [ 2556 | "FlatStairWithWallRightUper_0_0_2", 2557 | "LoopHalfLower_0_0_0" 2558 | ], 2559 | "0_0_1": [ 2560 | "LoopHalfLower_0_0_0", 2561 | "FlatStairWithWallLeftLowerUper_0_0_0" 2562 | ], 2563 | "0_1_0": [ 2564 | "Empty" 2565 | ], 2566 | "1_0_0": [ 2567 | "Empty" 2568 | ] 2569 | }, 2570 | "EdgeHalfLower_0_0_1": { 2571 | "-1_0_0": [ 2572 | "FlatStairWithWallRightUper_0_0_3", 2573 | "LoopHalfLower_0_0_1" 2574 | ], 2575 | "0_-1_0": [ 2576 | "ArchLeft_0_3_2", 2577 | "ArchRight_0_3_0" 2578 | ], 2579 | "0_0_-1": [ 2580 | "Empty" 2581 | ], 2582 | "0_0_1": [ 2583 | "EdgeHalfLower_0_0_3" 2584 | ], 2585 | "0_1_0": [ 2586 | "Empty" 2587 | ], 2588 | "1_0_0": [ 2589 | "LoopHalfLower_0_0_1", 2590 | "FlatStairWithWallLeftLowerUper_0_0_1" 2591 | ] 2592 | }, 2593 | "LoopHalfLower_0_0_2": { 2594 | "-1_0_0": [ 2595 | "Empty" 2596 | ], 2597 | "0_-1_0": [ 2598 | "Empty" 2599 | ], 2600 | "0_0_-1": [ 2601 | "LoopHalfLower_0_0_2", 2602 | "EdgeHalfLower_0_0_2" 2603 | ], 2604 | "0_0_1": [ 2605 | "EdgeHalfLower_0_0_2", 2606 | "LoopHalfLower_0_0_2" 2607 | ], 2608 | "0_1_0": [ 2609 | "Empty" 2610 | ], 2611 | "1_0_0": [ 2612 | "LoopHalfLower_0_0_0" 2613 | ] 2614 | }, 2615 | "LoopHalfLower_0_0_3": { 2616 | "-1_0_0": [ 2617 | "LoopHalfLower_0_0_3", 2618 | "EdgeHalfLower_0_0_3" 2619 | ], 2620 | "0_-1_0": [ 2621 | "Empty" 2622 | ], 2623 | "0_0_-1": [ 2624 | "LoopHalfLower_0_0_1" 2625 | ], 2626 | "0_0_1": [ 2627 | "Empty" 2628 | ], 2629 | "0_1_0": [ 2630 | "Empty" 2631 | ], 2632 | "1_0_0": [ 2633 | "EdgeHalfLower_0_0_3", 2634 | "LoopHalfLower_0_0_3" 2635 | ] 2636 | }, 2637 | "LoopHalfLower_0_0_0": { 2638 | "-1_0_0": [ 2639 | "LoopHalfLower_0_0_2" 2640 | ], 2641 | "0_-1_0": [ 2642 | "Empty" 2643 | ], 2644 | "0_0_-1": [ 2645 | "EdgeHalfLower_0_0_0", 2646 | "LoopHalfLower_0_0_0" 2647 | ], 2648 | "0_0_1": [ 2649 | "LoopHalfLower_0_0_0", 2650 | "EdgeHalfLower_0_0_0" 2651 | ], 2652 | "0_1_0": [ 2653 | "Empty" 2654 | ], 2655 | "1_0_0": [ 2656 | "Empty" 2657 | ] 2658 | }, 2659 | "LoopHalfLower_0_0_1": { 2660 | "-1_0_0": [ 2661 | "EdgeHalfLower_0_0_1", 2662 | "LoopHalfLower_0_0_1" 2663 | ], 2664 | "0_-1_0": [ 2665 | "Empty" 2666 | ], 2667 | "0_0_-1": [ 2668 | "Empty" 2669 | ], 2670 | "0_0_1": [ 2671 | "LoopHalfLower_0_0_3" 2672 | ], 2673 | "0_1_0": [ 2674 | "Empty" 2675 | ], 2676 | "1_0_0": [ 2677 | "LoopHalfLower_0_0_1", 2678 | "EdgeHalfLower_0_0_1" 2679 | ] 2680 | }, 2681 | "FlatStairWithWallLeftLowerUper_0_0_2": { 2682 | "-1_0_0": [ 2683 | "BendWallOuterTop_1_0_0", 2684 | "Corner_0_3_2" 2685 | ], 2686 | "0_-1_0": [ 2687 | "Connector_0_0_0" 2688 | ], 2689 | "0_0_-1": [ 2690 | "Wall_0_3_0", 2691 | "Wall_0_3_2" 2692 | ], 2693 | "0_0_1": [ 2694 | "EdgeHalfLower_0_0_2" 2695 | ], 2696 | "0_1_0": [ 2697 | "Empty" 2698 | ], 2699 | "1_0_0": [ 2700 | "FlatStairWithWallRightUper_0_0_2" 2701 | ] 2702 | }, 2703 | "FlatStairWithWallLeftLowerUper_0_0_3": { 2704 | "-1_0_0": [ 2705 | "Wall_0_3_1", 2706 | "Wall_0_3_3" 2707 | ], 2708 | "0_-1_0": [ 2709 | "Connector_0_0_0" 2710 | ], 2711 | "0_0_-1": [ 2712 | "FlatStairWithWallRightUper_0_0_3" 2713 | ], 2714 | "0_0_1": [ 2715 | "BendWallOuterTop_1_0_1", 2716 | "Corner_0_3_3" 2717 | ], 2718 | "0_1_0": [ 2719 | "Empty" 2720 | ], 2721 | "1_0_0": [ 2722 | "EdgeHalfLower_0_0_3" 2723 | ] 2724 | }, 2725 | "FlatStairWithWallLeftLowerUper_0_0_0": { 2726 | "-1_0_0": [ 2727 | "FlatStairWithWallRightUper_0_0_0" 2728 | ], 2729 | "0_-1_0": [ 2730 | "Connector_0_0_0" 2731 | ], 2732 | "0_0_-1": [ 2733 | "EdgeHalfLower_0_0_0" 2734 | ], 2735 | "0_0_1": [ 2736 | "Wall_0_3_2", 2737 | "Wall_0_3_0" 2738 | ], 2739 | "0_1_0": [ 2740 | "Empty" 2741 | ], 2742 | "1_0_0": [ 2743 | "BendWallOuterTop_1_0_2", 2744 | "Corner_0_3_0" 2745 | ] 2746 | }, 2747 | "FlatStairWithWallLeftLowerUper_0_0_1": { 2748 | "-1_0_0": [ 2749 | "EdgeHalfLower_0_0_1" 2750 | ], 2751 | "0_-1_0": [ 2752 | "Connector_0_0_0" 2753 | ], 2754 | "0_0_-1": [ 2755 | "BendWallOuterTop_1_0_3", 2756 | "Corner_0_3_1" 2757 | ], 2758 | "0_0_1": [ 2759 | "FlatStairWithWallRightUper_0_0_1" 2760 | ], 2761 | "0_1_0": [ 2762 | "Empty" 2763 | ], 2764 | "1_0_0": [ 2765 | "Wall_0_3_3", 2766 | "Wall_0_3_1" 2767 | ] 2768 | } 2769 | } -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import Head from "next/head" 2 | import { AppProps } from "next/app" 3 | import "../styles/globals.css" 4 | 5 | export default function MyApp({ Component, pageProps }: AppProps) { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | 13 | Infty 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | ) 29 | } 30 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Body from "@/components/body/body" 2 | import Generator from "@/components/generator/generator" 3 | import Scene from "@/components/scenes/scene" 4 | 5 | const Home = () => { 6 | return ( 7 | <> 8 |
19 | 20 |
21 | 22 | 23 | 40 | 41 | 42 | ) 43 | } 44 | 45 | export default Home 46 | -------------------------------------------------------------------------------- /src/stores/generationStore.tsx: -------------------------------------------------------------------------------- 1 | import constraints from "@/models/constraints.json" 2 | import produce, { Draft } from "immer" 3 | import { Vector3 } from "three" 4 | import create, { State, StateCreator } from "zustand" 5 | 6 | export interface Pos3 { 7 | x: number 8 | y: number 9 | z: number 10 | } 11 | 12 | export interface Prototype { 13 | id: string 14 | neighbourCells: Record 15 | } 16 | interface PrototypeObject { 17 | id: string 18 | key: string 19 | position: Vector3 20 | } 21 | 22 | type GenerationStore = { 23 | prototypes: Prototype[] 24 | size: Pos3 25 | waves: number[][][][] 26 | entropyObjects: PrototypeObject[] 27 | prototypeObjects: PrototypeObject[] 28 | setGeneration: (waves: number[][][][]) => void 29 | probabilities: Record 30 | exporting: boolean 31 | setExport: (exporting: boolean) => void 32 | setProbabilities: (probabilities: Record) => void 33 | } 34 | 35 | const constraintIdArray = Object.keys(constraints) 36 | const constraintArray: Prototype[] = [] 37 | Object.entries(constraints).forEach(([key, value]) => { 38 | const neighboursCells: Record = {} 39 | 40 | const diag = [-1, 0, 1] 41 | diag.forEach((dx) => { 42 | diag.forEach((dy) => { 43 | diag.forEach((dz) => { 44 | neighboursCells["" + dx + "_" + dy + "_" + dz + ""] = [] 45 | }) 46 | }) 47 | }) 48 | 49 | Object.entries(value).forEach(([key, value]) => { 50 | const neighbourCellAxis = value.map((id) => { 51 | return constraintIdArray.indexOf(id) 52 | }) 53 | 54 | // @ts-ignore 55 | neighboursCells[key] = neighbourCellAxis 56 | }) 57 | 58 | constraintArray.push({ 59 | id: key, 60 | neighbourCells: neighboursCells, 61 | }) 62 | }) 63 | 64 | const immer = 65 | (config: StateCreator) => void) => void>): StateCreator => 66 | (set, get, api) => 67 | config((fn) => set(produce(fn)), get, api) 68 | 69 | export const useGenerationStore = create( 70 | immer((set, get) => ({ 71 | size: { x: 32, y: 16, z: 32 }, 72 | prototypes: constraintArray, 73 | prototypeObjects: [], 74 | entropyObjects: [], 75 | waves: [[[]]], 76 | exporting: false, 77 | probabilities: { 78 | Empty: 10, // 10 79 | Wall: 2, 80 | Stairs: 1, 81 | StairsLeft: 3, 82 | StairsRight: 3, 83 | }, 84 | 85 | setGeneration: (waves: number[][][][]): void => { 86 | set((state) => { 87 | const prototypeObjects: PrototypeObject[] = [] 88 | const prototypeIds: string[] = useGenerationStore.getState().prototypes.map((p) => p.id) 89 | 90 | for (let x = 0; x < waves.length; x++) { 91 | for (let y = 0; y < waves[0].length; y++) { 92 | for (let z = 0; z < waves[0][0].length; z++) { 93 | let protoypeId = waves[x][y][z][0] 94 | if (protoypeId == -1) { 95 | protoypeId = 0 96 | } 97 | 98 | const prototypeName = prototypeIds[protoypeId] 99 | if (prototypeName !== "Empty" && prototypeName !== undefined) { 100 | prototypeObjects.push({ 101 | key: "" + x + "_" + y + "_" + z, 102 | id: prototypeIds[protoypeId], 103 | position: new Vector3(x, y, z), 104 | }) 105 | } 106 | } 107 | } 108 | } 109 | 110 | state.waves = waves 111 | state.prototypeObjects = prototypeObjects 112 | }) 113 | }, 114 | 115 | setExport: (exporting: boolean): void => { 116 | set((state) => { 117 | state.exporting = exporting 118 | }) 119 | }, 120 | 121 | setProbabilities: (probabilities: Record): void => { 122 | set((state) => { 123 | state.probabilities = probabilities 124 | }) 125 | }, 126 | })) 127 | ) 128 | -------------------------------------------------------------------------------- /src/styles/globals.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | font-family: "Lato", sans-serif; 4 | } 5 | 6 | a { 7 | text-decoration: none; 8 | color: inherit; 9 | } 10 | 11 | button { 12 | cursor: pointer; 13 | border-radius: 5px; 14 | display: flex; 15 | justify-content: center; 16 | align-items: center; 17 | background-color: #222; 18 | background: #222; 19 | color: white; 20 | font-weight: bold; 21 | font-size: 1rem; 22 | padding: 4px 16px; 23 | height: 45px; 24 | border: none; 25 | pointer-events: all; 26 | z-index: 100; 27 | } 28 | 29 | button:hover { 30 | background-color: #333; 31 | background: #333; 32 | } 33 | 34 | .lds-default { 35 | display: inline-block; 36 | position: relative; 37 | width: 80px; 38 | height: 80px; 39 | } 40 | .lds-default div { 41 | position: absolute; 42 | width: 6px; 43 | height: 6px; 44 | background: #fff; 45 | border-radius: 50%; 46 | animation: lds-default 1.2s linear infinite; 47 | } 48 | .lds-default div:nth-child(1) { 49 | animation-delay: 0s; 50 | top: 37px; 51 | left: 66px; 52 | } 53 | .lds-default div:nth-child(2) { 54 | animation-delay: -0.1s; 55 | top: 22px; 56 | left: 62px; 57 | } 58 | .lds-default div:nth-child(3) { 59 | animation-delay: -0.2s; 60 | top: 11px; 61 | left: 52px; 62 | } 63 | .lds-default div:nth-child(4) { 64 | animation-delay: -0.3s; 65 | top: 7px; 66 | left: 37px; 67 | } 68 | .lds-default div:nth-child(5) { 69 | animation-delay: -0.4s; 70 | top: 11px; 71 | left: 22px; 72 | } 73 | .lds-default div:nth-child(6) { 74 | animation-delay: -0.5s; 75 | top: 22px; 76 | left: 11px; 77 | } 78 | .lds-default div:nth-child(7) { 79 | animation-delay: -0.6s; 80 | top: 37px; 81 | left: 7px; 82 | } 83 | .lds-default div:nth-child(8) { 84 | animation-delay: -0.7s; 85 | top: 52px; 86 | left: 11px; 87 | } 88 | .lds-default div:nth-child(9) { 89 | animation-delay: -0.8s; 90 | top: 62px; 91 | left: 22px; 92 | } 93 | .lds-default div:nth-child(10) { 94 | animation-delay: -0.9s; 95 | top: 66px; 96 | left: 37px; 97 | } 98 | .lds-default div:nth-child(11) { 99 | animation-delay: -1s; 100 | top: 62px; 101 | left: 52px; 102 | } 103 | .lds-default div:nth-child(12) { 104 | animation-delay: -1.1s; 105 | top: 52px; 106 | left: 62px; 107 | } 108 | @keyframes lds-default { 109 | 0%, 110 | 20%, 111 | 80%, 112 | 100% { 113 | transform: scale(1); 114 | } 115 | 50% { 116 | transform: scale(1.5); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/utils/mapNumbers.ts: -------------------------------------------------------------------------------- 1 | export const map_range = (value: number, low1: number, high1: number, low2: number, high2: number): number => { 2 | return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1) 3 | } 4 | -------------------------------------------------------------------------------- /src/utils/useInterval.ts: -------------------------------------------------------------------------------- 1 | import { useRef, useEffect } from "react" 2 | 3 | // useInterval hook from Dan Abramov blog https://overreacted.io/making-setinterval-declarative-with-react-hooks/ 4 | export default function useInterval(callback: () => void, delay: number) { 5 | const savedCallback = useRef<() => void>(callback) 6 | 7 | // Remember the latest callback. 8 | useEffect(() => { 9 | savedCallback.current = callback 10 | }, [callback]) 11 | 12 | // Set up the interval. 13 | useEffect(() => { 14 | function tick() { 15 | savedCallback.current() 16 | } 17 | if (delay !== null) { 18 | const id = setInterval(tick, delay) 19 | return () => clearInterval(id) 20 | } else { 21 | return undefined 22 | } 23 | }, [delay]) 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/wfc.ts: -------------------------------------------------------------------------------- 1 | import { MathUtils } from "three" 2 | 3 | export interface Prototype { 4 | id: string 5 | neighbourCells: Record 6 | } 7 | 8 | export interface Vector3 { 9 | x: number 10 | y: number 11 | z: number 12 | } 13 | 14 | export class Model { 15 | size: Vector3 16 | waves: number[][][][] 17 | prototypes: Prototype[] 18 | 19 | constructor() { 20 | this.prototypes = [] 21 | this.size = { x: 0, y: 0, z: 0 } 22 | this.waves = [[[]]] 23 | } 24 | 25 | public init = (prototypes: Prototype[], size: Vector3) => { 26 | this.size = size 27 | this.prototypes = prototypes 28 | this.waves = new Array(this.size.x) 29 | .fill(0) 30 | .map(() => new Array(this.size.y).fill(0).map(() => new Array(this.size.z).fill(0))) 31 | 32 | for (let x = 0; x < this.size.x; x++) { 33 | for (let y = 0; y < this.size.y; y++) { 34 | for (let z = 0; z < this.size.z; z++) { 35 | this.waves[x][y][z] = [...Array(this.prototypes.length).keys()] 36 | } 37 | } 38 | } 39 | 40 | // Zero Pad 41 | for (let x = 0; x < this.size.x; x++) { 42 | for (let y = 0; y < this.size.y; y++) { 43 | for (let z = 0; z < this.size.z; z++) { 44 | if ( 45 | x === 0 || 46 | // y === 0 || 47 | z === 0 || 48 | x === this.size.x - 1 || 49 | y === this.size.y - 1 || 50 | z === this.size.z - 1 51 | ) { 52 | this.observeWith({ x: x, y: y, z: z }, 0) 53 | this.propagate({ x: x, y: y, z: z }) 54 | } 55 | } 56 | } 57 | } 58 | } 59 | 60 | public run = (seed: number, limit: number): boolean => { 61 | for (let l = 0; l < limit; l++) { 62 | const nodeIndex = this.nextUnobservedNode() 63 | 64 | if (nodeIndex != null) { 65 | this.observe(nodeIndex) 66 | const success = this.propagate(nodeIndex) 67 | if (!success) { 68 | console.log("Could not be solved") 69 | return false 70 | } 71 | } else { 72 | return true 73 | } 74 | } 75 | 76 | return true 77 | } 78 | 79 | private observe = (nodeIndex: Vector3): void => { 80 | const { x, y, z } = nodeIndex 81 | const wave = this.waves[x][y][z] 82 | 83 | /*let pick = 0 84 | if (wave.length >= 1) { 85 | const waveSet = new Set(wave) 86 | if (waveSet.has(0)) { 87 | const dir = [-1, 0, 1] 88 | let zeroCount = 0 89 | let nonZeroCount = 0 90 | dir.forEach((dx) => { 91 | dir.forEach((dy) => { 92 | dir.forEach((dz) => { 93 | if (Math.abs(dx) + Math.abs(dy) + Math.abs(dz) <= 1) { 94 | if ( 95 | x + dx >= 0 && 96 | x + dx < this.size.x && 97 | y + dy >= 0 && 98 | y + dy < this.size.y && 99 | z + dz >= 0 && 100 | z + dz < this.size.z 101 | ) { 102 | const neighbourWave = this.waves[x + dx][y + dy][z + dz] 103 | if (this.waves[x + dx][y + dy][z + dz].length === 1) { 104 | if (neighbourWave[0] === 0) { 105 | zeroCount++ 106 | } else { 107 | nonZeroCount++ 108 | } 109 | } 110 | } 111 | } 112 | }) 113 | }) 114 | }) 115 | 116 | if (zeroCount > nonZeroCount) { 117 | pick = 0 118 | } else { 119 | waveSet.delete(0) 120 | MathUtils.randInt(0, waveSet.size - 1) 121 | } 122 | } else { 123 | pick = MathUtils.randInt(0, wave.length - 1) 124 | } 125 | }*/ 126 | 127 | const pick = MathUtils.randInt(0, wave.length - 1) 128 | 129 | this.waves[x][y][z] = [wave[pick]] 130 | } 131 | 132 | private observeWith = (nodeIndex: Vector3, observeIndex: number): void => { 133 | const { x, y, z } = nodeIndex 134 | this.waves[x][y][z] = [observeIndex] 135 | } 136 | 137 | private propagate = (nodeIndex: Vector3): boolean => { 138 | const stack = [nodeIndex] 139 | 140 | while (stack.length > 0) { 141 | const currentNodeIndex = stack.pop() as Vector3 142 | const { x, y, z } = currentNodeIndex 143 | const wave = this.waves[x][y][z] 144 | 145 | const neighboursXP = new Set() 146 | const neighboursXN = new Set() 147 | const neighboursYP = new Set() 148 | const neighboursYN = new Set() 149 | const neighboursZP = new Set() 150 | const neighboursZN = new Set() 151 | 152 | wave.forEach((protypeId) => { 153 | const prototype = this.prototypes[protypeId] 154 | 155 | prototype.neighbourCells.px.forEach((neighbourCells) => neighboursXP.add(neighbourCells)) 156 | prototype.neighbourCells.nx.forEach((neighbourCells) => neighboursXN.add(neighbourCells)) 157 | prototype.neighbourCells.py.forEach((neighbourCells) => neighboursYP.add(neighbourCells)) 158 | prototype.neighbourCells.ny.forEach((neighbourCells) => neighboursYN.add(neighbourCells)) 159 | prototype.neighbourCells.pz.forEach((neighbourCells) => neighboursZP.add(neighbourCells)) 160 | prototype.neighbourCells.nz.forEach((neighbourCells) => neighboursZN.add(neighbourCells)) 161 | }) 162 | 163 | if (x + 1 < this.size.x) { 164 | const neighbourWave = this.waves[x + 1][y][z] 165 | const newNeighbourWave = new Set() 166 | neighbourWave.forEach((protypeId) => { 167 | if (neighboursXP.has(protypeId)) newNeighbourWave.add(protypeId) 168 | }) 169 | if (newNeighbourWave.size == 0) return false 170 | 171 | if (newNeighbourWave.size != neighbourWave.length) { 172 | stack.push({ x: x + 1, y, z }) 173 | this.waves[x + 1][y][z] = [...newNeighbourWave] 174 | } 175 | } 176 | 177 | if (y + 1 < this.size.y) { 178 | const neighbourWave = this.waves[x][y + 1][z] 179 | const newNeighbourWave = new Set() 180 | neighbourWave.forEach((protypeId) => { 181 | if (neighboursYP.has(protypeId)) newNeighbourWave.add(protypeId) 182 | }) 183 | if (newNeighbourWave.size == 0) return false 184 | 185 | if (newNeighbourWave.size != neighbourWave.length) { 186 | stack.push({ x, y: y + 1, z }) 187 | this.waves[x][y + 1][z] = [...newNeighbourWave] 188 | } 189 | } 190 | 191 | if (z + 1 < this.size.z) { 192 | const neighbourWave = this.waves[x][y][z + 1] 193 | const newNeighbourWave = new Set() 194 | neighbourWave.forEach((protypeId) => { 195 | if (neighboursZP.has(protypeId)) newNeighbourWave.add(protypeId) 196 | }) 197 | if (newNeighbourWave.size == 0) return false 198 | 199 | if (newNeighbourWave.size != neighbourWave.length) { 200 | stack.push({ x, y, z: z + 1 }) 201 | this.waves[x][y][z + 1] = [...newNeighbourWave] 202 | } 203 | } 204 | 205 | if (x - 1 >= 0) { 206 | const neighbourWave = this.waves[x - 1][y][z] 207 | const newNeighbourWave = new Set() 208 | neighbourWave.forEach((protypeId) => { 209 | if (neighboursXN.has(protypeId)) newNeighbourWave.add(protypeId) 210 | }) 211 | if (newNeighbourWave.size == 0) return false 212 | 213 | if (newNeighbourWave.size != neighbourWave.length) { 214 | stack.push({ x: x - 1, y, z }) 215 | this.waves[x - 1][y][z] = [...newNeighbourWave] 216 | } 217 | } 218 | 219 | if (y - 1 >= 0) { 220 | const neighbourWave = this.waves[x][y - 1][z] 221 | const newNeighbourWave = new Set() 222 | neighbourWave.forEach((protypeId) => { 223 | if (neighboursYN.has(protypeId)) newNeighbourWave.add(protypeId) 224 | }) 225 | if (newNeighbourWave.size == 0) return false 226 | 227 | if (newNeighbourWave.size != neighbourWave.length) { 228 | stack.push({ x, y: y - 1, z }) 229 | this.waves[x][y - 1][z] = [...newNeighbourWave] 230 | } 231 | } 232 | 233 | if (z - 1 >= 0) { 234 | const neighbourWave = this.waves[x][y][z - 1] 235 | const newNeighbourWave = new Set() 236 | neighbourWave.forEach((protypeId) => { 237 | if (neighboursZN.has(protypeId)) newNeighbourWave.add(protypeId) 238 | }) 239 | if (newNeighbourWave.size == 0) return false 240 | 241 | if (newNeighbourWave.size != neighbourWave.length) { 242 | stack.push({ x, y, z: z - 1 }) 243 | this.waves[x][y][z - 1] = [...newNeighbourWave] 244 | } 245 | } 246 | } 247 | 248 | return true 249 | } 250 | 251 | public nextUnobservedNode = (): Vector3 | null => { 252 | let minNodeIndex = null 253 | let minNodeEntropy = Infinity 254 | 255 | for (let x = 0; x < this.size.x; x++) { 256 | for (let y = 0; y < this.size.y; y++) { 257 | for (let z = 0; z < this.size.z; z++) { 258 | const entropy = this.waves[x][y][z].length 259 | 260 | if (entropy < minNodeEntropy && entropy > 1) { 261 | minNodeIndex = { x: x, y: y, z: z } 262 | minNodeEntropy = entropy 263 | } 264 | } 265 | } 266 | } 267 | 268 | return minNodeIndex 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"], 19 | "@/public/*": [ "./public/*"] 20 | } 21 | }, 22 | "exclude": ["node_modules"], 23 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"] 24 | } 25 | --------------------------------------------------------------------------------