aframe.js 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507
  1. /*
  2. The MIT License (MIT)
  3. Copyright (c) 2014-2020 Nikolai Suslov and the Krestianstvo.org project contributors. (https://github.com/NikolaySuslov/livecodingspace/blob/master/LICENSE.md)
  4. */
  5. // VWF & A-Frame model driver
  6. import { Fabric } from '/core/vwf/fabric.js';
  7. class AFrameModel extends Fabric {
  8. constructor(module) {
  9. console.log("AFrame constructor");
  10. super(module, "Model");
  11. }
  12. factory() {
  13. let _self_ = this;
  14. return this.load(this.module, {
  15. // == Module Definition ====================================================================
  16. // -- initialize ---------------------------------------------------------------------------
  17. initialize: function () {
  18. let self = this;
  19. this.state = {
  20. nodes: {},
  21. scenes: {},
  22. prototypes: {},
  23. createLocalNode: function (nodeID, childID, childExtendsID, childImplementsIDs,
  24. childSource, childType, childIndex, childName, callback) {
  25. return {
  26. "parentID": nodeID,
  27. "ID": childID,
  28. "extendsID": childExtendsID,
  29. "implementsIDs": childImplementsIDs,
  30. "source": childSource,
  31. "type": childType,
  32. "name": childName,
  33. "prototypes": undefined,
  34. "aframeObj": undefined,
  35. "scene": undefined,
  36. "componentName": undefined,
  37. "events": {
  38. "clickable": false
  39. }
  40. };
  41. },
  42. isAFrameClass: function (prototypes, classID) {
  43. if (prototypes) {
  44. for (var i = 0; i < prototypes.length; i++) {
  45. if (prototypes[i] === classID) {
  46. //console.info( "prototypes[ i ]: " + prototypes[ i ] );
  47. return true;
  48. }
  49. }
  50. }
  51. return false;
  52. },
  53. isAFrameComponent: function (prototypes) {
  54. var found = false;
  55. if (prototypes) {
  56. for (var i = 0; i < prototypes.length && !found; i++) {
  57. found = (prototypes[i] === "proxy/aframe/node.vwf");
  58. }
  59. }
  60. return found;
  61. },
  62. isNodeDefinition: function (prototypes) {
  63. var found = false;
  64. if (prototypes) {
  65. for (var i = 0; i < prototypes.length && !found; i++) {
  66. found = (prototypes[i] == "proxy/aframe/node.vwf");
  67. }
  68. }
  69. return found;
  70. },
  71. isAEntityDefinition: function (prototypes) {
  72. var found = false;
  73. if (prototypes) {
  74. for (var i = 0; i < prototypes.length && !found; i++) {
  75. found = (prototypes[i] == "proxy/aframe/aentity.vwf");
  76. }
  77. }
  78. return found;
  79. },
  80. setAFrameProperty: function (propertyName, propertyValue, aframeObject) {
  81. //console.log(propertyValue);
  82. if (propertyValue.hasOwnProperty('x')) {
  83. aframeObject.setAttribute(propertyName, propertyValue)
  84. } else
  85. if (Array.isArray(propertyValue)) {
  86. aframeObject.setAttribute(propertyName, {
  87. x: propertyValue[0],
  88. y: propertyValue[1],
  89. z: propertyValue[2]
  90. })
  91. } else if (typeof propertyValue === 'string') {
  92. propertyValue.includes(',') ? aframeObject.setAttribute(propertyName, AFRAME.utils.coordinates.parse(propertyValue.split(',').join(' '))) : aframeObject.setAttribute(propertyName, AFRAME.utils.coordinates.parse(propertyValue))
  93. //aframeObject.setAttribute(propertyName, AFRAME.utils.coordinates.parse(propertyValue))
  94. } else if (propertyValue.hasOwnProperty('0')) {
  95. aframeObject.setAttribute(propertyName, {
  96. x: propertyValue[0],
  97. y: propertyValue[1],
  98. z: propertyValue[2]
  99. })
  100. }
  101. },
  102. setFromValue: function (propertyValue) {
  103. var value = new THREE.Vector3(); //goog.vec.Vec3.create();
  104. if (propertyValue.hasOwnProperty('x')) {
  105. value = value.set(propertyValue.x, propertyValue.y, propertyValue.z)
  106. } else if (Array.isArray(propertyValue) || propertyValue instanceof Float32Array) {
  107. value = value.fromArray(propertyValue);
  108. } else if (typeof propertyValue === 'string') {
  109. let val = propertyValue.includes(',') ? AFRAME.utils.coordinates.parse(propertyValue.split(',').join(' ')) : AFRAME.utils.coordinates.parse(propertyValue);
  110. value = value.set(val.x, val.y, val.z)
  111. // let val = AFRAME.utils.coordinates.parse(propertyValue);
  112. // value = goog.vec.Vec3.createFromValues(val.x, val.y, val.z)
  113. } else if (propertyValue.hasOwnProperty('0')) {
  114. value = value.set(propertyValue[0], propertyValue[1], propertyValue[2])
  115. }
  116. return value
  117. },
  118. updateStoredTransformFor: function (node, propertyName) {
  119. if (node && node.aframeObj && node.aframeObj.object3D) {
  120. // Add a local model-side transform that can stay pure even if the view changes the
  121. // transform on the threeObject - this already happened in creatingNode for those nodes that
  122. // didn't need to load a model
  123. if (!node.transform)
  124. node.transform = {};
  125. if (propertyName == 'position') {
  126. let pos = (new THREE.Vector3()).copy(node.aframeObj.object3D.position);
  127. node.transform.position = new THREE.Vector3(pos.x, pos.y, pos.z);
  128. node.transform.storedPositionDirty = false;
  129. }
  130. if (propertyName == 'rotation') {
  131. // let rot = (new THREE.Vector3()).copy(node.aframeObj.object3D.rotation);
  132. let rot = node.aframeObj.getAttribute('rotation');
  133. node.transform.rotation = new THREE.Vector3(rot.x, rot.y, rot.z);
  134. node.transform.storedRotationDirty = false;
  135. }
  136. if (propertyName == 'scale') {
  137. let scale = (new THREE.Vector3()).copy(node.aframeObj.object3D.scale);
  138. node.transform.scale = new THREE.Vector3(scale.x, scale.y, scale.z);
  139. node.transform.storedScaleDirty = false;
  140. }
  141. //node.transform.position = AFRAME.utils.coordinates.stringify(node.aframeObj.object3D.position);
  142. // node.transform.rotation = AFRAME.utils.coordinates.stringify(node.aframeObj.object3D.rotation);
  143. // node.storedTransformDirty = false;
  144. }
  145. },
  146. addNodeToHierarchy: function (node) {
  147. if (node.aframeObj) {
  148. if (this.nodes[node.parentID] !== undefined) {
  149. var parent = this.nodes[node.parentID];
  150. if (parent.aframeObj) {
  151. if (parent.children === undefined) {
  152. parent.children = [];
  153. }
  154. parent.children.push(node.ID);
  155. //console.info( "Adding child: " + childID + " to " + nodeID );
  156. if (node.aframeObj.nodeName !== "A-ASSET-ITEM" &&
  157. node.aframeObj.nodeName !== "IMG" &&
  158. node.aframeObj.nodeName !== "AUDIO" &&
  159. node.aframeObj.nodeName !== "VIDEO"
  160. ) {
  161. parent.aframeObj.appendChild(node.aframeObj);
  162. }
  163. }
  164. }
  165. if (node.aframeObj.nodeName !== "A-SCENE") {
  166. node.scene = this.scenes[self.kernel.application()];
  167. }
  168. }
  169. },
  170. createAFrameObject: function (node, config) {
  171. var protos = node.prototypes;
  172. var aframeObj = undefined;
  173. if (this.isAFrameClass(protos, "proxy/aframe/ascene.vwf")) {
  174. aframeObj = document.createElement('a-scene');
  175. let assetsElement = document.createElement('a-assets');
  176. aframeObj.appendChild(assetsElement);
  177. aframeObj.setAttribute('scene-utils', "");
  178. aframeObj.setAttribute('light', 'defaultLightsEnabled', false);
  179. //aframeObj.setAttribute('embedded', {});
  180. //aframeObj.setAttribute('loading-screen', "backgroundColor: black");
  181. this.scenes[node.ID] = aframeObj;
  182. //TODO: move from veiw here
  183. //document.body.appendChild(aframeObj);
  184. }
  185. if (this.isAFrameClass(protos, "proxy/aframe/a-asset-item.vwf")) {
  186. let assets = document.querySelector('a-assets');
  187. if (assets) {
  188. aframeObj = document.createElement('a-asset-item');
  189. aframeObj.setAttribute('id', "item-" + _self_.helpers.GUID());
  190. aframeObj.setAttribute('src', "");
  191. aframeObj.setAttribute('crossorigin', "anonymous");
  192. assets.appendChild(aframeObj);
  193. }
  194. } else if (this.isAFrameClass(protos, "proxy/aframe/a-asset-image-item.vwf")) {
  195. let assets = document.querySelector('a-assets');
  196. if (assets) {
  197. let elID = "item-" + _self_.helpers.GUID();
  198. aframeObj = document.createElement('img');
  199. aframeObj.setAttribute('id', elID);
  200. aframeObj.setAttribute('src', "");
  201. aframeObj.setAttribute('crossorigin', "anonymous");
  202. assets.appendChild(aframeObj);
  203. }
  204. } else if (this.isAFrameClass(protos, "proxy/aframe/a-asset-audio-item.vwf")) {
  205. let assets = document.querySelector('a-assets');
  206. if (assets) {
  207. aframeObj = document.createElement('audio');
  208. aframeObj.setAttribute('id', "item-" + _self_.helpers.GUID());
  209. aframeObj.setAttribute('src', "");
  210. aframeObj.setAttribute('crossorigin', "anonymous");
  211. assets.appendChild(aframeObj);
  212. }
  213. } else if (this.isAFrameClass(protos, "proxy/aframe/a-asset-video-item.vwf")) {
  214. let assets = document.querySelector('a-assets');
  215. if (assets) {
  216. aframeObj = document.createElement('video');
  217. aframeObj.setAttribute('id', "item-" + _self_.helpers.GUID());
  218. aframeObj.setAttribute('src', "");
  219. aframeObj.setAttribute('crossorigin', "anonymous");
  220. aframeObj.setAttribute('autoplay', "");
  221. aframeObj.setAttribute('loop', true);
  222. assets.appendChild(aframeObj);
  223. }
  224. }
  225. else if (this.isAFrameClass(protos, "proxy/aframe/asky.vwf")) {
  226. aframeObj = document.createElement('a-sky');
  227. } else if (this.isAFrameClass(protos, "proxy/aframe/a-arjs-anchor.vwf")) {
  228. aframeObj = document.createElement('a-anchor');
  229. } else if (this.isAFrameClass(protos, "proxy/aframe/alight.vwf")) {
  230. aframeObj = document.createElement('a-light');
  231. } else if (this.isAFrameClass(protos, "proxy/aframe/acursor.vwf")) {
  232. aframeObj = document.createElement('a-cursor');
  233. } else if (this.isAFrameClass(protos, "proxy/aframe/a-sun-sky.vwf")) {
  234. aframeObj = document.createElement('a-sun-sky');
  235. } else if (this.isAFrameClass(protos, "proxy/aframe/abox.vwf")) {
  236. aframeObj = document.createElement('a-box');
  237. aframeObj.setAttribute('geometry', {
  238. primitive: 'box'
  239. });
  240. } else if (this.isAFrameClass(protos, "proxy/aframe/asphere.vwf")) {
  241. aframeObj = document.createElement('a-sphere');
  242. aframeObj.setAttribute('geometry', {
  243. primitive: 'sphere'
  244. });
  245. } else if (this.isAFrameClass(protos, "proxy/aframe/aplane.vwf")) {
  246. aframeObj = document.createElement('a-plane');
  247. aframeObj.setAttribute('geometry', {
  248. primitive: 'plane'
  249. });
  250. } else if (this.isAFrameClass(protos, "proxy/aframe/acylinder.vwf")) {
  251. aframeObj = document.createElement('a-cylinder');
  252. aframeObj.setAttribute('geometry', {
  253. primitive: 'cylinder'
  254. });
  255. } else if (this.isAFrameClass(protos, "proxy/aframe/acone.vwf")) {
  256. aframeObj = document.createElement('a-cone');
  257. aframeObj.setAttribute('geometry', {
  258. primitive: 'cone'
  259. });
  260. }
  261. else if (this.isAFrameClass(protos, "proxy/aframe/atext.vwf")) {
  262. aframeObj = document.createElement('a-text');
  263. } else if (this.isAFrameClass(protos, "proxy/aframe/acolladamodel.vwf")) {
  264. aframeObj = document.createElement('a-collada-model');
  265. } else if (this.isAFrameClass(protos, "proxy/aframe/aobjmodel.vwf")) {
  266. aframeObj = document.createElement('a-obj-model');
  267. } else if (this.isAFrameClass(protos, "proxy/aframe/agltfmodel.vwf")) {
  268. aframeObj = document.createElement('a-gltf-model');
  269. } else if (this.isAFrameClass(protos, "proxy/aframe/aanimation.vwf")) {
  270. aframeObj = document.createElement('a-animation');
  271. } else if (this.isAFrameClass(protos, "proxy/aframe/acamera.vwf")) {
  272. aframeObj = document.createElement('a-camera');
  273. aframeObj.setAttribute('camera', 'active', false);
  274. }
  275. else if (this.isAFrameClass(protos, "proxy/aframe/aentity.vwf")) {
  276. aframeObj = document.createElement('a-entity');
  277. }
  278. if (aframeObj.nodeName !== "A-ASSET-ITEM" &&
  279. aframeObj.nodeName !== "IMG" &&
  280. aframeObj.nodeName !== "AUDIO" &&
  281. aframeObj.nodeName !== "VIDEO"
  282. ) {
  283. aframeObj.setAttribute('id', node.ID);
  284. }
  285. return aframeObj;
  286. }
  287. };
  288. this.state.kernel = this.kernel.kernel.kernel;
  289. this.aframePrimitives = ["a-box", "a-circle", "a-cone", "a-cylinder", "a-dodecahedron", "a-icosahedron", "a-octahedron", "a-plane", "a-ring", "a-sphere", "a-tetrahedron", "a-torus", "a-torus-knot", "a-triangle", "a-text",
  290. "a-light", "a-sky"] //Object.keys(AFRAME.primitives.primitives);
  291. },
  292. // == Model API ============================================================================
  293. // -- creatingNode -------------------------------------------------------------------------
  294. creatingNode: function (nodeID, childID, childExtendsID, childImplementsIDs,
  295. childSource, childType, childIndex, childName, callback /* ( ready ) */) {
  296. // If the parent nodeID is 0, this node is attached directly to the root and is therefore either
  297. // the scene or a prototype. In either of those cases, save the uri of the new node
  298. var childURI = (nodeID === 0 ? childIndex : undefined);
  299. var appID = this.kernel.application();
  300. // If the node being created is a prototype, construct it and add it to the array of prototypes,
  301. // and then return
  302. var prototypeID = _self_.utility.ifPrototypeGetId(appID, this.state.prototypes, nodeID, childID);
  303. if (prototypeID !== undefined) {
  304. this.state.prototypes[prototypeID] = {
  305. parentID: nodeID,
  306. ID: childID,
  307. extendsID: childExtendsID,
  308. implementsID: childImplementsIDs,
  309. source: childSource,
  310. type: childType,
  311. name: childName
  312. };
  313. return;
  314. }
  315. var protos = _self_.constructor.getPrototypes(this.kernel, childExtendsID);
  316. //var kernel = this.kernel.kernel.kernel;
  317. var node;
  318. if (this.state.isAFrameComponent(protos)) {
  319. // Create the local copy of the node properties
  320. if (this.state.nodes[childID] === undefined) {
  321. this.state.nodes[childID] = this.state.createLocalNode(nodeID, childID, childExtendsID, childImplementsIDs,
  322. childSource, childType, childIndex, childName, callback);
  323. }
  324. node = this.state.nodes[childID];
  325. node.prototypes = protos;
  326. // if (childType == "component") {
  327. // if (nodeID !== undefined) {
  328. // node.aframeObj = setAFrameObjectComponents(node);
  329. // addNodeToHierarchy(node);
  330. // }
  331. // } else {
  332. node.aframeObj = this.state.createAFrameObject(node);
  333. this.state.addNodeToHierarchy(node);
  334. if (this.state.isAEntityDefinition(node.prototypes)) {
  335. //updateStoredTransform( node );
  336. this.state.updateStoredTransformFor(node, 'position');
  337. this.state.updateStoredTransformFor(node, 'rotation');
  338. this.state.updateStoredTransformFor(node, 'scale');
  339. }
  340. //notifyDriverOfPrototypeAndBehaviorProps();
  341. // }
  342. //addNodeToHierarchy(node);
  343. }
  344. },
  345. // initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs,
  346. // childSource, childType, childIndex, childName ) {
  347. // var node = this.state.nodes[childID];
  348. // if ( node && childType == "component" ) {
  349. // }
  350. // },
  351. // -- initializingProperty -----------------------------------------------------------------
  352. initializingProperty: function (nodeID, propertyName, propertyValue) {
  353. var value = undefined;
  354. var node = this.state.nodes[nodeID];
  355. if (node !== undefined) {
  356. value = this.settingProperty(nodeID, propertyName, propertyValue);
  357. }
  358. return value;
  359. },
  360. // -- creatingProperty ---------------------------------------------------------------------
  361. creatingProperty: function (nodeID, propertyName, propertyValue) {
  362. return this.initializingProperty(nodeID, propertyName, propertyValue);
  363. },
  364. // -- callingMethod ------------------------------------------------------------------------
  365. callingMethod: function (nodeID, methodName, methodParameters) {
  366. let self = this;
  367. var node = this.state.nodes[nodeID];
  368. if (!node) return;
  369. if (node && node.aframeObj) {
  370. if (methodName == 'lookAt') {
  371. console.log('lookAt: ' + methodParameters[0]);
  372. let target = methodParameters[0];
  373. node.aframeObj.object3D.lookAt(new THREE.Vector3(target.x, target.y, target.z));
  374. let newRotation = node.aframeObj.getAttribute('rotation');
  375. self.kernel.setProperty(nodeID, "rotation", {
  376. x: 0,
  377. y: newRotation.y,
  378. z: 0
  379. });
  380. }
  381. if (methodName == 'worldRotation') {
  382. var worldQuat = new THREE.Quaternion();
  383. node.aframeObj.object3D.getWorldQuaternion(worldQuat);
  384. let angle = (new THREE.Euler()).setFromQuaternion(worldQuat, 'XYZ');
  385. let rotation = (new THREE.Vector3(THREE.Math.radToDeg(angle.x),
  386. THREE.Math.radToDeg(angle.y), THREE.Math.radToDeg(angle.z)));
  387. return rotation
  388. }
  389. if (methodName == 'worldPosition') {
  390. var position = new THREE.Vector3();
  391. node.aframeObj.object3D.getWorldPosition(position);
  392. return position
  393. }
  394. if (methodName == 'boundingBox') {
  395. let bbox = new THREE.Box3().setFromObject(node.aframeObj.object3D);
  396. return bbox;
  397. }
  398. if (methodName == 'localQuaternion') {
  399. return node.aframeObj.object3D.quaternion.clone()
  400. }
  401. if (methodName == 'worldQuaternion') {
  402. let worldQuaternion = new THREE.Quaternion();
  403. node.aframeObj.object3D.getWorldQuaternion(worldQuaternion);
  404. return worldQuaternion
  405. }
  406. if (methodName == 'worldScale') {
  407. let worldScale = new THREE.Vector3();
  408. node.aframeObj.object3D.getWorldScale(worldScale);
  409. return worldScale
  410. }
  411. if (methodName == 'worldDirection') {
  412. let worldDirection = new THREE.Vector3();
  413. node.aframeObj.object3D.getWorldDirection(worldDirection);
  414. return worldDirection
  415. }
  416. if (methodName == 'localToWorld') {
  417. let target = this.state.setFromValue(methodParameters[0] || []);
  418. let worldPoint = node.aframeObj.object3D.localToWorld(target);
  419. return worldPoint
  420. }
  421. if (methodName == 'worldToLocal') {
  422. let target = this.state.setFromValue(methodParameters[0] || []);
  423. let localPoint = node.aframeObj.object3D.worldToLocal(target);
  424. return localPoint
  425. }
  426. if (methodName == 'applyMatrix') {
  427. let fromNode = this.state.nodes[methodParameters[0]];
  428. let matrix = fromNode.aframeObj.object3D.matrix;
  429. node.aframeObj.object3D.applyMatrix(matrix);
  430. }
  431. if (methodName == 'getMatrix') {
  432. node.aframeObj.object3D.updateMatrix( true );
  433. return node.aframeObj.object3D.matrix
  434. }
  435. //.worldToLocal
  436. }
  437. },
  438. // -- deletingNode -------------------------------------------------------------------------
  439. //deletingNode: function( nodeID ) {
  440. //},
  441. // -- deletingNode -------------------------------------------------------------------------
  442. deletingNode: function (nodeID) {
  443. if (nodeID) {
  444. var childNode = this.state.nodes[nodeID];
  445. if (!childNode) return;
  446. if (childNode !== undefined) {
  447. if (childNode.children) {
  448. for (var i = 0; i < childNode.children.length; i++) {
  449. this.deletingNode(childNode.children[i]);
  450. }
  451. }
  452. if (childNode.aframeObj !== undefined) {
  453. // removes and destroys object
  454. childNode.aframeObj.parentNode.removeChild(childNode.aframeObj);
  455. childNode.aframeObj.destroy();
  456. childNode.aframeObj = undefined;
  457. }
  458. delete this.state.nodes[nodeID];
  459. }
  460. }
  461. },
  462. // -- settingProperty ----------------------------------------------------------------------
  463. settingProperty: function (nodeID, propertyName, propertyValue) {
  464. let self = this;
  465. var node = this.state.nodes[nodeID];
  466. var value = undefined;
  467. // if (node.componentName == 'line') {
  468. // console.log(node.aframeObj);
  469. // }
  470. if (node && node.aframeObj && _self_.utility.validObject(propertyValue)) {
  471. var aframeObject = node.aframeObj;
  472. if (this.state.isNodeDefinition(node.prototypes)) {
  473. // 'id' will be set to the nodeID
  474. value = propertyValue;
  475. switch (propertyName) {
  476. default:
  477. value = undefined;
  478. break;
  479. }
  480. }
  481. if (value === undefined && this.state.isAEntityDefinition(node.prototypes)) {
  482. value = propertyValue;
  483. switch (propertyName) {
  484. case "position":
  485. if (!node.transform)
  486. node.transform = {};
  487. var position = this.state.setFromValue(propertyValue || []); //goog.vec.Vec3.createFromArray( propertyValue || [] );
  488. node.transform.position = position.clone();
  489. //value = propertyValue;
  490. node.transform.storedPositionDirty = true;
  491. //setTransformsDirty( threeObject );
  492. //this.state.setAFrameProperty('position', propertyValue, aframeObject);
  493. break;
  494. case "rotation":
  495. if (!node.transform)
  496. node.transform = {};
  497. var rotation = this.state.setFromValue(propertyValue || []); //goog.vec.Vec3.createFromArray( propertyValue || [] );
  498. node.transform.rotation = rotation.clone();
  499. //value = propertyValue;
  500. node.transform.storedRotationDirty = true;
  501. //this.state.setAFrameProperty('rotation', propertyValue, aframeObject);
  502. break;
  503. case "scale":
  504. if (!node.transform)
  505. node.transform = {};
  506. var scale = this.state.setFromValue(propertyValue || []); //goog.vec.Vec3.createFromArray( propertyValue || [] );
  507. node.transform.scale = scale.clone();
  508. //value = propertyValue;
  509. node.transform.storedScaleDirty = true;
  510. //setTransformsDirty( threeObject );
  511. //this.state.setAFrameProperty('position', propertyValue, aframeObject);
  512. //this.state.setAFrameProperty('scale', propertyValue, aframeObject);
  513. break;
  514. case "animationTimeUpdated":
  515. if (node.transform) {
  516. node.transform.storedPositionDirty = true;
  517. node.transform.storedRotationDirty = true;
  518. node.transform.storedScaleDirty = true;
  519. }
  520. break;
  521. case "clickable":
  522. if (propertyValue) {
  523. aframeObject.setAttribute('class', 'intersectable');
  524. } else {
  525. aframeObject.setAttribute('class', 'nonintersectable');
  526. }
  527. node.events.clickable = propertyValue;
  528. break;
  529. case "class":
  530. var newClasses = [];
  531. if (propertyValue.includes(',')) {
  532. newClasses = propertyValue.split(',');
  533. } else {
  534. newClasses = propertyValue.split(' ')
  535. }
  536. // let newClasses = propertyValue.split(','); //trim()
  537. aframeObject.setAttribute('class', "");
  538. newClasses.forEach(el => {
  539. aframeObject.classList.add(el.trim());
  540. })
  541. break;
  542. case "ownedBy":
  543. aframeObject.setAttribute('ownedby', propertyValue);
  544. break;
  545. case "visible":
  546. aframeObject.setAttribute('visible', propertyValue);
  547. break;
  548. // case "clickable":
  549. // console.log("set clickable!");
  550. // value = propertyValue;
  551. // break;
  552. // case "clickable":
  553. // if (propertyValue) {
  554. // aframeObject.addEventListener('click', function (evt) {
  555. // console.log("click!");
  556. // vwf_view.kernel.fireEvent(node.ID, "clickEvent",evt.detail.cursorEl.id);
  557. // });
  558. // }
  559. // break;
  560. // case "look-controls-enabled":
  561. // aframeObject.setAttribute('look-controls', 'enabled', propertyValue);
  562. // break;
  563. case "wasd-controls":
  564. aframeObject.setAttribute('wasd-controls', 'enabled', propertyValue);
  565. break;
  566. default:
  567. value = undefined;
  568. break;
  569. }
  570. }
  571. if (value === undefined && aframeObject.nodeName == "A-ASSET-ITEM") {
  572. value = propertyValue;
  573. switch (propertyName) {
  574. case "itemID":
  575. aframeObject.setAttribute('id', propertyValue);
  576. break;
  577. case "itemSrc":
  578. aframeObject.setAttribute('src', propertyValue);
  579. break;
  580. default:
  581. value = undefined;
  582. break;
  583. }
  584. }
  585. if (value === undefined && aframeObject.nodeName == "IMG") {
  586. value = propertyValue;
  587. switch (propertyName) {
  588. case "itemID":
  589. aframeObject.setAttribute('id', propertyValue);
  590. break;
  591. case "itemSrc":
  592. aframeObject.setAttribute('src', propertyValue);
  593. break;
  594. // case "width":
  595. // aframeObject.width = propertyValue;
  596. // break;
  597. // case "height":
  598. // aframeObject.height = propertyValue;
  599. // break;
  600. default:
  601. value = undefined;
  602. break;
  603. }
  604. }
  605. if (value === undefined && aframeObject.nodeName == "AUDIO") {
  606. value = propertyValue;
  607. switch (propertyName) {
  608. case "itemID":
  609. aframeObject.setAttribute('id', propertyValue);
  610. break;
  611. case "itemSrc":
  612. aframeObject.setAttribute('src', propertyValue);
  613. break;
  614. default:
  615. value = undefined;
  616. break;
  617. }
  618. }
  619. if (value === undefined && aframeObject.nodeName == "VIDEO") {
  620. value = propertyValue;
  621. switch (propertyName) {
  622. case "itemID":
  623. aframeObject.setAttribute('id', propertyValue);
  624. break;
  625. case "itemSrc":
  626. aframeObject.setAttribute('src', propertyValue);
  627. break;
  628. default:
  629. value = undefined;
  630. break;
  631. }
  632. }
  633. if (value === undefined && aframeObject.nodeName == "A-SCENE") {
  634. value = propertyValue;
  635. switch (propertyName) {
  636. case "color":
  637. aframeObject.setAttribute('background', {
  638. 'color': propertyValue
  639. });
  640. break;
  641. case "transparent":
  642. aframeObject.setAttribute('background', {
  643. 'transparent': propertyValue
  644. });
  645. break;
  646. // case "fog":
  647. // aframeObject.setAttribute('fog', propertyValue);
  648. // break;
  649. case "assets":
  650. _self_.initAssets(propertyValue)
  651. break;
  652. default:
  653. value = undefined;
  654. break;
  655. }
  656. }
  657. if (value === undefined && aframeObject.nodeName == "A-GLTF-MODEL") {
  658. value = propertyValue;
  659. switch (propertyName) {
  660. case "src":
  661. aframeObject.setAttribute('src', propertyValue);
  662. break;
  663. default:
  664. value = undefined;
  665. break;
  666. }
  667. }
  668. if (value === undefined && aframeObject.nodeName == "A-COLLADA-MODEL") {
  669. value = propertyValue;
  670. switch (propertyName) {
  671. case "src":
  672. aframeObject.setAttribute('src', propertyValue);
  673. break;
  674. default:
  675. value = undefined;
  676. break;
  677. }
  678. }
  679. if (value === undefined && aframeObject.nodeName == "A-OBJ-MODEL") {
  680. value = propertyValue;
  681. switch (propertyName) {
  682. case "src":
  683. aframeObject.setAttribute('src', propertyValue);
  684. break;
  685. case "mtl":
  686. aframeObject.setAttribute('mtl', propertyValue);
  687. break;
  688. default:
  689. value = undefined;
  690. break;
  691. }
  692. }
  693. //A-Frame geometries & primitives
  694. if (value === undefined && self.aframePrimitives.includes(aframeObject.nodeName.toLowerCase())) {
  695. value = propertyValue;
  696. //let geometry = aframeObject.nodeName.toLowerCase().slice(2);
  697. //AFRAME.geometries[geometry].schema;
  698. let mappings = AFRAME.primitives.primitives[aframeObject.nodeName.toLowerCase()].prototype.mappings;
  699. let el = Object.keys(mappings).includes(propertyName);
  700. if (el) {
  701. aframeObject.setAttribute(propertyName, propertyValue);
  702. } else {
  703. value = undefined
  704. }
  705. if (value === undefined && aframeObject.nodeName == "A-LIGHT") {
  706. value = propertyValue;
  707. switch (propertyName) {
  708. case "castShadow":
  709. aframeObject.setAttribute('light', 'castShadow', propertyValue);
  710. break;
  711. case "shadowCameraVisible":
  712. aframeObject.setAttribute('light', 'shadowCameraVisible', propertyValue);
  713. break;
  714. default:
  715. value = undefined;
  716. break;
  717. }
  718. }
  719. }
  720. if (value === undefined && aframeObject.nodeName == "A-ANIMATION") {
  721. value = propertyValue;
  722. switch (propertyName) {
  723. // attribute:
  724. // dur:
  725. // from:
  726. // to:
  727. // repeat:
  728. case "dur":
  729. aframeObject.setAttribute('dur', propertyValue);
  730. break;
  731. case "from":
  732. aframeObject.setAttribute('from', propertyValue);
  733. break;
  734. case "to":
  735. aframeObject.setAttribute('to', propertyValue);
  736. break;
  737. case "repeat":
  738. aframeObject.setAttribute('repeat', propertyValue);
  739. break;
  740. case "attribute":
  741. aframeObject.setAttribute('attribute', propertyValue);
  742. break;
  743. case "begin":
  744. aframeObject.setAttribute('begin', propertyValue);
  745. break;
  746. default:
  747. value = undefined;
  748. break;
  749. }
  750. }
  751. if (value === undefined && aframeObject.nodeName == "A-CAMERA") {
  752. value = propertyValue;
  753. switch (propertyName) {
  754. case "user-height":
  755. aframeObject.setAttribute('user-height', propertyValue);
  756. break;
  757. case "look-controls-enabled":
  758. aframeObject.setAttribute('look-controls-enabled', propertyValue);
  759. break;
  760. case "wasd-controls-enabled":
  761. aframeObject.setAttribute('wasd-controls-enabled', propertyValue);
  762. break;
  763. // case "active":
  764. // aframeObject.setAttribute('camera', 'active', propertyValue);
  765. // break;
  766. default:
  767. value = undefined;
  768. break;
  769. }
  770. }
  771. if (value === undefined && aframeObject.nodeName == "A-SUN-SKY") {
  772. value = propertyValue;
  773. switch (propertyName) {
  774. case "sunPosition":
  775. aframeObject.setAttribute('material', 'sunPosition', propertyValue);
  776. break;
  777. // case "active":
  778. // aframeObject.setAttribute('camera', 'active', propertyValue);
  779. // break;
  780. default:
  781. value = undefined;
  782. break;
  783. }
  784. }
  785. if (value === undefined && aframeObject.nodeName == "A-ANCHOR") {
  786. value = propertyValue;
  787. switch (propertyName) {
  788. case "changeMatrixMode":
  789. aframeObject.setAttribute('arjs-anchor', 'changeMatrixMode', propertyValue);
  790. break;
  791. case 'hit-testing-enabled':
  792. aframeObject.setAttribute('hit-testing-enabled', propertyValue);
  793. break;
  794. case 'preset':
  795. aframeObject.setAttribute('preset', propertyValue);
  796. break;
  797. case 'markerType':
  798. aframeObject.setAttribute('type', propertyValue);
  799. break;
  800. case 'markerValue':
  801. aframeObject.setAttribute('velue', propertyValue);
  802. break;
  803. default:
  804. value = undefined;
  805. break;
  806. }
  807. }
  808. }
  809. return value;
  810. },
  811. // -- gettingProperty ----------------------------------------------------------------------
  812. gettingProperty: function (nodeID, propertyName, propertyValue) {
  813. let self = this;
  814. var node = this.state.nodes[nodeID];
  815. var value = undefined;
  816. if (node && node.aframeObj) {
  817. var aframeObject = node.aframeObj;
  818. if (this.state.isNodeDefinition(node.prototypes)) {
  819. switch (propertyName) { }
  820. }
  821. if (value === undefined && this.state.isAEntityDefinition(node.prototypes)) {
  822. switch (propertyName) {
  823. case "position":
  824. // var pos = aframeObject.getAttribute('position');
  825. // if (pos !== undefined) {
  826. // value = pos//[pos.x, pos.y, pos.z]//AFRAME.utils.coordinates.stringify(pos);
  827. // }
  828. if (node.transform.position) {
  829. if (node.transform.storedPositionDirty) {
  830. this.state.updateStoredTransformFor(node, 'position');
  831. }
  832. value = node.transform.position.clone();
  833. //value = node.transform.position;
  834. }
  835. break;
  836. case "rotation":
  837. if (node.transform.rotation) {
  838. if (node.transform.storedRotationDirty) {
  839. this.state.updateStoredTransformFor(node, 'rotation');
  840. }
  841. value = node.transform.rotation.clone();
  842. // var rot = aframeObject.getAttribute('rotation');
  843. // if (rot !== undefined) {
  844. // value = rot//AFRAME.utils.coordinates.stringify(rot);
  845. // }
  846. }
  847. break;
  848. case "scale":
  849. if (node.transform.scale) {
  850. if (node.transform.storedScaleDirty) {
  851. this.state.updateStoredTransformFor(node, 'scale');
  852. }
  853. value = node.transform.scale.clone();
  854. // var scale = aframeObject.getAttribute('scale');
  855. // if (scale !== undefined) {
  856. // value = scale//AFRAME.utils.coordinates.stringify(scale);
  857. // }
  858. }
  859. break;
  860. case "clickable":
  861. value = node.events.clickable;
  862. break;
  863. case "class":
  864. value = aframeObject.classList.toString();
  865. //aframeObject.getAttribute('class');
  866. break;
  867. // case "look-controls-enabled":
  868. // var look = aframeObject.getAttribute('look-controls-enabled');
  869. // if (look !== null && look !== undefined) {
  870. // value = aframeObject.getAttribute('look-controls').enabled;
  871. // }
  872. // break;
  873. // case "wasd-controls":
  874. // var wasd = aframeObject.getAttribute('wasd-controls');
  875. // if (wasd !== null && wasd !== undefined) {
  876. // value = aframeObject.getAttribute('wasd-controls').enabled;
  877. // }
  878. // break;
  879. case "ownedBy":
  880. value = aframeObject.getAttribute('ownedby');
  881. break;
  882. case "visible":
  883. value = aframeObject.getAttribute('visible');
  884. break;
  885. }
  886. }
  887. if (value === undefined && aframeObject.nodeName == "A-ASSET-ITEM") {
  888. switch (propertyName) {
  889. case "itemID":
  890. value = aframeObject.getAttribute('id');
  891. break;
  892. case "itemSrc":
  893. value = aframeObject.getAttribute('src');
  894. break;
  895. }
  896. }
  897. if (value === undefined && aframeObject.nodeName == "IMG") {
  898. switch (propertyName) {
  899. case "itemID":
  900. value = aframeObject.getAttribute('id');
  901. break;
  902. case "itemSrc":
  903. value = aframeObject.getAttribute('src');
  904. break;
  905. case "width":
  906. value = aframeObject.width;
  907. break;
  908. case "height":
  909. value = aframeObject.height;
  910. break;
  911. }
  912. }
  913. if (value === undefined && aframeObject.nodeName == "AUDIO") {
  914. switch (propertyName) {
  915. case "itemID":
  916. value = aframeObject.getAttribute('id');
  917. break;
  918. case "itemSrc":
  919. value = aframeObject.getAttribute('src');
  920. break;
  921. }
  922. }
  923. if (value === undefined && aframeObject.nodeName == "VIDEO") {
  924. switch (propertyName) {
  925. case "itemID":
  926. value = aframeObject.getAttribute('id');
  927. break;
  928. case "itemSrc":
  929. value = aframeObject.getAttribute('src');
  930. break;
  931. case "videoWidth":
  932. value = aframeObject.videoWidth;
  933. break;
  934. case "videoHeight":
  935. value = aframeObject.videoHeight;
  936. break;
  937. }
  938. }
  939. if (value === undefined && aframeObject.nodeName == "A-SCENE") {
  940. switch (propertyName) {
  941. // case "fog":
  942. // value = aframeObject.getAttribute('fog');
  943. // break;
  944. case "assets":
  945. break;
  946. case "color":
  947. if (aframeObject.getAttribute('background')) {
  948. value = aframeObject.getAttribute('background').color;
  949. }
  950. break;
  951. case "transparent":
  952. if (aframeObject.getAttribute('background')) {
  953. value = aframeObject.getAttribute('background').transparent;
  954. }
  955. break;
  956. }
  957. }
  958. //A-Frame geometries & primitives
  959. if (value === undefined && self.aframePrimitives.includes(aframeObject.nodeName.toLowerCase())) {
  960. // let geometry = aframeObject.nodeName.toLowerCase().slice(2);
  961. // let schema = AFRAME.geometries[geometry].schema;
  962. let mappings = AFRAME.primitives.primitives[aframeObject.nodeName.toLowerCase()].prototype.mappings;
  963. let el = Object.keys(mappings).includes(propertyName);
  964. value = el ? aframeObject.getAttribute(propertyName) : undefined;
  965. // if(el && !value){
  966. // let attr = mappings[propertyName].split('.');
  967. // value = aframeObject.getAttribute(attr[0],attr[1])
  968. // }
  969. //Light specific
  970. if (value === undefined && aframeObject.nodeName == "A-LIGHT") {
  971. switch (propertyName) {
  972. case "castShadow":
  973. value = aframeObject.getAttribute('light').castShadow;
  974. break;
  975. case "shadowCameraVisible":
  976. value = aframeObject.getAttribute('light').shadowCameraVisible;
  977. break;
  978. }
  979. }
  980. }
  981. if (value === undefined && aframeObject.nodeName == "A-ANIMATION") {
  982. switch (propertyName) {
  983. case "attribute":
  984. value = aframeObject.getAttribute('attribute');
  985. break;
  986. case "dur":
  987. value = aframeObject.getAttribute('dur');
  988. break;
  989. case "from":
  990. value = aframeObject.getAttribute('from');
  991. break;
  992. case "to":
  993. value = aframeObject.getAttribute('to');
  994. break;
  995. case "repeat":
  996. value = aframeObject.getAttribute('repeat');
  997. break;
  998. case "begin":
  999. value = aframeObject.getAttribute('begin');
  1000. break;
  1001. }
  1002. }
  1003. if (value === undefined && aframeObject.nodeName == "A-CAMERA") {
  1004. switch (propertyName) {
  1005. case "user-height":
  1006. value = aframeObject.getAttribute('user-height');
  1007. break;
  1008. case "look-controls-enabled":
  1009. value = aframeObject.getAttribute('look-controls-enabled');
  1010. break;
  1011. case "wasd-controls-enabled":
  1012. value = aframeObject.getAttribute('wasd-controls-enabled');
  1013. break;
  1014. }
  1015. // switch (propertyName) {
  1016. // case "active":
  1017. // value = aframeObject.getAttribute('camera').active;
  1018. // break;
  1019. // }
  1020. }
  1021. if (value === undefined && aframeObject.nodeName == "A-SUN-SKY") {
  1022. switch (propertyName) {
  1023. case "sunPosition":
  1024. value = aframeObject.getAttribute('material').sunPosition;
  1025. break;
  1026. }
  1027. // switch (propertyName) {
  1028. // case "active":
  1029. // value = aframeObject.getAttribute('camera').active;
  1030. // break;
  1031. // }
  1032. }
  1033. if (value === undefined && aframeObject.nodeName == "A-COLLADA-MODEL") {
  1034. switch (propertyName) {
  1035. case "src":
  1036. value = aframeObject.getAttribute('src');
  1037. break;
  1038. }
  1039. }
  1040. if (value === undefined && aframeObject.nodeName == "A-OBJ-MODEL") {
  1041. switch (propertyName) {
  1042. case "src":
  1043. value = aframeObject.getAttribute('src');
  1044. break;
  1045. case "mtl":
  1046. value = aframeObject.getAttribute('mtl');
  1047. break;
  1048. }
  1049. }
  1050. if (value === undefined && aframeObject.nodeName == "A-GLTF-MODEL") {
  1051. switch (propertyName) {
  1052. case "src":
  1053. value = aframeObject.getAttribute('src');
  1054. break;
  1055. }
  1056. }
  1057. if (value === undefined && aframeObject.nodeName == "A-ANCHOR") {
  1058. switch (propertyName) {
  1059. case "changeMatrixMode":
  1060. value = aframeObject.getAttribute('arjs-anchor').changeMatrixMode;
  1061. break;
  1062. case "hit-testing-enabled":
  1063. value = aframeObject.getAttribute('hit-testing-enabled');
  1064. break;
  1065. case "preset":
  1066. value = aframeObject.getAttribute('preset');
  1067. break;
  1068. case 'markerType':
  1069. value = aframeObject.getAttribute('type');
  1070. break;
  1071. case 'markerValue':
  1072. value = aframeObject.getAttribute('value');
  1073. break;
  1074. }
  1075. }
  1076. }
  1077. if (value !== undefined) {
  1078. propertyValue = value;
  1079. }
  1080. return value;
  1081. }
  1082. });
  1083. }
  1084. async initAssets(propertyValue) {
  1085. let assetsEl = document.querySelector('a-assets');
  1086. if (!assetsEl) {
  1087. let newAssetsEl = document.createElement('a-assets');
  1088. aframeObject.appendChild(newAssetsEl);
  1089. }
  1090. var assetsElement = document.querySelector('a-assets');
  1091. if (propertyValue) {
  1092. let path = JSON.parse(localStorage.getItem('lcs_app')).path.public_path;
  1093. let worldName = path.slice(1);
  1094. let dbPath = propertyValue.split(".").join("_");
  1095. let userDB = _LCSDB.user(_LCS_WORLD_USER.pub);
  1096. userDB.get('worlds').get(worldName).get(dbPath).load(function (response) {
  1097. if (response) {
  1098. if (Object.keys(response).length > 0) {
  1099. //console.log(JSON.parse(response));
  1100. let assets = (typeof (response) == 'object') ? response : JSON.parse(response);
  1101. for (var prop in assets) {
  1102. var elm = document.createElement(assets[prop].tag);
  1103. elm.setAttribute('id', prop);
  1104. elm.setAttribute('src', assets[prop].src);
  1105. assetsElement.appendChild(elm);
  1106. }
  1107. }
  1108. }
  1109. });
  1110. }
  1111. }
  1112. }
  1113. export {
  1114. AFrameModel as default
  1115. }