90 lines
2.5 KiB
TypeScript
90 lines
2.5 KiB
TypeScript
import { AnimationClip, Bone, Object3D, SkinnedMesh } from 'three';
|
|
import { assetManager } from '../assets';
|
|
import { Group } from '../gameobjects/group.object';
|
|
import { MeshPart } from '../gameobjects/mesh.object';
|
|
import { Humanoid } from '../gameobjects/humanoid.object';
|
|
import * as SkeletonUtils from 'three/addons/utils/SkeletonUtils.js';
|
|
|
|
const cachedMeta: {
|
|
faceTexture: string;
|
|
root: Object3D | null;
|
|
clips: AnimationClip[];
|
|
} = {
|
|
faceTexture: '',
|
|
root: null,
|
|
clips: [],
|
|
};
|
|
|
|
export const loadBaseCharacter = async () => {
|
|
if (cachedMeta.root) return cachedMeta;
|
|
|
|
// TODO: temporary loading method
|
|
const loadMesh = await assetManager.loadMeshData(
|
|
'https://lunasqu.ee/freeblox/character-base.glb'
|
|
);
|
|
const loadFace = await assetManager.createAsset(
|
|
'https://lunasqu.ee/freeblox/face-1.png',
|
|
'CharacterFace1',
|
|
'Texture'
|
|
);
|
|
|
|
loadFace.texture!.flipY = false;
|
|
loadFace.texture!.needsUpdate = true;
|
|
cachedMeta.faceTexture = loadFace.path!;
|
|
cachedMeta.root = loadMesh.scene;
|
|
cachedMeta.clips = loadMesh.animations;
|
|
return cachedMeta;
|
|
};
|
|
|
|
export const instanceCharacterObject = async (name: string) => {
|
|
const base = await loadBaseCharacter();
|
|
|
|
const cloned = SkeletonUtils.clone(base.root!);
|
|
|
|
const baseObject = new Group();
|
|
const armature = cloned.getObjectByName('Armature');
|
|
const bone = armature!.getObjectByName('BRoot');
|
|
const bodyParts = [
|
|
armature!.getObjectByName('Head'),
|
|
armature!.getObjectByName('Torso'),
|
|
armature!.getObjectByName('ArmL'),
|
|
armature!.getObjectByName('ArmR'),
|
|
armature!.getObjectByName('LegR'),
|
|
armature!.getObjectByName('LegL'),
|
|
] as SkinnedMesh[];
|
|
|
|
const convertedBodyParts = bodyParts.map(MeshPart.fromLoaded);
|
|
|
|
const [head, torso, armL, armR, legR, legL] = convertedBodyParts;
|
|
|
|
head.name = 'Head';
|
|
torso.name = 'Torso';
|
|
armL.name = 'ArmLeft';
|
|
armR.name = 'ArmRight';
|
|
legR.name = 'LegRight';
|
|
legL.name = 'LegLeft';
|
|
|
|
baseObject.animations = base.clips;
|
|
baseObject.add(bone as Bone);
|
|
baseObject.archivable = false;
|
|
baseObject.name = name;
|
|
|
|
convertedBodyParts.forEach((object) => {
|
|
baseObject.add(object);
|
|
object.archivable = false;
|
|
});
|
|
|
|
head.texture = base.faceTexture;
|
|
|
|
const controller = new Humanoid();
|
|
controller.position.set(0, 4.75, 0);
|
|
controller.archivable = false;
|
|
baseObject.add(controller);
|
|
|
|
return baseObject;
|
|
};
|
|
|
|
export const getCharacterController = (object: Object3D) => {
|
|
return object.getObjectByName('Humanoid') as Humanoid;
|
|
};
|