aframe.js 62 KB

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