diff --git a/src/components/super-spawner.js b/src/components/super-spawner.js index 3045dace6ad28649c5176d36a705640b2f3f92df..67e3b63fc4cc0eaf036111d6078155699f4adec7 100644 --- a/src/components/super-spawner.js +++ b/src/components/super-spawner.js @@ -88,7 +88,7 @@ AFRAME.registerComponent("super-spawner", { const thisGrabId = nextGrabId++; this.heldEntities.set(hand, thisGrabId); - const entity = await addMedia(this.data.src); + const entity = addMedia(this.data.src); entity.object3D.position.copy( this.data.useCustomSpawnPosition ? this.data.spawnPosition : this.el.object3D.position ); diff --git a/src/hub.html b/src/hub.html index d31d47e24f4264d9e498af7cc6004aa9f5c2db82..70b171429ccade2a686fad03b41391fdf5247bd0 100644 --- a/src/hub.html +++ b/src/hub.html @@ -158,9 +158,8 @@ </a-entity> </template> - <template id="interactable-model"> + <template id="interactable-media"> <a-entity - gltf-model-plus="inflate: true;" class="interactable" super-networked-interactable="counter: #media-counter;" body="type: dynamic; shape: none; mass: 1;" @@ -179,27 +178,6 @@ </a-entity> </template> - <template id="interactable-image"> - <a-entity - class="interactable" - super-networked-interactable="counter: #media-counter;" - body="type: dynamic; shape: none; mass: 1;" - auto-scale-cannon-physics-body - grabbable - stretchable="useWorldPosition: true; usePhysics: never" - hoverable - image-plus - sticky-object="autoLockOnLoad: true; autoLockOnRelease: true;" - position-at-box-shape-border="target:.delete-button;dirs:forward,back" - destroy-at-extreme-distances - > - <a-entity class="delete-button" visible-while-frozen> - <a-entity mixin="rounded-text-button" remove-networked-object-button position="0 0 0"> </a-entity> - <a-entity text=" value:Delete; width:2.5; align:center;" text-raycast-hack position="0 0 0.01"></a-entity> - </a-entity> - </a-entity> - </template> - <a-mixin id="rounded-text-button" text-button=" haptic:#player-right-controller; diff --git a/src/network-schemas.js b/src/network-schemas.js index e471c3b013c84c6805aa3d73b89831f2e8a95f18..5993934a4b0c613ca5b311d14c585fda7a44856c 100644 --- a/src/network-schemas.js +++ b/src/network-schemas.js @@ -82,7 +82,7 @@ function registerNetworkSchemas() { }); NAF.schemas.add({ - template: "#interactable-image", + template: "#interactable-media", components: [ { component: "position", @@ -93,23 +93,7 @@ function registerNetworkSchemas() { requiresNetworkUpdate: vectorRequiresUpdate(0.5) }, "scale", - "image-plus" - ] - }); - - NAF.schemas.add({ - template: "#interactable-model", - components: [ - { - component: "position", - requiresNetworkUpdate: vectorRequiresUpdate(0.001) - }, - { - component: "rotation", - requiresNetworkUpdate: vectorRequiresUpdate(0.5) - }, - "scale", - "gltf-model-plus" + "media-loader" ] }); } diff --git a/src/utils/media-utils.js b/src/utils/media-utils.js index 52b0c85787c7a0db789fbdde9ee45236ec1ca80a..5749035d5ea11b371e12891b990c8493c9e2369a 100644 --- a/src/utils/media-utils.js +++ b/src/utils/media-utils.js @@ -24,17 +24,17 @@ let interactableId = 0; const offset = { x: 0, y: 0, z: -1.5 }; export const spawnNetworkedImage = (entity, src, contentType) => { entity.id = "interactable-image-" + interactableId++; - entity.setAttribute("networked", { template: "#interactable-image" }); - entity.addEventListener("image-loaded", function onImageLoaded() { - entity.removeEventListener("image-loaded", onImageLoaded); - }); + // entity.setAttribute("networked", { template: "#interactable-image" }); + // entity.addEventListener("image-loaded", function onBodyLoaded() { + // entity.removeEventListener("image-loaded", onBodyLoaded); + // }); entity.setAttribute("image-plus", { src, contentType }); return entity; }; export const spawnNetworkedInteractable = (entity, src, basePath) => { entity.id = "interactable-model-" + interactableId++; - entity.setAttribute("networked", { template: "#interactable-model" }); + // entity.setAttribute("networked", { template: "#interactable-model" }); entity.addEventListener("model-loaded", function onModelLoaded(evt) { entity.removeEventListener("model-loaded", onModelLoaded); setShapeAndScale(entity, evt.detail.didInflate); @@ -43,42 +43,60 @@ export const spawnNetworkedInteractable = (entity, src, basePath) => { return entity; }; -export const addMedia = async url => { +AFRAME.registerComponent("media-loader", { + schema: { + src: { type: "string" } + }, + + async update() { + const entity = this.el; + const url = this.data.src; + + try { + // show loading mesh + entity.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial())); + setShapeAndScale(entity); + + const { raw, origin, meta } = await resolveFarsparkUrl(url); + console.log("resolved", url, raw, origin, meta); + + const contentType = (meta && meta.expected_content_type) || (await fetchContentType(raw)); + if (contentType.startsWith("image/") || contentType.startsWith("video/")) { + return spawnNetworkedImage(entity, raw, contentType); + } else if (contentType.startsWith("model/gltf") || url.endsWith(".gltf") || url.endsWith(".glb")) { + return spawnNetworkedInteractable(entity, raw, THREE.LoaderUtils.extractUrlBase(origin)); + } else { + throw new Error(`Unsupported content type: ${contentType}`); + } + } catch (e) { + console.error("Error adding media", e); + return spawnNetworkedImage(entity, "error"); + } + } +}); + +export const addMedia = url => { const scene = AFRAME.scenes[0]; const entity = document.createElement("a-entity"); - entity.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial())); - entity.classList.add("interactable"); - entity.setAttribute("body", { type: "dynamic", shape: "none", mass: "1" }); - entity.setAttribute("grabbable", ""); - entity.setAttribute("hoverable", ""); - entity.setAttribute("stretchable", { useWorldPosition: true, usePhysics: "never" }); - entity.setAttribute("sticky-object", { autoLockOnRelease: true, autoLockOnLoad: true }); - entity.setAttribute("destroy-at-extreme-distances", ""); + entity.setAttribute("networked", { template: "#interactable-media" }); + // entity.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial())); + // entity.classList.add("interactable"); + // entity.setAttribute("body", { type: "dynamic", shape: "none", mass: "1" }); + // entity.setAttribute("grabbable", ""); + // entity.setAttribute("hoverable", ""); + // entity.setAttribute("stretchable", { useWorldPosition: true, usePhysics: "never" }); + // entity.setAttribute("sticky-object", { autoLockOnRelease: true, autoLockOnLoad: true }); + // entity.setAttribute("destroy-at-extreme-distances", ""); entity.setAttribute("offset-relative-to", { target: "#player-camera", offset: offset, selfDestruct: true }); - setShapeAndScale(entity); + entity.setAttribute("media-loader", { src: url }); + // setShapeAndScale(entity); scene.appendChild(entity); - - try { - const { raw, origin, meta } = await resolveFarsparkUrl(url); - console.log("resolved", url, raw, origin, meta); - - const contentType = (meta && meta.expected_content_type) || (await fetchContentType(raw)); - if (contentType.startsWith("image/") || contentType.startsWith("video/")) { - return spawnNetworkedImage(entity, raw, contentType); - } else if (contentType.startsWith("model/gltf") || url.endsWith(".gltf") || url.endsWith(".glb")) { - return spawnNetworkedInteractable(entity, raw, THREE.LoaderUtils.extractUrlBase(origin)); - } else { - throw new Error(`Unsupported content type: ${contentType}`); - } - } catch (e) { - console.error("Error adding media", e); - return spawnNetworkedImage(entity, "error"); - } + return entity; }; function setShapeAndScale(entity, didInflate) {