This commit is contained in:
netpro2k 2022-06-01 20:57:22 -07:00
Родитель 0a2c26f497
Коммит 9dcf69e0cf
7 изменённых файлов: 21 добавлений и 414 удалений

Просмотреть файл

@ -1,46 +1,12 @@
import Store from "./storage/store";
import MediaSearchStore from "./storage/media-search-store";
import qsTruthy from "./utils/qs_truthy";
import { addEntity, createWorld, defineQuery, enterQuery, hasComponent, pipe } from "bitecs";
import {
Networked,
Owned,
Spin,
Object3DTag,
RemoteHoverTarget,
CursorRaycastable,
Holdable,
OffersRemoteConstraint,
Rigidbody,
PhysicsShape,
FloatyObject,
AEntity
} from "./bit-components";
import { ACTIVATION_STATE, FIT, SHAPE } from "three-ammo/constants";
import "./aframe-to-bit-components";
import * as bitecs from "bitecs";
window.$B = bitecs;
import { addEntity, createWorld, defineQuery, pipe } from "bitecs";
import "./aframe-to-bit-components";
import { AEntity, Networked, Object3DTag, Owned, Spin } from "./bit-components";
import MediaSearchStore from "./storage/media-search-store";
import Store from "./storage/store";
import qsTruthy from "./utils/qs_truthy";
Object.defineProperties(THREE.Object3D.prototype, {
components: {
get: function() {
// console.warn("Accessing 'components' on an Object3D");
return {};
}
},
classList: {
get: function() {
// console.warn("Accessing 'classlist' on an Object3D");
return {
contains() {
return false;
}
};
}
}
});
window.$B = bitecs;
const timeSystem = world => {
const { time } = world;
@ -52,30 +18,6 @@ const timeSystem = world => {
return world;
};
const spinQuery = defineQuery([Spin, Object3DTag]);
const spinSystem = world => {
const ents = spinQuery(world);
for (let i = 0; i < ents.length; i++) {
const eid = ents[i];
const obj = world.eid2obj.get(eid);
const deltaSeconds = world.time.delta / 1000;
obj.rotation.x += Spin.x[eid] * deltaSeconds;
obj.rotation.y += Spin.y[eid] * deltaSeconds;
obj.rotation.z += Spin.z[eid] * deltaSeconds;
obj.matrixNeedsUpdate = true;
}
return world;
};
let lasteNetworkTick = 0;
const networkedQuery = defineQuery([Networked]);
const pipeline = pipe(
timeSystem,
spinSystem
);
export class App {
constructor() {
this.scene = null;
@ -208,7 +150,7 @@ export class App {
// TODO pass this into systems that care about it (like input) once they are moved into this loop
sceneEl.frame = xrFrame;
pipeline(APP.world);
timeSystem(APP.world);
// Tick AFrame systems and components
if (sceneEl.isPlaying) {

Просмотреть файл

@ -5,7 +5,8 @@ import {
HandRight,
HandLeft,
RemoteHoverTarget,
NotRemoteHoverTarget
NotRemoteHoverTarget,
RemoveNetworkedEntityButton
// CursorRaycastable,
// HandCollisionTarget,
@ -32,7 +33,8 @@ import {
["hand-right", HandRight],
["hand-left", HandLeft],
["is-remote-hover-target", RemoteHoverTarget],
["is-not-remote-hover-target", NotRemoteHoverTarget]
["is-not-remote-hover-target", NotRemoteHoverTarget],
["remove-networked-object-button", RemoveNetworkedEntityButton]
// ["holdable", Holdable],
// ["offers-remote-constraint", OffersRemoteConstraint],

Просмотреть файл

@ -1,12 +0,0 @@
import { addComponent, removeComponent } from "bitecs";
import { RemoveNetworkedEntityButton } from "../bit-components";
AFRAME.registerComponent("remove-networked-object-button", {
init() {
addComponent(APP.world, RemoveNetworkedEntityButton, this.el.object3D.eid);
},
remove() {
removeComponent(APP.world, RemoveNetworkedEntityButton, this.el.object3D.eid);
}
});

Просмотреть файл

@ -107,7 +107,6 @@ import "./components/pin-networked-object-button";
import "./components/mirror-media-button";
import "./components/close-mirrored-media-button";
import "./components/drop-object-button";
import "./components/remove-networked-object-button";
import "./components/camera-focus-button";
import "./components/unmute-video-button";
import "./components/destroy-at-extreme-distances";

Просмотреть файл

@ -1,274 +1,15 @@
import { renderAsAframeEntity, createElementEntity, createRef } from "../utils/jsx-entity";
/** @jsx createElementEntity */
import { getThemeColor } from "../utils/theme";
const actionColor = getThemeColor("action-color");
const actionHoverColor = getThemeColor("action-color-highlight");
const buttonStyles = {
"rounded-button": {
slice9: {
width: 0.2,
height: 0.2,
left: 64,
top: 64,
right: 66,
bottom: 66,
transparent: false,
alphaTest: 0.1,
src: "button"
},
"text-button": {
textHoverColor: actionHoverColor,
textColor: actionColor,
backgroundColor: "#fff",
backgroundHoverColor: "#aaa"
}
},
"rounded-action-button": {
slice9: {
width: 0.2,
height: 0.2,
left: 64,
top: 64,
right: 66,
bottom: 66,
transparent: false,
alphaTest: 0.1,
src: "action-button"
},
"text-button": {
textHoverColor: "#fff",
textColor: "#fff",
backgroundColor: actionColor,
backgroundHoverColor: actionHoverColor
}
}
};
function ActionButton({
image,
hoverImage = image,
type = "rounded-button",
iconScale = 0.075,
iconClassName,
...props
}) {
return (
<a-entity {...buttonStyles[type]} is-remote-hover-target tags="singleActionButton: true;" {...props}>
{image && (
<a-entity
sprite
className={iconClassName}
icon-button={{ image, hoverImage }}
scale={[iconScale, iconScale, iconScale]}
position={[0, 0, 0.001]}
/>
)}
</a-entity>
);
}
function RecordButton() {
return (
<a-entity
className="record-button"
is-remote-hover-target
tags={{ singleActionButton: true }}
position={[0, -0.15, 0.075]}
scale={[0.75, 0.75, 0.75]}
{...buttonStyles["rounded-action-button"]}
>
<a-entity
sprite=""
className="record-icon"
icon-button={{ image: "record-action.png", hoverImage: "record-action.png" }}
scale={[0.175, 0.175, 0.175]}
position={[0, 0, 0.001]}
/>
<a-entity
sprite
className="record-alpha-icon"
icon-button={{ image: "record-action-alpha.png", hoverImage: "record-action-alpha.png" }}
scale={[0.175, 0.175, 0.175]}
position={[0, 0, 0.001]}
/>
</a-entity>
);
}
function InteractableCamera() {
const labelRef = createRef();
const snapButtonRef = createRef();
const snapMenuRef = createRef();
const screenRef = createRef();
const selfieScreenRef = createRef();
const screenMaterial = new THREE.MeshBasicMaterial({ toneMapped: false });
const width = 0.28;
const aspect = 1280 / 720;
const screenGeometry = new THREE.PlaneBufferGeometry(width, width / aspect);
return (
<a-entity
className="interactable"
body-helper={{ type: "dynamic", mass: "0.001", collisionFilterGroup: "1", collisionFilterMask: "8" }}
camera-tool={{ labelRef, snapButtonRef, snapMenuRef, screenRef, selfieScreenRef }}
is-remote-hover-target
tags={{ isHandCollisionTarget: true, isHoldable: true, offersHandConstraint: true, offersRemoteConstraint: true }}
matrix-auto-update
shape-helper={{ type: "box", fit: "manual", halfExtents: "0.22 0.14 0.1", offset: "0 0.02 0" }}
floaty-object={{ autoLockOnRelease: true, autoLockOnLoad: true }}
owned-object-limiter={{ counter: "#camera-counter" }}
set-unowned-body-kinematic
scalable-when-grabbed
position-at-border={{ target: ".camera-menu", isFlat: true }}
set-yxz-order
>
<entity ref={cameraRef} camera={layers} rotation={rotation} position={position} />
<entity object3D={loadGLTF(src)} />
<THREE.Mesh
name="screen"
ref={screenRef}
geometry={screenGeometry}
material={screenMaterial}
position={[0, 0, -0.042]}
rotation={[0, Math.PI, 0]}
/>
<THREE.Mesh
name="selfie screen"
ref={selfieScreenRef}
geometry={screenGeometry}
material={screenMaterial}
position={[0, 0.4, 0]}
scale={[-2, 2, 2]}
/>
<a-entity className="ui interactable-ui" ref={snapMenuRef}>
<a-entity
ref={labelRef}
position={[0, 0.15, 0.081]}
text={{ value: 3, textAlign: "center", color: "#fafafa", fontSize: 0.09 }}
/>
<ActionButton
className="label-action-background"
type="rounded-action-button"
position={[0, 0.15, 0.08]}
scale={[0.75, 0.75, 0.75]}
/>
<ActionButton className="label-background" position={[0, 0.15, 0.08]} scale={[0.75, 0.75, 0.75]} />
<a-entity
className="duration"
text="value: 5s; textAlign: center; color: #fafafa; fontSize: 0.09;"
position={[0, -0.15, 0.09]}
/>
<ActionButton
ref={snapButtonRef}
type="rounded-action-button"
image="snap_camera.png"
position={[0, 0.15, 0.08]}
scale={[0.75, 0.75, 0.75]}
iconScale={0.2}
/>
<RecordButton />
<ActionButton
className="cancel-button"
image="close-action.png"
position={[0, -0.15, 0.075]}
scale={[0.65, 0.65, 0.65]}
/>
<ActionButton
className="prev-duration"
image="prev.png"
position={[-0.135, -0.15, 0.075]}
scale={[0.5, 0.5, 0.5]}
/>
<ActionButton
className="next-duration"
image="next.png"
position={[0.135, -0.15, 0.075]}
scale={[0.5, 0.5, 0.5]}
/>
<ActionButton
className="stop-button"
type="rounded-action-button"
position={[0, 0.15, 0.08]}
scale={[0.75, 0.75, 0.75]}
image="stop-action.png"
/>
</a-entity>
<a-entity
className="ui interactable-ui camera-menu"
visibility-while-frozen={{ withinDistance: 100, withPermission: "spawn_camera" }}
>
<ActionButton
type="rounded-action-button"
className="capture-audio"
iconClassName="capture-audio-icon"
position={[0, 0.125, 0.001]}
image="unmute-action.png"
iconScale={0.165}
/>
<ActionButton
type="rounded-action-button"
transform-button="mode: align;"
position={[-0.15, -0.125, 0.001]}
image="recenter-action.png"
iconScale={0.165}
/>
<ActionButton
type="rounded-action-button"
tags="isHoldable: true; holdableButton: true;"
transform-button
transform-button-selector
position={[0.15, -0.125, 0.001]}
image="rotate-action.png"
iconScale={0.165}
/>
<ActionButton
remove-networked-object-button
position={[0, -0.35, 0.001]}
iconScale={0.165}
image="remove-action.png"
/>
</a-entity>
</a-entity>
);
}
export default {
template: "#interactable-camera",
addEntity: function() {
const c = <InteractableCamera />;
console.log(c);
return renderAsAframeEntity(c);
},
components: [
"position",
"rotation",
{
component: "camera-tool",
property: "isSnapping"
},
{
component: "camera-tool",
property: "isRecording"
},
{
component: "camera-tool",
property: "label"
}
]
};
import { MediaType, textureLoader } from "../utils/media-utils";
import cameraModelSrc from "../assets/camera_tool.glb";
import buttonSrc from "../assets/hud/button.9.png";
import { loadModel } from "../components/gltf-model-plus";
import { Layers } from "../components/layers";
import { BUTTON_TYPES } from "../systems/single-action-button-system";
import { waitForDOMContentLoaded } from "../utils/async-utils";
import { createElementEntity, createRef } from "../utils/jsx-entity";
import { textureLoader } from "../utils/media-utils";
import { cloneObject3D } from "../utils/three-utils";
const buttonTexture = textureLoader.load(buttonSrc);
function Button({ text, width, height, texture = buttonTexture, type = BUTTON_TYPES.DEFAULT, ...props }) {
@ -310,11 +51,6 @@ function HoldableButton({ text, width, height, texture = buttonTexture, ...props
);
}
import { loadModel } from "../components/gltf-model-plus";
import cameraModelSrc from "../assets/camera_tool.glb";
import { waitForDOMContentLoaded } from "../utils/async-utils";
import { cloneObject3D } from "../utils/three-utils";
let model;
(async () => {
model = await waitForDOMContentLoaded().then(() => loadModel(cameraModelSrc));
@ -323,9 +59,6 @@ let model;
const RENDER_WIDTH = 1280;
const RENDER_HEIGHT = 720;
import { Layers } from "../components/layers";
import { BUTTON_TYPES } from "../systems/single-action-button-system";
export function CameraPrefab(_props) {
// TODO: What if model didn't load yet?
const cameraModel = cloneObject3D(model.scene);
@ -449,35 +182,4 @@ export function CameraPrefab(_props) {
/>
</entity>
);
// return (
// <entity networked-transform logger={{ buttons }}>
// <HoldableButton position={[0, 1, 0]} width={1} height={0.5} text="Welcome to our wonderfully grabbable world" />
// {buttons}
// <entity
// scale={[0.25, 0.25, 0.25]}
// object3D={cube}
// cursor-raycastable
// remote-hover-target
// offers-remote-constraint
// holdable
// rigidbody
// />
// </entity>
// );
}
export const FLAGS = {
captureAudio: 1,
showCameraViewfinder: 1 << 1
};
export const STATES = {
isDoingNothing: 0,
isSnapping: 1,
isRecording: 2
};
// Data on a camera
// label, snapButton, snapMenu, screen, selfieScreen
// renderTarget, camera

Просмотреть файл

@ -1,26 +0,0 @@
import { createElementEntity, renderAsAframeEntity } from "../utils/jsx-entity";
/** @jsx createElementEntity */
export const mediaFrameSchema = {
template: "#interactable-media-frame",
addEntity: function(componentProps) {
return renderAsAframeEntity(
<a-entity>
<entity media-frame={componentProps} />
</a-entity>,
APP.world
);
},
components: [
{
component: "media-frame",
property: "targetId"
},
{
component: "media-frame",
property: "originalTargetScale"
}
],
// TODO we probably want media frames to support permissioning of some form
nonAuthorizedComponents: ["media-frame"]
};

Просмотреть файл