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", {
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
);
......
......@@ -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;
......
......@@ -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"
]
});
}
......
......@@ -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) {
......
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