diff --git a/.gitignore b/.gitignore index b512c09..70b7f5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,61 @@ -node_modules \ No newline at end of file +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +.husky +.DS_Store diff --git a/dist/aframe-room-component.js b/dist/aframe-room-component.js index 7c7962b..bff0750 100644 --- a/dist/aframe-room-component.js +++ b/dist/aframe-room-component.js @@ -1,781 +1,44 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; +/* + * ATTENTION: An "eval-source-map" devtool has been used. + * This devtool is neither made for production nor for readable output files. + * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. + * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) + * or disable the default devtool with "devtool: false". + * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else { + var a = factory(); + for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; + } +})(self, () => { +return /******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "./index.js": +/*!******************!*\ + !*** ./index.js ***! + \******************/ +/***/ (() => { + +eval("AFRAME.registerSystem('building',{\r\n\t\r\n\treexamineBuilding:function(){\r\n\t\t\r\n\t\t//console.log(\" = REEVALUATION REQUESTED...\");\r\n\t\t\r\n\t\tvar buildingSelf = this;\r\n\t\tvar HAIR = 0.0001;\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t/*\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\thttps://github.com/omgitsraven/aframe-room-component\r\n\t\tv0.4.2\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tOPTIMIZATION:\r\n\t\t\r\n\t\tcurrently, the entire building is getting re-generated from scratch any time anything in it changes.\r\n\t\tobviously this is wasteful, but:\r\n\t\t- this library isn't particularly likely to be used in a context where these properties will be changing at runtime (at least outside of debugging)\r\n\t\t- right now I am more concerned with getting it out the door than making it perfect anyway\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tPLANNED FEATURES TO COME (in order):\r\n\t\t- greater control over UV generation\r\n\t\t- automatic collision assignment\r\n\t\t- doors lifted above the ground (i.e. windows)\r\n\t\t- accept a shape to be extruded around a doorhole to make a doorframe (& around a floor to make a baseboard)\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tKNOWN ISSUES (with no obvious solution that would preserve ease of use):\r\n\t\t- floor/ceiling triangulation is not controllable (and therefore varying wall verticality is nearly useless unless slope is consistent)\r\n\t\t- doorhole parenting is always level to the horizon even on slope-floored walls\r\n\t\t- the setTimeout thing results in a one-frame flash of invisible walls: is it worth it? (is there a smarter thing to listen for, maybe?)\r\n\t\t\r\n\t\tISSUES THAT COULD THEORETICALLY BE FIXED BUT DON'T SEEM WORTH THE TROUBLE:\r\n\t\t- walls are internally rearranged to always wind CW, which means wall parenting will point towards the \"previous\" wall if you entered them in CCW order\r\n\t\t\r\n\t\t*/\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tfunction flipGeom(geom){\r\n\t\t\tconst indices = geom.getIndex().array;\r\n\t\t\tfor (let i = 0; i < indices.length; i += 3) {\r\n\t\t\t\tconst tempIndex = indices[i + 2];\r\n\t\t\t\tindices[i + 2] = indices[i + 1];\r\n\t\t\t\tindices[i + 1] = tempIndex;\r\n\t\t\t}\r\n\r\n\t\t\tgeom.getIndex().needsUpdate = true;\r\n\t\t}\r\n\t\t\r\n\t\tfunction makeUvsForGeom(geom,callback){\r\n\t\t\tvar allUVs = [];\r\n\t\t\tfor(var faceVertIndex=0; faceVertIndex 0) shouldReverse = !shouldReverse;\r\n\t\t\tif (isOutside) shouldReverse = !shouldReverse;\r\n\t\t\tif (shouldReverse) walls.reverse();\r\n\t\t\t\r\n\t\t\treturn walls;\r\n\t\t\t\r\n\t\t}\r\n\t\tfunction getNextWallEl(wallEl){\r\n\t\t\tvar wallList = getRoomWallArray(wallEl.parentNode);\r\n\t\t\tvar curWallIndex = wallList.indexOf(wallEl);\r\n\t\t\treturn wallList[(curWallIndex+1)%wallList.length];\r\n\t\t}\r\n\t\t\r\n\t\tvar worldWallPos = new THREE.Vector3();\r\n\t\tvar worldNextPos = new THREE.Vector3();\r\n\t\tvar worldLinkPos = new THREE.Vector3();\r\n\t\tfunction moveForLink(doorholeEl,doorlinkEl){\r\n\t\t\t\r\n\t\t\tvar holeWallEl = doorholeEl.parentNode;\r\n\t\t\tvar nextWallEl = getNextWallEl(holeWallEl);\r\n\t\t\tif (!nextWallEl) return;\r\n\t\t\t\r\n\t\t\tholeWallEl.object3D.getWorldPosition(worldWallPos);\r\n\t\t\tnextWallEl.object3D.getWorldPosition(worldNextPos);\r\n\t\t\tdoorlinkEl.object3D.getWorldPosition(worldLinkPos);\r\n\t\t\t\r\n\t\t\tvar linkGapX = worldLinkPos.x - worldWallPos.x;\r\n\t\t\tvar linkGapZ = worldLinkPos.z - worldWallPos.z;\r\n\t\t\t\r\n\t\t\tvar wallGapX = worldNextPos.x - worldWallPos.x;\r\n\t\t\tvar wallGapZ = worldNextPos.z - worldWallPos.z;\r\n\t\t\tvar wallAng = Math.atan2(wallGapZ,wallGapX);\r\n\t\t\tvar wallLength = Math.sqrt(wallGapX*wallGapX + wallGapZ*wallGapZ);\r\n\t\t\t\r\n\t\t\tvar localLinkX = linkGapX*Math.cos(-wallAng) - linkGapZ*Math.sin(-wallAng);\r\n\t\t\t//var localLinkZ = linkGapX*Math.sin(-wallAng) + linkGapZ*Math.cos(-wallAng);\r\n\t\t\t\r\n\t\t\tvar doorHalf = doorlinkEl.components.doorlink.data.width / 2;\r\n\t\t\tlocalLinkX = Math.max(localLinkX,doorHalf+HAIR);\r\n\t\t\tlocalLinkX = Math.min(localLinkX,wallLength-doorHalf-HAIR);\r\n\t\t\t\r\n\t\t\tdoorholeEl.setAttribute(\"position\",{x:localLinkX,y:0,z:0});\r\n\t\t\tdoorholeEl.object3D.updateMatrixWorld();\r\n\t\t\t\r\n\t\t}\r\n\t\t\r\n\t\tfunction getHoleLink(doorholeEl){\r\n\t\t\tvar doorlinks = buildingSelf.el.querySelectorAll('[doorlink]');\r\n\t\t\tfor(var curLinkIndex=0; curLinkIndex= 4) {\r\n\t\t\t\t\t\t\t\tif (rawWalls.length > 4) console.error(\"rooms with WIDTH and LENGTH should only have four walls!\");\r\n\t\t\t\t\t\t\t\trawWalls[0].setAttribute(\"position\",{x:0,y:0,z:0});\r\n\t\t\t\t\t\t\t\trawWalls[1].setAttribute(\"position\",{x:w,y:0,z:0});\r\n\t\t\t\t\t\t\t\trawWalls[2].setAttribute(\"position\",{x:w,y:0,z:l});\r\n\t\t\t\t\t\t\t\trawWalls[3].setAttribute(\"position\",{x:0,y:0,z:l});\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tconsole.error(\"rooms with WIDTH and LENGTH must have four walls!\");\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tconsole.error(\"rooms with WIDTH must also have LENGTH (and vice versa)\");\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\tvar walls=getRoomWallArray(sceneChildNode);\r\n\t\t\t\t\tif (walls.length > 2) {\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tfor(var wallIndex=0; wallIndex 2) {\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tfor(var wallIndex=0; wallIndex maxTopY) topY = maxTopY;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tfunction addWorldVert(ptY){\r\n\t\t\t\t\t\t\t\t\t\tvar tempPos = new THREE.Vector3(ptX,ptY,0);\r\n\t\t\t\t\t\t\t\t\t\tcurWallNode.object3D.localToWorld(tempPos);\r\n\t\t\t\t\t\t\t\t\t\tholeEl.myVerts.push(tempPos);\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\taddWorldVert(floorY);\r\n\t\t\t\t\t\t\t\t\taddWorldVert(topY);\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tif (holeSide < 0) {\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,floorY);\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,topY);\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,topY);\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,floorY);\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\twallShape.lineTo(\r\n\t\t\t\t\t\t\t\twallLength,\r\n\t\t\t\t\t\t\t\tnextWallNode.components.position.data.y-curWallNode.components.position.data.y\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\twallShape.lineTo(\r\n\t\t\t\t\t\t\t\twallLength,\r\n\t\t\t\t\t\t\t\t(nextWallNode.components.position.data.y-curWallNode.components.position.data.y)+getWallHeight(nextWallNode)\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tvar wallGeom = new THREE.ShapeGeometry(wallShape);\r\n\t\t\t\t\t\t\tmakePlaneUvs(wallGeom,'x','y',1,1);\r\n\t\t\t\t\t\t\tfinishGeom(wallGeom);\r\n\t\t\t\t\t\t\tvar myMat = curWallNode.components.material ? curWallNode.components.material.material : curWallNode.parentNode.components.material.material;\r\n\t\t\t\t\t\t\tif (curWallNode.myMesh) {\r\n\t\t\t\t\t\t\t\tcurWallNode.myMesh.geometry = wallGeom;\r\n\t\t\t\t\t\t\t\tcurWallNode.myMesh.material = myMat;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tcurWallNode.myMesh = new THREE.Mesh(wallGeom, myMat);\r\n\t\t\t\t\t\t\t\tcurWallNode.setObject3D('wallMesh',curWallNode.myMesh);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tvar caps=[];\r\n\t\t\t\t\t\tfor(var roomChildNodeIndex=0; roomChildNodeIndex 0) shouldReverse = !shouldReverse; - if (isOutside) shouldReverse = !shouldReverse; - if (shouldReverse) walls.reverse(); - - return walls; - - } - function getNextWallEl(wallEl){ - var wallList = getRoomWallArray(wallEl.parentNode); - var curWallIndex = wallList.indexOf(wallEl); - return wallList[(curWallIndex+1)%wallList.length]; - } - - var worldWallPos = new THREE.Vector3(); - var worldNextPos = new THREE.Vector3(); - var worldLinkPos = new THREE.Vector3(); - function moveForLink(doorholeEl,doorlinkEl){ - - var holeWallEl = doorholeEl.parentNode; - var nextWallEl = getNextWallEl(holeWallEl); - if (!nextWallEl) return; - - holeWallEl.object3D.getWorldPosition(worldWallPos); - nextWallEl.object3D.getWorldPosition(worldNextPos); - doorlinkEl.object3D.getWorldPosition(worldLinkPos); - - var linkGapX = worldLinkPos.x - worldWallPos.x; - var linkGapZ = worldLinkPos.z - worldWallPos.z; - - var wallGapX = worldNextPos.x - worldWallPos.x; - var wallGapZ = worldNextPos.z - worldWallPos.z; - var wallAng = Math.atan2(wallGapZ,wallGapX); - var wallLength = Math.sqrt(wallGapX*wallGapX + wallGapZ*wallGapZ); - - var localLinkX = linkGapX*Math.cos(-wallAng) - linkGapZ*Math.sin(-wallAng); - //var localLinkZ = linkGapX*Math.sin(-wallAng) + linkGapZ*Math.cos(-wallAng); - - var doorHalf = doorlinkEl.components.doorlink.data.width / 2; - localLinkX = Math.max(localLinkX,doorHalf+HAIR); - localLinkX = Math.min(localLinkX,wallLength-doorHalf-HAIR); - - doorholeEl.setAttribute("position",{x:localLinkX,y:0,z:0}); - doorholeEl.object3D.updateMatrixWorld(); - - } - - function getHoleLink(doorholeEl){ - var doorlinks = buildingSelf.el.querySelectorAll('[doorlink]'); - for(var curLinkIndex=0; curLinkIndex= 4) { - if (rawWalls.length > 4) console.error("rooms with WIDTH and LENGTH should only have four walls!"); - rawWalls[0].setAttribute("position",{x:0,y:0,z:0}); - rawWalls[1].setAttribute("position",{x:w,y:0,z:0}); - rawWalls[2].setAttribute("position",{x:w,y:0,z:l}); - rawWalls[3].setAttribute("position",{x:0,y:0,z:l}); - } else { - console.error("rooms with WIDTH and LENGTH must have four walls!"); - } - } else { - console.error("rooms with WIDTH must also have LENGTH (and vice versa)"); - } - } - - - var walls=getRoomWallArray(sceneChildNode); - if (walls.length > 2) { - - for(var wallIndex=0; wallIndex 2) { - - - for(var wallIndex=0; wallIndex maxTopY) topY = maxTopY; - - function addWorldVert(ptY){ - var tempPos = new THREE.Vector3(ptX,ptY,0); - curWallNode.object3D.localToWorld(tempPos); - holeEl.myVerts.push(tempPos); - } - addWorldVert(floorY); - addWorldVert(topY); - - if (holeSide < 0) { - wallShape.lineTo(ptX,floorY); - wallShape.lineTo(ptX,topY); - } else { - wallShape.lineTo(ptX,topY); - wallShape.lineTo(ptX,floorY); - } - } - - } - - wallShape.lineTo( - wallLength, - nextWallNode.components.position.data.y-curWallNode.components.position.data.y - ); - wallShape.lineTo( - wallLength, - (nextWallNode.components.position.data.y-curWallNode.components.position.data.y)+getWallHeight(nextWallNode) - ); - - var wallGeom = new THREE.ShapeGeometry(wallShape); - makePlaneUvs(wallGeom,'x','y',1,1); - finishGeom(wallGeom); - var myMat = curWallNode.components.material ? curWallNode.components.material.material : curWallNode.parentNode.components.material.material; - if (curWallNode.myMesh) { - curWallNode.myMesh.geometry = wallGeom; - curWallNode.myMesh.material = myMat; - } else { - curWallNode.myMesh = new THREE.Mesh(wallGeom, myMat); - curWallNode.setObject3D('wallMesh',curWallNode.myMesh); - } - - - } - - - - - - var caps=[]; - for(var roomChildNodeIndex=0; roomChildNodeIndex0&&(p=!p),t&&(p=!p),p&&o.reverse(),o}function a(e){var t=i(e.parentNode),o=t.indexOf(e);return t[(o+1)%t.length]}function s(e,t){var o=e.parentNode,n=a(o);if(n){o.object3D.getWorldPosition(d),n.object3D.getWorldPosition(h),t.object3D.getWorldPosition(u);var r=u.x-d.x,i=u.z-d.z,s=h.x-d.x,l=h.z-d.z,m=Math.atan2(l,s),p=Math.sqrt(s*s+l*l),f=r*Math.cos(-m)-i*Math.sin(-m),g=t.components.doorlink.data.width/2;f=Math.max(f,g+c),f=Math.min(f,p-g-c),e.setAttribute("position",{x:f,y:0,z:0}),e.object3D.updateMatrixWorld()}}function l(e){for(var t=p.el.querySelectorAll("[doorlink]"),o=0;o=4?(y.length>4&&console.error("rooms with WIDTH and LENGTH should only have four walls!"),y[0].setAttribute("position",{x:0,y:0,z:0}),y[1].setAttribute("position",{x:g,y:0,z:0}),y[2].setAttribute("position",{x:g,y:0,z:v}),y[3].setAttribute("position",{x:0,y:0,z:v})):console.error("rooms with WIDTH and LENGTH must have four walls!")}else console.error("rooms with WIDTH must also have LENGTH (and vice versa)");var E=i(f);if(E.length>2)for(var w=0;w2){for(var w=0;wU&&(Y=U),a(X),a(Y),L<0?(N.lineTo(q,X),N.lineTo(q,Y)):(N.lineTo(q,Y),N.lineTo(q,X))}}N.lineTo(V,x.components.position.data.y-M.components.position.data.y),N.lineTo(V,x.components.position.data.y-M.components.position.data.y+m(x));var J=new THREE.ShapeGeometry(N);o(J,"x","y",1,1),n(J);var K=M.components.material?M.components.material.material:M.parentNode.components.material.material;M.myMesh?(M.myMesh.geometry=J,M.myMesh.material=K):(M.myMesh=new THREE.Mesh(J,K),M.setObject3D("wallMesh",M.myMesh))}for(var Q=[],$=0;$(()=>{function e(e){e&&e.systems.building&&e.systems.building.reexamineBuilding()}function t(t){"position"==t.detail.name&&e(t.detail.target.sceneEl)}AFRAME.registerSystem("building",{reexamineBuilding:function(){var e=this,t=1e-4;function o(e){for(var t=e.getIndex().array,o=0;o0&&(p=!p),t&&(p=!p),p&&o.reverse(),o}var l=new THREE.Vector3,m=new THREE.Vector3,p=new THREE.Vector3;function c(e,o){var n,r,i,a=e.parentNode,c=(i=(r=s((n=a).parentNode)).indexOf(n),r[(i+1)%r.length]);if(c){a.object3D.getWorldPosition(l),c.object3D.getWorldPosition(m),o.object3D.getWorldPosition(p);var d=p.x-l.x,h=p.z-l.z,u=m.x-l.x,f=m.z-l.z,g=Math.atan2(f,u),v=Math.sqrt(u*u+f*f),y=d*Math.cos(-g)-h*Math.sin(-g),E=o.components.doorlink.data.width/2;y=Math.max(y,E+t),y=Math.min(y,v-E-t),e.setAttribute("position",{x:y,y:0,z:0}),e.object3D.updateMatrixWorld()}}function d(t){for(var o=e.el.querySelectorAll("[doorlink]"),n=0;n=4?(u.length>4&&console.error("rooms with WIDTH and LENGTH should only have four walls!"),u[0].setAttribute("position",{x:0,y:0,z:0}),u[1].setAttribute("position",{x:m,y:0,z:0}),u[2].setAttribute("position",{x:m,y:0,z:p}),u[3].setAttribute("position",{x:0,y:0,z:p})):console.error("rooms with WIDTH and LENGTH must have four walls!")}else console.error("rooms with WIDTH must also have LENGTH (and vice versa)");if((x=s(A)).length>2)for(var f=0;f2){for(f=0;f(q=I+L-t)&&(O=q),e(I),e(O),B<0?(C.lineTo(ee,I),C.lineTo(ee,O)):(C.lineTo(ee,O),C.lineTo(ee,I))},B=-1;B<=1;B+=2){var I,O,L,q;W()}}C.lineTo(H,R.components.position.data.y-g.components.position.data.y),C.lineTo(H,R.components.position.data.y-g.components.position.data.y+h(R));var X=new THREE.ShapeGeometry(C);r(X,"x","y",1,1),i(X);var Y=g.components.material?g.components.material.material:g.parentNode.components.material.material;g.myMesh?(g.myMesh.geometry=X,g.myMesh.material=Y):(g.myMesh=new THREE.Mesh(X,Y),g.setObject3D("wallMesh",g.myMesh))}for(var Z=[],U=0;U {\nreturn ","AFRAME.registerSystem('building',{\r\n\t\r\n\treexamineBuilding:function(){\r\n\t\t\r\n\t\t//console.log(\" = REEVALUATION REQUESTED...\");\r\n\t\t\r\n\t\tvar buildingSelf = this;\r\n\t\tvar HAIR = 0.0001;\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t/*\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\thttps://github.com/omgitsraven/aframe-room-component\r\n\t\tv0.4.2\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tOPTIMIZATION:\r\n\t\t\r\n\t\tcurrently, the entire building is getting re-generated from scratch any time anything in it changes.\r\n\t\tobviously this is wasteful, but:\r\n\t\t- this library isn't particularly likely to be used in a context where these properties will be changing at runtime (at least outside of debugging)\r\n\t\t- right now I am more concerned with getting it out the door than making it perfect anyway\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tPLANNED FEATURES TO COME (in order):\r\n\t\t- greater control over UV generation\r\n\t\t- automatic collision assignment\r\n\t\t- doors lifted above the ground (i.e. windows)\r\n\t\t- accept a shape to be extruded around a doorhole to make a doorframe (& around a floor to make a baseboard)\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tKNOWN ISSUES (with no obvious solution that would preserve ease of use):\r\n\t\t- floor/ceiling triangulation is not controllable (and therefore varying wall verticality is nearly useless unless slope is consistent)\r\n\t\t- doorhole parenting is always level to the horizon even on slope-floored walls\r\n\t\t- the setTimeout thing results in a one-frame flash of invisible walls: is it worth it? (is there a smarter thing to listen for, maybe?)\r\n\t\t\r\n\t\tISSUES THAT COULD THEORETICALLY BE FIXED BUT DON'T SEEM WORTH THE TROUBLE:\r\n\t\t- walls are internally rearranged to always wind CW, which means wall parenting will point towards the \"previous\" wall if you entered them in CCW order\r\n\t\t\r\n\t\t*/\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\t\r\n\t\tfunction flipGeom(geom){\r\n\t\t\tconst indices = geom.getIndex().array;\r\n\t\t\tfor (let i = 0; i < indices.length; i += 3) {\r\n\t\t\t\tconst tempIndex = indices[i + 2];\r\n\t\t\t\tindices[i + 2] = indices[i + 1];\r\n\t\t\t\tindices[i + 1] = tempIndex;\r\n\t\t\t}\r\n\r\n\t\t\tgeom.getIndex().needsUpdate = true;\r\n\t\t}\r\n\t\t\r\n\t\tfunction makeUvsForGeom(geom,callback){\r\n\t\t\tvar allUVs = [];\r\n\t\t\tfor(var faceVertIndex=0; faceVertIndex 0) shouldReverse = !shouldReverse;\r\n\t\t\tif (isOutside) shouldReverse = !shouldReverse;\r\n\t\t\tif (shouldReverse) walls.reverse();\r\n\t\t\t\r\n\t\t\treturn walls;\r\n\t\t\t\r\n\t\t}\r\n\t\tfunction getNextWallEl(wallEl){\r\n\t\t\tvar wallList = getRoomWallArray(wallEl.parentNode);\r\n\t\t\tvar curWallIndex = wallList.indexOf(wallEl);\r\n\t\t\treturn wallList[(curWallIndex+1)%wallList.length];\r\n\t\t}\r\n\t\t\r\n\t\tvar worldWallPos = new THREE.Vector3();\r\n\t\tvar worldNextPos = new THREE.Vector3();\r\n\t\tvar worldLinkPos = new THREE.Vector3();\r\n\t\tfunction moveForLink(doorholeEl,doorlinkEl){\r\n\t\t\t\r\n\t\t\tvar holeWallEl = doorholeEl.parentNode;\r\n\t\t\tvar nextWallEl = getNextWallEl(holeWallEl);\r\n\t\t\tif (!nextWallEl) return;\r\n\t\t\t\r\n\t\t\tholeWallEl.object3D.getWorldPosition(worldWallPos);\r\n\t\t\tnextWallEl.object3D.getWorldPosition(worldNextPos);\r\n\t\t\tdoorlinkEl.object3D.getWorldPosition(worldLinkPos);\r\n\t\t\t\r\n\t\t\tvar linkGapX = worldLinkPos.x - worldWallPos.x;\r\n\t\t\tvar linkGapZ = worldLinkPos.z - worldWallPos.z;\r\n\t\t\t\r\n\t\t\tvar wallGapX = worldNextPos.x - worldWallPos.x;\r\n\t\t\tvar wallGapZ = worldNextPos.z - worldWallPos.z;\r\n\t\t\tvar wallAng = Math.atan2(wallGapZ,wallGapX);\r\n\t\t\tvar wallLength = Math.sqrt(wallGapX*wallGapX + wallGapZ*wallGapZ);\r\n\t\t\t\r\n\t\t\tvar localLinkX = linkGapX*Math.cos(-wallAng) - linkGapZ*Math.sin(-wallAng);\r\n\t\t\t//var localLinkZ = linkGapX*Math.sin(-wallAng) + linkGapZ*Math.cos(-wallAng);\r\n\t\t\t\r\n\t\t\tvar doorHalf = doorlinkEl.components.doorlink.data.width / 2;\r\n\t\t\tlocalLinkX = Math.max(localLinkX,doorHalf+HAIR);\r\n\t\t\tlocalLinkX = Math.min(localLinkX,wallLength-doorHalf-HAIR);\r\n\t\t\t\r\n\t\t\tdoorholeEl.setAttribute(\"position\",{x:localLinkX,y:0,z:0});\r\n\t\t\tdoorholeEl.object3D.updateMatrixWorld();\r\n\t\t\t\r\n\t\t}\r\n\t\t\r\n\t\tfunction getHoleLink(doorholeEl){\r\n\t\t\tvar doorlinks = buildingSelf.el.querySelectorAll('[doorlink]');\r\n\t\t\tfor(var curLinkIndex=0; curLinkIndex= 4) {\r\n\t\t\t\t\t\t\t\tif (rawWalls.length > 4) console.error(\"rooms with WIDTH and LENGTH should only have four walls!\");\r\n\t\t\t\t\t\t\t\trawWalls[0].setAttribute(\"position\",{x:0,y:0,z:0});\r\n\t\t\t\t\t\t\t\trawWalls[1].setAttribute(\"position\",{x:w,y:0,z:0});\r\n\t\t\t\t\t\t\t\trawWalls[2].setAttribute(\"position\",{x:w,y:0,z:l});\r\n\t\t\t\t\t\t\t\trawWalls[3].setAttribute(\"position\",{x:0,y:0,z:l});\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tconsole.error(\"rooms with WIDTH and LENGTH must have four walls!\");\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tconsole.error(\"rooms with WIDTH must also have LENGTH (and vice versa)\");\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t\tvar walls=getRoomWallArray(sceneChildNode);\r\n\t\t\t\t\tif (walls.length > 2) {\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tfor(var wallIndex=0; wallIndex 2) {\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tfor(var wallIndex=0; wallIndex maxTopY) topY = maxTopY;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tfunction addWorldVert(ptY){\r\n\t\t\t\t\t\t\t\t\t\tvar tempPos = new THREE.Vector3(ptX,ptY,0);\r\n\t\t\t\t\t\t\t\t\t\tcurWallNode.object3D.localToWorld(tempPos);\r\n\t\t\t\t\t\t\t\t\t\tholeEl.myVerts.push(tempPos);\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\taddWorldVert(floorY);\r\n\t\t\t\t\t\t\t\t\taddWorldVert(topY);\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\t\tif (holeSide < 0) {\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,floorY);\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,topY);\r\n\t\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,topY);\r\n\t\t\t\t\t\t\t\t\t\twallShape.lineTo(ptX,floorY);\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\twallShape.lineTo(\r\n\t\t\t\t\t\t\t\twallLength,\r\n\t\t\t\t\t\t\t\tnextWallNode.components.position.data.y-curWallNode.components.position.data.y\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\twallShape.lineTo(\r\n\t\t\t\t\t\t\t\twallLength,\r\n\t\t\t\t\t\t\t\t(nextWallNode.components.position.data.y-curWallNode.components.position.data.y)+getWallHeight(nextWallNode)\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tvar wallGeom = new THREE.ShapeGeometry(wallShape);\r\n\t\t\t\t\t\t\tmakePlaneUvs(wallGeom,'x','y',1,1);\r\n\t\t\t\t\t\t\tfinishGeom(wallGeom);\r\n\t\t\t\t\t\t\tvar myMat = curWallNode.components.material ? curWallNode.components.material.material : curWallNode.parentNode.components.material.material;\r\n\t\t\t\t\t\t\tif (curWallNode.myMesh) {\r\n\t\t\t\t\t\t\t\tcurWallNode.myMesh.geometry = wallGeom;\r\n\t\t\t\t\t\t\t\tcurWallNode.myMesh.material = myMat;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tcurWallNode.myMesh = new THREE.Mesh(wallGeom, myMat);\r\n\t\t\t\t\t\t\t\tcurWallNode.setObject3D('wallMesh',curWallNode.myMesh);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tvar caps=[];\r\n\t\t\t\t\t\tfor(var roomChildNodeIndex=0; roomChildNodeIndexA-Frame Room Component - Basic - + diff --git a/index.js b/index.js index 11e4bae..6809e52 100644 --- a/index.js +++ b/index.js @@ -14,7 +14,7 @@ AFRAME.registerSystem('building',{ https://github.com/omgitsraven/aframe-room-component - v0.4.1 + v0.4.2 @@ -56,13 +56,14 @@ AFRAME.registerSystem('building',{ function flipGeom(geom){ - var indexCopy = geom.index; - for(var curFaceIndex=0; curFaceIndex=1.2.0" }, "semistandard": { "globals": [ diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..ba75da7 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,26 @@ +'use strict'; + +const Path = require('path'); + +module.exports = [ + { + entry: './index.js', + output: { + filename: 'aframe-room-component.js', + library: { type: 'umd' }, + path: Path.resolve(__dirname, 'dist'), + publicPath: '/dist/' + }, + mode: 'development', + devtool: 'eval-source-map', + stats: { colors: true }, + devServer: { + port: process.env.PORT || 8000, + hot: false, + liveReload: true, + static: { + directory: Path.resolve(__dirname) + } + } + } +]; diff --git a/webpack.prod.config.js b/webpack.prod.config.js new file mode 100644 index 0000000..6dc9d38 --- /dev/null +++ b/webpack.prod.config.js @@ -0,0 +1,44 @@ +'use strict'; + +const Path = require('path'); + +const TerserPlugin = require('terser-webpack-plugin'); + +module.exports = [ + { + entry: './index.js', + output: { + filename: 'aframe-room-component.min.js', + library: { type: 'umd' }, + path: Path.resolve(__dirname, 'dist') + }, + mode: 'production', + devtool: 'source-map', + stats: { colors: true }, + module: { + rules: [ + { + test: /\.js$/, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env'] + } + } + } + ] + }, + optimization: { + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: { + compress: { passes: 2 }, + format: { comments: false } + }, + extractComments: false + }) + ] + } + } +];