Skip to content

Commit

Permalink
Merge pull request #2000 from webaverse/aim-action
Browse files Browse the repository at this point in the history
Add aim action support
  • Loading branch information
Avaer Kazmer authored Dec 14, 2021
2 parents fb22827 + f830622 commit 12a6c4b
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 27 deletions.
67 changes: 59 additions & 8 deletions avatars/avatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {angleDifference, getVelocityDampingFactor} from '../util.js';
import easing from '../easing.js';
import CBOR from '../cbor.js';
import Simplex from '../simplex-noise.js';
import {crouchMaxTime, useMaxTime, avatarInterpolationFrameRate, avatarInterpolationTimeDelay, avatarInterpolationNumFrames} from '../constants.js';
import {crouchMaxTime, useMaxTime, aimMaxTime, avatarInterpolationFrameRate, avatarInterpolationTimeDelay, avatarInterpolationNumFrames} from '../constants.js';
import {FixedTimeStep} from '../interpolants.js';
import metaversefile from 'metaversefile';
import {
Expand Down Expand Up @@ -215,6 +215,7 @@ let animationsBaseModel;
let jumpAnimation;
let floatAnimation;
let useAnimations;
let aimAnimations;
let sitAnimations;
let danceAnimations;
let throwAnimations;
Expand Down Expand Up @@ -339,20 +340,37 @@ const loadPromise = (async () => {
swordSideSlash = animations.find(a => a.isSwordSideSlash);
swordTopDownSlash = animations.find(a => a.isSwordTopDownSlash)

function mergeAnimations(a, b) {
const o = {};
for (const k in a) {
o[k] = a[k];
}
for (const k in b) {
o[k] = b[k];
}
return o;
}

jumpAnimation = animations.find(a => a.isJump);
// sittingAnimation = animations.find(a => a.isSitting);
floatAnimation = animations.find(a => a.isFloat);
// rifleAnimation = animations.find(a => a.isRifle);
// hitAnimation = animations.find(a => a.isHit);
useAnimations = {
aimAnimations = {
swordSideIdle: animations.find(a => a.name === 'sword_idle_side.fbx'),
swordSideIdleStatic: animations.find(a => a.name === 'sword_idle_side_static.fbx'),
swordSideSlash: animations.find(a => a.name === 'sword_side_slash.fbx'),
swordTopDownSlash: animations.find(a => a.name === 'sword_topdown_slash.fbx'),
swordUndraw: animations.find(a => a.name === 'sword_undraw.fbx'),
};
useAnimations = mergeAnimations({
combo: animations.find(a => a.isCombo),
slash: animations.find(a => a.isSlash),
rifle: animations.find(a => a.isRifle),
pistol: animations.find(a => a.isPistol),
magic: animations.find(a => a.isMagic),
drink: animations.find(a => a.isDrinking),
};
}, aimAnimations);
sitAnimations = {
chair: animations.find(a => a.isSitting),
saddle: animations.find(a => a.isSitting),
Expand Down Expand Up @@ -1220,8 +1238,9 @@ class Avatar {
this.swordSideSlashTime = 0;
this.swordTopDownSlashState = false;
this.swordTopDownSlashTime = 0;
this.aimState = false;
this.aimDirection = new THREE.Vector3();
this.aimTime = NaN;
this.aimAnimation = null;
// this.aimDirection = new THREE.Vector3();

// internal state
this.lastPosition = new THREE.Vector3();
Expand Down Expand Up @@ -2212,7 +2231,8 @@ class Avatar {

_getHorizontalBlend(k, lerpFn, dst);
};
if (this.useTime >= 0) {
// console.log('got aim time', this.useAnimation, this.useTime, this.aimAnimation, this.aimTime);
if (this.useAnimation) {
return spec => {
const {
animationTrackName: k,
Expand All @@ -2221,9 +2241,17 @@ class Avatar {
} = spec;

if (isTop) {
const useAnimation = (this.useAnimation && useAnimations[this.useAnimation]) //|| useAnimations[defaultUseAnimation];
const isCombo = Array.isArray(this.useAnimation);
const useAnimationName = isCombo ? this.useAnimation[this.useAnimationIndex] : this.useAnimation;
const useAnimation = (useAnimationName && useAnimations[useAnimationName]);
if (useAnimation) {
const t2 = (this.useTime/useMaxTime) % useAnimation.duration;
const t2 = (() => {
if (isCombo) {
return Math.min(this.useTime/1000, useAnimation.duration);
} else {
return (this.useTime/1000) % useAnimation.duration;
}
})();
const src2 = useAnimation.interpolants[k];
const v2 = src2.evaluate(t2);

Expand All @@ -2235,6 +2263,29 @@ class Avatar {
_handleDefault(spec);
}
};
} else if (this.aimAnimation) {
return spec => {
const {
animationTrackName: k,
dst,
isTop,
} = spec;

if (isTop) {
const aimAnimation = (this.aimAnimation && aimAnimations[this.aimAnimation]);
if (aimAnimation) {
const t2 = (this.aimTime/aimMaxTime) % aimAnimation.duration;
const src2 = aimAnimation.interpolants[k];
const v2 = src2.evaluate(t2);

dst.fromArray(v2);
} else {
_handleDefault(spec);
}
} else {
_handleDefault(spec);
}
};
}
return _handleDefault;
};
Expand Down
4 changes: 4 additions & 0 deletions character-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ class InterpolatedPlayer extends Player {
crouch: new BinaryInterpolant(() => this.hasAction('crouch'), avatarInterpolationTimeDelay, avatarInterpolationNumFrames),
activate: new BinaryInterpolant(() => this.hasAction('activate'), avatarInterpolationTimeDelay, avatarInterpolationNumFrames),
use: new BinaryInterpolant(() => this.hasAction('use'), avatarInterpolationTimeDelay, avatarInterpolationNumFrames),
aim: new BinaryInterpolant(() => this.hasAction('aim'), avatarInterpolationTimeDelay, avatarInterpolationNumFrames),
narutoRun: new BinaryInterpolant(() => this.hasAction('narutoRun'), avatarInterpolationTimeDelay, avatarInterpolationNumFrames),
fly: new BinaryInterpolant(() => this.hasAction('fly'), avatarInterpolationTimeDelay, avatarInterpolationNumFrames),
jump: new BinaryInterpolant(() => this.hasAction('jump'), avatarInterpolationTimeDelay, avatarInterpolationNumFrames),
Expand All @@ -574,6 +575,7 @@ class InterpolatedPlayer extends Player {
crouch: new FixedTimeStep(timeDiff => {this.actionBinaryInterpolants.crouch.snapshot(timeDiff);}, avatarInterpolationFrameRate),
activate: new FixedTimeStep(timeDiff => {this.actionBinaryInterpolants.activate.snapshot(timeDiff);}, avatarInterpolationFrameRate),
use: new FixedTimeStep(timeDiff => {this.actionBinaryInterpolants.use.snapshot(timeDiff);}, avatarInterpolationFrameRate),
aim: new FixedTimeStep(timeDiff => {this.actionBinaryInterpolants.aim.snapshot(timeDiff);}, avatarInterpolationFrameRate),
narutoRun: new FixedTimeStep(timeDiff => {this.actionBinaryInterpolants.narutoRun.snapshot(timeDiff);}, avatarInterpolationFrameRate),
fly: new FixedTimeStep(timeDiff => {this.actionBinaryInterpolants.fly.snapshot(timeDiff);}, avatarInterpolationFrameRate),
jump: new FixedTimeStep(timeDiff => {this.actionBinaryInterpolants.jump.snapshot(timeDiff);}, avatarInterpolationFrameRate),
Expand All @@ -590,6 +592,7 @@ class InterpolatedPlayer extends Player {
crouch: new BiActionInterpolant(() => this.actionBinaryInterpolants.crouch.get(), 0, crouchMaxTime),
activate: new UniActionInterpolant(() => this.actionBinaryInterpolants.activate.get(), 0, activateMaxTime),
use: new InfiniteActionInterpolant(() => this.actionBinaryInterpolants.use.get(), 0),
aim: new InfiniteActionInterpolant(() => this.actionBinaryInterpolants.aim.get(), 0),
narutoRun: new InfiniteActionInterpolant(() => this.actionBinaryInterpolants.narutoRun.get(), 0),
fly: new InfiniteActionInterpolant(() => this.actionBinaryInterpolants.fly.get(), 0),
jump: new InfiniteActionInterpolant(() => this.actionBinaryInterpolants.jump.get(), 0),
Expand Down Expand Up @@ -636,6 +639,7 @@ class UninterpolatedPlayer extends Player {
crouch: new BiActionInterpolant(() => this.hasAction('crouch'), 0, crouchMaxTime),
activate: new UniActionInterpolant(() => this.hasAction('activate'), 0, activateMaxTime),
use: new InfiniteActionInterpolant(() => this.hasAction('use'), 0),
aim: new InfiniteActionInterpolant(() => this.hasAction('aim'), 0),
narutoRun: new InfiniteActionInterpolant(() => this.hasAction('narutoRun'), 0),
fly: new InfiniteActionInterpolant(() => this.hasAction('fly'), 0),
jump: new InfiniteActionInterpolant(() => this.hasAction('jump'), 0),
Expand Down
1 change: 1 addition & 0 deletions constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const metaverseProfileDefinition = `kjzl6cwe1jw145wm7u2sy1wpa33hglvmuy6th
export const crouchMaxTime = 200;
export const activateMaxTime = 750;
export const useMaxTime = 750;
export const aimMaxTime = 1000;
export const minFov = 60;
export const maxFov = 120;
export const initialPosY = 1.5;
Expand Down
34 changes: 34 additions & 0 deletions game.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,14 @@ const _click = () => {
}
}
};
let lastUseIndex = 0;
const _getNextUseIndex = animation => {
if (Array.isArray(animation)) {
return (lastUseIndex++) % animation.length;
} else {
return 0;
}
};
let lastPistolUseStartTime = -Infinity;
const _startUse = () => {
const localPlayer = metaversefileApi.useLocalPlayer();
Expand All @@ -336,13 +344,16 @@ const _startUse = () => {
if (!useAction) {
const {instanceId} = wearApp;
const {subtype, boneAttachment, animation, position, quaternion, scale} = useComponent;
const index = _getNextUseIndex(animation);
// console.log('index', index, swordTopDownSlash);
const newUseAction = {
type: 'use',
subtype,
// time: 0,
instanceId,
animation,
boneAttachment,
index,
position,
quaternion,
scale,
Expand Down Expand Up @@ -1301,8 +1312,31 @@ const gameManager = {
menuAim() {
const localPlayer = metaversefileApi.useLocalPlayer();
if (!localPlayer.hasAction('aim')) {
const wearAimApp = (() => {
const wearApps = Array.from(localPlayer.getActionsState())
.filter(action => action.type === 'wear')
.map(({instanceId}) => metaversefileApi.getAppByInstanceId(instanceId));
for (const wearApp of wearApps) {
const aimComponent = wearApp.getComponent('aim');
if (aimComponent) {
return wearApp;
}
}
return null;
})();
const wearAimComponent = wearAimApp?.getComponent('aim');

const {instanceId} = wearAimApp ?? {};
const {appAnimation, playerAnimation, boneAttachment, position, quaternion, scale} = wearAimComponent ?? {};
const aimAction = {
type: 'aim',
instanceId,
appAnimation,
playerAnimation,
boneAttachment,
position,
quaternion,
scale,
};
localPlayer.addAction(aimAction);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/totum
Submodule totum updated 2 files
+16 −0 README.md
+93 −31 type_templates/glb.js
20 changes: 7 additions & 13 deletions physics-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ it contains code for character capsules and world simulation.
*/

import * as THREE from 'three';
import {getRenderer, camera, dolly} from './renderer.js';
// import {getRenderer, camera, dolly} from './renderer.js';
import physx from './physx.js';
import cameraManager from './camera-manager.js';
import ioManager from './io-manager.js';
import {getPlayerCrouchFactor} from './character-controller.js';
// import cameraManager from './camera-manager.js';
// import ioManager from './io-manager.js';
// import {getPlayerCrouchFactor} from './character-controller.js';
import metaversefileApi from 'metaversefile';
import {getNextPhysicsId, convertMeshToPhysicsMesh} from './util.js';
import {applyVelocity} from './util.js';
// import {applyVelocity} from './util.js';
// import {groundFriction} from './constants.js';
import {CapsuleGeometry} from './CapsuleGeometry.js';

Expand All @@ -24,10 +24,8 @@ const localQuaternion = new THREE.Quaternion();
const localQuaternion2 = new THREE.Quaternion();
const localMatrix = new THREE.Matrix4();

const localVelocity = new THREE.Vector3();

const zeroVector = new THREE.Vector3(0, 0, 0);
const upVector = new THREE.Vector3(0, 1, 0);
// const zeroVector = new THREE.Vector3(0, 0, 0);
// const upVector = new THREE.Vector3(0, 1, 0);

const physicsManager = new EventTarget();

Expand All @@ -51,7 +49,6 @@ const _extractPhysicsGeometryForId = physicsId => {

physicsManager.addCapsuleGeometry = (position, quaternion, radius, halfHeight, physicsMaterial, ccdEnabled) => {
const physicsId = getNextPhysicsId();
// console.log('woot', {physics: physx.physics, position, quaternion, radius, halfHeight, physicsMaterial, physicsId, ccdEnabled});
physx.physxWorker.addCapsuleGeometryPhysics(physx.physics, position, quaternion, radius, halfHeight, physicsMaterial, physicsId, ccdEnabled);

const physicsObject = _makePhysicsObject(physicsId, position, quaternion);
Expand All @@ -61,9 +58,6 @@ physicsManager.addCapsuleGeometry = (position, quaternion, radius, halfHeight, p
physicsMesh.visible = false;
physicsObject.add(physicsMesh);
physicsObject.physicsMesh = physicsMesh;
//console.log(physicsId);
//physicsObject.position.add(new THREE.Vector3(0, 3, 0));
//physicsManager.disablePhysicsObject(physicsObject); // Disabled on creation, enabled on if(this.player.avatar) in character-physics.js
return physicsObject;
};

Expand Down
11 changes: 6 additions & 5 deletions player-avatar-binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function applyPlayerModesToAvatar(player, session, rig) {
return null;
})();
for (let i = 0; i < 2; i++) {
rig.setHandEnabled(i, !!session || (i === 0 && !!aimAction && !!aimComponent)/* || (useTime === -1 && !!appManager.equippedObjects[i])*/);
rig.setHandEnabled(i, !!session || (i === 0 && (!!aimAction && !aimAction.playerAnimation) && !!aimComponent)/* || (useTime === -1 && !!appManager.equippedObjects[i])*/);
}
rig.setTopEnabled(
(!!session && (rig.inputs.leftGamepad.enabled || rig.inputs.rightGamepad.enabled))
Expand Down Expand Up @@ -94,19 +94,20 @@ export function applyPlayerActionsToAvatar(player, rig) {
const swordTopDownSlash = player.getAction('swordTopDownSlash');
const swordTopDownSlashAnimation = swordTopDownSlash ? swordTopDownSlash.animation : '';


rig.jumpState = !!jumpAction;
rig.jumpTime = player.actionInterpolants.jump.get();
rig.flyState = !!flyAction;
rig.flyTime = flyAction ? player.actionInterpolants.fly.get() : -1;
rig.activateTime = player.actionInterpolants.activate.get();
rig.useTime = player.actionInterpolants.use.get();
rig.useAnimation = (useAction?.animation) || '';
rig.useAnimationIndex = useAction?.index;
rig.narutoRunState = !!narutoRunAction && !crouchAction;
rig.narutoRunTime = player.actionInterpolants.narutoRun.get();
rig.aimState = !!aimAction;
rig.aimDirection.set(0, 0, -1);
aimAction && rig.aimDirection.applyQuaternion(rig.inputs.hmd.quaternion);
rig.aimTime = player.actionInterpolants.aim.get();
rig.aimAnimation = (aimAction?.playerAnimation) || '';
// rig.aimDirection.set(0, 0, -1);
// aimAction && rig.aimDirection.applyQuaternion(rig.inputs.hmd.quaternion);
rig.sitState = !!sitAction;
rig.sitAnimation = sitAnimation;
rig.danceState = !!danceAction;
Expand Down
Binary file modified public/animations/animations.cbor
Binary file not shown.

0 comments on commit 12a6c4b

Please sign in to comment.