mirror of
https://github.com/modrinth/code.git
synced 2026-08-27 01:54:47 +00:00
feat: add Ears mod support to skin selector (#6775)
* feat: add Ears mod support to skin selector * fix: lint * feat: ears mod notice + toggle + fix uv issues * fix: lint
This commit is contained in:
@@ -16,6 +16,7 @@ export * from './server-backups-queue'
|
||||
export * from './server-console'
|
||||
export * from './server-manage-core-runtime'
|
||||
export * from './server-permissions'
|
||||
export { applyEarsMod, removeEarsMod } from './skin-rendering/use-ears-mod-features'
|
||||
export * from './sticky-observer'
|
||||
export * from './terminal'
|
||||
export * from './use-loading-bar-token'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ import {
|
||||
} from '#ui/utils/webgl/skin-rendering.ts'
|
||||
|
||||
import type { SkinPreviewTuple } from './types'
|
||||
import { applyEarsMod, removeEarsMod } from './use-ears-mod-features'
|
||||
|
||||
const SKIN_LAYER_DEPTH_BIAS = -1
|
||||
|
||||
@@ -109,13 +110,17 @@ type MaybeReadonlyRef<T> = Ref<T> | ComputedRef<T>
|
||||
export function useSkinPreviewScene({
|
||||
selectedModelSrc,
|
||||
textureSrc,
|
||||
earsTextureSrc,
|
||||
capeSrc,
|
||||
earsEnabled,
|
||||
initializeAnimations,
|
||||
cleanupAnimationState,
|
||||
}: {
|
||||
selectedModelSrc: MaybeReadonlyRef<string>
|
||||
textureSrc: MaybeReadonlyRef<string>
|
||||
earsTextureSrc: MaybeReadonlyRef<string | undefined>
|
||||
capeSrc: MaybeReadonlyRef<string | undefined>
|
||||
earsEnabled: MaybeReadonlyRef<boolean>
|
||||
initializeAnimations: (loadedScene: THREE.Object3D, clips: THREE.AnimationClip[]) => void
|
||||
cleanupAnimationState: (root: THREE.Object3D | null) => void
|
||||
}) {
|
||||
@@ -123,16 +128,20 @@ export function useSkinPreviewScene({
|
||||
const lastCapeSrc = ref<string | undefined>(undefined)
|
||||
const loadedModelSrc = ref<string | undefined>(undefined)
|
||||
const loadedTextureSrc = ref<string | undefined>(undefined)
|
||||
const loadedEarsTextureSrc = ref<string | undefined>(undefined)
|
||||
const loadedCapeSrc = ref<string | undefined>(undefined)
|
||||
const texture = shallowRef<THREE.Texture | null>(null)
|
||||
const earsTexture = shallowRef<THREE.Texture | null>(null)
|
||||
const capeTexture = shallowRef<THREE.Texture | null>(null)
|
||||
const transparentTexture = createTransparentTexture()
|
||||
const modelCenter = ref<SkinPreviewTuple>([0, 1, 0])
|
||||
const modelSize = ref<SkinPreviewTuple>([1, 2, 1])
|
||||
const isModelLoaded = ref(false)
|
||||
const isTextureLoaded = ref(false)
|
||||
const hasEarsFeatures = ref(false)
|
||||
let modelLoadVersion = 0
|
||||
let textureLoadVersion = 0
|
||||
let earsTextureLoadVersion = 0
|
||||
let capeLoadVersion = 0
|
||||
let isUnmounted = false
|
||||
|
||||
@@ -147,6 +156,18 @@ export function useSkinPreviewScene({
|
||||
}
|
||||
|
||||
applyTexture(scene.value, texture.value)
|
||||
const featureTextureSrc = earsTextureSrc.value
|
||||
const featureTexture = featureTextureSrc ? earsTexture.value : texture.value
|
||||
if (
|
||||
!featureTexture ||
|
||||
(featureTextureSrc && loadedEarsTextureSrc.value !== featureTextureSrc)
|
||||
) {
|
||||
removeEarsMod(scene.value)
|
||||
hasEarsFeatures.value = false
|
||||
return
|
||||
}
|
||||
|
||||
hasEarsFeatures.value = applyEarsMod(scene.value, featureTexture, earsEnabled.value)
|
||||
}
|
||||
|
||||
function applyCapeTextureToLoadedModel() {
|
||||
@@ -173,6 +194,7 @@ export function useSkinPreviewScene({
|
||||
|
||||
const previousScene = scene.value
|
||||
cleanupAnimationState(previousScene)
|
||||
removeEarsMod(previousScene)
|
||||
disposeSceneMaterials(previousScene)
|
||||
scene.value = clonedScene
|
||||
loadedModelSrc.value = src
|
||||
@@ -232,6 +254,19 @@ export function useSkinPreviewScene({
|
||||
applyCapeTextureToLoadedModel()
|
||||
}
|
||||
|
||||
async function loadAndApplyEarsTexture(src: string | undefined) {
|
||||
const loadVersion = ++earsTextureLoadVersion
|
||||
hasEarsFeatures.value = false
|
||||
|
||||
const loadedEarsTexture = src ? await loadAndApplyTexture(src) : null
|
||||
if (isUnmounted || loadVersion !== earsTextureLoadVersion) return
|
||||
|
||||
earsTexture.value = loadedEarsTexture
|
||||
loadedEarsTextureSrc.value = src
|
||||
applyTextureToLoadedModel()
|
||||
updateModelInfo()
|
||||
}
|
||||
|
||||
function updateModelInfo() {
|
||||
const box = scene.value ? getVisibleMeshBox(scene.value) : null
|
||||
|
||||
@@ -261,6 +296,7 @@ export function useSkinPreviewScene({
|
||||
const loadVersion = ++textureLoadVersion
|
||||
|
||||
isTextureLoaded.value = false
|
||||
hasEarsFeatures.value = false
|
||||
const loadedTexture = await loadAndApplyTexture(newSrc)
|
||||
if (isUnmounted || loadVersion !== textureLoadVersion) return
|
||||
|
||||
@@ -270,6 +306,19 @@ export function useSkinPreviewScene({
|
||||
isTextureLoaded.value = true
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => earsTextureSrc.value,
|
||||
async (newEarsTextureSrc) => {
|
||||
await loadAndApplyEarsTexture(newEarsTextureSrc)
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => earsEnabled.value,
|
||||
() => {
|
||||
applyTextureToLoadedModel()
|
||||
updateModelInfo()
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => capeSrc.value,
|
||||
async (newCapeSrc) => {
|
||||
@@ -284,6 +333,7 @@ export function useSkinPreviewScene({
|
||||
loadedTextureSrc.value = textureSrc.value
|
||||
isTextureLoaded.value = true
|
||||
|
||||
await loadAndApplyEarsTexture(earsTextureSrc.value)
|
||||
await loadModel(selectedModelSrc.value)
|
||||
|
||||
if (capeSrc.value) {
|
||||
@@ -298,15 +348,18 @@ export function useSkinPreviewScene({
|
||||
isUnmounted = true
|
||||
modelLoadVersion++
|
||||
textureLoadVersion++
|
||||
earsTextureLoadVersion++
|
||||
capeLoadVersion++
|
||||
|
||||
cleanupAnimationState(scene.value)
|
||||
removeEarsMod(scene.value)
|
||||
disposeSceneMaterials(scene.value)
|
||||
scene.value = null
|
||||
transparentTexture.dispose()
|
||||
})
|
||||
|
||||
return {
|
||||
hasEarsFeatures,
|
||||
isModelLoaded,
|
||||
isTextureLoaded,
|
||||
modelCenter,
|
||||
|
||||
Reference in New Issue
Block a user