Skip to content

Instantly share code, notes, and snippets.

@skang2-sc
Created February 28, 2025 05:46
Show Gist options
  • Save skang2-sc/ba16032bca41d092c3317478c3f4a2d1 to your computer and use it in GitHub Desktop.
Save skang2-sc/ba16032bca41d092c3317478c3f4a2d1 to your computer and use it in GitHub Desktop.
Adds a OneEuro Filter to Head Tracking
import {
OneEuroFilterQuat,
OneEuroFilterVec3,
} from "./SpectaclesInteractionKit/Utils/OneEuroFilter";
const FILTER_CONFIG = {
frequency: 60,
minCutoff: 2,
beta: 0.015,
dcutoff: 1,
};
@component
export class HeadTrackingSmoothing extends BaseScriptComponent {
@input
head: Head;
private transform: Transform;
private headTransform: Transform;
private translateFilter: OneEuroFilterVec3;
private rotationFilter: OneEuroFilterQuat;
private isFaceTracking: boolean = false;
onAwake() {
this.transform = this.sceneObject.getTransform();
this.headTransform = this.head.getTransform();
this.translateFilter = new OneEuroFilterVec3(FILTER_CONFIG);
this.rotationFilter = new OneEuroFilterQuat(FILTER_CONFIG);
this.createEvent("UpdateEvent").bind(() => {
if (!this.isFaceTracking) {
return;
}
this.transform.setWorldPosition(
this.translateFilter.filter(
this.headTransform.getWorldPosition(),
getTime()
)
);
this.transform.setWorldRotation(
this.rotationFilter.filter(
this.headTransform.getWorldRotation(),
getTime()
)
);
});
this.createEvent("FaceFoundEvent").bind(() => {
this.translateFilter.reset();
this.rotationFilter.reset();
this.isFaceTracking = true;
});
this.createEvent("FaceLostEvent").bind(() => {
this.isFaceTracking = false;
});
}
}
@skang2-sc
Copy link
Author

Head Binding Component Configuration:
image

@skang2-sc
Copy link
Author

Head Mesh Configuration:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment