Skip to content
Snippets Groups Projects
Commit a8a2a1b2 authored by netpro2k's avatar netpro2k
Browse files

Unify media into a single component so each client does its own farspark

resolution and gets loading indicators
parent 57c08442
No related branches found
No related tags found
No related merge requests found
...@@ -88,7 +88,7 @@ AFRAME.registerComponent("super-spawner", { ...@@ -88,7 +88,7 @@ AFRAME.registerComponent("super-spawner", {
const thisGrabId = nextGrabId++; const thisGrabId = nextGrabId++;
this.heldEntities.set(hand, thisGrabId); this.heldEntities.set(hand, thisGrabId);
const entity = await addMedia(this.data.src); const entity = addMedia(this.data.src);
entity.object3D.position.copy( entity.object3D.position.copy(
this.data.useCustomSpawnPosition ? this.data.spawnPosition : this.el.object3D.position this.data.useCustomSpawnPosition ? this.data.spawnPosition : this.el.object3D.position
); );
......
...@@ -158,9 +158,8 @@ ...@@ -158,9 +158,8 @@
</a-entity> </a-entity>
</template> </template>
<template id="interactable-model"> <template id="interactable-media">
<a-entity <a-entity
gltf-model-plus="inflate: true;"
class="interactable" class="interactable"
super-networked-interactable="counter: #media-counter;" super-networked-interactable="counter: #media-counter;"
body="type: dynamic; shape: none; mass: 1;" body="type: dynamic; shape: none; mass: 1;"
...@@ -179,27 +178,6 @@ ...@@ -179,27 +178,6 @@
</a-entity> </a-entity>
</template> </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" <a-mixin id="rounded-text-button"
text-button=" text-button="
haptic:#player-right-controller; haptic:#player-right-controller;
......
...@@ -82,7 +82,7 @@ function registerNetworkSchemas() { ...@@ -82,7 +82,7 @@ function registerNetworkSchemas() {
}); });
NAF.schemas.add({ NAF.schemas.add({
template: "#interactable-image", template: "#interactable-media",
components: [ components: [
{ {
component: "position", component: "position",
...@@ -93,23 +93,7 @@ function registerNetworkSchemas() { ...@@ -93,23 +93,7 @@ function registerNetworkSchemas() {
requiresNetworkUpdate: vectorRequiresUpdate(0.5) requiresNetworkUpdate: vectorRequiresUpdate(0.5)
}, },
"scale", "scale",
"image-plus" "media-loader"
]
});
NAF.schemas.add({
template: "#interactable-model",
components: [
{
component: "position",
requiresNetworkUpdate: vectorRequiresUpdate(0.001)
},
{
component: "rotation",
requiresNetworkUpdate: vectorRequiresUpdate(0.5)
},
"scale",
"gltf-model-plus"
] ]
}); });
} }
......
...@@ -24,17 +24,17 @@ let interactableId = 0; ...@@ -24,17 +24,17 @@ let interactableId = 0;
const offset = { x: 0, y: 0, z: -1.5 }; const offset = { x: 0, y: 0, z: -1.5 };
export const spawnNetworkedImage = (entity, src, contentType) => { export const spawnNetworkedImage = (entity, src, contentType) => {
entity.id = "interactable-image-" + interactableId++; entity.id = "interactable-image-" + interactableId++;
entity.setAttribute("networked", { template: "#interactable-image" }); // entity.setAttribute("networked", { template: "#interactable-image" });
entity.addEventListener("image-loaded", function onImageLoaded() { // entity.addEventListener("image-loaded", function onBodyLoaded() {
entity.removeEventListener("image-loaded", onImageLoaded); // entity.removeEventListener("image-loaded", onBodyLoaded);
}); // });
entity.setAttribute("image-plus", { src, contentType }); entity.setAttribute("image-plus", { src, contentType });
return entity; return entity;
}; };
export const spawnNetworkedInteractable = (entity, src, basePath) => { export const spawnNetworkedInteractable = (entity, src, basePath) => {
entity.id = "interactable-model-" + interactableId++; 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.addEventListener("model-loaded", function onModelLoaded(evt) {
entity.removeEventListener("model-loaded", onModelLoaded); entity.removeEventListener("model-loaded", onModelLoaded);
setShapeAndScale(entity, evt.detail.didInflate); setShapeAndScale(entity, evt.detail.didInflate);
...@@ -43,42 +43,60 @@ export const spawnNetworkedInteractable = (entity, src, basePath) => { ...@@ -43,42 +43,60 @@ export const spawnNetworkedInteractable = (entity, src, basePath) => {
return entity; 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 scene = AFRAME.scenes[0];
const entity = document.createElement("a-entity"); const entity = document.createElement("a-entity");
entity.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial())); entity.setAttribute("networked", { template: "#interactable-media" });
entity.classList.add("interactable"); // entity.setObject3D("mesh", new THREE.Mesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial()));
entity.setAttribute("body", { type: "dynamic", shape: "none", mass: "1" }); // entity.classList.add("interactable");
entity.setAttribute("grabbable", ""); // entity.setAttribute("body", { type: "dynamic", shape: "none", mass: "1" });
entity.setAttribute("hoverable", ""); // entity.setAttribute("grabbable", "");
entity.setAttribute("stretchable", { useWorldPosition: true, usePhysics: "never" }); // entity.setAttribute("hoverable", "");
entity.setAttribute("sticky-object", { autoLockOnRelease: true, autoLockOnLoad: true }); // entity.setAttribute("stretchable", { useWorldPosition: true, usePhysics: "never" });
entity.setAttribute("destroy-at-extreme-distances", ""); // entity.setAttribute("sticky-object", { autoLockOnRelease: true, autoLockOnLoad: true });
// entity.setAttribute("destroy-at-extreme-distances", "");
entity.setAttribute("offset-relative-to", { entity.setAttribute("offset-relative-to", {
target: "#player-camera", target: "#player-camera",
offset: offset, offset: offset,
selfDestruct: true selfDestruct: true
}); });
setShapeAndScale(entity); entity.setAttribute("media-loader", { src: url });
// setShapeAndScale(entity);
scene.appendChild(entity); scene.appendChild(entity);
return 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");
}
}; };
function setShapeAndScale(entity, didInflate) { function setShapeAndScale(entity, didInflate) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment