UNPKG

prendy

Version:

Make games with prerendered backdrops using babylonjs and repond

134 lines (118 loc) 5 kB
import { AbstractMesh, AnimationGroup, Bone, InstantiatedEntries, Material, Skeleton } from "@babylonjs/core"; import { forEach } from "chootils/dist/loops"; import { defaultPosition as defaultPosition2d } from "chootils/dist/points2d"; import { Point3D } from "chootils/dist/points3d"; import { mover3dRefs, mover3dState, moverRefs, moverState } from "repond-movers"; import { MyTypes } from "../../declarations"; import get_dollStoreUtils from "./dollStoreUtils"; import { ModelName, AnySpotName, AnimationNameByModel, MeshNameByModel, BoneNameByModel, MaterialNameByModel, DollName, DollOptions, } from "../../types"; const HIDDEN_POSITION = { x: 0, y: 0, z: -1000 }; export default function dolls<T_MyTypes extends MyTypes = MyTypes>(prendyAssets: T_MyTypes["Assets"]) { const { modelNames, dollNames, modelInfoByName, dollOptions } = prendyAssets; const { defaultInRange, makeModelAnimWeightsMoverState, makeToggledMeshesState, modelMoverRefs, modelOtherMeshesRefs, } = get_dollStoreUtils(prendyAssets); const defaultModelName = modelNames[0]; const getDefaultState = <T_DollName extends string, T_ModelName extends ModelName>( _dollName: T_DollName, modelName?: T_ModelName ) => { const safeModelName = modelName ?? defaultModelName; const { animationNames } = modelInfoByName[safeModelName]; return { modelName: safeModelName as NonNullable<T_ModelName>, // to reference in refs aswell // New room goalSpotNameAtNewPlace: null as null | AnySpotName, // when going to new place, start at this spot goalPositionAtNewPlace: null as null | Point3D, // when going to new place, start at this spot // Movers ...mover3dState("position", { value: HIDDEN_POSITION, valueGoal: HIDDEN_POSITION, }), // could have semnticolor icons split by numbers too ...moverState("rotationY"), // nowWalkSpeed: 0, positionOnScreen: defaultPosition2d(), // nowAnimation: animationNames[0] as AnimationNameByModel[T_ModelName], // animation Weights mover ...makeModelAnimWeightsMoverState<T_ModelName>(safeModelName as T_ModelName)("animWeights"), toggledMeshes: makeToggledMeshesState<T_ModelName>(safeModelName as T_ModelName), nowAnimation: animationNames[0] as AnimationNameByModel[T_ModelName], // NOTE AnimationNameFromDoll might work here? animationLoops: true, // currently unused // inRange: defaultInRange(), // isVisible: true, }; }; type DollAssetRefs<T_ModelName extends ModelName> = { meshes: Record<MeshNameByModel[T_ModelName] | "__root__", AbstractMesh>; skeleton: Skeleton; bones: Record<BoneNameByModel[T_ModelName], Bone>; aniGroups: Record<AnimationNameByModel[T_ModelName], AnimationGroup>; materials: Record<MaterialNameByModel[T_ModelName], Material>; }; const getDefaultRefs = <T_DollName extends DollName, T_ModelName extends ModelName>( dollName: T_DollName, itemState: ReturnType<typeof getDefaultState<T_DollName, DollOptions[T_DollName]["model"]>> ) => { const modelName = itemState.modelName; return { // local refs ( maybe replace with just the container hm) meshRef: null as null | AbstractMesh, otherMeshes: modelOtherMeshesRefs(modelName), entriesRef: null as null | InstantiatedEntries, aniGroupsRef: null as null | Record<AnimationNameByModel[T_ModelName], AnimationGroup>, assetRefs: null as null | DollAssetRefs<T_ModelName>, groundRef: null as null | AbstractMesh, canGoThroughWalls: false, ...mover3dRefs("position", { mass: 20, damping: 0.5, friction: 0.5, stiffness: 0.65, }), // maybe also start movers using the main name ...moverRefs("rotationY", { mass: 100, damping: 2, stiffness: 20, friction: 20 }), ...modelMoverRefs(modelName, "animWeights"), }; }; // automatically make atleast a doll for each model // type DollModelStartStates = { // [K_Doll in ModelName]: StateReturnType<K_ModelName, K_ModelName>; // }; // before moving the file into a function it used "ModelName & DollName" // type DollModelStartStates = { // [K_ModelName in ModelName & DollName]: StateReturnType< // K_ModelName, // K_ModelName // >; // }; type DollStartStates = { [K_DollName in DollName]: ReturnType<typeof getDefaultState<K_DollName, DollOptions[K_DollName]["model"]>>; }; function makeAutmaticModelDollStartStates() { const partialDollStates = {} as Partial<DollStartStates>; forEach(dollNames as DollName[], (dollName) => { partialDollStates[dollName] = getDefaultState(dollName, dollOptions[dollName].model); }); return partialDollStates as DollStartStates; } const startStates = { // Automatically make dolls ...makeAutmaticModelDollStartStates(), }; return { startStates, getDefaultState, getDefaultRefs }; }