@myned-ai/gsplat-flame-avatar-renderer 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -21
- package/dist/gsplat-flame-avatar-renderer.cjs.js +12875 -0
- package/dist/{gsplat-flame-avatar-renderer.umd.js.map → gsplat-flame-avatar-renderer.cjs.js.map} +1 -1
- package/dist/gsplat-flame-avatar-renderer.esm.js +1 -1
- package/package.json +5 -3
- package/src/api/index.js +7 -0
- package/src/buffers/SplatBuffer.js +1394 -0
- package/src/buffers/SplatBufferGenerator.js +41 -0
- package/src/buffers/SplatPartitioner.js +110 -0
- package/src/buffers/UncompressedSplatArray.js +106 -0
- package/src/buffers/index.js +11 -0
- package/src/core/SplatGeometry.js +48 -0
- package/src/core/SplatMesh.js +2620 -0
- package/src/core/SplatScene.js +43 -0
- package/src/core/SplatTree.js +200 -0
- package/src/core/Viewer.js +2895 -0
- package/src/core/index.js +13 -0
- package/src/enums/EngineConstants.js +58 -0
- package/src/enums/LogLevel.js +13 -0
- package/src/enums/RenderMode.js +11 -0
- package/src/enums/SceneFormat.js +21 -0
- package/src/enums/SceneRevealMode.js +11 -0
- package/src/enums/SplatRenderMode.js +10 -0
- package/src/enums/index.js +13 -0
- package/src/flame/FlameAnimator.js +271 -0
- package/src/flame/FlameConstants.js +21 -0
- package/src/flame/FlameTextureManager.js +293 -0
- package/src/flame/index.js +22 -0
- package/src/flame/utils.js +50 -0
- package/src/index.js +39 -0
- package/src/loaders/DirectLoadError.js +14 -0
- package/src/loaders/INRIAV1PlyParser.js +223 -0
- package/src/loaders/PlyLoader.js +261 -0
- package/src/loaders/PlyParser.js +19 -0
- package/src/loaders/PlyParserUtils.js +311 -0
- package/src/loaders/index.js +13 -0
- package/src/materials/SplatMaterial.js +1065 -0
- package/src/materials/SplatMaterial2D.js +358 -0
- package/src/materials/SplatMaterial3D.js +278 -0
- package/src/materials/index.js +11 -0
- package/src/raycaster/Hit.js +37 -0
- package/src/raycaster/Ray.js +123 -0
- package/src/raycaster/Raycaster.js +175 -0
- package/src/raycaster/index.js +10 -0
- package/src/renderer/AnimationManager.js +574 -0
- package/src/renderer/AppConstants.js +101 -0
- package/src/renderer/GaussianSplatRenderer.js +695 -0
- package/src/renderer/index.js +24 -0
- package/src/utils/LoaderUtils.js +65 -0
- package/src/utils/Util.js +375 -0
- package/src/utils/index.js +9 -0
- package/src/worker/SortWorker.js +284 -0
- package/src/worker/index.js +8 -0
- package/dist/gsplat-flame-avatar-renderer.esm.min.js +0 -2
- package/dist/gsplat-flame-avatar-renderer.esm.min.js.map +0 -1
- package/dist/gsplat-flame-avatar-renderer.umd.js +0 -12876
- package/dist/gsplat-flame-avatar-renderer.umd.min.js +0 -2
- package/dist/gsplat-flame-avatar-renderer.umd.min.js.map +0 -1
- package/dist/gsplat-flame-avatar.esm.js +0 -12755
- package/dist/gsplat-flame-avatar.esm.js.map +0 -1
- package/dist/gsplat-flame-avatar.esm.min.js +0 -2
- package/dist/gsplat-flame-avatar.esm.min.js.map +0 -1
- package/dist/gsplat-flame-avatar.umd.js +0 -12876
- package/dist/gsplat-flame-avatar.umd.js.map +0 -1
- package/dist/gsplat-flame-avatar.umd.min.js +0 -2
- package/dist/gsplat-flame-avatar.umd.min.js.map +0 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gsplat-flame-avatar - Core Module
|
|
3
|
+
* Core rendering engine components.
|
|
4
|
+
*
|
|
5
|
+
* Based on @mkkellogg/gaussian-splats-3d (MIT License)
|
|
6
|
+
* Extended with FLAME avatar support.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export { SplatGeometry } from './SplatGeometry.js';
|
|
10
|
+
export { SplatMesh } from './SplatMesh.js';
|
|
11
|
+
export { SplatScene } from './SplatScene.js';
|
|
12
|
+
export { SplatTree } from './SplatTree.js';
|
|
13
|
+
export { Viewer } from './Viewer.js';
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EngineConstants
|
|
3
|
+
*
|
|
4
|
+
* Derived from @mkkellogg/gaussian-splats-3d (MIT License)
|
|
5
|
+
* https://github.com/mkkellogg/GaussianSplats3D
|
|
6
|
+
*
|
|
7
|
+
* Core constants for Gaussian Splat rendering.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export class Constants {
|
|
11
|
+
static DefaultSplatSortDistanceMapPrecision = 16;
|
|
12
|
+
static MemoryPageSize = 65536;
|
|
13
|
+
static BytesPerFloat = 4;
|
|
14
|
+
static BytesPerInt = 4;
|
|
15
|
+
static MaxScenes = 32;
|
|
16
|
+
static ProgressiveLoadSectionSize = 262144;
|
|
17
|
+
static ProgressiveLoadSectionDelayDuration = 15;
|
|
18
|
+
static SphericalHarmonics8BitCompressionRange = 3;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const DefaultSphericalHarmonics8BitCompressionRange = Constants.SphericalHarmonics8BitCompressionRange;
|
|
22
|
+
|
|
23
|
+
// SplatMesh constants
|
|
24
|
+
export const COVARIANCES_ELEMENTS_PER_SPLAT = 6;
|
|
25
|
+
export const CENTER_COLORS_ELEMENTS_PER_SPLAT = 4;
|
|
26
|
+
|
|
27
|
+
export const COVARIANCES_ELEMENTS_PER_TEXEL_STORED = 4;
|
|
28
|
+
export const COVARIANCES_ELEMENTS_PER_TEXEL_ALLOCATED = 4;
|
|
29
|
+
export const COVARIANCES_ELEMENTS_PER_TEXEL_COMPRESSED_STORED = 6;
|
|
30
|
+
export const COVARIANCES_ELEMENTS_PER_TEXEL_COMPRESSED_ALLOCATED = 8;
|
|
31
|
+
export const SCALES_ROTATIONS_ELEMENTS_PER_TEXEL = 4;
|
|
32
|
+
export const CENTER_COLORS_ELEMENTS_PER_TEXEL = 4;
|
|
33
|
+
export const SCENE_INDEXES_ELEMENTS_PER_TEXEL = 1;
|
|
34
|
+
|
|
35
|
+
export const SCENE_FADEIN_RATE_FAST = 0.012;
|
|
36
|
+
export const SCENE_FADEIN_RATE_GRADUAL = 0.003;
|
|
37
|
+
|
|
38
|
+
// Viewer constants
|
|
39
|
+
export const THREE_CAMERA_FOV = 50;
|
|
40
|
+
export const MINIMUM_DISTANCE_TO_NEW_FOCAL_POINT = 0.5;
|
|
41
|
+
export const CONSECUTIVE_RENDERED_FRAMES_FOR_FPS_CALCULATION = 60;
|
|
42
|
+
export const MIN_SPLAT_COUNT_TO_SHOW_SPLAT_TREE_LOADING_SPINNER = 1500000;
|
|
43
|
+
export const FOCUS_MARKER_FADE_IN_SPEED = 0.4;
|
|
44
|
+
export const FOCUS_MARKER_FADE_OUT_SPEED = 0.12;
|
|
45
|
+
|
|
46
|
+
// Internal load types for loaders
|
|
47
|
+
export const InternalLoadType = {
|
|
48
|
+
DirectToSplatBuffer: 0,
|
|
49
|
+
DirectToSplatArray: 1,
|
|
50
|
+
DownloadBeforeProcessing: 2
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Loader status
|
|
54
|
+
export const LoaderStatus = {
|
|
55
|
+
'Downloading': 0,
|
|
56
|
+
'Processing': 1,
|
|
57
|
+
'Done': 2
|
|
58
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log level enumeration for controlling verbosity
|
|
3
|
+
*
|
|
4
|
+
* Derived from @mkkellogg/gaussian-splats-3d (MIT License)
|
|
5
|
+
* https://github.com/mkkellogg/GaussianSplats3D
|
|
6
|
+
*/
|
|
7
|
+
export const LogLevel = {
|
|
8
|
+
None: 0,
|
|
9
|
+
Error: 1,
|
|
10
|
+
Warning: 2,
|
|
11
|
+
Info: 3,
|
|
12
|
+
Debug: 4
|
|
13
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene format enumeration for supported file types
|
|
3
|
+
*
|
|
4
|
+
* Derived from @mkkellogg/gaussian-splats-3d (MIT License)
|
|
5
|
+
* https://github.com/mkkellogg/GaussianSplats3D
|
|
6
|
+
*
|
|
7
|
+
* Simplified for FLAME avatar usage - only PLY format is supported.
|
|
8
|
+
*/
|
|
9
|
+
export const SceneFormat = {
|
|
10
|
+
'Ply': 0
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Determine scene format from file path
|
|
15
|
+
* @param {string} path - File path
|
|
16
|
+
* @returns {number|null} Scene format or null if unknown
|
|
17
|
+
*/
|
|
18
|
+
export const sceneFormatFromPath = (path) => {
|
|
19
|
+
if (path.endsWith('.ply')) return SceneFormat.Ply;
|
|
20
|
+
return null;
|
|
21
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gsplat-flame-avatar - Enums Module
|
|
3
|
+
* Constants and enumerations for rendering configuration.
|
|
4
|
+
*
|
|
5
|
+
* Derived from @mkkellogg/gaussian-splats-3d (MIT License)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export * from './LogLevel.js';
|
|
9
|
+
export * from './RenderMode.js';
|
|
10
|
+
export * from './SceneFormat.js';
|
|
11
|
+
export * from './SceneRevealMode.js';
|
|
12
|
+
export * from './SplatRenderMode.js';
|
|
13
|
+
export * from './EngineConstants.js';
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlameAnimator
|
|
3
|
+
*
|
|
4
|
+
* Derived from gaussian-splat-renderer-for-lam
|
|
5
|
+
*
|
|
6
|
+
* Handles FLAME model animation and skeleton updates:
|
|
7
|
+
* - Bone rotation from FLAME parameters
|
|
8
|
+
* - Blendshape weight updates
|
|
9
|
+
* - Skeleton synchronization with gaussian splat mesh
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
Vector3,
|
|
14
|
+
Quaternion,
|
|
15
|
+
Matrix4,
|
|
16
|
+
Bone,
|
|
17
|
+
Skeleton
|
|
18
|
+
} from 'three';
|
|
19
|
+
|
|
20
|
+
import { FlameTextureManager } from './FlameTextureManager.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* FlameAnimator - Manages FLAME parametric head model animation
|
|
24
|
+
*/
|
|
25
|
+
export class FlameAnimator {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.skeleton = null;
|
|
28
|
+
this.bones = null;
|
|
29
|
+
this.flameParams = null;
|
|
30
|
+
this.lbsWeight = null;
|
|
31
|
+
this.frame = 0;
|
|
32
|
+
this.totalFrames = 0;
|
|
33
|
+
this.useFlame = true;
|
|
34
|
+
this.avatarMesh = null;
|
|
35
|
+
this.gaussianSplatCount = 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Initialize with FLAME parameters and LBS weights
|
|
40
|
+
* @param {object} flameParams - FLAME animation parameters
|
|
41
|
+
* @param {object} boneTree - Skeleton hierarchy data
|
|
42
|
+
* @param {Array} lbsWeight - LBS weights for each vertex
|
|
43
|
+
* @param {THREE.SkinnedMesh} avatarMesh - The FLAME avatar mesh
|
|
44
|
+
*/
|
|
45
|
+
initialize(flameParams, boneTree, lbsWeight, avatarMesh) {
|
|
46
|
+
this.flameParams = flameParams;
|
|
47
|
+
this.lbsWeight = lbsWeight;
|
|
48
|
+
this.avatarMesh = avatarMesh;
|
|
49
|
+
|
|
50
|
+
if (flameParams && flameParams.rotation) {
|
|
51
|
+
this.totalFrames = flameParams.rotation.length;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.gaussianSplatCount = avatarMesh.geometry.attributes.position.count;
|
|
55
|
+
|
|
56
|
+
// Build skeleton from bone tree
|
|
57
|
+
this.buildSkeleton(boneTree);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Build skeleton from bone tree data
|
|
62
|
+
* @param {object} boneTree - Skeleton hierarchy definition
|
|
63
|
+
*/
|
|
64
|
+
buildSkeleton(boneTree) {
|
|
65
|
+
if (!boneTree) return;
|
|
66
|
+
|
|
67
|
+
this.bones = [];
|
|
68
|
+
const boneInverses = [];
|
|
69
|
+
|
|
70
|
+
// Create bones from tree structure
|
|
71
|
+
const createBone = (boneData, parentBone = null) => {
|
|
72
|
+
const bone = new Bone();
|
|
73
|
+
bone.name = boneData.name || `bone_${this.bones.length}`;
|
|
74
|
+
|
|
75
|
+
if (boneData.position) {
|
|
76
|
+
bone.position.fromArray(boneData.position);
|
|
77
|
+
}
|
|
78
|
+
if (boneData.rotation) {
|
|
79
|
+
bone.rotation.fromArray(boneData.rotation);
|
|
80
|
+
}
|
|
81
|
+
if (boneData.scale) {
|
|
82
|
+
bone.scale.fromArray(boneData.scale);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (parentBone) {
|
|
86
|
+
parentBone.add(bone);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
this.bones.push(bone);
|
|
90
|
+
|
|
91
|
+
// Create inverse bind matrix
|
|
92
|
+
const inverseMatrix = new Matrix4();
|
|
93
|
+
if (boneData.inverseBindMatrix) {
|
|
94
|
+
inverseMatrix.fromArray(boneData.inverseBindMatrix);
|
|
95
|
+
} else {
|
|
96
|
+
bone.updateMatrixWorld(true);
|
|
97
|
+
inverseMatrix.copy(bone.matrixWorld).invert();
|
|
98
|
+
}
|
|
99
|
+
boneInverses.push(inverseMatrix);
|
|
100
|
+
|
|
101
|
+
// Process children
|
|
102
|
+
if (boneData.children) {
|
|
103
|
+
boneData.children.forEach(child => createBone(child, bone));
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// If boneTree is array, create bones directly
|
|
108
|
+
if (Array.isArray(boneTree)) {
|
|
109
|
+
boneTree.forEach((boneData, index) => {
|
|
110
|
+
const bone = new Bone();
|
|
111
|
+
bone.name = boneData.name || `bone_${index}`;
|
|
112
|
+
|
|
113
|
+
if (boneData.position) {
|
|
114
|
+
bone.position.fromArray(boneData.position);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
this.bones.push(bone);
|
|
118
|
+
|
|
119
|
+
const inverseMatrix = new Matrix4();
|
|
120
|
+
if (boneData.inverseBindMatrix) {
|
|
121
|
+
inverseMatrix.fromArray(boneData.inverseBindMatrix);
|
|
122
|
+
}
|
|
123
|
+
boneInverses.push(inverseMatrix);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Set up hierarchy (FLAME: root -> neck -> jaw, eyes)
|
|
127
|
+
if (this.bones.length >= 5) {
|
|
128
|
+
this.bones[0].add(this.bones[1]); // root -> neck
|
|
129
|
+
this.bones[1].add(this.bones[2]); // neck -> jaw
|
|
130
|
+
this.bones[1].add(this.bones[3]); // neck -> leftEye
|
|
131
|
+
this.bones[1].add(this.bones[4]); // neck -> rightEye
|
|
132
|
+
}
|
|
133
|
+
} else if (boneTree.root) {
|
|
134
|
+
createBone(boneTree.root);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Create skeleton
|
|
138
|
+
this.skeleton = new Skeleton(this.bones, boneInverses);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Set bone rotation from axis-angle or quaternion
|
|
143
|
+
* @param {THREE.Bone} bone - Target bone
|
|
144
|
+
* @param {Array} angles - Rotation values
|
|
145
|
+
* @param {boolean} isQuat - Whether angles are quaternion
|
|
146
|
+
*/
|
|
147
|
+
setBoneRotation(bone, angles, isQuat = false) {
|
|
148
|
+
let quaternion;
|
|
149
|
+
|
|
150
|
+
if (isQuat) {
|
|
151
|
+
quaternion = new Quaternion(angles[0], angles[1], angles[2], angles[3]);
|
|
152
|
+
} else {
|
|
153
|
+
// Axis-angle representation
|
|
154
|
+
const value = new Vector3(angles[0], angles[1], angles[2]);
|
|
155
|
+
const angleInRadians = value.length();
|
|
156
|
+
const axis = value.normalize();
|
|
157
|
+
quaternion = new Quaternion().setFromAxisAngle(axis, angleInRadians);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
bone.quaternion.copy(quaternion);
|
|
161
|
+
bone.updateMatrixWorld(true);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Update FLAME bones from current frame parameters
|
|
166
|
+
*/
|
|
167
|
+
updateFlameBones() {
|
|
168
|
+
if (!this.flameParams || !this.skeleton) return {};
|
|
169
|
+
|
|
170
|
+
const frame = this.frame;
|
|
171
|
+
const bsWeight = this.flameParams['expr'][frame];
|
|
172
|
+
|
|
173
|
+
// Root bone rotation
|
|
174
|
+
const rootAngle = this.flameParams['rotation'][frame];
|
|
175
|
+
this.setBoneRotation(this.skeleton.bones[0], rootAngle);
|
|
176
|
+
|
|
177
|
+
// Neck rotation
|
|
178
|
+
const neckAngle = this.flameParams['neck_pose'][frame];
|
|
179
|
+
this.setBoneRotation(this.skeleton.bones[1], neckAngle);
|
|
180
|
+
|
|
181
|
+
// Jaw rotation
|
|
182
|
+
const jawAngle = this.flameParams['jaw_pose'][frame];
|
|
183
|
+
this.setBoneRotation(this.skeleton.bones[2], jawAngle);
|
|
184
|
+
|
|
185
|
+
// Eyes rotation (combined in eyes_pose array)
|
|
186
|
+
const eyesAngle = this.flameParams['eyes_pose'][frame];
|
|
187
|
+
this.setBoneRotation(this.skeleton.bones[3], eyesAngle);
|
|
188
|
+
this.setBoneRotation(this.skeleton.bones[4], [eyesAngle[3], eyesAngle[4], eyesAngle[5]]);
|
|
189
|
+
|
|
190
|
+
// Update skeleton matrices
|
|
191
|
+
this.skeleton.update();
|
|
192
|
+
|
|
193
|
+
// Get updated bone matrices
|
|
194
|
+
const numBones = 5;
|
|
195
|
+
const bonesMatrix = FlameTextureManager.getUpdatedBoneMatrices(this.skeleton, numBones);
|
|
196
|
+
|
|
197
|
+
return {
|
|
198
|
+
bsWeight,
|
|
199
|
+
bonesMatrix,
|
|
200
|
+
bonesNum: numBones,
|
|
201
|
+
bonesWeight: this.lbsWeight
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Run morph update - main animation loop function
|
|
207
|
+
* @param {SplatMesh} splatMesh - The gaussian splat mesh to update
|
|
208
|
+
*/
|
|
209
|
+
runMorphUpdate(splatMesh) {
|
|
210
|
+
const morphedMesh = new Float32Array(
|
|
211
|
+
this.avatarMesh.geometry.attributes.position.array
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
splatMesh.gaussianSplatCount = this.gaussianSplatCount;
|
|
215
|
+
splatMesh.bonesNum = 5;
|
|
216
|
+
|
|
217
|
+
if (this.useFlame) {
|
|
218
|
+
const updateData = this.updateFlameBones();
|
|
219
|
+
splatMesh.bsWeight = updateData.bsWeight;
|
|
220
|
+
splatMesh.bonesMatrix = updateData.bonesMatrix;
|
|
221
|
+
splatMesh.bonesNum = updateData.bonesNum;
|
|
222
|
+
splatMesh.bonesWeight = updateData.bonesWeight;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
splatMesh.morphedMesh = morphedMesh;
|
|
226
|
+
|
|
227
|
+
// Update textures
|
|
228
|
+
const splatNum = splatMesh.morphedMesh.length / 3;
|
|
229
|
+
if (splatMesh.splatDataTextures && splatMesh.splatDataTextures['flameModel']) {
|
|
230
|
+
splatMesh.updateTextureAfterBSAndSkeleton(0, splatNum - 1, this.useFlame);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Set current animation frame
|
|
236
|
+
* @param {number} frame - Frame number
|
|
237
|
+
*/
|
|
238
|
+
setFrame(frame) {
|
|
239
|
+
this.frame = frame % this.totalFrames;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Advance to next frame
|
|
244
|
+
*/
|
|
245
|
+
nextFrame() {
|
|
246
|
+
this.frame = (this.frame + 1) % this.totalFrames;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Get skeleton for external use
|
|
251
|
+
*/
|
|
252
|
+
getSkeleton() {
|
|
253
|
+
return this.skeleton;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get current frame number
|
|
258
|
+
*/
|
|
259
|
+
getFrame() {
|
|
260
|
+
return this.frame;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Get total frame count
|
|
265
|
+
*/
|
|
266
|
+
getTotalFrames() {
|
|
267
|
+
return this.totalFrames;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export default FlameAnimator;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlameConstants
|
|
3
|
+
*
|
|
4
|
+
* Derived from gaussian-splat-renderer-for-lam
|
|
5
|
+
* FLAME-specific constants for parametric head model.
|
|
6
|
+
*
|
|
7
|
+
* Note: General engine constants (MaxScenes, etc.) are in enums/EngineConstants.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const Constants = {
|
|
11
|
+
// FLAME model constants
|
|
12
|
+
FlameBonesCount: 5, // root, neck, jaw, leftEye, rightEye
|
|
13
|
+
DefaultBlendshapeCount: 52, // ARKit blendshapes
|
|
14
|
+
|
|
15
|
+
// Texture sizes for FLAME data
|
|
16
|
+
FlameModelTextureSize: { width: 4096, height: 2048 },
|
|
17
|
+
BoneTextureSize: { width: 4, height: 32 },
|
|
18
|
+
BoneWeightTextureSize: { width: 512, height: 512 }
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default Constants;
|