Skip to content

Commit

Permalink
Update the local avatar's nametag position with the hip bone position
Browse files Browse the repository at this point in the history
Allows the nametag to move up/down along with animations.

Related to #142.
  • Loading branch information
Gigabyte5671 committed Sep 4, 2023
1 parent 1833ff9 commit e7f313a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
20 changes: 17 additions & 3 deletions src/modules/entity/entities/NametagEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/* eslint-disable @typescript-eslint/no-magic-numbers */
/* eslint-disable new-cap */

import { AbstractMesh,
import { type AbstractMesh,
Color3,
DynamicTexture,
Matrix,
Expand All @@ -25,6 +25,7 @@ import { AbstractMesh,
import { DEFAULT_MESH_RENDER_GROUP_ID } from "@Modules/object";
import { Renderer } from "@Modules/scene";
import { userStore } from "@Stores/index";
import { Hysteresis } from "@Modules/utility/hysteresis";

/**
* Contains all of the memoized nametag meshes within the scene.
Expand Down Expand Up @@ -119,7 +120,7 @@ export class NametagEntity {
*/
public static create(
object: Mesh | AbstractMesh | TransformNode,
height: number,
height: number | (() => number),
name: string,
icon = false,
color?: Color3,
Expand Down Expand Up @@ -310,7 +311,15 @@ export class NametagEntity {

// Position the nametag above the center of the object.
const positionOffset = new Vector3(0, 0.15, 0);
mesh.position = new Vector3(positionOffset.x, height + positionOffset.y, positionOffset.z);
let h = 0;
let heightHysteresis: Nullable<Hysteresis> = null;
if (typeof height === "number") {
h = height + positionOffset.y;
} else {
h = height() + positionOffset.y;
heightHysteresis = new Hysteresis(() => height() + positionOffset.y, 100, positionOffset.y);
}
mesh.position = new Vector3(positionOffset.x, h, positionOffset.z);

const scaleAdjustmentFactorX = object.scaling.x > 0 ? 1 / object.scaling.x : 1;
const scaleAdjustmentFactorY = object.scaling.y > 0 ? 1 / object.scaling.y : 1;
Expand All @@ -331,6 +340,11 @@ export class NametagEntity {
if (!mesh) {
return;
}
// Update the nametag's position.
if (heightHysteresis) {
mesh.position.y = heightHysteresis.get();
}
// Update the nametag's opacity.
const avatar = Renderer.getScene()?.getMyAvatar();
if (avatar) {
const avatarPosition = avatar.getAbsolutePosition().clone();
Expand Down
5 changes: 3 additions & 2 deletions src/modules/scene/vscene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@ export class VScene {
}
const avatarHeight = boundingVectors.max.y - boundingVectors.min.y;

const hipPosition = result.skeleton?.bones.find((bone) => bone.name === "Hips")?.position;
const hipBone = result.skeleton?.bones.find((bone) => bone.name === "Hips");
const hipPosition = hipBone?.position;

// Reload the avatar animations file in case the new avatar is a different size than the previous one.
// The browser cache will prevent this from being fetched over the network if the avatar is switched frequently.
Expand Down Expand Up @@ -380,7 +381,7 @@ export class VScene {
let nametagColor = userStore.account.isAdmin ? Color3.FromHexString(applicationStore.theme.colors.primary) : undefined;
NametagEntity.create(
this._myAvatar,
avatarHeight,
() => (hipBone?.position.y ?? avatarHeight / 2) + avatarHeight / 2,
userStore.avatar.displayName,
false,
nametagColor
Expand Down

0 comments on commit e7f313a

Please sign in to comment.