This commit is contained in:
Manuel Martin 2023-07-18 11:21:09 +02:00
Родитель 057d9bb253
Коммит 5532398df1
18 изменённых файлов: 66 добавлений и 24200 удалений

24126
package-lock.json сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -125,7 +125,8 @@ export const PhysicsShape = defineComponent({
offset: [Types.f32, 3],
orientation: [Types.f32, 4],
heightfieldData: [Types.f32],
heightfieldDistance: Types.f32
heightfieldDistance: Types.f32,
flags: Types.ui8
});
export const DestroyAtExtremeDistance = defineComponent();
export const MediaLoading = defineComponent();
@ -165,7 +166,6 @@ export const MediaContentBounds = defineComponent({
bounds: [Types.f32, 3]
});
MediaLoaded.map = new Map();
export const MediaVisible = defineComponent();
// MediaImageLoaderData and MediaVideoLoaderData are
// for parameters that are set at glTF inflators

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

@ -15,9 +15,8 @@ import {
writeNodeSpecsToJSON
} from "@oveddan-behave-graph/core";
import { defineQuery, enterQuery, exitQuery, hasComponent } from "bitecs";
import { AnimationMixer } from "three";
import { HubsWorld } from "../app";
import { BehaviorGraph, CustomTags, Interacted, LocalAvatar, MixerAnimatable, RemoteAvatar, Rigidbody } from "../bit-components";
import { BehaviorGraph, CustomTags, Interacted, LocalAvatar, RemoteAvatar, Rigidbody } from "../bit-components";
import { findAncestorEntity } from "../utils/bit-utils";
import { ClientID, EntityID } from "../utils/networking-types";
import { AnimationNodes, animationValueDefs } from "./behavior-graph/animation-nodes";
@ -62,44 +61,19 @@ const registry: IRegistry = {
}
};
const easingNode = registry.nodes["math/easing"] as any;
const easingNode = registry.nodes["math/easing"] as any;
easingNode.in.easingMode.choices = easingNode.in.easingMode.options.map((v: any) => ({ text: v, value: v }));
easingNode.in.easingFunction.choices = easingNode.in.easingFunction.options.map((v: any) => ({ text: v, value: v }));
const orders = ["XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY" ].map(v => ({text: v, value: v}));
const orders = ["XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"].map(v => ({ text: v, value: v }));
const eulerCombineNode = registry.nodes["math/euler/combine"] as any;
eulerCombineNode.in()[3].choices = orders
eulerCombineNode.in()[3].defaultValue = orders[0].value
eulerCombineNode.in()[3].choices = orders;
eulerCombineNode.in()[3].defaultValue = orders[0].value;
const nodeSpec = cleanupNodespac(writeNodeSpecsToJSON({ ...registry, dependencies: {} }));
console.log("registry", registry, nodeSpec);
console.log(JSON.stringify(nodeSpec, null, 2));
const mixerAnimatableQuery = defineQuery([MixerAnimatable]);
const mixerAnimatableEnteryQuery = enterQuery(mixerAnimatableQuery);
const mixerAnimatableExitQuery = exitQuery(mixerAnimatableQuery);
function stubAnimationMixerSystem(world: HubsWorld) {
mixerAnimatableEnteryQuery(world).forEach(eid => {
const obj = world.eid2obj.get(eid)!;
const mixer = new AnimationMixer(obj);
MixerAnimatable.mixers.set(eid, mixer);
// TODO remove, only for debug
(obj as any).mixer = mixer;
});
mixerAnimatableExitQuery(world).forEach(eid => {
const mixer = MixerAnimatable.mixers.get(eid)!;
mixer.stopAllAction();
MixerAnimatable.mixers.delete(eid);
});
mixerAnimatableQuery(world).forEach(eid => {
MixerAnimatable.mixers.get(eid)!.update(world.time.delta / 1000);
});
}
type EngineState = {
engine: Engine;
lifecycleEmitter: ManualLifecycleEventEmitter;
@ -113,8 +87,6 @@ const interactedQuery = defineQuery([Interacted]);
const customTagsExitQuery = exitQuery(defineQuery([CustomTags]));
export function behaviorGraphSystem(world: HubsWorld) {
stubAnimationMixerSystem(world);
behaviorGraphEnterQuery(world).forEach(function (eid) {
const obj = world.eid2obj.get(eid)!;
const graphJson = obj.userData.behaviorGraph as GraphJSON;
@ -174,13 +146,13 @@ export function behaviorGraphSystem(world: HubsWorld) {
});
customTagsExitQuery(world).forEach(function (eid) {
CustomTags.tags.delete(eid)
})
CustomTags.tags.delete(eid);
});
// TODO allocations
const collisionCheckEntiteis = entityEvents.keys();
const collisionCheckEntities = entityEvents.keys();
// TODO lots of traversal and can probably be simplified a good deal
for (const eid of collisionCheckEntiteis) {
for (const eid of collisionCheckEntities) {
const triggerState = entityEvents.get(eid)!;
const physicsSystem = AFRAME.scenes[0].systems["hubs-systems"].physicsSystem;

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

@ -18,7 +18,7 @@ import {
NormalAnimationBlendMode
} from "three";
import { HubsWorld } from "../../app";
import { MixerAnimatable } from "../../bit-components";
import { MixerAnimatableData } from "../../bit-components";
import { EntityID } from "../../utils/networking-types";
import { definitionListToMap } from "./utils";
@ -58,7 +58,7 @@ const createAnimationActionDef = makeFlowNodeDefinition({
const rootEid = graph.getDependency<EntityID>("rootEntity")!;
const world = graph.getDependency<HubsWorld>("world")!;
const obj = world.eid2obj.get(rootEid)!;
const mixer = MixerAnimatable.mixers.get(rootEid)!;
const mixer = MixerAnimatableData.get(rootEid)!;
const action = mixer.clipAction(AnimationClip.findByName(obj.animations, clipName));
action.blendMode = additiveBlending ? AdditiveAnimationBlendMode : NormalAnimationBlendMode;

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

@ -142,7 +142,7 @@ function makeObjectPropertyFlowNode<T extends keyof Object3D>(property: T, value
return;
}
const value = read(property) as Object3D[T];
const prop = obj[property];
const prop = obj[property]!;
if (typeof prop === "object" && "copy" in prop) {
prop.copy(value);
if (["position", "rotation", "scale"].includes(property)) obj.matrixNeedsUpdate = true;

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

@ -9,6 +9,7 @@ import { Euler, Matrix4, Object3D, Quaternion, Vector3 } from "three";
import { getPlayerInfo } from "../../utils/component-utils";
import { ClientID } from "../../utils/networking-types";
import { definitionListToMap } from "./utils";
import { AElement } from "aframe";
export const playerValueDefs = {
player: new ValueType(
@ -165,7 +166,7 @@ export const playerNodedefs = definitionListToMap([
in: [{ player: "player" }],
out: [{ position: "vec3" }, { rotation: "euler" }, { scale: "vec3" }],
exec: (player: ClientID) => {
const info = getPlayerInfo(player);
const info = getPlayerInfo(player)!;
const obj = info.el.object3D as Object3D;
return {
// TODO this is largely so that variables work since they are set using =. We can add support for .copy()-able things
@ -182,8 +183,9 @@ export const playerNodedefs = definitionListToMap([
in: [{ player: "player" }],
out: [{ position: "vec3" }, { rotation: "euler" }, { scale: "vec3" }],
exec: (player: ClientID) => {
const info = getPlayerInfo(player);
const obj = info.el.querySelector(".camera").object3D as Object3D;
const info = getPlayerInfo(player)!;
const camera = info.el.querySelector(".camera")! as AElement;
const obj = camera.object3D as Object3D;
return {
// TODO this is largely so that variables work since they are set using =. We can add support for .copy()-able things
position: obj.position.clone(),
@ -199,8 +201,9 @@ export const playerNodedefs = definitionListToMap([
in: [{ player: "player" }],
out: [{ position: "vec3" }, { rotation: "euler" }, { scale: "vec3" }],
exec: (player: ClientID) => {
const info = getPlayerInfo(player);
const obj = info.el.querySelector(".camera").object3D as Object3D;
const info = getPlayerInfo(player)!;
const camera = info.el.querySelector(".camera")! as AElement;
const obj = camera.object3D as Object3D;
obj.updateMatrices();
const position = new Vector3();
const rotation = new Quaternion();

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

@ -211,7 +211,7 @@ function rotateWithRightClick(world, camera) {
userinput.get(paths.device.mouse.buttonRight)
) {
const rightCursor = anyEntityWith(world, RemoteRight);
physicsSystem.updateRigidBodyOptions(camera, { type: "kinematic" });
physicsSystem.updateRigidBody(camera, { type: "kinematic" });
transformSystem.startTransform(world.eid2obj.get(camera), world.eid2obj.get(rightCursor), {
mode: "cursor"
});

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

@ -1,5 +1,5 @@
import { addComponent, defineQuery, enterQuery, exitQuery, hasComponent, removeComponent } from "bitecs";
import { AnimationAction, AnimationClip, AnimationMixer, LoopRepeat } from "three";
import { AnimationClip, LoopRepeat } from "three";
import {
MixerAnimatable,
MixerAnimatableData,
@ -47,12 +47,16 @@ const getActiveClips = (
export function loopAnimationSystem(world: HubsWorld): void {
loopAnimationInitializeEnterQuery(world).forEach((eid: number): void => {
const params = LoopAnimationInitializeData.get(eid)!;
if (!params.length) {
return;
}
const object = world.eid2obj.get(eid)!;
const mixer = MixerAnimatableData.get(eid)!;
addComponent(world, LoopAnimation, eid);
const params = LoopAnimationInitializeData.get(eid)!;
const activeAnimations = [];
for (let i = 0; i < params.length; i++) {

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

@ -96,7 +96,7 @@ function startRotation(world: HubsWorld, targetEid: EntityID) {
}
const transformSystem = APP.scene!.systems["transform-selected-object"];
const physicsSystem = AFRAME.scenes[0].systems["hubs-systems"].physicsSystem;
physicsSystem.updateRigidBodyOptions(Rigidbody.bodyId[targetEid], { type: "kinematic" });
physicsSystem.updateRigidBody(Rigidbody.bodyId[targetEid], { type: "kinematic" });
const rightCursorEid = anyEntityWith(world, RemoteRight)!;
transformSystem.startTransform(world.eid2obj.get(targetEid)!, world.eid2obj.get(rightCursorEid)!, {
mode: TRANSFORM_MODE.CURSOR
@ -126,7 +126,7 @@ function startScaling(world: HubsWorld, targetEid: EntityID) {
// TODO: Remove the dependency with AFRAME
const transformSystem = (AFRAME as any).scenes[0].systems["transform-selected-object"];
const physicsSystem = AFRAME.scenes[0].systems["hubs-systems"].physicsSystem;
physicsSystem.updateRigidBodyOptions(Rigidbody.bodyId[targetEid], { type: "kinematic" });
physicsSystem.updateRigidBody(Rigidbody.bodyId[targetEid], { type: "kinematic" });
const rightCursorEid = anyEntityWith(world, RemoteRight)!;
scalingHandler = new ScalingHandler(world.eid2obj.get(targetEid), transformSystem);
scalingHandler!.objectToScale = world.eid2obj.get(targetEid);

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

@ -29,17 +29,11 @@ const ELEMENT_DEFAULTS: Required<ElementParams> = {
timeScale: 1.0
};
const DEFAULTS: Required<LoopAnimationParams> = [ELEMENT_DEFAULTS];
export function inflateLoopAnimationInitialize(
world: HubsWorld,
eid: number,
params: LoopAnimationParams = []
): number {
if (params.length === 0) {
params = DEFAULTS;
}
const componentParams = [];
for (let i = 0; i < params.length; i++) {
const requiredParams = Object.assign({}, ELEMENT_DEFAULTS, params[i]) as Required<ElementParams>;

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

@ -10,6 +10,13 @@ export enum Type {
KINEMATIC
}
export enum CollisionGroup {
OBJECTS = "objects",
ENVIRONMENT = "environment",
TRIGGERS = "triggers",
AVATARS = "avatars"
}
export enum ActivationState {
ACTIVE_TAG = 0,
ISLAND_SLEEPING = 1,
@ -158,7 +165,6 @@ export interface GLTFRigidBodyParams
export function inflateGLTFRigidBody(world: HubsWorld, eid: number, params: GLTFRigidBodyParams) {
const bodyParams = Object.assign({}, GLTF_DEFAULTS, params);
addComponent(world, Rigidbody, eid);
inflateRigidBody(world, eid, {
...bodyParams,
type: Object.values(GLTFRigidBodyType).indexOf(bodyParams.type),

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

@ -81,6 +81,7 @@ function updateMessageGroups(messageGroups: any[], newMessage: NewMessageT) {
case "scene_changed":
case "hub_name_changed":
case "hub_changed":
case "script_message":
case "log":
return [
...messageGroups,

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

@ -49,7 +49,7 @@ function add(world, physicsSystem, interactor, constraintComponent, entities) {
if (hasComponent(world, Networked, eid)) {
takeOwnership(world, eid);
}
physicsSystem.updateRigidBodyOptions(eid, grabBodyOptions);
physicsSystem.updateRigidBody(eid, grabBodyOptions);
physicsSystem.addConstraint(interactor, Rigidbody.bodyId[eid], Rigidbody.bodyId[interactor], {});
addComponent(world, Constraint, eid);
addComponent(world, constraintComponent, eid);
@ -61,7 +61,7 @@ function remove(world, offersConstraint, constraintComponent, physicsSystem, int
const eid = findAncestorEntity(world, entities[i], ancestor => hasComponent(world, Rigidbody, ancestor));
if (!entityExists(world, eid)) continue;
if (hasComponent(world, offersConstraint, entities[i]) && hasComponent(world, Rigidbody, eid)) {
physicsSystem.updateRigidBodyOptions(eid, releaseBodyOptions);
physicsSystem.updateRigidBody(eid, releaseBodyOptions);
physicsSystem.removeConstraint(interactor);
removeComponent(world, constraintComponent, eid);
if (

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

@ -361,7 +361,7 @@ export function mediaFramesSystem(world, physicsSystem) {
if (capturedEid && isCapturedOwned && !isCapturedHeld && !isFrameDeleting && isCapturedColliding) {
snapToFrame(world, frame, capturedEid);
physicsSystem.updateRigidBodyOptions(capturedEid, { type: "kinematic" });
physicsSystem.updateRigidBody(capturedEid, { type: "kinematic" });
} else if (
(isFrameOwned && MediaFrame.capturedNid[frame] && world.deletedNids.has(MediaFrame.capturedNid[frame])) ||
(capturedEid && isCapturedOwned && !isCapturedColliding) ||
@ -392,7 +392,7 @@ export function mediaFramesSystem(world, physicsSystem) {
obj.updateMatrices();
tmpVec3.setFromMatrixScale(obj.matrixWorld).toArray(NetworkedMediaFrame.scale[frame]);
snapToFrame(world, frame, capturable);
physicsSystem.updateRigidBodyOptions(capturable, { type: "kinematic" });
physicsSystem.updateRigidBody(capturable, { type: "kinematic" });
}
}
@ -405,7 +405,7 @@ export function mediaFramesSystem(world, physicsSystem) {
// TODO: If you are resetting scale because you lost a race for the frame,
// you should probably also move the object away from the frame.
setMatrixScale(world.eid2obj.get(capturedEid), MediaFrame.scale[frame]);
physicsSystem.updateRigidBodyOptions(capturedEid, { type: "dynamic" });
physicsSystem.updateRigidBody(capturedEid, { type: "dynamic" });
}
MediaFrame.capturedNid[frame] = NetworkedMediaFrame.capturedNid[frame];

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

@ -53,7 +53,7 @@ function makeKinematicOnRelease(world) {
const physicsSystem = AFRAME.scenes[0].systems["hubs-systems"].physicsSystem;
makeKinematicOnReleaseExitQuery(world).forEach(eid => {
if (!entityExists(world, eid) || !hasComponent(world, Owned, eid)) return;
physicsSystem.updateRigidBodyOptions(eid, { type: "kinematic" });
physicsSystem.updateRigidBody(eid, { type: "kinematic" });
});
}
@ -73,14 +73,14 @@ export const floatyObjectSystem = world => {
const physicsSystem = AFRAME.scenes[0].systems["hubs-systems"].physicsSystem;
enteredFloatyObjectsQuery(world).forEach(eid => {
physicsSystem.updateRigidBodyOptions(eid, {
physicsSystem.updateRigidBody(eid, {
type: "kinematic",
gravity: { x: 0, y: 0, z: 0 }
});
});
enterHeldFloatyObjectsQuery(world).forEach(eid => {
physicsSystem.updateRigidBodyOptions(eid, {
physicsSystem.updateRigidBody(eid, {
gravity: { x: 0, y: 0, z: 0 },
type: "dynamic",
collisionFilterMask: COLLISION_LAYERS.HANDS | COLLISION_LAYERS.MEDIA_FRAMES | COLLISION_LAYERS.TRIGGERS
@ -95,7 +95,7 @@ export const floatyObjectSystem = world => {
const bodyData = physicsSystem.bodyUuidToData.get(bodyId);
if (FloatyObject.flags[eid] & FLOATY_OBJECT_FLAGS.MODIFY_GRAVITY_ON_RELEASE) {
if (bodyData.linearVelocity < 1.85) {
physicsSystem.updateRigidBodyOptions(eid, {
physicsSystem.updateRigidBody(eid, {
gravity: { x: 0, y: 0, z: 0 },
angularDamping: FloatyObject.flags[eid] & FLOATY_OBJECT_FLAGS.REDUCE_ANGULAR_FLOAT ? 0.89 : 0.5,
linearDamping: 0.95,
@ -105,7 +105,7 @@ export const floatyObjectSystem = world => {
});
addComponent(world, MakeStaticWhenAtRest, eid);
} else {
physicsSystem.updateRigidBodyOptions(eid, {
physicsSystem.updateRigidBody(eid, {
gravity: { x: 0, y: FloatyObject.releaseGravity[eid], z: 0 },
angularDamping: 0.01,
linearDamping: 0.01,
@ -131,7 +131,7 @@ export const floatyObjectSystem = world => {
const angle = Math.random() * Math.PI * 2;
const x = Math.cos(angle);
const z = Math.sin(angle);
physicsSystem.updateRigidBodyOptions(eid, {
physicsSystem.updateRigidBody(eid, {
gravity: { x, y: force, z },
angularDamping: 0.01,
linearDamping: 0.01,
@ -142,7 +142,7 @@ export const floatyObjectSystem = world => {
removeComponent(world, MakeStaticWhenAtRest, eid);
}
} else {
physicsSystem.updateRigidBodyOptions(eid, {
physicsSystem.updateRigidBody(eid, {
collisionFilterMask: COLLISION_LAYERS.DEFAULT_INTERACTABLE,
gravity: { x: 0, y: -9.8, z: 0 }
});

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

@ -27,7 +27,7 @@ export function onOwnershipLost(world) {
}
if (hasComponent(world, Rigidbody, eid)) {
physicsSystem.updateRigidBodyOptions(eid, kinematicOptions);
physicsSystem.updateRigidBody(eid, kinematicOptions);
}
}
}

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

@ -260,18 +260,6 @@ export class PhysicsSystem {
}
}
updateRigidBodyOptions(eid, options) {
const bodyId = Rigidbody.bodyId[eid];
updateRigiBodyParams(eid, options);
const bodyData = this.bodyUuidToData.get(bodyId);
if (!bodyData) {
// TODO: Fix me.
console.warn("updateBodyOptions called for invalid bodyId");
return;
}
this.workerHelpers.updateBody(bodyId, Object.assign(this.bodyUuidToData.get(bodyId).options, options));
}
removeBody(uuid) {
const bodyData = this.bodyUuidToData.get(uuid);
if (!bodyData) {

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

@ -91,7 +91,7 @@ import { inflateAudioParams } from "../inflators/audio-params";
import { AudioSourceParams, inflateAudioSource } from "../inflators/audio-source";
import { AudioTargetParams, inflateAudioTarget } from "../inflators/audio-target";
import { PhysicsShapeParams, inflatePhysicsShape } from "../inflators/physics-shape";
import { inflateRigidBody, RigidBodyParams } from "../inflators/rigid-body";
import { inflateGLTFRigidBody, inflateRigidBody, RigidBodyParams } from "../inflators/rigid-body";
import { AmmoShapeParams, inflateAmmoShape } from "../inflators/ammo-shape";
import { BoxColliderParams, inflateBoxCollider } from "../inflators/box-collider";
import { inflateTrimesh } from "../inflators/trimesh";
@ -513,7 +513,7 @@ export const gltfInflators: Required<{ [K in keyof GLTFComponentData]: InflatorF
heightfield: inflateHeightField,
audioSettings: inflateAudioSettings,
interactable: createDefaultInflator(SingleActionButton),
rigidbody: inflateRigidBody,
rigidbody: inflateGLTFRigidBody,
physicsShape: inflateAmmoShape,
customTags: inflateCustomTags
};