From e00ffb754a9b9f4062b65521f472cbe4d34f59d8 Mon Sep 17 00:00:00 2001 From: tr7zw Date: Fri, 22 Dec 2023 19:06:01 +0100 Subject: [PATCH] Init multibuild --- .github/workflows/build.yml | 10 +- .github/workflows/tag.yml | 27 +- .gitignore | 7 +- .../dev/tr7zw/skinlayers/SkinLayersMod.java | 12 - .../src/main/resources/fabric.mod.json | 37 - .../test/java/dev/tr7zw/tests/MixinTests.java | 107 --- .../test/java/dev/tr7zw/tests/TestUtil.java | 142 ---- .../dev/tr7zw/skinlayers/SkinLayersMod.java | 39 - .../src/main/resources/META-INF/mods.toml | 24 - .../src/main/resources/pack.mcmeta | 6 - .../tr7zw/skinlayers/versionless/ModBase.java | 56 ++ .../versionless/config}/Config.java | 2 +- .../versionless/render/CustomModelPart.java | 78 ++ .../versionless}/render/CustomizableCube.java | 62 +- .../versionless/util/Direction.java | 79 ++ .../skinlayers/versionless/util/Mth.java | 680 ++++++++++++++++++ .../skinlayers/versionless/util/Vector3.java | 89 +++ .../util/wrapper/ModelBuilder.java | 17 + .../util/wrapper/SolidPixelWrapper.java | 259 +++++++ .../versionless/util/wrapper/TextureData.java | 11 + .../java/dev/tr7zw/skinlayers/api/Mesh.java | 30 - .../skinlayers/render/SolidPixelWrapper.java | 189 ----- .../HeadLayerFeatureRenderer.java | 94 --- .../main/resources/3dskinlayers.mixins.json | 23 - .../assets/3dskinlayers/lang/sv_se.json | 37 - .../assets/3dskinlayers/lang/zh_cn.json | 37 - curseforge.md | 8 +- gradle-compose.yml | 24 +- modrinth.md | 2 +- settings.json | 24 + .../dev/tr7zw/skinlayers/SkinLayersMod.java | 124 ++++ .../tr7zw/skinlayers/SkinLayersModBase.java | 27 + .../tr7zw/skinlayers/SkinLayersModMenu.java | 6 +- .../java/dev/tr7zw/skinlayers/SkinUtil.java | 59 +- .../tr7zw/skinlayers/SkullRendererCache.java | 2 +- .../accessor/HttpTextureAccessor.java | 0 .../accessor/PlayerEntityModelAccessor.java | 0 .../skinlayers/accessor/PlayerSettings.java | 0 .../accessor/SkullModelAccessor.java | 0 .../skinlayers/accessor/SkullSettings.java | 4 +- .../api/LayerFeatureTransformerAPI.java | 0 .../java/dev/tr7zw/skinlayers/api/Mesh.java | 79 ++ .../dev/tr7zw/skinlayers/api/MeshHelper.java | 0 .../tr7zw/skinlayers/api/MeshProvider.java | 0 .../tr7zw/skinlayers/api/MeshTransformer.java | 7 + .../api/MeshTransformerProvider.java | 0 .../dev/tr7zw/skinlayers/api/PlayerData.java | 0 .../tr7zw/skinlayers/api/SkinLayersAPI.java | 19 +- .../dev/tr7zw/skinlayers/api/SkullData.java | 0 .../config/ConfigScreenProvider.java | 129 ++-- .../BlockEntityWithoutLevelRendererMixin.java | 25 +- .../mixin/CustomHeadLayerMixin.java | 0 .../skinlayers/mixin/HttpTextureMixin.java | 0 .../tr7zw/skinlayers/mixin/PlayerMixin.java | 0 .../skinlayers/mixin/PlayerModelMixin.java | 8 + .../skinlayers/mixin/PlayerRendererMixin.java | 28 +- .../mixin/SkullBlockEntityMixin.java | 0 .../mixin/SkullBlockEntityRendererMixin.java | 57 +- .../skinlayers/mixin/SkullModelMixin.java | 21 + .../render/CustomizableCubeListBuilder.java | 38 +- .../render/CustomizableModelPart.java | 149 ++-- .../skinlayers/render/PreviewHelper.java | 2 + .../CustomLayerFeatureRenderer.java | 98 ++- .../dev/tr7zw/skinlayers/util/NMSWrapper.java | 74 ++ .../assets/skinlayers3d}/lang/cs_cz.json | 1 - .../assets/skinlayers3d}/lang/de_de.json | 3 +- .../assets/skinlayers3d}/lang/en_us.json | 3 +- .../assets/skinlayers3d}/lang/es_es.json | 1 - .../assets/skinlayers3d}/lang/it_it.json | 3 +- .../assets/skinlayers3d}/lang/ko_kr.json | 1 - .../assets/skinlayers3d}/lang/pt_br.json | 3 +- .../assets/skinlayers3d}/lang/pt_pt.json | 3 +- .../assets/skinlayers3d}/lang/ru_ru.json | 2 - .../assets/skinlayers3d/lang/sv_se.json | 36 + .../assets/skinlayers3d}/lang/tr_tr.json | 5 +- .../assets/skinlayers3d}/lang/uk_ua.json | 3 +- .../assets/skinlayers3d/lang/zh_cn.json | 19 + .../assets/skinlayers3d}/lang/zh_tw.json | 73 +- .../main/resources}/icon.png | Bin src/main/resources/pack.mcmeta | 6 + src/main/resources/skinlayers3d.mixins.json | 22 + .../main/resources/skinlayers3d.accesswidener | 5 + .../resources/META-INF/accesstransformer.cfg | 4 + .../main/resources/skinlayers3d.accesswidener | 5 + versions/mainProject | 1 + 85 files changed, 2204 insertions(+), 1163 deletions(-) delete mode 100644 3dSkinLayers-Fabric/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java delete mode 100644 3dSkinLayers-Fabric/src/main/resources/fabric.mod.json delete mode 100644 3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/MixinTests.java delete mode 100644 3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/TestUtil.java delete mode 100644 3dSkinLayers-Forge/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java delete mode 100644 3dSkinLayers-Forge/src/main/resources/META-INF/mods.toml delete mode 100644 3dSkinLayers-Forge/src/main/resources/pack.mcmeta create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/ModBase.java rename {Shared/src/main/java/dev/tr7zw/skinlayers => 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/config}/Config.java (93%) create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/render/CustomModelPart.java rename {Shared/src/main/java/dev/tr7zw/skinlayers => 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless}/render/CustomizableCube.java (77%) create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Direction.java create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Mth.java create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Vector3.java create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/ModelBuilder.java create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/SolidPixelWrapper.java create mode 100644 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/TextureData.java delete mode 100644 Shared/src/main/java/dev/tr7zw/skinlayers/api/Mesh.java delete mode 100644 Shared/src/main/java/dev/tr7zw/skinlayers/render/SolidPixelWrapper.java delete mode 100644 Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/HeadLayerFeatureRenderer.java delete mode 100644 Shared/src/main/resources/3dskinlayers.mixins.json delete mode 100644 Shared/src/main/resources/assets/3dskinlayers/lang/sv_se.json delete mode 100644 Shared/src/main/resources/assets/3dskinlayers/lang/zh_cn.json create mode 100644 settings.json create mode 100644 src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java create mode 100644 src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java rename {3dSkinLayers-Fabric/src => src}/main/java/dev/tr7zw/skinlayers/SkinLayersModMenu.java (68%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/SkinUtil.java (74%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/SkullRendererCache.java (99%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/accessor/HttpTextureAccessor.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/accessor/PlayerEntityModelAccessor.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/accessor/PlayerSettings.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/accessor/SkullModelAccessor.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/accessor/SkullSettings.java (98%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/LayerFeatureTransformerAPI.java (100%) create mode 100644 src/main/java/dev/tr7zw/skinlayers/api/Mesh.java rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/MeshHelper.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/MeshProvider.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/MeshTransformer.java (83%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/MeshTransformerProvider.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/PlayerData.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/SkinLayersAPI.java (66%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/api/SkullData.java (100%) rename Shared/src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java => src/main/java/dev/tr7zw/skinlayers/config/ConfigScreenProvider.java (60%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/BlockEntityWithoutLevelRendererMixin.java (88%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/CustomHeadLayerMixin.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/HttpTextureMixin.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/PlayerMixin.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/PlayerModelMixin.java (83%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/PlayerRendererMixin.java (87%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityMixin.java (100%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityRendererMixin.java (69%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/mixin/SkullModelMixin.java (61%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/render/CustomizableCubeListBuilder.java (53%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/render/CustomizableModelPart.java (64%) rename {Shared/src => src}/main/java/dev/tr7zw/skinlayers/render/PreviewHelper.java (99%) rename Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/BodyLayerFeatureRenderer.java => src/main/java/dev/tr7zw/skinlayers/renderlayers/CustomLayerFeatureRenderer.java (70%) create mode 100644 src/main/java/dev/tr7zw/skinlayers/util/NMSWrapper.java rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/cs_cz.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/de_de.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/en_us.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/es_es.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/it_it.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/ko_kr.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/pt_br.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/pt_pt.json (99%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/ru_ru.json (99%) create mode 100644 src/main/resources/assets/skinlayers3d/lang/sv_se.json rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/tr_tr.json (94%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/uk_ua.json (99%) create mode 100644 src/main/resources/assets/skinlayers3d/lang/zh_cn.json rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources/assets/skinlayers3d}/lang/zh_tw.json (98%) rename {Shared/src/main/resources/assets/3dskinlayers => src/main/resources}/icon.png (100%) create mode 100644 src/main/resources/pack.mcmeta create mode 100644 src/main/resources/skinlayers3d.mixins.json create mode 100644 versions/1.16.5-fabric/src/main/resources/skinlayers3d.accesswidener create mode 100644 versions/1.16.5-forge/src/main/resources/META-INF/accesstransformer.cfg create mode 100644 versions/1.16.5-forge/src/main/resources/skinlayers3d.accesswidener create mode 100644 versions/mainProject diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ae4daee..77504b2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,6 +14,12 @@ jobs: uses: actions/setup-java@v1 with: java-version: 17 + # to cache gradle files + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + with: + cache-read-only: false + gradle-home-cache-cleanup: true - name: make gradle wrapper executable if: ${{ runner.os != 'Windows' }} run: chmod +x ./gradlecw @@ -23,9 +29,7 @@ jobs: uses: actions/upload-artifact@v2 with: name: Artifacts - path: | - 3dSkinLayers-Fabric/build/libs/* - 3dSkinLayers-Forge/build/libs/* + path: '**/build/libs/*.jar' - name: Test Report uses: dorny/test-reporter@v1 if: success() || failure() diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml index 96e3757..d3e888b 100644 --- a/.github/workflows/tag.yml +++ b/.github/workflows/tag.yml @@ -15,13 +15,31 @@ jobs: - name: make gradle wrapper executable run: chmod +x ./gradlecw - name: build - run: ./gradlecw build + run: ./gradlecw build -Pbuild.release=true - name: Release uses: softprops/action-gh-release@v1 with: files: | - 3dSkinLayers-Fabric/build/libs/* - 3dSkinLayers-Forge/build/libs/* + 3dSkinLayers-Versionless/build/libs/* + - name: Publish-Neo-Curseforge + uses: Kir-Antipov/mc-publish@v3.2 + with: + curseforge-id: 521480 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + loaders: neoforge + name: ${{github.ref_name}} - NeoForge + version-type: beta + files: '*Neo/build/libs/!(*-@(dev|sources|javadoc|all)).jar' + game-versions: $targetVersions$ + - name: Publish-Neo-Modrinth + uses: Kir-Antipov/mc-publish@v3.2 + with: + modrinth-id: zV5r3pPn + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + loaders: neoforge + name: ${{github.ref_name}} - NeoForge + files: '*Neo/build/libs/!(*-@(dev|sources|javadoc|all)).jar' + game-versions: $targetVersions$ - name: Publish-Forge-Curseforge uses: Kir-Antipov/mc-publish@v3.2 with: @@ -31,6 +49,7 @@ jobs: name: ${{github.ref_name}} - Forge version-type: beta files: '*Forge/build/libs/!(*-@(dev|sources|javadoc|all)).jar' + game-versions: $targetVersions$ - name: Publish-Forge-Modrinth uses: Kir-Antipov/mc-publish@v3.2 with: @@ -39,6 +58,7 @@ jobs: loaders: forge name: ${{github.ref_name}} - Forge files: '*Forge/build/libs/!(*-@(dev|sources|javadoc|all)).jar' + game-versions: $targetVersions$ - name: Publish-Fabric uses: Kir-Antipov/mc-publish@v3.2 with: @@ -49,3 +69,4 @@ jobs: loaders: fabric name: ${{github.ref_name}} - Fabric files: '*Fabric/build/libs/!(*-@(dev|sources|javadoc|all)).jar' + game-versions: $targetVersions$ diff --git a/.gitignore b/.gitignore index 111aff0..fc4436f 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,9 @@ logs/ gradle/wrapper VersionShared UtilityCode -logs/ \ No newline at end of file +formatter.xml +src/main/fabric-resources/fabric.mod.json +src/main/forge-resources/META-INF/mods.toml +src/main/neoforge-resources/META-INF/mods.toml +**/src/main/java/dev/tr7zw/config/CustomConfigScreen.java +**/src/main/java/dev/tr7zw/util/ComponentProvider.java \ No newline at end of file diff --git a/3dSkinLayers-Fabric/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java b/3dSkinLayers-Fabric/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java deleted file mode 100644 index ad9acfa..0000000 --- a/3dSkinLayers-Fabric/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.tr7zw.skinlayers; - -import net.fabricmc.api.ClientModInitializer; - -public class SkinLayersMod extends SkinLayersModBase implements ClientModInitializer { - - @Override - public void onInitializeClient() { - this.onInitialize(); - } - -} diff --git a/3dSkinLayers-Fabric/src/main/resources/fabric.mod.json b/3dSkinLayers-Fabric/src/main/resources/fabric.mod.json deleted file mode 100644 index 92f5572..0000000 --- a/3dSkinLayers-Fabric/src/main/resources/fabric.mod.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "schemaVersion": 1, - "id": "skinlayers", - "version": "${version}", - - "name": "3d Skin Layers", - "description": "Renders the player skin layer in 3d", - "authors": [ - "tr7zw" - ], - "contact": { - "homepage": "https://github.com/tr7zw", - "sources": "https://github.com/tr7zw/3d-skin-layers" - }, - - "license": "tr7zw Protective License", - "icon": "assets/3dskinlayers/icon.png", - - "environment": "client", - "entrypoints": { - "client": [ - "dev.tr7zw.skinlayers.SkinLayersMod" - ], - "modmenu": [ - "dev.tr7zw.skinlayers.SkinLayersModMenu" - ] - }, - "mixins": [ - "3dskinlayers.mixins.json" - ], - "depends": { - "minecraft": ">=1.20.2" - }, - "breaks": { - "tlskincape": "*" - } -} diff --git a/3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/MixinTests.java b/3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/MixinTests.java deleted file mode 100644 index d5f89e8..0000000 --- a/3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/MixinTests.java +++ /dev/null @@ -1,107 +0,0 @@ -package dev.tr7zw.tests; - -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.lang.reflect.Field; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.objenesis.Objenesis; -import org.objenesis.ObjenesisStd; - -import dev.tr7zw.config.CustomConfigScreen; -import dev.tr7zw.skinlayers.Config; -import dev.tr7zw.skinlayers.SkinLayersMod; -import dev.tr7zw.skinlayers.SkinLayersModBase; -import dev.tr7zw.skinlayers.accessor.PlayerEntityModelAccessor; -import dev.tr7zw.skinlayers.accessor.PlayerSettings; -import dev.tr7zw.skinlayers.accessor.SkullModelAccessor; -import dev.tr7zw.skinlayers.renderlayers.BodyLayerFeatureRenderer; -import dev.tr7zw.skinlayers.renderlayers.HeadLayerFeatureRenderer; -import net.minecraft.SharedConstants; -import net.minecraft.client.OptionInstance; -import net.minecraft.client.model.PlayerModel; -import net.minecraft.client.model.SkullModel; -import net.minecraft.client.player.RemotePlayer; -import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; -import net.minecraft.client.renderer.blockentity.SkullBlockRenderer; -import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.client.renderer.entity.layers.CustomHeadLayer; -import net.minecraft.client.renderer.entity.layers.RenderLayer; -import net.minecraft.client.renderer.entity.player.PlayerRenderer; -import net.minecraft.locale.Language; -import net.minecraft.server.Bootstrap; -import net.minecraft.world.level.block.entity.SkullBlockEntity; - -public class MixinTests { - - @BeforeAll - public static void setup() { - SharedConstants.tryDetectVersion(); - Bootstrap.bootStrap(); - } - - @Test - public void testInjectedInterfaces() { - Objenesis objenesis = new ObjenesisStd(); - assertTrue(objenesis.newInstance(RemotePlayer.class) instanceof PlayerSettings); - assertTrue(objenesis.newInstance(PlayerModel.class) instanceof PlayerEntityModelAccessor); - assertTrue(objenesis.newInstance(SkullModel.class) instanceof SkullModelAccessor); - } - - @Test - public void testMixins() { - Objenesis objenesis = new ObjenesisStd(); - objenesis.newInstance(PlayerRenderer.class); - objenesis.newInstance(BlockEntityWithoutLevelRenderer.class); - objenesis.newInstance(CustomHeadLayer.class); - objenesis.newInstance(RemotePlayer.class); - objenesis.newInstance(PlayerModel.class); - objenesis.newInstance(PlayerRenderer.class); - objenesis.newInstance(SkullBlockEntity.class); - objenesis.newInstance(SkullBlockRenderer.class); - objenesis.newInstance(SkullModel.class); - } - -// @Test -// public void checkInjectedPlayerLayers() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { -// PlayerRenderer renderer = TestUtil.getPlayerRenderer(); -// Field field = LivingEntityRenderer.class.getDeclaredField("layers"); -// field.setAccessible(true); -// List> layers = (List>) field.get(renderer); -// System.out.println(layers); -// boolean foundBodyLayer = false; -// boolean foundHeadLayer = false; -// for(RenderLayer layer : layers) { -// if(layer instanceof BodyLayerFeatureRenderer) { -// foundBodyLayer = true; -// } else if(layer instanceof HeadLayerFeatureRenderer) { -// foundHeadLayer = true; -// } -// } -// assertTrue(foundBodyLayer); -// assertTrue(foundHeadLayer); -// } - - @Test - public void langTests() throws Throwable { -// Language.getInstance().loadFromJson(new FileInputStream("../3d-Skin-Layers/Shared/src/main/resources/assets/3dskinlayers/lang/en_us.json"), null); - Language lang = TestUtil.loadDefault("/assets/3dskinlayers/lang/en_us.json"); - SkinLayersModBase.instance = new ObjenesisStd().newInstance(SkinLayersMod.class); - SkinLayersModBase.config = new Config(); - CustomConfigScreen screen = (CustomConfigScreen) SkinLayersModBase.instance.createConfigScreen(null); - List> options = TestUtil.bootStrapCustomConfigScreen(screen); - assertNotEquals(screen.getTitle().getString(), lang.getOrDefault(screen.getTitle().getString())); - for(OptionInstance option : options) { - Set keys = TestUtil.getKeys(option, false); - for(String key : keys) { - System.out.println(key + " " + lang.getOrDefault(key)); - assertNotEquals(key, lang.getOrDefault(key)); - } - } - } - -} \ No newline at end of file diff --git a/3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/TestUtil.java b/3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/TestUtil.java deleted file mode 100644 index 82547ed..0000000 --- a/3dSkinLayers-Fabric/src/test/java/dev/tr7zw/tests/TestUtil.java +++ /dev/null @@ -1,142 +0,0 @@ -package dev.tr7zw.tests; - -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.function.BiConsumer; - -import com.google.common.collect.ImmutableMap; - -import dev.tr7zw.config.CustomConfigScreen; -import net.minecraft.client.OptionInstance; -import net.minecraft.client.gui.components.OptionsList; -import net.minecraft.client.model.PlayerModel; -import net.minecraft.client.model.geom.EntityModelSet; -import net.minecraft.client.model.geom.ModelLayerLocation; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.model.geom.PartPose; -import net.minecraft.client.model.geom.builders.CubeDeformation; -import net.minecraft.client.model.geom.builders.CubeListBuilder; -import net.minecraft.client.model.geom.builders.PartDefinition; -import net.minecraft.client.renderer.entity.EntityRendererProvider; -import net.minecraft.client.renderer.entity.EntityRendererProvider.Context; -import net.minecraft.client.renderer.entity.player.PlayerRenderer; -import net.minecraft.locale.Language; -import net.minecraft.network.chat.FormattedText; -import net.minecraft.util.FormattedCharSequence; - -public class TestUtil { - - public static PlayerRenderer getPlayerRenderer() { - EntityRendererProvider.Context context = new Context(null, null, null, null, null, new DummyModelSet(), null); - return new PlayerRenderer(context, false); - } - - private static class DummyModelSet extends EntityModelSet { - - @Override - public ModelPart bakeLayer(ModelLayerLocation modelLayerLocation) { - PartDefinition part = PlayerModel.createMesh(CubeDeformation.NONE, false).getRoot(); - part.getChild("head").addOrReplaceChild("jaw", CubeListBuilder.create(), PartPose.ZERO); - part.getChild("head").addOrReplaceChild("left_ear", CubeListBuilder.create(), PartPose.ZERO); - part.getChild("head").addOrReplaceChild("right_ear", CubeListBuilder.create(), PartPose.ZERO); - part.addOrReplaceChild("left_wing", CubeListBuilder.create(), PartPose.ZERO); - part.addOrReplaceChild("right_wing", CubeListBuilder.create(), PartPose.ZERO); - part.addOrReplaceChild("tail", CubeListBuilder.create(), PartPose.ZERO); - part.getChild("head").addOrReplaceChild("feather", CubeListBuilder.create(), PartPose.ZERO); - part.addOrReplaceChild("box", CubeListBuilder.create(), PartPose.ZERO); - return part.bake(0, 0); - } - - } - - public static Language loadDefault(String file) throws Throwable { - ImmutableMap.Builder builder = ImmutableMap.builder(); - Objects.requireNonNull(builder); - BiConsumer biConsumer = builder::put; - InputStream inputStream = Language.class.getResourceAsStream(file); - try { - Language.loadFromJson(inputStream, biConsumer); - if (inputStream != null) - inputStream.close(); - } catch (Throwable throwable) { - if (inputStream != null) - try { - inputStream.close(); - } catch (Throwable throwable1) { - throwable.addSuppressed(throwable1); - } - throw throwable; - } - final ImmutableMap storage = builder.build(); - return new Language() { - public String getOrDefault(String string) { - return (String) storage.getOrDefault(string, string); - } - - public boolean has(String string) { - return storage.containsKey(string); - } - - public boolean isDefaultRightToLeft() { - return false; - } - - public FormattedCharSequence getVisualOrder(FormattedText formattedText) { - return null; - } - - @Override - public String getOrDefault(String paramString1, String paramString2) { - return (String) storage.getOrDefault(paramString1, paramString2); - } - }; - } - - public static Set getKeys(OptionInstance optionsInstance, boolean tooltips) { - Set keys = new HashSet<>(); - keys.add(optionsInstance.toString()); - if(tooltips) { - keys.add(optionsInstance.toString() + ".tooltip"); - } - return keys; - } - - public static List> bootStrapCustomConfigScreen(CustomConfigScreen screen) throws Exception { - Field optionsField = CustomConfigScreen.class.getDeclaredField("list"); - optionsField.setAccessible(true); - CustomOptionsList list = new CustomOptionsList(); - optionsField.set(screen, list); - Method init = CustomConfigScreen.class.getDeclaredMethod("initialize"); - init.setAccessible(true); - init.invoke(screen); - return list.options; - } - - private static class CustomOptionsList extends OptionsList { - - public List> options = new ArrayList<>(); - - public CustomOptionsList() { - super(null, 0, 0, 0, 0, 0); - } - - @Override - public int addBig(OptionInstance optionInstance) { - options.add(optionInstance); - return 0; - } - - @Override - public void addSmall(OptionInstance optionInstance, OptionInstance optionInstance2) { - options.add(optionInstance); - } - - } - -} diff --git a/3dSkinLayers-Forge/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java b/3dSkinLayers-Forge/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java deleted file mode 100644 index d08962a..0000000 --- a/3dSkinLayers-Forge/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java +++ /dev/null @@ -1,39 +0,0 @@ -package dev.tr7zw.skinlayers; - -import net.minecraftforge.client.ConfigScreenHandler.ConfigScreenFactory; -import net.minecraftforge.fml.IExtensionPoint; -import net.minecraftforge.fml.ModLoadingContext; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; - -@Mod("skinlayers3d") -public class SkinLayersMod extends SkinLayersModBase { - - //Forge only - private boolean onServer = false; - - public SkinLayersMod() { - try { - Class clientClass = net.minecraft.client.Minecraft.class; - }catch(Throwable ex) { - System.out.println("3dSkinLayers Mod installed on a Server. Going to sleep."); - onServer = true; - return; - } - ModLoadingContext.get().registerExtensionPoint(ConfigScreenFactory.class, () -> new ConfigScreenFactory((mc, screen) -> { - return createConfigScreen(screen); - })); - ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, - () -> new IExtensionPoint.DisplayTest( - () -> ModLoadingContext.get().getActiveContainer().getModInfo().getVersion().toString(), - (remote, isServer) -> true)); - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - } - - private void setup(final FMLCommonSetupEvent event) { - if(onServer)return; - onInitialize(); - } - -} diff --git a/3dSkinLayers-Forge/src/main/resources/META-INF/mods.toml b/3dSkinLayers-Forge/src/main/resources/META-INF/mods.toml deleted file mode 100644 index e7ff561..0000000 --- a/3dSkinLayers-Forge/src/main/resources/META-INF/mods.toml +++ /dev/null @@ -1,24 +0,0 @@ -modLoader="javafml" -loaderVersion="[35,)" -license="tr7zw Protective License" -[[mods]] -modId="skinlayers3d" -version="1.5.6" -displayName="3dSkinLayers" -authors="tr7zw" -description=''' -Renders the player skin layer in 3d -''' -[[dependencies.skinlayers3d]] #optional - modId="forge" - mandatory=true - versionRange="[35,)" - ordering="NONE" - side="CLIENT" -# Here's another dependency -[[dependencies.skinlayers3d]] - modId="minecraft" - mandatory=true - versionRange="[1.20.2,)" - ordering="NONE" - side="CLIENT" diff --git a/3dSkinLayers-Forge/src/main/resources/pack.mcmeta b/3dSkinLayers-Forge/src/main/resources/pack.mcmeta deleted file mode 100644 index 3867207..0000000 --- a/3dSkinLayers-Forge/src/main/resources/pack.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pack": { - "description": "3dskinlayers resources", - "pack_format": 15 - } -} diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/ModBase.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/ModBase.java new file mode 100644 index 0000000..1be6b88 --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/ModBase.java @@ -0,0 +1,56 @@ +package dev.tr7zw.skinlayers.versionless; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import dev.tr7zw.skinlayers.versionless.config.Config; + +public abstract class ModBase { + + public static final Logger LOGGER = LogManager.getLogger(); + public static Config config = null; + private File settingsFile = new File("config", "skinlayers.json"); + private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + public static boolean disguiseHeadsCompatibility = false; + + public void onInitialize() { + if (settingsFile.exists()) { + try { + config = new Gson().fromJson( + new String(Files.readAllBytes(settingsFile.toPath()), StandardCharsets.UTF_8), Config.class); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + if (config == null) { + config = new Config(); + writeConfig(); + } + try { + Class clientClass = Class.forName("dev.tr7zw.disguiseheads.DisguiseHeadsShared"); + disguiseHeadsCompatibility = clientClass != null; // to shut up the compiler that the var is not used + LOGGER.info("Found DisguiseHeads, enable compatibility!"); + } catch (Throwable ex) { + // not installed + } + } + + public void writeConfig() { + if (settingsFile.exists()) + settingsFile.delete(); + try { + Files.write(settingsFile.toPath(), gson.toJson(config).getBytes(StandardCharsets.UTF_8)); + } catch (IOException e1) { + e1.printStackTrace(); + } + } + +} diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/Config.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/config/Config.java similarity index 93% rename from Shared/src/main/java/dev/tr7zw/skinlayers/Config.java rename to 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/config/Config.java index a26ff28..1e2dc4b 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/Config.java +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/config/Config.java @@ -1,4 +1,4 @@ -package dev.tr7zw.skinlayers; +package dev.tr7zw.skinlayers.versionless.config; public class Config { diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/render/CustomModelPart.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/render/CustomModelPart.java new file mode 100644 index 0000000..c0983bb --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/render/CustomModelPart.java @@ -0,0 +1,78 @@ +package dev.tr7zw.skinlayers.versionless.render; + +import java.util.List; + +import dev.tr7zw.skinlayers.versionless.render.CustomizableCube.Polygon; +import dev.tr7zw.skinlayers.versionless.render.CustomizableCube.Vertex; +import dev.tr7zw.skinlayers.versionless.util.Vector3; + +/** + * Cut down copy of the Vanilla ModelPart to bypass Optifine/Sodium screwing + * with the CustomizableCube class + * + */ +public abstract class CustomModelPart { + + protected float x; + protected float y; + protected float z; + protected float xRot; + protected float yRot; + protected float zRot; + protected boolean visible = true; + protected float[] polygonData = null; + protected int polygonAmount = 0; + protected final int polyDataSize = 23; + + public CustomModelPart(List customCubes) { + compactCubes(customCubes); + } + + private void compactCubes(List customCubes) { + for (CustomizableCube cube : customCubes) { + polygonAmount += cube.polygonCount; + } + polygonData = new float[polygonAmount * polyDataSize]; + int offset = 0; + Polygon polygon; + for (CustomizableCube cube : customCubes) { + for (int id = 0; id < cube.polygonCount; id++) { + polygon = cube.polygons[id]; + Vector3 vector3f = polygon.normal; + polygonData[offset + 0] = vector3f.x; + polygonData[offset + 1] = vector3f.y; + polygonData[offset + 2] = vector3f.z; + for (int i = 0; i < 4; i++) { + Vertex vertex = polygon.vertices[i]; + polygonData[offset + 3 + (i * 5) + 0] = vertex.scaledX; + polygonData[offset + 3 + (i * 5) + 1] = vertex.scaledY; + polygonData[offset + 3 + (i * 5) + 2] = vertex.scaledZ; + polygonData[offset + 3 + (i * 5) + 3] = vertex.u; + polygonData[offset + 3 + (i * 5) + 4] = vertex.v; + } + offset += polyDataSize; + } + } + } + + public void setPosition(float f, float g, float h) { + this.x = f; + this.y = g; + this.z = h; + } + + public void setRotation(float f, float g, float h) { + this.xRot = f; + this.yRot = g; + this.zRot = h; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } + + public boolean isVisible() { + return visible; + } + +} diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCube.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/render/CustomizableCube.java similarity index 77% rename from Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCube.java rename to 3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/render/CustomizableCube.java index 92e4a69..4010557 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCube.java +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/render/CustomizableCube.java @@ -1,21 +1,12 @@ -package dev.tr7zw.skinlayers.render; +package dev.tr7zw.skinlayers.versionless.render; -import java.util.Collections; import java.util.HashMap; import java.util.Map; -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Vector3f; -import org.joml.Vector4f; +import dev.tr7zw.skinlayers.versionless.util.Direction; +import dev.tr7zw.skinlayers.versionless.util.Vector3; -import com.mojang.blaze3d.vertex.PoseStack.Pose; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.geom.ModelPart.Cube; -import net.minecraft.core.Direction; - -class CustomizableCube extends Cube { +public class CustomizableCube { private final Direction[] hidden; protected final Polygon[] polygons; @@ -30,8 +21,6 @@ class CustomizableCube extends Cube { public CustomizableCube(int u, int v, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float extraX, float extraY, float extraZ, boolean mirror, float textureWidth, float textureHeight, Direction[] hide, Direction[][] hideCorners) { - super(u, v, x, y, z, sizeX, sizeY, sizeZ, extraX, extraY, extraZ, mirror, textureWidth, textureHeight, - Collections.emptySet()); // unused this.hidden = hide; this.minX = x; this.minY = y; @@ -145,8 +134,8 @@ private static Vertex[] removeCornerVertex(Vertex[] vertices, Direction[] corner private static Vertex compareVertices(Vertex vertex1, Vertex vertex2, Direction[] corner) { for (Direction dir : corner) { - double d = dir.getAxis().choose(vertex1.pos.x() - vertex2.pos.x(), vertex1.pos.y() - vertex2.pos.y(), - vertex1.pos.z() - vertex2.pos.z()) * dir.getAxisDirection().getStep(); + double d = dir.getAxis().choose(vertex1.pos.x - vertex2.pos.x, vertex1.pos.y - vertex2.pos.y, + vertex1.pos.z - vertex2.pos.z) * dir.getDirStep(); if (d > 0) { return vertex1; } else if (d < 0) { @@ -156,33 +145,10 @@ private static Vertex compareVertices(Vertex vertex1, Vertex vertex2, Direction[ return vertex1; } - @Override - public void compile(Pose pose, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, - float blue, float alpha) { - Matrix4f matrix4f = pose.pose(); - Matrix3f matrix3f = pose.normal(); - Polygon polygon; - for (int id = 0; id < this.polygonCount; id++) { - polygon = this.polygons[id]; - Vector3f vector3f = new Vector3f(polygon.normal); - vector3f.mul(matrix3f); - float x = vector3f.x(); - float y = vector3f.y(); - float z = vector3f.z(); - for (int i = 0; i < 4; i++) { - Vertex vertex = polygon.vertices[i]; - Vector4f vector4f = new Vector4f(vertex.scaledX, vertex.scaledY, vertex.scaledZ, 1.0F); - vector4f.mul(matrix4f); - vertexConsumer.vertex(vector4f.x(), vector4f.y(), vector4f.z(), red, green, blue, alpha, vertex.u, - vertex.v, overlay, light, x, y, z); - } - } - } - protected static class Polygon { public final Vertex[] vertices; - public final Vector3f normal; + public final Vector3 normal; public Polygon(Vertex[] vertexs, float minU, float minV, float maxU, float maxV, float textureWidth, float textureHeight, boolean mirror, Direction direction) { @@ -201,33 +167,33 @@ public Polygon(Vertex[] vertexs, float minU, float minV, float maxU, float maxV, vertexs[vertexCount - 1 - i] = vertex; } } - this.normal = direction.step(); + this.normal = new Vector3(direction.getStepX(), direction.getStepY(), direction.getStepZ()); if (mirror) this.normal.mul(-1.0F, 1.0F, 1.0F); } } protected static class Vertex { - public final Vector3f pos; + public final Vector3 pos; public final float u; public final float v; public final float scaledX, scaledY, scaledZ; public Vertex(float x, float y, float z, float u, float v) { - this(new Vector3f(x, y, z), u, v); + this(new Vector3(x, y, z), u, v); } public Vertex remap(float u, float v) { return new Vertex(this.pos, u, v); } - public Vertex(Vector3f vector3f, float u, float v) { + public Vertex(Vector3 vector3f, float u, float v) { this.pos = vector3f; this.u = u; this.v = v; - this.scaledX = pos.x() / 16.0F; - this.scaledY = pos.y() / 16.0F; - this.scaledZ = pos.z() / 16.0F; + this.scaledX = pos.x / 16.0F; + this.scaledY = pos.y / 16.0F; + this.scaledZ = pos.z / 16.0F; } } diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Direction.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Direction.java new file mode 100644 index 0000000..eafa2a4 --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Direction.java @@ -0,0 +1,79 @@ +package dev.tr7zw.skinlayers.versionless.util; + +public enum Direction { + DOWN(Axis.Y, 0, -1, 0), UP(Axis.Y, 0, 1, 0), NORTH(Axis.Z, 0, 0, -1), SOUTH(Axis.Z, 0, 0, 1), + WEST(Axis.X, -1, 0, 0), EAST(Axis.X, 1, 0, 0); + + private static Direction[] opposite = new Direction[] { UP, DOWN, SOUTH, NORTH, EAST, WEST }; + + private final Axis axis; + private final int x, y, z; + + Direction(Axis axis, int x, int y, int z) { + this.axis = axis; + this.x = x; + this.y = y; + this.z = z; + } + + public Direction getOpposite() { + return opposite[this.ordinal()]; + } + + public Axis getAxis() { + return axis; + } + + public int getStepX() { + return x; + } + + public int getStepY() { + return y; + } + + public int getStepZ() { + return z; + } + + public int getDirStep() { + return x + y + z; + } + + public enum Axis { + X { + public int choose(int i, int j, int k) { + return i; + } + + public double choose(double d, double e, double f) { + return d; + } + }, + Y { + public int choose(int i, int j, int k) { + return j; + } + + public double choose(double d, double e, double f) { + return e; + } + }, + Z { + public int choose(int i, int j, int k) { + return k; + } + + public double choose(double d, double e, double f) { + return f; + } + }; + + public static Axis[] VALUES = values(); + + public abstract int choose(int param1Int1, int param1Int2, int param1Int3); + + public abstract double choose(double param1Double1, double param1Double2, double param1Double3); + } + +} diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Mth.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Mth.java new file mode 100644 index 0000000..2bb6ab9 --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Mth.java @@ -0,0 +1,680 @@ +package dev.tr7zw.skinlayers.versionless.util; + +import java.util.function.IntPredicate; + +public class Mth { + + public static final float PI = 3.1415927F; + + public static final float HALF_PI = 1.5707964F; + + public static final float TWO_PI = 6.2831855F; + + public static final float DEG_TO_RAD = 0.017453292F; + + public static final float RAD_TO_DEG = 57.295776F; + + public static final float EPSILON = 1.0E-5F; + + public static final float SQRT_OF_TWO = sqrt(2.0F); + + public static float truncate(float f, float g) { + float h = (float) Math.pow(10.0D, g); + return (int) (f * h) / h; + } + + public static float sqrt(float f) { + return (float) Math.sqrt(f); + } + + public static int floor(float f) { + int i = (int) f; + return (f < i) ? (i - 1) : i; + } + + public static int fastFloor(double d) { + return (int) (d + 1024.0D) - 1024; + } + + public static int floor(double d) { + int i = (int) d; + return (d < i) ? (i - 1) : i; + } + + public static long lfloor(double d) { + long l = (long) d; + return (d < l) ? (l - 1L) : l; + } + + public static int absFloor(double d) { + return (int) ((d >= 0.0D) ? d : (-d + 1.0D)); + } + + public static float abs(float f) { + return Math.abs(f); + } + + public static int abs(int i) { + return Math.abs(i); + } + + public static int ceil(float f) { + int i = (int) f; + return (f > i) ? (i + 1) : i; + } + + public static int ceil(double d) { + int i = (int) d; + return (d > i) ? (i + 1) : i; + } + + public static byte clamp(byte b, byte c, byte d) { + if (b < c) + return c; + if (b > d) + return d; + return b; + } + + public static int clamp(int i, int j, int k) { + if (i < j) + return j; + if (i > k) + return k; + return i; + } + + public static long clamp(long l, long m, long n) { + if (l < m) + return m; + if (l > n) + return n; + return l; + } + + public static float clamp(float f, float g, float h) { + if (f < g) + return g; + if (f > h) + return h; + return f; + } + + public static double clamp(double d, double e, double f) { + if (d < e) + return e; + if (d > f) + return f; + return d; + } + + public static double clampedLerp(double d, double e, double f) { + if (f < 0.0D) + return d; + if (f > 1.0D) + return e; + return lerp(f, d, e); + } + + public static float clampedLerp(float f, float g, float h) { + if (h < 0.0F) + return f; + if (h > 1.0F) + return g; + return lerp(h, f, g); + } + + public static double absMax(double d, double e) { + if (d < 0.0D) + d = -d; + if (e < 0.0D) + e = -e; + return (d > e) ? d : e; + } + + public static int intFloorDiv(int i, int j) { + return Math.floorDiv(i, j); + } + + public static double average(long[] ls) { + long l = 0L; + for (long m : ls) + l += m; + return l / ls.length; + } + + public static boolean equal(float f, float g) { + return (Math.abs(g - f) < 1.0E-5F); + } + + public static boolean equal(double d, double e) { + return (Math.abs(e - d) < 9.999999747378752E-6D); + } + + public static int positiveModulo(int i, int j) { + return Math.floorMod(i, j); + } + + public static float positiveModulo(float f, float g) { + return (f % g + g) % g; + } + + public static double positiveModulo(double d, double e) { + return (d % e + e) % e; + } + + public static boolean isDivisionInteger(int i, int j) { + return (i / j * j == i); + } + + public static int wrapDegrees(int i) { + int j = i % 360; + if (j >= 180) + j -= 360; + if (j < -180) + j += 360; + return j; + } + + public static float wrapDegrees(float f) { + float g = f % 360.0F; + if (g >= 180.0F) + g -= 360.0F; + if (g < -180.0F) + g += 360.0F; + return g; + } + + public static double wrapDegrees(double d) { + double e = d % 360.0D; + if (e >= 180.0D) + e -= 360.0D; + if (e < -180.0D) + e += 360.0D; + return e; + } + + public static float degreesDifference(float f, float g) { + return wrapDegrees(g - f); + } + + public static float degreesDifferenceAbs(float f, float g) { + return abs(degreesDifference(f, g)); + } + + public static float rotateIfNecessary(float f, float g, float h) { + float i = degreesDifference(f, g); + float j = clamp(i, -h, h); + return g - j; + } + + public static float approach(float f, float g, float h) { + h = abs(h); + if (f < g) + return clamp(f + h, f, g); + return clamp(f - h, g, f); + } + + public static float approachDegrees(float f, float g, float h) { + float i = degreesDifference(f, g); + return approach(f, f + i, h); + } + + public static double getDouble(String string, double d) { + try { + return Double.parseDouble(string); + } catch (Throwable throwable) { + return d; + } + } + + public static double getDouble(String string, double d, double e) { + return Math.max(e, getDouble(string, d)); + } + + public static int smallestEncompassingPowerOfTwo(int i) { + int j = i - 1; + j |= j >> 1; + j |= j >> 2; + j |= j >> 4; + j |= j >> 8; + j |= j >> 16; + return j + 1; + } + + public static boolean isPowerOfTwo(int i) { + return (i != 0 && (i & i - 1) == 0); + } + + private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[] { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, + 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; + + public static int ceillog2(int i) { + i = isPowerOfTwo(i) ? i : smallestEncompassingPowerOfTwo(i); + return MULTIPLY_DE_BRUIJN_BIT_POSITION[(int) (i * 125613361L >> 27L) & 0x1F]; + } + + public static int log2(int i) { + return ceillog2(i) - (isPowerOfTwo(i) ? 0 : 1); + } + + public static int color(float f, float g, float h) { + return color(floor(f * 255.0F), floor(g * 255.0F), floor(h * 255.0F)); + } + + public static int color(int i, int j, int k) { + int l = i; + l = (l << 8) + j; + l = (l << 8) + k; + return l; + } + + public static int colorMultiply(int i, int j) { + int k = (i & 0xFF0000) >> 16; + int l = (j & 0xFF0000) >> 16; + int m = (i & 0xFF00) >> 8; + int n = (j & 0xFF00) >> 8; + int o = (i & 0xFF) >> 0; + int p = (j & 0xFF) >> 0; + int q = (int) (k * l / 255.0F); + int r = (int) (m * n / 255.0F); + int s = (int) (o * p / 255.0F); + return i & 0xFF000000 | q << 16 | r << 8 | s; + } + + public static int colorMultiply(int i, float f, float g, float h) { + int j = (i & 0xFF0000) >> 16; + int k = (i & 0xFF00) >> 8; + int l = (i & 0xFF) >> 0; + int m = (int) (j * f); + int n = (int) (k * g); + int o = (int) (l * h); + return i & 0xFF000000 | m << 16 | n << 8 | o; + } + + public static float frac(float f) { + return f - floor(f); + } + + public static double frac(double d) { + return d - lfloor(d); + } + + public static long getSeed(int i, int j, int k) { + long l = (i * 3129871) ^ k * 116129781L ^ j; + l = l * l * 42317861L + l * 11L; + return l >> 16L; + } + + public static double inverseLerp(double d, double e, double f) { + return (d - e) / (f - e); + } + + public static float inverseLerp(float f, float g, float h) { + return (f - g) / (h - g); + } + + public static double atan2(double d, double e) { + double f = e * e + d * d; + if (Double.isNaN(f)) + return Double.NaN; + boolean bl = (d < 0.0D); + if (bl) + d = -d; + boolean bl2 = (e < 0.0D); + if (bl2) + e = -e; + boolean bl3 = (d > e); + if (bl3) { + double d1 = e; + e = d; + d = d1; + } + double g = fastInvSqrt(f); + e *= g; + d *= g; + double h = FRAC_BIAS + d; + int i = (int) Double.doubleToRawLongBits(h); + double j = ASIN_TAB[i]; + double k = COS_TAB[i]; + double l = h - FRAC_BIAS; + double m = d * k - e * l; + double n = (6.0D + m * m) * m * 0.16666666666666666D; + double o = j + n; + if (bl3) + o = 1.5707963267948966D - o; + if (bl2) + o = Math.PI - o; + if (bl) + o = -o; + return o; + } + + public static float fastInvSqrt(float f) { + float g = 0.5F * f; + int i = Float.floatToIntBits(f); + i = 1597463007 - (i >> 1); + f = Float.intBitsToFloat(i); + f *= 1.5F - g * f * f; + return f; + } + + public static double fastInvSqrt(double d) { + double e = 0.5D * d; + long l = Double.doubleToRawLongBits(d); + l = 6910469410427058090L - (l >> 1L); + d = Double.longBitsToDouble(l); + d *= 1.5D - e * d * d; + return d; + } + + public static float fastInvCubeRoot(float f) { + int i = Float.floatToIntBits(f); + i = 1419967116 - i / 3; + float g = Float.intBitsToFloat(i); + g = 0.6666667F * g + 1.0F / 3.0F * g * g * f; + g = 0.6666667F * g + 1.0F / 3.0F * g * g * f; + return g; + } + + private static final double FRAC_BIAS = Double.longBitsToDouble(4805340802404319232L); + + private static final double[] ASIN_TAB = new double[257]; + + private static final double[] COS_TAB = new double[257]; + + static { + for (int i = 0; i < 257; i++) { + double d = i / 256.0D; + double e = Math.asin(d); + COS_TAB[i] = Math.cos(e); + ASIN_TAB[i] = e; + } + } + + public static int hsvToRgb(float f, float g, float h) { + float n, o, p; + int q, r, s, i = (int) (f * 6.0F) % 6; + float j = f * 6.0F - i; + float k = h * (1.0F - g); + float l = h * (1.0F - j * g); + float m = h * (1.0F - (1.0F - j) * g); + switch (i) { + case 0: + n = h; + o = m; + p = k; + q = clamp((int) (n * 255.0F), 0, 255); + r = clamp((int) (o * 255.0F), 0, 255); + s = clamp((int) (p * 255.0F), 0, 255); + return q << 16 | r << 8 | s; + case 1: + n = l; + o = h; + p = k; + q = clamp((int) (n * 255.0F), 0, 255); + r = clamp((int) (o * 255.0F), 0, 255); + s = clamp((int) (p * 255.0F), 0, 255); + return q << 16 | r << 8 | s; + case 2: + n = k; + o = h; + p = m; + q = clamp((int) (n * 255.0F), 0, 255); + r = clamp((int) (o * 255.0F), 0, 255); + s = clamp((int) (p * 255.0F), 0, 255); + return q << 16 | r << 8 | s; + case 3: + n = k; + o = l; + p = h; + q = clamp((int) (n * 255.0F), 0, 255); + r = clamp((int) (o * 255.0F), 0, 255); + s = clamp((int) (p * 255.0F), 0, 255); + return q << 16 | r << 8 | s; + case 4: + n = m; + o = k; + p = h; + q = clamp((int) (n * 255.0F), 0, 255); + r = clamp((int) (o * 255.0F), 0, 255); + s = clamp((int) (p * 255.0F), 0, 255); + return q << 16 | r << 8 | s; + case 5: + n = h; + o = k; + p = l; + q = clamp((int) (n * 255.0F), 0, 255); + r = clamp((int) (o * 255.0F), 0, 255); + s = clamp((int) (p * 255.0F), 0, 255); + return q << 16 | r << 8 | s; + } + throw new RuntimeException( + "Something went wrong when converting from HSV to RGB. Input was " + f + ", " + g + ", " + h); + } + + public static int murmurHash3Mixer(int i) { + i ^= i >>> 16; + i *= -2048144789; + i ^= i >>> 13; + i *= -1028477387; + i ^= i >>> 16; + return i; + } + + public static long murmurHash3Mixer(long l) { + l ^= l >>> 33L; + l *= -49064778989728563L; + l ^= l >>> 33L; + l *= -4265267296055464877L; + l ^= l >>> 33L; + return l; + } + + public static double[] cumulativeSum(double... ds) { + double d = 0.0D; + for (double e : ds) + d += e; + int i; + for (i = 0; i < ds.length; i++) + ds[i] = ds[i] / d; + for (i = 0; i < ds.length; i++) + ds[i] = ((i == 0) ? 0.0D : ds[i - 1]) + ds[i]; + return ds; + } + + public static double[] binNormalDistribution(double d, double e, double f, int i, int j) { + double[] ds = new double[j - i + 1]; + int k = 0; + for (int l = i; l <= j; l++) { + ds[k] = Math.max(0.0D, d * + + StrictMath.exp(-(l - f) * (l - f) / 2.0D * e * e)); + k++; + } + return ds; + } + + public static double[] binBiModalNormalDistribution(double d, double e, double f, double g, double h, double i, + int j, int k) { + double[] ds = new double[k - j + 1]; + int l = 0; + for (int m = j; m <= k; m++) { + ds[l] = Math.max(0.0D, d * + + StrictMath.exp(-(m - f) * (m - f) / 2.0D * e * e) + + g * StrictMath.exp(-(m - i) * (m - i) / 2.0D * h * h)); + l++; + } + return ds; + } + + public static double[] binLogDistribution(double d, double e, int i, int j) { + double[] ds = new double[j - i + 1]; + int k = 0; + for (int l = i; l <= j; l++) { + ds[k] = Math.max(d * StrictMath.log(l) + e, 0.0D); + k++; + } + return ds; + } + + public static int binarySearch(int i, int j, IntPredicate intPredicate) { + int k = j - i; + while (k > 0) { + int l = k / 2; + int m = i + l; + if (intPredicate.test(m)) { + k = l; + continue; + } + i = m + 1; + k -= l + 1; + } + return i; + } + + public static float lerp(float f, float g, float h) { + return g + f * (h - g); + } + + public static double lerp(double d, double e, double f) { + return e + d * (f - e); + } + + public static double lerp2(double d, double e, double f, double g, double h, double i) { + return lerp(e, + + lerp(d, f, g), lerp(d, h, i)); + } + + public static double lerp3(double d, double e, double f, double g, double h, double i, double j, double k, double l, + double m, double n) { + return lerp(f, + + lerp2(d, e, g, h, i, j), lerp2(d, e, k, l, m, n)); + } + + public static float catmullrom(float f, float g, float h, float i, float j) { + return 0.5F * (2.0F * h + (i - g) * f + (2.0F * g - 5.0F * h + 4.0F * i - j) * f * f + + (3.0F * h - g - 3.0F * i + j) * f * f * f); + } + + public static double smoothstep(double d) { + return d * d * d * (d * (d * 6.0D - 15.0D) + 10.0D); + } + + public static double smoothstepDerivative(double d) { + return 30.0D * d * d * (d - 1.0D) * (d - 1.0D); + } + + public static int sign(double d) { + if (d == 0.0D) + return 0; + return (d > 0.0D) ? 1 : -1; + } + + public static float rotLerp(float f, float g, float h) { + return g + f * wrapDegrees(h - g); + } + + public static float diffuseLight(float f, float g, float h) { + return Math.min(f * f * 0.6F + g * g * (3.0F + g) / 4.0F + h * h * 0.8F, 1.0F); + } + + @Deprecated + public static float rotlerp(float f, float g, float h) { + float i = g - f; + while (i < -180.0F) + i += 360.0F; + while (i >= 180.0F) + i -= 360.0F; + return f + h * i; + } + + @Deprecated + public static float rotWrap(double d) { + while (d >= 180.0D) + d -= 360.0D; + while (d < -180.0D) + d += 360.0D; + return (float) d; + } + + public static float triangleWave(float f, float g) { + return (Math.abs(f % g - g * 0.5F) - g * 0.25F) / g * 0.25F; + } + + public static float square(float f) { + return f * f; + } + + public static double square(double d) { + return d * d; + } + + public static int square(int i) { + return i * i; + } + + public static long square(long l) { + return l * l; + } + + public static float cube(float f) { + return f * f * f; + } + + public static double clampedMap(double d, double e, double f, double g, double h) { + return clampedLerp(g, h, inverseLerp(d, e, f)); + } + + public static float clampedMap(float f, float g, float h, float i, float j) { + return clampedLerp(i, j, inverseLerp(f, g, h)); + } + + public static double map(double d, double e, double f, double g, double h) { + return lerp(inverseLerp(d, e, f), g, h); + } + + public static float map(float f, float g, float h, float i, float j) { + return lerp(inverseLerp(f, g, h), i, j); + } + + public static int roundToward(int i, int j) { + return positiveCeilDiv(i, j) * j; + } + + public static int positiveCeilDiv(int i, int j) { + return -Math.floorDiv(-i, j); + } + + public static double lengthSquared(double d, double e) { + return d * d + e * e; + } + + public static double length(double d, double e) { + return Math.sqrt(lengthSquared(d, e)); + } + + public static double lengthSquared(double d, double e, double f) { + return d * d + e * e + f * f; + } + + public static double length(double d, double e, double f) { + return Math.sqrt(lengthSquared(d, e, f)); + } + + public static int quantize(double d, int i) { + return floor(d / i) * i; + } + + public static float cos(float deg) { + return (float) Math.cos(deg); + } + + public static float sin(float deg) { + return (float) Math.sin(deg); + } + +} \ No newline at end of file diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Vector3.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Vector3.java new file mode 100644 index 0000000..168e873 --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/Vector3.java @@ -0,0 +1,89 @@ +package dev.tr7zw.skinlayers.versionless.util; + +public class Vector3 { + public float x, y, z; + + public Vector3(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3 clone() { + return new Vector3(x, y, z); + } + + public void copy(Vector3 vec) { + this.x = vec.x; + this.y = vec.y; + this.z = vec.z; + } + + public Vector3 add(Vector3 vec) { + this.x += vec.x; + this.y += vec.y; + this.z += vec.z; + return this; + } + + public Vector3 subtract(Vector3 vec) { + this.x -= vec.x; + this.y -= vec.y; + this.z -= vec.z; + return this; + } + + public Vector3 div(float amount) { + this.x /= amount; + this.y /= amount; + this.z /= amount; + return this; + } + + public Vector3 mul(float amount) { + this.x *= amount; + this.y *= amount; + this.z *= amount; + return this; + } + + public Vector3 mul(float xa, float ya, float za) { + this.x *= xa; + this.y *= ya; + this.z *= za; + return this; + } + + public Vector3 normalize() { + float f = Mth.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + if (f < 1.0E-4F) { + this.x = 0; + this.y = 0; + this.z = 0; + } else { + this.x /= f; + this.y /= f; + this.z /= f; + } + return this; + } + + public Vector3 rotateDegrees(float deg) { + float ox = x; + float oy = y; + deg = (float) Math.toRadians(deg); + x = Mth.cos(deg) * ox - Mth.sin(deg) * oy; + y = Mth.sin(deg) * ox + Mth.cos(deg) * oy; + return this; + } + + @Override + public String toString() { + return "Vector2 [x=" + x + ", y=" + y + "]"; + } + + public float sqrMagnitude() { + return x * x + y * y + z * z; + } + +} \ No newline at end of file diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/ModelBuilder.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/ModelBuilder.java new file mode 100644 index 0000000..b81a887 --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/ModelBuilder.java @@ -0,0 +1,17 @@ +package dev.tr7zw.skinlayers.versionless.util.wrapper; + +import dev.tr7zw.skinlayers.versionless.util.Direction; + +public interface ModelBuilder { + + ModelBuilder uv(int u, int v); + + ModelBuilder mirror(boolean bl); + + ModelBuilder addBox(float x, float y, float z, float pixelSize, Direction[] hide, Direction[][] corners); + + ModelBuilder addVanillaBox(float x, float y, float z, float width, float height, float depth); + + boolean isEmpty(); + +} \ No newline at end of file diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/SolidPixelWrapper.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/SolidPixelWrapper.java new file mode 100644 index 0000000..9feb0b0 --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/SolidPixelWrapper.java @@ -0,0 +1,259 @@ +package dev.tr7zw.skinlayers.versionless.util.wrapper; + +import java.util.HashSet; +import java.util.Set; + +import dev.tr7zw.skinlayers.versionless.ModBase; +import dev.tr7zw.skinlayers.versionless.util.Direction; +import lombok.AllArgsConstructor; +import lombok.Getter; + +public class SolidPixelWrapper { + + @AllArgsConstructor + public static class UV { + int u; + int v; + + public int u() { + return u; + } + + public int v() { + return v; + } + } + + @AllArgsConstructor + public static class Dimensions { + private final int width; + private final int height; + private final int depth; + + public int width() { + return width; + } + + public int height() { + return height; + } + + public int depth() { + return depth; + } + } + + @AllArgsConstructor + public static class Position { + private final float x; + private final float y; + private final float z; + + public float x() { + return x; + } + + public float y() { + return y; + } + + public float z() { + return z; + } + } + + @AllArgsConstructor + public static class VoxelPosition { + private final int x; + private final int y; + private final int z; + + public int x() { + return x; + } + + public int y() { + return y; + } + + public int z() { + return z; + } + } + + private static final float pixelSize = 1f; + + /** + * Side to Direction: Top - DOWN Down - UP Front - NORTH Back - SOUTH Right - + * WEST Left - EAST + **/ + public static ModelBuilder wrapBox(ModelBuilder builder, TextureData natImage, int width, int height, int depth, + int textureU, int textureV, boolean topPivot, float rotationOffset) { + float staticXOffset = -width / 2f; + float staticYOffset = topPivot ? +rotationOffset : -height + rotationOffset; + float staticZOffset = -depth / 2f; + Position staticOffset = new Position(staticXOffset, staticYOffset, staticZOffset); + Dimensions dimensions = new Dimensions(width, height, depth); + UV textureUV = new UV(textureU, textureV); + try { + for (Direction face : Direction.values()) { + UV sizeUV = getSizeUV(dimensions, face); + for (int u = 0; u < sizeUV.u; u++) { + for (int v = 0; v < sizeUV.v; v++) { + addPixel(natImage, builder, staticOffset, face, dimensions, new UV(u, v), textureUV, sizeUV); + } + } + } + } catch (Exception ex) { // Some calculation went wrong and out of bounds/some other issue + ModBase.LOGGER.error("Error while creating 3d skin model. Please report on the Github/Discord.", ex); + return null; + } + + // if cubes is empty, there are no pixels. Don't add an empty box. + if (ModBase.config.fastRender && !builder.isEmpty()) { + builder.uv(textureU, textureV).addVanillaBox(staticXOffset, staticYOffset, staticZOffset, width, height, + depth); + } + + return builder; + } + + private static UV getSizeUV(Dimensions dimensions, Direction face) { + if (face == Direction.DOWN || face == Direction.UP) { + return new UV(dimensions.width, dimensions.depth); + } else if (face == Direction.NORTH || face == Direction.SOUTH) { + return new UV(dimensions.width, dimensions.height); + } else { // Assuming the remaining cases are WEST or EAST + return new UV(dimensions.depth, dimensions.height); + } + } + + private static UV getOnTextureUV(UV textureUV, UV onFaceUV, Dimensions dimensions, Direction face) { + if (face == Direction.DOWN) { + return new UV(textureUV.u + dimensions.depth + onFaceUV.u, textureUV.v + onFaceUV.v); + } else if (face == Direction.UP) { + return new UV(textureUV.u + dimensions.width + dimensions.depth + onFaceUV.u, textureUV.v + onFaceUV.v); + } else if (face == Direction.NORTH) { + return new UV(textureUV.u + dimensions.depth + onFaceUV.u, textureUV.v + dimensions.depth + onFaceUV.v); + } else if (face == Direction.SOUTH) { + return new UV(textureUV.u + dimensions.depth + dimensions.width + dimensions.depth + onFaceUV.u, + textureUV.v + dimensions.depth + onFaceUV.v); + } else if (face == Direction.WEST) { + return new UV(textureUV.u + onFaceUV.u, textureUV.v + dimensions.depth + onFaceUV.v); + } else { // Assuming the remaining case is EAST + return new UV(textureUV.u + dimensions.depth + dimensions.width + onFaceUV.u, + textureUV.v + dimensions.depth + onFaceUV.v); + } + } + + private static VoxelPosition UVtoXYZ(UV onFaceUV, Dimensions dimensions, Direction face) { + if (face == Direction.DOWN) { + return new VoxelPosition(onFaceUV.u, 0, dimensions.depth - 1 - onFaceUV.v); + } else if (face == Direction.UP) { + return new VoxelPosition(onFaceUV.u, dimensions.height - 1, dimensions.depth - 1 - onFaceUV.v); + } else if (face == Direction.NORTH) { + return new VoxelPosition(onFaceUV.u + 0, onFaceUV.v, 0); + } else if (face == Direction.SOUTH) { + return new VoxelPosition(dimensions.width - 1 - onFaceUV.u, onFaceUV.v, dimensions.depth - 1); + } else if (face == Direction.WEST) { + return new VoxelPosition(0, onFaceUV.v, dimensions.depth - 1 - onFaceUV.u); + } else { // Assuming the remaining case is EAST + return new VoxelPosition(dimensions.width - 1, onFaceUV.v, onFaceUV.u + 0); + } + } + + private static UV XYZtoUV(VoxelPosition voxelPosition, Dimensions dimensions, Direction face) { + if (face == Direction.DOWN || face == Direction.UP) { + return new UV(voxelPosition.x, dimensions.depth - 1 - voxelPosition.z); + } else if (face == Direction.NORTH) { + return new UV(voxelPosition.x + 0, voxelPosition.y); + } else if (face == Direction.SOUTH) { + return new UV(dimensions.width - 1 - voxelPosition.x, voxelPosition.y); + } else if (face == Direction.WEST) { + return new UV(dimensions.depth - 1 - voxelPosition.z, voxelPosition.y); + } else { // Assuming the remaining case is EAST + return new UV(voxelPosition.z + 0, voxelPosition.y); + } + } + + private static void addPixel(TextureData natImage, ModelBuilder cubes, Position staticOffset, Direction face, + Dimensions dimensions, UV onFaceUV, UV textureUV, UV sizeUV) { + UV onTextureUV = getOnTextureUV(textureUV, onFaceUV, dimensions, face); + if (!natImage.isPresent(onTextureUV)) + return; + + VoxelPosition voxelPosition = UVtoXYZ(onFaceUV, dimensions, face); + Position position = new Position(staticOffset.x + voxelPosition.x, staticOffset.y + voxelPosition.y, + staticOffset.z + voxelPosition.z); + boolean solidPixel = natImage.isSolid(onTextureUV); + + Set hide = new HashSet<>(); + Set corners = new HashSet<>(); + + boolean isOnBorder = false; + boolean backsideOverlaps = false; + for (Direction neighbourFace : Direction.values()) { + if (neighbourFace.getAxis() == face.getAxis()) + continue; + + VoxelPosition neighbourVoxelPosition = new VoxelPosition(voxelPosition.x + neighbourFace.getStepX(), + voxelPosition.y + neighbourFace.getStepY(), voxelPosition.z + neighbourFace.getStepZ()); + UV neighbourOnFaceUV = XYZtoUV(neighbourVoxelPosition, dimensions, face); + if (isOnFace(neighbourOnFaceUV, sizeUV)) { + if (natImage.isPresent(getOnTextureUV(textureUV, neighbourOnFaceUV, dimensions, face))) { + if (!(solidPixel + && !natImage.isSolid(getOnTextureUV(textureUV, neighbourOnFaceUV, dimensions, face)))) { + hide.add(neighbourFace); + } + } else { + VoxelPosition farNeighbourVoxelPosition = new VoxelPosition( + neighbourVoxelPosition.x + neighbourFace.getStepX(), + neighbourVoxelPosition.y + neighbourFace.getStepY(), + neighbourVoxelPosition.z + neighbourFace.getStepZ()); + UV farNeighbourOnFaceUV = XYZtoUV(farNeighbourVoxelPosition, dimensions, face); + if (!isOnFace(farNeighbourOnFaceUV, sizeUV)) { + farNeighbourOnFaceUV = XYZtoUV(farNeighbourVoxelPosition, dimensions, neighbourFace); + if (natImage.isPresent( + getOnTextureUV(textureUV, farNeighbourOnFaceUV, dimensions, neighbourFace))) { + if (!(solidPixel && !natImage.isSolid( + getOnTextureUV(textureUV, farNeighbourOnFaceUV, dimensions, neighbourFace)))) { + hide.add(neighbourFace); + } + } + } + } + } else { + isOnBorder = true; + neighbourOnFaceUV = XYZtoUV(voxelPosition, dimensions, neighbourFace); + if (natImage.isPresent(getOnTextureUV(textureUV, neighbourOnFaceUV, dimensions, neighbourFace))) { + backsideOverlaps = true; + hide.add(neighbourFace); + corners.add(new Direction[] { face.getOpposite(), neighbourFace }); + } else { + UV downNeighbourOnFaceUV = XYZtoUV(new VoxelPosition(voxelPosition.x - face.getStepX(), + voxelPosition.y - face.getStepY(), voxelPosition.z - face.getStepZ()), dimensions, + neighbourFace); + if (natImage + .isPresent(getOnTextureUV(textureUV, downNeighbourOnFaceUV, dimensions, neighbourFace))) { + backsideOverlaps = true; + } + } + } + } + + if (!isOnBorder || backsideOverlaps) { + hide.add(face.getOpposite()); + } + if (ModBase.config.fastRender) { + hide.add(face); // the front face gets handled in one big cube + } + + cubes.uv(onTextureUV.u, onTextureUV.v).addBox(position.x, position.y, position.z, pixelSize, + hide.toArray(new Direction[0]), corners.toArray(new Direction[0][0])); + } + + private static boolean isOnFace(UV onFaceUV, UV sizeUV) { + return onFaceUV.u >= 0 && onFaceUV.u < sizeUV.u && onFaceUV.v >= 0 && onFaceUV.v < sizeUV.v; + } + +} diff --git a/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/TextureData.java b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/TextureData.java new file mode 100644 index 0000000..a4f7642 --- /dev/null +++ b/3dSkinLayers-Versionless/src/main/java/dev/tr7zw/skinlayers/versionless/util/wrapper/TextureData.java @@ -0,0 +1,11 @@ +package dev.tr7zw.skinlayers.versionless.util.wrapper; + +import dev.tr7zw.skinlayers.versionless.util.wrapper.SolidPixelWrapper.UV; + +public interface TextureData { + + public boolean isPresent(UV onTextureUV); + + public boolean isSolid(UV onTextureUV); + +} diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/Mesh.java b/Shared/src/main/java/dev/tr7zw/skinlayers/api/Mesh.java deleted file mode 100644 index d45686c..0000000 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/api/Mesh.java +++ /dev/null @@ -1,30 +0,0 @@ -package dev.tr7zw.skinlayers.api; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.model.geom.PartPose; - -public interface Mesh { - - public default void render(PoseStack poseStack, VertexConsumer vertexConsumer, int light, int overlay) { - render(null, poseStack, vertexConsumer, light, overlay, 1.0F, 1.0F, 1.0F, 1.0F); - } - - public void render(ModelPart vanillaModel, PoseStack poseStack, VertexConsumer vertexConsumer, int light, - int overlay, float red, float green, float blue, float alpha); - - public void setPosition(float x, float y, float z); - - public void setRotation(float xRot, float yRot, float zRot); - - public void loadPose(PartPose partPose); - - public void copyFrom(ModelPart modelPart); - - public void setVisible(boolean visible); - - public boolean isVisible(); - -} diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/render/SolidPixelWrapper.java b/Shared/src/main/java/dev/tr7zw/skinlayers/render/SolidPixelWrapper.java deleted file mode 100644 index 45c67ea..0000000 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/render/SolidPixelWrapper.java +++ /dev/null @@ -1,189 +0,0 @@ -package dev.tr7zw.skinlayers.render; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -import com.mojang.blaze3d.platform.NativeImage; - -import dev.tr7zw.skinlayers.SkinLayersModBase; -import dev.tr7zw.skinlayers.api.Mesh; -import net.minecraft.client.model.geom.ModelPart.Cube; -import net.minecraft.core.Direction; - -public class SolidPixelWrapper { - - public record UV(int u, int v) { - } - - public record Dimensions(int width, int height, int depth) { - } - - public record Position(float x, float y, float z) { - } - - public record VoxelPosition(int x, int y, int z) { - } - - private static final float pixelSize = 1f; - - /** - * Side to Direction: - * Top - DOWN - * Down - UP - * Front - NORTH - * Back - SOUTH - * Right - WEST - * Left - EAST - **/ - public static Mesh wrapBox(NativeImage natImage, - int width, int height, int depth, int textureU, int textureV, boolean topPivot, float rotationOffset) { - CustomizableCubeListBuilder cubes = CustomizableCubeListBuilder.create(); - float staticXOffset = -width / 2f; - float staticYOffset = topPivot ? +rotationOffset : -height + rotationOffset; - float staticZOffset = -depth / 2f; - Position staticOffset = new Position(staticXOffset, staticYOffset, staticZOffset); - Dimensions dimensions = new Dimensions(width, height, depth); - UV textureUV = new UV(textureU, textureV); - //StaticData staticData = new StaticData(natImage, cubes, textureUV, dimensions); - try { - for(Direction face : Direction.values()) { - UV sizeUV = getSizeUV(dimensions, face); - for(int u = 0; u < sizeUV.u; u++) { - for(int v = 0; v < sizeUV.v; v++) { - addPixel(natImage, cubes, staticOffset, face, dimensions, new UV(u, v), textureUV, sizeUV); - } - } - } - } catch (Exception ex) { // Some calculation went wrong and out of bounds/some other issue - SkinLayersModBase.LOGGER.error("Error while creating 3d skin model. Please report on the Github/Discord.", - ex); - return new CustomizableModelPart(new ArrayList(), new ArrayList<>(), new HashMap<>()); // empty model - } - - // if cubes is empty, there are no pixels. Don't add an empty box. - if(SkinLayersModBase.config.fastRender && !cubes.getCubes().isEmpty()) { - cubes.uv(textureU, textureV).addVanillaBox(staticXOffset, staticYOffset, staticZOffset, width, height, depth, pixelSize); - } - - return new CustomizableModelPart(cubes.getVanillaCubes(), cubes.getCubes(), new HashMap<>()); - } - - private static UV getSizeUV(Dimensions dimensions, Direction face) { - return switch(face) { - case DOWN , UP -> new UV(dimensions.width, dimensions.depth ); - case NORTH, SOUTH -> new UV(dimensions.width, dimensions.height); - case WEST , EAST -> new UV(dimensions.depth, dimensions.height); - }; - } - - private static UV getOnTextureUV(UV textureUV, UV onFaceUV, Dimensions dimensions, Direction face) { - return switch(face) { - case DOWN -> new UV(textureUV.u + dimensions.depth + onFaceUV.u , textureUV.v + onFaceUV.v ); - case UP -> new UV(textureUV.u + dimensions.width + dimensions.depth + onFaceUV.u , textureUV.v + onFaceUV.v ); - case NORTH -> new UV(textureUV.u + dimensions.depth + onFaceUV.u , textureUV.v + dimensions.depth + onFaceUV.v); - case SOUTH -> new UV(textureUV.u + dimensions.depth + dimensions.width + dimensions.depth + onFaceUV.u, textureUV.v + dimensions.depth + onFaceUV.v); - case WEST -> new UV(textureUV.u + onFaceUV.u , textureUV.v + dimensions.depth + onFaceUV.v); - case EAST -> new UV(textureUV.u + dimensions.depth + dimensions.width + onFaceUV.u , textureUV.v + dimensions.depth + onFaceUV.v); - }; - } - - private static VoxelPosition UVtoXYZ(UV onFaceUV, Dimensions dimensions, Direction face) { - return switch(face) { - case DOWN -> new VoxelPosition(onFaceUV.u, 0 , dimensions.depth - 1 - onFaceUV.v); - case UP -> new VoxelPosition(onFaceUV.u, dimensions.height - 1, dimensions.depth - 1 - onFaceUV.v); - case NORTH -> new VoxelPosition(onFaceUV.u + 0 , onFaceUV.v, 0 ); - case SOUTH -> new VoxelPosition(dimensions.width - 1 - onFaceUV.u, onFaceUV.v, dimensions.depth - 1); - case WEST -> new VoxelPosition(0 , onFaceUV.v, dimensions.depth - 1 - onFaceUV.u); - case EAST -> new VoxelPosition(dimensions.width - 1, onFaceUV.v, onFaceUV.u + 0 ); - }; - } - - private static UV XYZtoUV(VoxelPosition voxelPosition, Dimensions dimensions, Direction face) { - return switch(face) { - case DOWN, UP -> new UV(voxelPosition.x, dimensions.depth - 1 - voxelPosition.z); - case NORTH -> new UV(voxelPosition.x + 0 , voxelPosition.y); - case SOUTH -> new UV(dimensions.width - 1 - voxelPosition.x, voxelPosition.y); - case WEST -> new UV(dimensions.depth - 1 - voxelPosition.z, voxelPosition.y); - case EAST -> new UV(voxelPosition.z + 0 , voxelPosition.y); - }; - } - - private static void addPixel(NativeImage natImage, CustomizableCubeListBuilder cubes, - Position staticOffset, Direction face, Dimensions dimensions, UV onFaceUV, UV textureUV, UV sizeUV) { - UV onTextureUV = getOnTextureUV(textureUV, onFaceUV, dimensions, face); - if(!isPresent(natImage, onTextureUV)) return; - - VoxelPosition voxelPosition = UVtoXYZ(onFaceUV, dimensions, face); - Position position = new Position(staticOffset.x + voxelPosition.x, staticOffset.y + voxelPosition.y, staticOffset.z + voxelPosition.z); - boolean solidPixel = isSolid(natImage, onTextureUV); - - Set hide = new HashSet<>(); - Set corners = new HashSet<>(); - - boolean isOnBorder = false; - boolean backsideOverlaps = false; - for (Direction neighbourFace : Direction.values()) { - if(neighbourFace.getAxis() == face.getAxis()) continue; - - VoxelPosition neighbourVoxelPosition = new VoxelPosition(voxelPosition.x + neighbourFace.getStepX(), voxelPosition.y + neighbourFace.getStepY(), voxelPosition.z + neighbourFace.getStepZ()); - UV neighbourOnFaceUV = XYZtoUV(neighbourVoxelPosition, dimensions, face); - if(isOnFace(neighbourOnFaceUV, sizeUV)) { - if(isPresent(natImage, getOnTextureUV(textureUV, neighbourOnFaceUV, dimensions, face))) { - if(!(solidPixel && !isSolid(natImage, getOnTextureUV(textureUV, neighbourOnFaceUV, dimensions, face)))) { - hide.add(neighbourFace); - } - } else { - VoxelPosition farNeighbourVoxelPosition = new VoxelPosition(neighbourVoxelPosition.x + neighbourFace.getStepX(), neighbourVoxelPosition.y + neighbourFace.getStepY(), neighbourVoxelPosition.z + neighbourFace.getStepZ()); - UV farNeighbourOnFaceUV = XYZtoUV(farNeighbourVoxelPosition, dimensions, face); - if(!isOnFace(farNeighbourOnFaceUV, sizeUV)) { - farNeighbourOnFaceUV = XYZtoUV(farNeighbourVoxelPosition, dimensions, neighbourFace); - if(isPresent(natImage, getOnTextureUV(textureUV, farNeighbourOnFaceUV, dimensions, neighbourFace))) { - if(!(solidPixel && !isSolid(natImage, getOnTextureUV(textureUV, farNeighbourOnFaceUV, dimensions, neighbourFace)))) { - hide.add(neighbourFace); - } - } - } - } - } else { - isOnBorder = true; - neighbourOnFaceUV = XYZtoUV(voxelPosition, dimensions, neighbourFace); - if(isPresent(natImage, getOnTextureUV(textureUV, neighbourOnFaceUV, dimensions, neighbourFace))) { - backsideOverlaps = true; - hide.add(neighbourFace); - corners.add(new Direction[]{ face.getOpposite(), neighbourFace }); - } else { - UV downNeighbourOnFaceUV = XYZtoUV(new VoxelPosition(voxelPosition.x - face.getStepX(), voxelPosition.y - face.getStepY(), voxelPosition.z - face.getStepZ()), dimensions, neighbourFace); - if(isPresent(natImage, getOnTextureUV(textureUV, downNeighbourOnFaceUV, dimensions, neighbourFace))) { - backsideOverlaps = true; - } - } - } - } - - if(!isOnBorder || backsideOverlaps) { - hide.add(face.getOpposite()); - } - if(SkinLayersModBase.config.fastRender) { - hide.add(face); // the front face gets handled in one big cube - } - - cubes.uv(onTextureUV.u, onTextureUV.v) - .addBox(position.x, position.y, position.z, pixelSize, - hide.toArray(Direction[]::new), corners.toArray(Direction[][]::new)); - } - - private static boolean isPresent(NativeImage natImage, UV onTextureUV) { - return natImage.getLuminanceOrAlpha(onTextureUV.u, onTextureUV.v) != 0; - } - - private static boolean isSolid(NativeImage natImage, UV onTextureUV) { - return natImage.getLuminanceOrAlpha(onTextureUV.u, onTextureUV.v) == -1; - } - - private static boolean isOnFace(UV onFaceUV, UV sizeUV) { - return onFaceUV.u >= 0 && onFaceUV.u < sizeUV.u && onFaceUV.v >= 0 && onFaceUV.v < sizeUV.v; - } - -} diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/HeadLayerFeatureRenderer.java b/Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/HeadLayerFeatureRenderer.java deleted file mode 100644 index f6be0e8..0000000 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/HeadLayerFeatureRenderer.java +++ /dev/null @@ -1,94 +0,0 @@ -package dev.tr7zw.skinlayers.renderlayers; - -import java.util.Set; - -import com.google.common.collect.Sets; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; - -import dev.tr7zw.skinlayers.SkinLayersModBase; -import dev.tr7zw.skinlayers.SkinUtil; -import dev.tr7zw.skinlayers.accessor.PlayerEntityModelAccessor; -import dev.tr7zw.skinlayers.accessor.PlayerSettings; -import net.minecraft.client.Minecraft; -import net.minecraft.client.model.PlayerModel; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.client.renderer.entity.RenderLayerParent; -import net.minecraft.client.renderer.entity.layers.RenderLayer; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.entity.player.PlayerModelPart; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; - -public class HeadLayerFeatureRenderer extends RenderLayer> { - - public HeadLayerFeatureRenderer( - RenderLayerParent> renderLayerParent) { - super(renderLayerParent); - thinArms = ((PlayerEntityModelAccessor) getParentModel()).hasThinArms(); - } - - private Set hideHeadLayers = Sets.newHashSet(Items.ZOMBIE_HEAD, Items.CREEPER_HEAD, Items.DRAGON_HEAD, - Items.SKELETON_SKULL, Items.WITHER_SKELETON_SKULL); - - private static final Minecraft mc = Minecraft.getInstance(); - - private final boolean thinArms; - - public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, AbstractClientPlayer player, - float f, float g, float h, float j, float k, float l) { - if (player.isInvisible() || !SkinLayersModBase.config.enableHat) { - return; - } - if (mc.level == null) { - return; // in a menu or something and the model gets rendered - } - if (mc.player.distanceToSqr(player) > SkinLayersModBase.config.renderDistanceLOD - * SkinLayersModBase.config.renderDistanceLOD) - return; - - ItemStack itemStack = player.getItemBySlot(EquipmentSlot.HEAD); - if (itemStack != null && hideHeadLayers.contains(itemStack.getItem())) { - return; - } - if (itemStack != null && itemStack.getItem() == Items.PLAYER_HEAD - && !SkinLayersModBase.disguiseHeadsCompatibility) { - return; - } - - PlayerSettings settings = (PlayerSettings) player; - // check for it being setup first to speedup the rendering - if (!SkinUtil.setup3dLayers(player, settings, thinArms, this.getParentModel())) { - return; // no head layer setup and wasn't able to setup - } - - VertexConsumer vertexConsumer = multiBufferSource - .getBuffer(RenderType.entityTranslucent(player.getSkin().texture(), true)); - int overlay = LivingEntityRenderer.getOverlayCoords(player, 0.0f); - renderCustomHelmet(settings, player, poseStack, vertexConsumer, i, overlay); - } - - public void renderCustomHelmet(PlayerSettings settings, AbstractClientPlayer abstractClientPlayer, - PoseStack matrixStack, VertexConsumer vertices, int light, int overlay) { - if (settings.getHeadMesh() == null) - return; - if (!this.getParentModel().head.visible || !abstractClientPlayer.isModelPartShown(PlayerModelPart.HAT)) - return; - float voxelSize = SkinLayersModBase.config.headVoxelSize; - matrixStack.pushPose(); - this.getParentModel().head.translateAndRotate(matrixStack); - matrixStack.translate(0, -0.25, 0); - matrixStack.scale(voxelSize, voxelSize, voxelSize); - matrixStack.translate(0, 0.25, 0); - matrixStack.translate(0, -0.04, 0); - settings.getHeadMesh().render(this.getParentModel().head, matrixStack, vertices, light, overlay, 1.0f, 1.0f, - 1.0f, 1.0f); - matrixStack.popPose(); - - } - -} diff --git a/Shared/src/main/resources/3dskinlayers.mixins.json b/Shared/src/main/resources/3dskinlayers.mixins.json deleted file mode 100644 index 6c17717..0000000 --- a/Shared/src/main/resources/3dskinlayers.mixins.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "dev.tr7zw.skinlayers.mixin", - "compatibilityLevel": "JAVA_16", - "refmap": "3dskinlayers.refmap.mixins.json", - "mixins": [ - ], - "client": [ - "PlayerRendererMixin", - "PlayerMixin", - "PlayerModelMixin", - "SkullBlockEntityRendererMixin", - "SkullModelMixin", - "SkullBlockEntityMixin", - "BlockEntityWithoutLevelRendererMixin", - "CustomHeadLayerMixin", - "HttpTextureMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/sv_se.json b/Shared/src/main/resources/assets/3dskinlayers/lang/sv_se.json deleted file mode 100644 index 1a10371..0000000 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/sv_se.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "text.skinlayers.title": "Inställningar för 3D Skin Layers", - - "text.skinlayers.enable.hat": "3D Hatt", - "text.skinlayers.enable.hat.tooltip": "Rendera spelarens hatt som en 3D-modell", - "text.skinlayers.enable.jacket": "3D Jacka", - "text.skinlayers.enable.jacket.tooltip": "Rendera spelarens jacka som en 3D-modell", - "text.skinlayers.enable.leftsleeve": "3D Vänster Ärm", - "text.skinlayers.enable.leftsleeve.tooltip": "Rendera spelarens vänstra ärm som en 3D-modell", - "text.skinlayers.enable.rightsleeve": "3D Höger Ärm", - "text.skinlayers.enable.rightsleeve.tooltip": "Rendera spelarens högra ärm som en 3D-modell", - "text.skinlayers.enable.leftpants": "3D Vänster Byxben", - "text.skinlayers.enable.leftpants.tooltip": "Rendera spelarens vänstra byxben som en 3D-modell", - "text.skinlayers.enable.rightpants": "3D Höger Byxben", - "text.skinlayers.enable.rightpants.tooltip": "Rendera spelarens högra byxben som en 3D-modell", - "text.skinlayers.renderdistancelod": "Detaljeringsnivå Avstånd", - "text.skinlayers.renderdistancelod.tooltip": "Avståndet från spelaren där modellen byter till en lägre nivå av detalj(vanilla 2d)", - "text.skinlayers.basevoxelsize": "Voxelstorlek", - "text.skinlayers.basevoxelsize.tooltip": "Storleken på voxlarna som används för spelare", - "text.skinlayers.headvoxelsize": "Huvud Voxelstorlek", - "text.skinlayers.headvoxelsize.tooltip": "Storleken på voxlarna som används för spelarens Huvud", - "text.skinlayers.bodyvoxelheightsize": "Kropp Voxelhöjd", - "text.skinlayers.bodyvoxelheightsize.tooltip": "Höjden på voxlarna som används för spelarens kropp(används för att förhindra att den fastnar i huudet/sticker ut ur armarna)", - "text.skinlayers.bodyvoxelwidthsize": "Överkropp Voxelbredd", - "text.skinlayers.bodyvoxelwidthsize.tooltip": "Bredden på voxlarna som används för spelarens överkropp(används för att förhindra att den fastnar i armarna)", - "text.skinlayers.skulls.enable": "3D Döskallar", - "text.skinlayers.skulls.enable.tooltip": "Rendera spelares huvuden(blocket) som en 3D-modell", - "text.skinlayers.skullsitems.enable": "3D Döskalleföremål", - "text.skinlayers.skullsitems.enable.tooltip": "Rendera spelares huvuden(föremålet) som en 3D-modell", - "text.skinlayers.skulls.voxelsize": "Döskalle Voxelstorlek", - "text.skinlayers.skulls.voxelsize.tooltip": "Storleken på voxlarna som används för spelares huvuden(blocket/föremålet)", - "text.skinlayers.reset": "Standard", - "text.skinlayers.fastrender.enable": "Snabb Rendering", - "text.skinlayers.fastrender.enable.tooltip": "Rendera 3D modellerna så fort som möjligt, det här kanske skapar några grafiska buggar med transperens", - "text.skinlayers.firstperson.voxelsize": "Första Person Voxel Storlek", - "text.skinlayers.firstperson.voxelsize.tooltip": "Storleken på voxlarna som används för spelarens hand i första person" -} \ No newline at end of file diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/zh_cn.json b/Shared/src/main/resources/assets/3dskinlayers/lang/zh_cn.json deleted file mode 100644 index d51201b..0000000 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/zh_cn.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "text.skinlayers.title": "3D 皮肤层设置", - "text.skinlayers.enable.hat": "3D 帽子", - "text.skinlayers.enable.hat.tooltip": "将玩家的帽子层渲染为 3D 模型", - "text.skinlayers.enable.jacket": "3D 外套", - "text.skinlayers.enable.jacket.tooltip": "将玩家外套层渲染为 3D 模型", - "text.skinlayers.enable.leftsleeve": "3D 左袖筒", - "text.skinlayers.enable.leftsleeve.tooltip": "将玩家左袖图层渲染为 3D 模型", - "text.skinlayers.enable.rightsleeve": "3D 右袖筒", - "text.skinlayers.enable.rightsleeve.tooltip": "将玩家右袖图层渲染为 3D 模型", - "text.skinlayers.enable.leftpants": "3D 左裤筒", - "text.skinlayers.enable.leftpants.tooltip": "将玩家左侧裤子层渲染为 3D 模型", - "text.skinlayers.enable.rightpants": "3D 右裤筒", - "text.skinlayers.enable.rightpants.tooltip": "将玩家右侧裤子层渲染为 3D 模型", - "text.skinlayers.renderdistancelod": "多层次细节距离", - "text.skinlayers.renderdistancelod.tooltip": "模型切换到较低细节级别的距离(原版 2D)", - "text.skinlayers.basevoxelsize": "像素大小", - "text.skinlayers.basevoxelsize.tooltip": "玩家皮肤使用的像素大小", - "text.skinlayers.headvoxelsize": "头部像素大小", - "text.skinlayers.headvoxelsize.tooltip": "玩家头部所用像素的大小", - "text.skinlayers.bodyvoxelheightsize": "身体像素高度", - "text.skinlayers.bodyvoxelheightsize.tooltip": "玩家身体所用像素的高度(用于防止剪切到头部或伸出手臂)", - "text.skinlayers.bodyvoxelwidthsize": "躯干像素宽度", - "text.skinlayers.bodyvoxelwidthsize.tooltip": "玩家躯干所用像素的宽度(用于防止剪切到手臂)。", - "text.skinlayers.skulls.enable": "3D 头颅", - "text.skinlayers.skulls.enable.tooltip": "将玩家的头(方块)渲染为 3D 模型", - "text.skinlayers.skullsitems.enable": "3D 头颅物品", - "text.skinlayers.skullsitems.enable.tooltip": "将玩家的头(物品)渲染为 3D 模型", - "text.skinlayers.skulls.voxelsize": "头颅体素大小", - "text.skinlayers.skulls.voxelsize.tooltip": "玩家头部(区块/项目)所用体素的大小", - "text.skinlayers.reset": "恢复为默认", - "text.skinlayers.fastrender.enable": "快速渲染", - "text.skinlayers.fastrender.enable.tooltip": "尽可能快地渲染 3D 模型,这可能会导致一些图形透明度问题", - "text.skinlayers.firstperson.voxelsize": "第一人称体素大小", - "text.skinlayers.firstperson.voxelsize.tooltip": "第一人称视角中玩家手部所使用的体素大小", - "modmenu.descriptionTranslation.skinlayers": "以 3D 渲染玩家皮肤层" -} diff --git a/curseforge.md b/curseforge.md index 4d09251..1639f74 100644 --- a/curseforge.md +++ b/curseforge.md @@ -37,10 +37,10 @@ Since this mod is purely visual and fully clientside, it doesn't have to be inst Make sure you pick the correct File depending on Forge/Fabric! -- [1.19.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A73407) -- [1.18.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A73250) -- [1.17.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A73242) -- [1.16.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A70886) +- [1.19.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A73407) +- [1.18.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A73250) +- [1.17.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A73242) +- [1.16.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A70886) - [1.15.x ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A68722) - [1.12.2 ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=2020709689%3A6756) - [1.8.9/8 ⬇️](https://www.curseforge.com/minecraft/mc-mods/skin-layers-3d/files/all?filter-status=1&filter-game-version=1738749986%3A4) diff --git a/gradle-compose.yml b/gradle-compose.yml index 9615776..805687b 100644 --- a/gradle-compose.yml +++ b/gradle-compose.yml @@ -1,9 +1,15 @@ version: '0.0.2' -source: "https://github.com/tr7zw/ModComposeTemplate/tree/1.20.2" +source: "https://github.com/tr7zw/ProcessedModTemplate/tree/master" replacements: name: "3d-Skin-Layers" - id: "3dskinlayers" + id: "skinlayers3d" version: "1.5.6" + description: "Renders the player skin layer in 3d" + homepageUrl: "https://modrinth.com/mod/3dskinlayers" + sourcesUrl: "https://github.com/tr7zw/3d-skin-layers" + issuesUrl: "https://github.com/tr7zw/3d-skin-layers/issues" + fabric_entrypoint: "dev.tr7zw.skinlayers.SkinLayersMod" + fabric_modmenu_entrypoint: "dev.tr7zw.skinlayers.SkinLayersModMenu" relocationpackage: "dev.tr7zw.skinlayers" modrinthid: zV5r3pPn curseforgeid: 521480 @@ -11,12 +17,18 @@ enabledFlags: - autopublish - publishFabric - publishForge + - publishNeo - modrinth - curseforge + - versionless rootProject: template: "." subProjects: - 3dSkinLayers-Fabric: - template: "Fabric" - 3dSkinLayers-Forge: - template: "Forge" \ No newline at end of file + 3dSkinLayers-Versionless: + template: "Versionless" + replacements: + dependencies: ' + compileOnly "com.google.code.gson:gson:2.10.1" + + compileOnly "org.apache.logging.log4j:log4j-core:2.20.0" + ' \ No newline at end of file diff --git a/modrinth.md b/modrinth.md index ae07108..8070aef 100644 --- a/modrinth.md +++ b/modrinth.md @@ -53,4 +53,4 @@ Check under Options > Skin Customization that you didn't accidentally disable yo ![](https://raw.githubusercontent.com/tr7zw/3d-Skin-Layers/1.19/img/MC_NU_BANNER3.png) -Support via [![Discord](https://tr7zw.dev/curse/Discord.png)](https://discord.gg/2wKH8yeThf) or [Github](https://github.com/tr7zw/3d-skin-layers)! \ No newline at end of file +Support via [![Discord](https://tr7zw.dev/curse/Discord.png)](https://discord.gg/2wKH8yeThf) or [Github](https://github.com/tr7zw/3d-skin-layers)! diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..ec993b7 --- /dev/null +++ b/settings.json @@ -0,0 +1,24 @@ +{ + "versions": [ + "1.16.5-fabric", + "1.16.5-forge", + "1.17.1-fabric", + "1.17.1-forge", + "1.18.2-fabric", + "1.18.2-forge", + "1.19.2-fabric", + "1.19.2-forge", + "1.19.3-fabric", + "1.19.3-forge", + "1.19.4-fabric", + "1.19.4-forge", + "1.20.1-fabric", + "1.20.1-forge", + "1.20.2-fabric", + "1.20.2-forge", + "1.20.2-neoforge", + "1.20.4-fabric", + "1.20.4-forge", + "1.20.4-neoforge" + ] +} diff --git a/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java b/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java new file mode 100644 index 0000000..f905539 --- /dev/null +++ b/src/main/java/dev/tr7zw/skinlayers/SkinLayersMod.java @@ -0,0 +1,124 @@ +package dev.tr7zw.skinlayers; + +//spotless:off +//#if FABRIC +import net.fabricmc.api.ClientModInitializer; + +public class SkinLayersMod extends SkinLayersModBase implements ClientModInitializer { + + @Override + public void onInitializeClient() { + this.onInitialize(); + } + + +//#elseif FORGE +//$$ + //$$ import net.minecraftforge.fml.ModLoadingContext; + //$$ import net.minecraftforge.fml.common.Mod; + //$$ import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; + //$$ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + //$$ import dev.tr7zw.skinlayers.config.ConfigScreenProvider; + //$$ import dev.tr7zw.config.CustomConfigScreen; + //$$ import dev.tr7zw.skinlayers.config.ConfigScreenProvider; + //$$ + //#if MC <= 11605 + //$$ import net.minecraftforge.fml.ExtensionPoint; + //$$ import net.minecraftforge.fml.network.FMLNetworkConstants; + //$$ import org.apache.commons.lang3.tuple.Pair; + //#elseif MC <= 11701 + //$$ import net.minecraftforge.fml.IExtensionPoint; + //$$ import net.minecraftforge.fmlclient.ConfigGuiHandler.ConfigGuiFactory; + //#elseif MC <= 11802 + //$$ import net.minecraftforge.fml.IExtensionPoint; + //$$ import net.minecraftforge.client.ConfigGuiHandler.ConfigGuiFactory; + //#else + //$$ import net.minecraftforge.fml.IExtensionPoint; + //$$ import net.minecraftforge.client.ConfigScreenHandler.ConfigScreenFactory; + //#endif + //$$ @Mod("skinlayers3d") + //$$ public class SkinLayersMod extends SkinLayersModBase { + //$$ + //$$ //Forge only + //$$ private boolean onServer = false; + //$$ + //$$ public SkinLayersMod() { + //$$ try { + //$$ Class clientClass = net.minecraft.client.Minecraft.class; + //$$ }catch(Throwable ex) { + //$$ System.out.println("3dSkinLayers Mod installed on a Server. Going to sleep."); + //$$ onServer = true; + //$$ return; + //$$ } + //#if MC <= 11605 + //$$ ModLoadingContext.get().registerExtensionPoint( + //$$ ExtensionPoint.CONFIGGUIFACTORY, + //$$ () -> (mc, screen) -> ConfigScreenProvider.createConfigScreen(screen)); + //#elseif MC <= 11802 + //$$ ModLoadingContext.get().registerExtensionPoint(ConfigGuiFactory.class, () -> new ConfigGuiFactory((mc, screen) -> { + //$$ return ConfigScreenProvider.createConfigScreen(screen); + //$$ })); + //#else + //$$ ModLoadingContext.get().registerExtensionPoint(ConfigScreenFactory.class, () -> new ConfigScreenFactory((mc, screen) -> { + //$$ return ConfigScreenProvider.createConfigScreen(screen); + //$$ })); + //#endif + //#if MC <= 11605 + //$$ ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.DISPLAYTEST, + //$$ () -> Pair.of(() -> FMLNetworkConstants.IGNORESERVERONLY, (remote, isServer) -> true)); + //#else + //$$ ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, + //$$ () -> new IExtensionPoint.DisplayTest( + //$$ () -> ModLoadingContext.get().getActiveContainer().getModInfo().getVersion().toString(), + //$$ (remote, isServer) -> true)); + //#endif + //$$ FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); + //$$ } + //$$ + //$$ private void setup(final FMLCommonSetupEvent event) { + //$$ if(onServer)return; + //$$ onInitialize(); + //$$ } + //#elseif NEOFORGE + //$$ import net.neoforged.fml.IExtensionPoint; + //$$ import net.neoforged.fml.ModLoadingContext; + //$$ import net.neoforged.fml.common.Mod; + //$$ import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; + //$$ import net.neoforged.fml.javafmlmod.FMLJavaModLoadingContext; + //$$ import net.neoforged.neoforge.client.ConfigScreenHandler.ConfigScreenFactory; + //$$ import dev.tr7zw.skinlayers.config.ConfigScreenProvider; + //$$ + //$$ @Mod("skinlayers3d") + //$$ public class SkinLayersMod extends SkinLayersModBase { + //$$ + //$$ // Forge only + //$$ private boolean onServer = false; + //$$ + //$$ public SkinLayersMod() { + //$$ try { + //$$ Class clientClass = net.minecraft.client.Minecraft.class; + //$$ } catch (Throwable ex) { + //$$ System.out.println("3dSkinLayers Mod installed on a Server. Going to sleep."); + //$$ onServer = true; + //$$ return; + //$$ } + //$$ ModLoadingContext.get().registerExtensionPoint(ConfigScreenFactory.class, + //$$ () -> new ConfigScreenFactory((mc, screen) -> { + //$$ return ConfigScreenProvider.createConfigScreen(screen); + //$$ })); + //$$ ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, + //$$ () -> new IExtensionPoint.DisplayTest( + //$$ () -> ModLoadingContext.get().getActiveContainer().getModInfo().getVersion().toString(), + //$$ (remote, isServer) -> true)); + //$$ FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); + //$$ } + //$$ + //$$ private void setup(final FMLCommonSetupEvent event) { + //$$ if (onServer) + //$$ return; + //$$ onInitialize(); + //$$ } +//#endif + // spotless:on + +} diff --git a/src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java b/src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java new file mode 100644 index 0000000..25143d2 --- /dev/null +++ b/src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java @@ -0,0 +1,27 @@ +package dev.tr7zw.skinlayers; + +import dev.tr7zw.skinlayers.accessor.PlayerSettings; +import dev.tr7zw.skinlayers.versionless.ModBase; +import dev.tr7zw.skinlayers.versionless.ModBase; +import dev.tr7zw.skinlayers.versionless.ModBase; +import net.minecraft.world.entity.player.Player; + +public abstract class SkinLayersModBase extends ModBase { + + public static SkinLayersModBase instance; + + @Override + public void onInitialize() { + instance = this; + super.onInitialize(); + } + + public void refreshLayers(Player player) { + if (player == null || !(player instanceof PlayerSettings)) + return; + PlayerSettings settings = (PlayerSettings) player; + settings.clearMeshes(); + settings.setCurrentSkin(null); + } + +} diff --git a/3dSkinLayers-Fabric/src/main/java/dev/tr7zw/skinlayers/SkinLayersModMenu.java b/src/main/java/dev/tr7zw/skinlayers/SkinLayersModMenu.java similarity index 68% rename from 3dSkinLayers-Fabric/src/main/java/dev/tr7zw/skinlayers/SkinLayersModMenu.java rename to src/main/java/dev/tr7zw/skinlayers/SkinLayersModMenu.java index f02de99..d681b6e 100644 --- a/3dSkinLayers-Fabric/src/main/java/dev/tr7zw/skinlayers/SkinLayersModMenu.java +++ b/src/main/java/dev/tr7zw/skinlayers/SkinLayersModMenu.java @@ -1,15 +1,19 @@ +//#if FABRIC package dev.tr7zw.skinlayers; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; +import dev.tr7zw.skinlayers.config.ConfigScreenProvider; + public class SkinLayersModMenu implements ModMenuApi { @Override public ConfigScreenFactory getModConfigScreenFactory() { return parent -> { - return SkinLayersModBase.instance.createConfigScreen(parent); + return ConfigScreenProvider.createConfigScreen(parent); }; } } +//#endif \ No newline at end of file diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/SkinUtil.java b/src/main/java/dev/tr7zw/skinlayers/SkinUtil.java similarity index 74% rename from Shared/src/main/java/dev/tr7zw/skinlayers/SkinUtil.java rename to src/main/java/dev/tr7zw/skinlayers/SkinUtil.java index 82e646d..353df73 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/SkinUtil.java +++ b/src/main/java/dev/tr7zw/skinlayers/SkinUtil.java @@ -13,13 +13,13 @@ import dev.tr7zw.skinlayers.accessor.HttpTextureAccessor; import dev.tr7zw.skinlayers.accessor.PlayerSettings; import dev.tr7zw.skinlayers.accessor.SkullSettings; -import dev.tr7zw.skinlayers.render.SolidPixelWrapper; +import dev.tr7zw.skinlayers.api.SkinLayersAPI; +import dev.tr7zw.skinlayers.util.NMSWrapper; import net.minecraft.client.Minecraft; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.texture.AbstractTexture; import net.minecraft.client.renderer.texture.DynamicTexture; -import net.minecraft.client.resources.PlayerSkin; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.Resource; @@ -40,15 +40,23 @@ public void onRemoval(RemovalNotification notifica }).build(); private static NativeImage getSkinTexture(AbstractClientPlayer player) { - return getTexture(player.getSkin().texture(), null); + return getTexture(NMSWrapper.getPlayerSkin(player), null); } private static NativeImage getTexture(ResourceLocation resourceLocation, SkullSettings settings) { try { + // spotless:off + //#if MC >= 11900 Optional optionalRes = Minecraft.getInstance().getResourceManager().getResource(resourceLocation); if (optionalRes.isPresent()) { Resource resource = optionalRes.get(); NativeImage skin = NativeImage.read(resource.open()); + //#else + //$$ if(Minecraft.getInstance().getResourceManager().hasResource(resourceLocation)) { + //$$ Resource resource = Minecraft.getInstance().getResourceManager().getResource(resourceLocation); + //$$ NativeImage skin = NativeImage.read(resource.getInputStream()); + //#endif + // spotless:on return skin; } AbstractTexture texture = Minecraft.getInstance().getTextureManager().getTexture(resourceLocation); @@ -95,16 +103,12 @@ private static NativeImage getTexture(ResourceLocation resourceLocation, SkullSe } // This would work, but hd skins will crash the JVM. Only /* - try { - NativeImage img = new NativeImage(Format.RGBA, 64, 64, true); - GlStateManager._bindTexture(texture.getId()); - img.downloadTexture(0, false); - cache.put(texture, img); - return img; - }catch(Exception ex) { - SkinLayersModBase.LOGGER.error("Error while trying to grab a texture from the GPU.", ex); - } - */ + * try { NativeImage img = new NativeImage(Format.RGBA, 64, 64, true); + * GlStateManager._bindTexture(texture.getId()); img.downloadTexture(0, false); + * cache.put(texture, img); return img; }catch(Exception ex) { + * SkinLayersModBase.LOGGER. + * error("Error while trying to grab a texture from the GPU.", ex); } + */ settings.setInitialized(true); // initialize as invalid SkinLayersModBase.LOGGER.warn("Unable to handle skin " + resourceLocation + ". Potentially a conflict with another mod. (" + texture.getClass().getName() + ")"); @@ -117,7 +121,7 @@ private static NativeImage getTexture(ResourceLocation resourceLocation, SkullSe public static boolean setup3dLayers(AbstractClientPlayer abstractClientPlayerEntity, PlayerSettings settings, boolean thinArms, PlayerModel model) { - ResourceLocation skinLocation = abstractClientPlayerEntity.getSkin().texture(); + ResourceLocation skinLocation = NMSWrapper.getPlayerSkin(abstractClientPlayerEntity); if (skinLocation == null) { return false;// this *should* never happen, but just to be sure } @@ -138,17 +142,17 @@ public static boolean setup3dLayers(AbstractClientPlayer abstractClientPlayerEnt settings.clearMeshes(); return false; } - settings.setLeftLegMesh(SolidPixelWrapper.wrapBox(skin, 4, 12, 4, 0, 48, true, 0f)); - settings.setRightLegMesh(SolidPixelWrapper.wrapBox(skin, 4, 12, 4, 0, 32, true, 0f)); + settings.setLeftLegMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 4, 12, 4, 0, 48, true, 0f)); + settings.setRightLegMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 4, 12, 4, 0, 32, true, 0f)); if (thinArms) { - settings.setLeftArmMesh(SolidPixelWrapper.wrapBox(skin, 3, 12, 4, 48, 48, true, -2f)); - settings.setRightArmMesh(SolidPixelWrapper.wrapBox(skin, 3, 12, 4, 40, 32, true, -2f)); + settings.setLeftArmMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 3, 12, 4, 48, 48, true, -2f)); + settings.setRightArmMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 3, 12, 4, 40, 32, true, -2f)); } else { - settings.setLeftArmMesh(SolidPixelWrapper.wrapBox(skin, 4, 12, 4, 48, 48, true, -2)); - settings.setRightArmMesh(SolidPixelWrapper.wrapBox(skin, 4, 12, 4, 40, 32, true, -2)); + settings.setLeftArmMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 4, 12, 4, 48, 48, true, -2)); + settings.setRightArmMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 4, 12, 4, 40, 32, true, -2)); } - settings.setTorsoMesh(SolidPixelWrapper.wrapBox(skin, 8, 12, 4, 16, 32, true, 0)); - settings.setHeadMesh(SolidPixelWrapper.wrapBox(skin, 8, 8, 8, 32, 0, false, 0.6f)); + settings.setTorsoMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 8, 12, 4, 16, 32, true, 0)); + settings.setHeadMesh(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 8, 8, 8, 32, 0, false, 0.6f)); settings.setCurrentSkin(skinLocation); settings.setThinArms(thinArms); return true; @@ -158,16 +162,15 @@ public static boolean setup3dLayers(GameProfile gameprofile, SkullSettings setti if (gameprofile == null) { return false; // no gameprofile } - PlayerSkin playerSkin = Minecraft.getInstance().getSkinManager() - .getInsecureSkin(gameprofile); - if (playerSkin.textureUrl() == null) { - return false; // it's a gameprofile, but no skin. + ResourceLocation playerSkin = NMSWrapper.getPlayerSkin(gameprofile); + if (playerSkin == null) { + return false; // no skin } - NativeImage skin = SkinUtil.getTexture(playerSkin.texture(), settings); + NativeImage skin = SkinUtil.getTexture(playerSkin, settings); if (skin == null || skin.getWidth() != 64 || skin.getHeight() != 64) { return false; } - settings.setupHeadLayers(SolidPixelWrapper.wrapBox(skin, 8, 8, 8, 32, 0, false, 0.6f)); + settings.setupHeadLayers(SkinLayersAPI.getMeshHelper().create3DMesh(skin, 8, 8, 8, 32, 0, false, 0.6f)); settings.setInitialized(true); return true; } diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/SkullRendererCache.java b/src/main/java/dev/tr7zw/skinlayers/SkullRendererCache.java similarity index 99% rename from Shared/src/main/java/dev/tr7zw/skinlayers/SkullRendererCache.java rename to src/main/java/dev/tr7zw/skinlayers/SkullRendererCache.java index 125211a..e804548 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/SkullRendererCache.java +++ b/src/main/java/dev/tr7zw/skinlayers/SkullRendererCache.java @@ -41,7 +41,7 @@ public void setInitialized(boolean initialized) { @Override public void setLastTexture(ResourceLocation texture) { // TODO Auto-generated method stub - + } @Override diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/accessor/HttpTextureAccessor.java b/src/main/java/dev/tr7zw/skinlayers/accessor/HttpTextureAccessor.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/accessor/HttpTextureAccessor.java rename to src/main/java/dev/tr7zw/skinlayers/accessor/HttpTextureAccessor.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/accessor/PlayerEntityModelAccessor.java b/src/main/java/dev/tr7zw/skinlayers/accessor/PlayerEntityModelAccessor.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/accessor/PlayerEntityModelAccessor.java rename to src/main/java/dev/tr7zw/skinlayers/accessor/PlayerEntityModelAccessor.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/accessor/PlayerSettings.java b/src/main/java/dev/tr7zw/skinlayers/accessor/PlayerSettings.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/accessor/PlayerSettings.java rename to src/main/java/dev/tr7zw/skinlayers/accessor/PlayerSettings.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/accessor/SkullModelAccessor.java b/src/main/java/dev/tr7zw/skinlayers/accessor/SkullModelAccessor.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/accessor/SkullModelAccessor.java rename to src/main/java/dev/tr7zw/skinlayers/accessor/SkullModelAccessor.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/accessor/SkullSettings.java b/src/main/java/dev/tr7zw/skinlayers/accessor/SkullSettings.java similarity index 98% rename from Shared/src/main/java/dev/tr7zw/skinlayers/accessor/SkullSettings.java rename to src/main/java/dev/tr7zw/skinlayers/accessor/SkullSettings.java index 410f62c..01719ef 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/accessor/SkullSettings.java +++ b/src/main/java/dev/tr7zw/skinlayers/accessor/SkullSettings.java @@ -13,9 +13,9 @@ public interface SkullSettings extends SkullData { public boolean initialized(); public void setInitialized(boolean initialized); - + public void setLastTexture(ResourceLocation texture); - + public ResourceLocation getLastTexture(); @Override diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/LayerFeatureTransformerAPI.java b/src/main/java/dev/tr7zw/skinlayers/api/LayerFeatureTransformerAPI.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/LayerFeatureTransformerAPI.java rename to src/main/java/dev/tr7zw/skinlayers/api/LayerFeatureTransformerAPI.java diff --git a/src/main/java/dev/tr7zw/skinlayers/api/Mesh.java b/src/main/java/dev/tr7zw/skinlayers/api/Mesh.java new file mode 100644 index 0000000..32db474 --- /dev/null +++ b/src/main/java/dev/tr7zw/skinlayers/api/Mesh.java @@ -0,0 +1,79 @@ +package dev.tr7zw.skinlayers.api; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; + +import net.minecraft.client.model.geom.ModelPart; +// spotless:off +//#if MC >= 11700 +import net.minecraft.client.model.geom.PartPose; +//#endif +//spotless:on + +public interface Mesh { + + public static final Mesh EMPTY = new Mesh() { + + @Override + public void setVisible(boolean visible) { + } + + @Override + public void setRotation(float xRot, float yRot, float zRot) { + } + + @Override + public void setPosition(float x, float y, float z) { + } + + @Override + public void render(ModelPart vanillaModel, PoseStack poseStack, VertexConsumer vertexConsumer, int light, + int overlay, float red, float green, float blue, float alpha) { + } + + @Override + // spotless:off + //#if MC >= 11700 + public void loadPose(PartPose partPose) { + //#else + //$$ public void loadPose(ModelPart partPose) { + //#endif + //spotless:on + } + + @Override + public boolean isVisible() { + return false; + } + + @Override + public void copyFrom(ModelPart modelPart) { + } + }; + + public default void render(PoseStack poseStack, VertexConsumer vertexConsumer, int light, int overlay) { + render(null, poseStack, vertexConsumer, light, overlay, 1.0F, 1.0F, 1.0F, 1.0F); + } + + public void render(ModelPart vanillaModel, PoseStack poseStack, VertexConsumer vertexConsumer, int light, + int overlay, float red, float green, float blue, float alpha); + + public void setPosition(float x, float y, float z); + + public void setRotation(float xRot, float yRot, float zRot); + + // spotless:off + //#if MC >= 11700 + public void loadPose(PartPose partPose); + //#else + //$$ public void loadPose(ModelPart partPose); + //#endif + //spotless:on + + public void copyFrom(ModelPart modelPart); + + public void setVisible(boolean visible); + + public boolean isVisible(); + +} diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshHelper.java b/src/main/java/dev/tr7zw/skinlayers/api/MeshHelper.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshHelper.java rename to src/main/java/dev/tr7zw/skinlayers/api/MeshHelper.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshProvider.java b/src/main/java/dev/tr7zw/skinlayers/api/MeshProvider.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshProvider.java rename to src/main/java/dev/tr7zw/skinlayers/api/MeshProvider.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformer.java b/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformer.java similarity index 83% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformer.java rename to src/main/java/dev/tr7zw/skinlayers/api/MeshTransformer.java index a1b042e..da1a7d8 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformer.java +++ b/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformer.java @@ -1,7 +1,14 @@ package dev.tr7zw.skinlayers.api; +//spotless:off +//#if MC >= 11903 import org.joml.Vector3f; import org.joml.Vector4f; +//#else +//$$ import com.mojang.math.Vector3f; +//$$ import com.mojang.math.Vector4f; +//#endif +//spotless:on import net.minecraft.client.model.geom.ModelPart.Cube; diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformerProvider.java b/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformerProvider.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/MeshTransformerProvider.java rename to src/main/java/dev/tr7zw/skinlayers/api/MeshTransformerProvider.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/PlayerData.java b/src/main/java/dev/tr7zw/skinlayers/api/PlayerData.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/PlayerData.java rename to src/main/java/dev/tr7zw/skinlayers/api/PlayerData.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/SkinLayersAPI.java b/src/main/java/dev/tr7zw/skinlayers/api/SkinLayersAPI.java similarity index 66% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/SkinLayersAPI.java rename to src/main/java/dev/tr7zw/skinlayers/api/SkinLayersAPI.java index e72042e..f8b42ce 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/api/SkinLayersAPI.java +++ b/src/main/java/dev/tr7zw/skinlayers/api/SkinLayersAPI.java @@ -1,8 +1,13 @@ package dev.tr7zw.skinlayers.api; +import java.util.Collections; + import com.mojang.blaze3d.platform.NativeImage; -import dev.tr7zw.skinlayers.render.SolidPixelWrapper; +import dev.tr7zw.skinlayers.render.CustomizableCubeListBuilder; +import dev.tr7zw.skinlayers.render.CustomizableModelPart; +import dev.tr7zw.skinlayers.util.NMSWrapper.WrappedNativeImage; +import dev.tr7zw.skinlayers.versionless.util.wrapper.SolidPixelWrapper; import net.minecraft.client.player.AbstractClientPlayer; public class SkinLayersAPI { @@ -36,8 +41,12 @@ private static class MeshHelperImplementation implements MeshHelper { @Override public Mesh create3DMesh(NativeImage natImage, int width, int height, int depth, int textureU, int textureV, boolean topPivot, float rotationOffset) { - return SolidPixelWrapper.wrapBox(natImage, width, height, depth, textureU, textureV, topPivot, - rotationOffset); + CustomizableCubeListBuilder builder = new CustomizableCubeListBuilder(); + if (SolidPixelWrapper.wrapBox(builder, new WrappedNativeImage(natImage), width, height, depth, textureU, + textureV, topPivot, rotationOffset) != null) { + return new CustomizableModelPart(builder.getVanillaCubes(), builder.getCubes(), Collections.emptyMap()); + } + return Mesh.EMPTY; } } @@ -46,8 +55,8 @@ private static class MeshProviderImplementation implements MeshProvider { @Override public PlayerData getPlayerMesh(AbstractClientPlayer abstractClientPlayerEntity) { - if (abstractClientPlayerEntity instanceof PlayerData data) { - return data; + if (abstractClientPlayerEntity instanceof PlayerData) { + return (PlayerData) abstractClientPlayerEntity; } return null; } diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/api/SkullData.java b/src/main/java/dev/tr7zw/skinlayers/api/SkullData.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/api/SkullData.java rename to src/main/java/dev/tr7zw/skinlayers/api/SkullData.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java b/src/main/java/dev/tr7zw/skinlayers/config/ConfigScreenProvider.java similarity index 60% rename from Shared/src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java rename to src/main/java/dev/tr7zw/skinlayers/config/ConfigScreenProvider.java index f971699..d495b07 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/SkinLayersModBase.java +++ b/src/main/java/dev/tr7zw/skinlayers/config/ConfigScreenProvider.java @@ -1,75 +1,37 @@ -package dev.tr7zw.skinlayers; +package dev.tr7zw.skinlayers.config; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.util.ArrayList; import java.util.List; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - import dev.tr7zw.config.CustomConfigScreen; -import dev.tr7zw.skinlayers.accessor.PlayerSettings; -import dev.tr7zw.skinlayers.render.PreviewHelper; -import net.minecraft.client.OptionInstance; +import dev.tr7zw.skinlayers.SkinLayersModBase; +import dev.tr7zw.skinlayers.versionless.ModBase; +import dev.tr7zw.skinlayers.versionless.config.Config; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.inventory.InventoryScreen; -import net.minecraft.world.entity.player.Player; - -public abstract class SkinLayersModBase { - - public static SkinLayersModBase instance; - public static final Logger LOGGER = LogManager.getLogger(); - public static Config config = null; - private File settingsFile = new File("config", "skinlayers.json"); - private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - public static boolean disguiseHeadsCompatibility = false; - - public void onInitialize() { - instance = this; - if (settingsFile.exists()) { - try { - config = new Gson().fromJson( - new String(Files.readAllBytes(settingsFile.toPath()), StandardCharsets.UTF_8), Config.class); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - if (config == null) { - config = new Config(); - writeConfig(); - } - try { - Class clientClass = Class.forName("dev.tr7zw.disguiseheads.DisguiseHeadsShared"); - disguiseHeadsCompatibility = clientClass != null; // to shut up the compiler that the var is not used - LOGGER.info("Found DisguiseHeads, enable compatibility!"); - } catch (Throwable ex) { - // not installed - } - } +//spotless:off +//#if MC <= 11904 +//$$ import net.minecraft.client.gui.screens.inventory.InventoryScreen; +//$$ import com.mojang.blaze3d.vertex.PoseStack; +//#else +import dev.tr7zw.skinlayers.render.PreviewHelper; +//#endif +//#if MC >= 11900 +import net.minecraft.client.OptionInstance; +//#else +//$$ import net.minecraft.client.Option; +//#endif +//spotless:on - public void writeConfig() { - if (settingsFile.exists()) - settingsFile.delete(); - try { - Files.write(settingsFile.toPath(), gson.toJson(config).getBytes(StandardCharsets.UTF_8)); - } catch (IOException e1) { - e1.printStackTrace(); - } - } +public class ConfigScreenProvider { - public Screen createConfigScreen(Screen parent) { - CustomConfigScreen screen = new CustomConfigScreen(parent, "text.skinlayers.title") { + public static Screen createConfigScreen(Screen parent) { + return new CustomConfigScreen(parent, "text.skinlayers.title") { @Override public void initialize() { - List> options = new ArrayList<>(); + Config config = SkinLayersModBase.config; + List options = new ArrayList<>(); options.add(getOnOffOption("text.skinlayers.enable.hat", () -> config.enableHat, (b) -> config.enableHat = b)); options.add(getOnOffOption("text.skinlayers.enable.jacket", () -> config.enableJacket, @@ -87,17 +49,17 @@ public void initialize() { options.add(getDoubleOption("text.skinlayers.basevoxelsize", 1.001f, 1.4f, 0.001f, () -> (double) config.baseVoxelSize, (i) -> { config.baseVoxelSize = i.floatValue(); - refreshLayers(this.minecraft.player); + SkinLayersModBase.instance.refreshLayers(this.minecraft.player); })); options.add(getDoubleOption("text.skinlayers.headvoxelsize", 1.001f, 1.25f, 0.001f, () -> (double) config.headVoxelSize, (i) -> { config.headVoxelSize = i.floatValue(); - refreshLayers(this.minecraft.player); + SkinLayersModBase.instance.refreshLayers(this.minecraft.player); })); options.add(getDoubleOption("text.skinlayers.bodyvoxelwidthsize", 1.001f, 1.4f, 0.001f, () -> (double) config.bodyVoxelWidthSize, (i) -> { config.bodyVoxelWidthSize = i.floatValue(); - refreshLayers(this.minecraft.player); + SkinLayersModBase.instance.refreshLayers(this.minecraft.player); })); options.add(getOnOffOption("text.skinlayers.skulls.enable", () -> config.enableSkulls, (b) -> config.enableSkulls = b)); @@ -113,18 +75,30 @@ public void initialize() { () -> (double) config.firstPersonPixelScaling, (i) -> { config.firstPersonPixelScaling = i.floatValue(); })); + // spotless:off + //#if MC >= 11900 getOptions().addSmall(options.toArray(new OptionInstance[0])); + //#else + //$$getOptions().addSmall(options.toArray(new Option[0])); + //#endif } @Override public void save() { - writeConfig(); + SkinLayersModBase.instance.writeConfig(); } @Override + // spotless:off + //#if MC >= 12001 public void render(GuiGraphics guiGraphics, int xMouse, int yMouse, float f) { super.render(guiGraphics, xMouse, yMouse, f); + //#else + //$$ public void render(PoseStack poseStack, int xMouse, int yMouse, float f) { + //$$ super.render(poseStack, xMouse, yMouse, f); + //#endif + // spotless:on if (this.minecraft.level != null) { int x = minecraft.getWindow().getGuiScaledWidth() / 2; int y = minecraft.getWindow().getGuiScaledHeight() - 45; @@ -133,27 +107,28 @@ public void render(GuiGraphics guiGraphics, int xMouse, int yMouse, float f) { float lookY = y - 80 - yMouse; // Prevent the model from clipping into the back of the gui^^ lookY = Math.min(lookY, 10); - PreviewHelper.renderEntityInInventoryFollowsMouse(guiGraphics, x, y, size, lookX, lookY, this.minecraft.player); + // spotless:off + //#if MC >= 12001 + PreviewHelper.renderEntityInInventoryFollowsMouse(guiGraphics, x, y, size, lookX, lookY, + this.minecraft.player); + //#elseif MC >= 11904 + //$$ InventoryScreen.renderEntityInInventoryFollowsMouse(poseStack, x, y, size, lookX, lookY, + //$$ this.minecraft.player); + //#else + //$$ InventoryScreen.renderEntityInInventory(x, y, size, lookX, lookY, + //$$ this.minecraft.player); + //#endif + // spotless:on } } @Override public void reset() { - config = new Config(); - writeConfig(); + ModBase.config = new Config(); + SkinLayersModBase.instance.writeConfig(); } }; - - return screen; - } - - public void refreshLayers(Player player) { - if (player == null || !(player instanceof PlayerSettings)) - return; - PlayerSettings settings = (PlayerSettings) player; - settings.clearMeshes(); - settings.setCurrentSkin(null); } } diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/BlockEntityWithoutLevelRendererMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/BlockEntityWithoutLevelRendererMixin.java similarity index 88% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/BlockEntityWithoutLevelRendererMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/BlockEntityWithoutLevelRendererMixin.java index 809c149..413962d 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/BlockEntityWithoutLevelRendererMixin.java +++ b/src/main/java/dev/tr7zw/skinlayers/mixin/BlockEntityWithoutLevelRendererMixin.java @@ -4,12 +4,9 @@ import static dev.tr7zw.skinlayers.SkullRendererCache.lastSkull; import static dev.tr7zw.skinlayers.SkullRendererCache.renderNext; -import java.util.Map; - import net.minecraft.Util; import org.apache.commons.lang3.StringUtils; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -21,28 +18,38 @@ import dev.tr7zw.skinlayers.SkinUtil; import dev.tr7zw.skinlayers.SkullRendererCache.ItemSettings; import dev.tr7zw.skinlayers.accessor.SkullSettings; -import net.minecraft.client.model.SkullModelBase; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemDisplayContext; + import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.AbstractSkullBlock; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SkullBlock; + +//spotless:off +//#if MC >= 11904 +import net.minecraft.world.item.ItemDisplayContext; +//#else +//$$ import net.minecraft.client.renderer.block.model.ItemTransforms; +//#endif +//spotless:on @Mixin(BlockEntityWithoutLevelRenderer.class) public class BlockEntityWithoutLevelRendererMixin { - @Shadow - private Map skullModels; - @Inject(method = "renderByItem", at = @At("HEAD")) + // spotless:off + //#if MC >= 11904 public void renderByItem(ItemStack itemStack, ItemDisplayContext itemDisplayContext, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, int j, CallbackInfo info) { + //#else + //$$ public void renderByItem(ItemStack itemStack, ItemTransforms.TransformType transformType, PoseStack poseStack, + //$$ MultiBufferSource multiBufferSource, int i, int j, CallbackInfo info) { + //#endif + // spotless:on if (!SkinLayersModBase.config.enableSkullsItems) return; Item item = itemStack.getItem(); diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/CustomHeadLayerMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/CustomHeadLayerMixin.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/CustomHeadLayerMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/CustomHeadLayerMixin.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/HttpTextureMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/HttpTextureMixin.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/HttpTextureMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/HttpTextureMixin.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerMixin.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/PlayerMixin.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerModelMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerModelMixin.java similarity index 83% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerModelMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/PlayerModelMixin.java index 7962bd7..4e74846 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerModelMixin.java +++ b/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerModelMixin.java @@ -12,9 +12,17 @@ @Mixin(PlayerModel.class) public class PlayerModelMixin extends HumanoidModel implements PlayerEntityModelAccessor { + // spotless:off + //#if MC >= 11700 public PlayerModelMixin(ModelPart modelPart) { super(modelPart); } + //#else + //$$ public PlayerModelMixin(float f) { + //$$ super(f); + //$$ } + //#endif + //spotless:on @Shadow private boolean slim; diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerRendererMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerRendererMixin.java similarity index 87% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerRendererMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/PlayerRendererMixin.java index 8141bbf..d65387d 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerRendererMixin.java +++ b/src/main/java/dev/tr7zw/skinlayers/mixin/PlayerRendererMixin.java @@ -12,32 +12,48 @@ import dev.tr7zw.skinlayers.accessor.PlayerEntityModelAccessor; import dev.tr7zw.skinlayers.accessor.PlayerSettings; import dev.tr7zw.skinlayers.api.Mesh; -import dev.tr7zw.skinlayers.renderlayers.BodyLayerFeatureRenderer; -import dev.tr7zw.skinlayers.renderlayers.HeadLayerFeatureRenderer; +import dev.tr7zw.skinlayers.renderlayers.CustomLayerFeatureRenderer; +import dev.tr7zw.skinlayers.util.NMSWrapper; import net.minecraft.client.Minecraft; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.EntityRendererProvider.Context; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.world.entity.player.PlayerModelPart; +// spotless:off +//#if MC >= 11700 +import net.minecraft.client.renderer.entity.EntityRendererProvider.Context; +//#else +//$$ +//#endif +// spotless:on @Mixin(PlayerRenderer.class) public abstract class PlayerRendererMixin extends LivingEntityRenderer> { + // spotless:off + //#if MC >= 11700 public PlayerRendererMixin(Context context, PlayerModel entityModel, float f) { super(context, entityModel, f); } + //#else + //$$ public PlayerRendererMixin(EntityRenderDispatcher entityRenderDispatcher, + //$$ PlayerModel entityModel, float f) { + //$$ super(entityRenderDispatcher, entityModel, f); + //$$ // TODO Auto-generated constructor stub + //$$ } + //#endif + // spotless:on @Inject(method = "*", at = @At("RETURN")) public void onCreate(CallbackInfo info) { - this.addLayer(new HeadLayerFeatureRenderer(this)); - this.addLayer(new BodyLayerFeatureRenderer(this)); + this.addLayer(new CustomLayerFeatureRenderer(this)); } @SuppressWarnings("resource") @@ -105,7 +121,7 @@ private void renderHand(PoseStack poseStack, MultiBufferSource multiBufferSource part.setPosition(x, y, 0); part.render(poseStack, multiBufferSource - .getBuffer(RenderType.entityTranslucent(abstractClientPlayer.getSkin().texture())), + .getBuffer(RenderType.entityTranslucent(NMSWrapper.getPlayerSkin(abstractClientPlayer))), i, OverlayTexture.NO_OVERLAY); part.setPosition(0, 0, 0); part.setRotation(0, 0, 0); diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityMixin.java similarity index 100% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityMixin.java diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityRendererMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityRendererMixin.java similarity index 69% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityRendererMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityRendererMixin.java index c584017..b7b17a2 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityRendererMixin.java +++ b/src/main/java/dev/tr7zw/skinlayers/mixin/SkullBlockEntityRendererMixin.java @@ -3,7 +3,10 @@ import static dev.tr7zw.skinlayers.SkullRendererCache.lastSkull; import static dev.tr7zw.skinlayers.SkullRendererCache.renderNext; +import java.util.Map; + import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -16,22 +19,38 @@ import dev.tr7zw.skinlayers.accessor.SkullModelAccessor; import dev.tr7zw.skinlayers.accessor.SkullSettings; import dev.tr7zw.skinlayers.api.Mesh; +import dev.tr7zw.skinlayers.util.NMSWrapper; import net.minecraft.client.Minecraft; -import net.minecraft.client.model.SkullModelBase; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.SkullBlockRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.SkinManager; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.entity.SkullBlockEntity; +// spotless:off +//#if MC >= 11700 +import net.minecraft.client.model.SkullModelBase; +//#else +//$$ import net.minecraft.world.level.block.SkullBlock; +//$$ import net.minecraft.client.model.SkullModel; +//#endif +// spotless:on @Mixin(SkullBlockRenderer.class) public class SkullBlockEntityRendererMixin { + // spotless:off + //#if MC <= 11605 + //$$ @Shadow + //$$ private static Map MODEL_BY_TYPE; + //$$ @Shadow + //$$ private static RenderType getRenderType(net.minecraft.world.level.block.SkullBlock.Type type, + //$$ GameProfile gameProfile) {return null;} + //#endif + @SuppressWarnings("resource") @Inject(method = "render", at = @At("HEAD")) public void render(SkullBlockEntity skullBlockEntity, float f, PoseStack poseStack, @@ -44,16 +63,16 @@ public void render(SkullBlockEntity skullBlockEntity, float f, PoseStack poseSta * SkinLayersModBase.config.renderDistanceLOD) { lastSkull = (SkullSettings) skullBlockEntity; GameProfile gameProfile = skullBlockEntity.getOwnerProfile(); - SkinManager skinManager = Minecraft.getInstance().getSkinManager(); if (gameProfile == null) return; - ResourceLocation textureLocation = skinManager.getInsecureSkin(gameProfile).texture(); - if(textureLocation != lastSkull.getLastTexture()) { + ResourceLocation textureLocation = NMSWrapper.getPlayerSkin(gameProfile); + if (textureLocation != lastSkull.getLastTexture()) { lastSkull.setInitialized(false); } if (!lastSkull.initialized() && lastSkull.getHeadLayers() == null) { - lastSkull.setInitialized(true); // do this first, so if anything goes horribly wrong, it doesn't happen next - // frame again + lastSkull.setInitialized(true); // do this first, so if anything goes horribly wrong, it doesn't happen + // next + // frame again lastSkull.setLastTexture(textureLocation); SkinUtil.setup3dLayers(gameProfile, lastSkull); } @@ -69,13 +88,21 @@ private double internalDistToCenterSqr(BlockPos pos, double d, double e, double } @Inject(method = "renderSkull", at = @At("HEAD")) + // spotless:off + //#if MC >= 11700 private static void renderSkull(Direction direction, float f, float g, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, SkullModelBase skullModelBase, RenderType renderType, CallbackInfo ci) { - if (lastSkull != null && skullModelBase instanceof SkullModelAccessor) { - Mesh mesh = lastSkull.getHeadLayers(); + //#else + //$$ private static void renderSkull(Direction direction, float f, + //$$ net.minecraft.world.level.block.SkullBlock.Type type, GameProfile gameProfile, float g, + //$$ PoseStack poseStack, MultiBufferSource multiBufferSource, int i, CallbackInfo ci) { + //$$ SkullModel skullModelBase = (SkullModel) MODEL_BY_TYPE.get(type); + //#endif + // spotless:on + if (skullModelBase instanceof SkullModelAccessor) { SkullModelAccessor accessor = (SkullModelAccessor) skullModelBase; - if (!renderNext || mesh == null) { + if (!renderNext) { accessor.showHat(true); lastSkull = null; return; @@ -92,10 +119,18 @@ private static void renderSkull(Direction direction, float f, float g, PoseStack poseStack.scale(-1.0F, -1.0F, 1.0F); float voxelSize = SkinLayersModBase.config.skullVoxelSize; poseStack.scale(voxelSize, voxelSize, voxelSize); + Mesh mesh = lastSkull.getHeadLayers(); mesh.setPosition(0, -0.25f, 0); mesh.setRotation(0, f * 0.017453292F, 0); - mesh.render(poseStack, multiBufferSource.getBuffer(renderType), i, + // spotless:off + //#if MC <= 11605 + //$$ lastSkull.getHeadLayers().render(poseStack, multiBufferSource.getBuffer(getRenderType(type, gameProfile)), i, + //$$ OverlayTexture.NO_OVERLAY); + //#else + lastSkull.getHeadLayers().render(poseStack, multiBufferSource.getBuffer(renderType), i, OverlayTexture.NO_OVERLAY); + //#endif + //spotless:on poseStack.popPose(); renderNext = false; lastSkull = null; diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullModelMixin.java b/src/main/java/dev/tr7zw/skinlayers/mixin/SkullModelMixin.java similarity index 61% rename from Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullModelMixin.java rename to src/main/java/dev/tr7zw/skinlayers/mixin/SkullModelMixin.java index 7cdd6ea..156b5d8 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/mixin/SkullModelMixin.java +++ b/src/main/java/dev/tr7zw/skinlayers/mixin/SkullModelMixin.java @@ -7,19 +7,40 @@ import net.minecraft.client.model.SkullModel; import net.minecraft.client.model.geom.ModelPart; +// spotless:off +//#if MC >= 11700 @Mixin(SkullModel.class) +//#else +//$$ import net.minecraft.client.model.HumanoidHeadModel; +//$$ +//$$ @Mixin(HumanoidHeadModel.class) +//#endif +//spotless:on public class SkullModelMixin implements SkullModelAccessor { @Shadow + // spotless:off + //#if MC >= 11700 private ModelPart head; + //#else + //$$ private ModelPart hat; + //#endif + //spotless:on @Override public void showHat(boolean val) { + // spotless:off + //#if MC >= 11700 head.getAllParts().forEach(part -> { if (part != head) { // is the hat, not the head part.visible = val; } }); + //#else + //$$ hat.visible = val; + //#endif + //spotless:on + } } diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCubeListBuilder.java b/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCubeListBuilder.java similarity index 53% rename from Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCubeListBuilder.java rename to src/main/java/dev/tr7zw/skinlayers/render/CustomizableCubeListBuilder.java index bb000ec..c49c365 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCubeListBuilder.java +++ b/src/main/java/dev/tr7zw/skinlayers/render/CustomizableCubeListBuilder.java @@ -4,11 +4,17 @@ import com.google.common.collect.Lists; +import dev.tr7zw.skinlayers.versionless.render.CustomizableCube; +import dev.tr7zw.skinlayers.versionless.util.Direction; +import dev.tr7zw.skinlayers.versionless.util.wrapper.ModelBuilder; import net.minecraft.client.model.geom.ModelPart.Cube; +// spotless:off +//#if MC >= 11700 import net.minecraft.client.model.geom.builders.CubeListBuilder; -import net.minecraft.core.Direction; +//#endif +// spotless:on -class CustomizableCubeListBuilder { +public class CustomizableCubeListBuilder implements ModelBuilder { private final List cubes = Lists.newArrayList(); private final List vanillaCubes = Lists.newArrayList(); @@ -16,17 +22,19 @@ class CustomizableCubeListBuilder { private int v; private boolean mirror; - public static CustomizableCubeListBuilder create() { + public static ModelBuilder create() { return new CustomizableCubeListBuilder(); } - public CustomizableCubeListBuilder uv(int u, int v) { + @Override + public ModelBuilder uv(int u, int v) { this.u = u; this.v = v; return this; } - public CustomizableCubeListBuilder mirror(boolean bl) { + @Override + public ModelBuilder mirror(boolean bl) { this.mirror = bl; return this; } @@ -39,21 +47,33 @@ public List getVanillaCubes() { return vanillaCubes; } - public CustomizableCubeListBuilder addBox(float x, float y, float z, float pixelSize, Direction[] hide, - Direction[][] corners) { + @Override + public ModelBuilder addBox(float x, float y, float z, float pixelSize, Direction[] hide, Direction[][] corners) { int textureSize = 64; this.cubes.add(new CustomizableCube(this.u, this.v, x, y, z, pixelSize, pixelSize, pixelSize, 0, 0, 0, this.mirror, textureSize, textureSize, hide, corners)); return this; } - public CustomizableCubeListBuilder addVanillaBox(float x, float y, float z, float width, float height, float depth, - float pixelSize) { + @Override + public ModelBuilder addVanillaBox(float x, float y, float z, float width, float height, float depth) { int textureSize = 64; + // spotless:off + //#if MC <= 11605 + //$$ this.vanillaCubes.add(new Cube(u, v, x, y, z, width, height, depth, 0, 0, 0, + //$$ this.mirror, textureSize, textureSize)); + //#else CubeListBuilder cubeList = CubeListBuilder.create(); cubeList.texOffs(u, v).addBox(x, y, z, width, height, depth); this.vanillaCubes.add(cubeList.getCubes().get(0).bake(textureSize, textureSize)); + //#endif + // spotless:on return this; } + @Override + public boolean isEmpty() { + return getCubes().isEmpty() && getVanillaCubes().isEmpty(); + } + } diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableModelPart.java b/src/main/java/dev/tr7zw/skinlayers/render/CustomizableModelPart.java similarity index 64% rename from Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableModelPart.java rename to src/main/java/dev/tr7zw/skinlayers/render/CustomizableModelPart.java index dbac41f..bec2675 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/render/CustomizableModelPart.java +++ b/src/main/java/dev/tr7zw/skinlayers/render/CustomizableModelPart.java @@ -2,13 +2,6 @@ import java.util.List; import java.util.Map; -import java.util.NoSuchElementException; - -import org.joml.Matrix3f; -import org.joml.Matrix4f; -import org.joml.Quaternionf; -import org.joml.Vector3f; -import org.joml.Vector4f; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -16,65 +9,47 @@ import dev.tr7zw.skinlayers.api.Mesh; import dev.tr7zw.skinlayers.api.MeshTransformer; import dev.tr7zw.skinlayers.api.SkinLayersAPI; -import dev.tr7zw.skinlayers.render.CustomizableCube.Polygon; -import dev.tr7zw.skinlayers.render.CustomizableCube.Vertex; +import dev.tr7zw.skinlayers.versionless.render.CustomModelPart; +import dev.tr7zw.skinlayers.versionless.render.CustomizableCube; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.model.geom.ModelPart.Cube; + +//spotless:off +//#if MC >= 11700 import net.minecraft.client.model.geom.PartPose; +//#endif +//#if MC >= 11903 +import org.joml.Matrix3f; +import org.joml.Matrix4f; +import org.joml.Quaternionf; +import org.joml.Vector3f; +import org.joml.Vector4f; +//#else +//$$ import com.mojang.math.Vector3f; +//$$ import com.mojang.math.Vector4f; +//$$ import com.mojang.math.Matrix3f; +//$$ import com.mojang.math.Matrix4f; +//#endif +//spotless:on /** * Cut down copy of the Vanilla ModelPart to bypass Optifine/Sodium screwing * with the CustomizableCube class * */ -class CustomizableModelPart implements Mesh { - - private float x; - private float y; - private float z; - private float xRot; - private float yRot; - private float zRot; - private boolean visible = true; +public class CustomizableModelPart extends CustomModelPart implements Mesh { + private final List cubes; private final Map children; - private float[] polygonData = null; - private int polygonAmount = 0; - private final int polyDataSize = 23; public CustomizableModelPart(List list, List customCubes, Map map) { + super(customCubes); this.cubes = list; this.children = map; - compactCubes(customCubes); - } - - private void compactCubes(List customCubes) { - for (CustomizableCube cube : customCubes) { - polygonAmount += cube.polygonCount; - } - polygonData = new float[polygonAmount * polyDataSize]; - int offset = 0; - Polygon polygon; - for (CustomizableCube cube : customCubes) { - for (int id = 0; id < cube.polygonCount; id++) { - polygon = cube.polygons[id]; - Vector3f vector3f = polygon.normal; - polygonData[offset + 0] = vector3f.x(); - polygonData[offset + 1] = vector3f.y(); - polygonData[offset + 2] = vector3f.z(); - for (int i = 0; i < 4; i++) { - Vertex vertex = polygon.vertices[i]; - polygonData[offset + 3 + (i * 5) + 0] = vertex.scaledX; - polygonData[offset + 3 + (i * 5) + 1] = vertex.scaledY; - polygonData[offset + 3 + (i * 5) + 2] = vertex.scaledZ; - polygonData[offset + 3 + (i * 5) + 3] = vertex.u; - polygonData[offset + 3 + (i * 5) + 4] = vertex.v; - } - offset += polyDataSize; - } - } } + // spotless:off + //#if MC >= 11700 public void loadPose(PartPose partPose) { this.x = partPose.x; this.y = partPose.y; @@ -83,6 +58,10 @@ public void loadPose(PartPose partPose) { this.yRot = partPose.yRot; this.zRot = partPose.zRot; } + //#else + //$$ public void loadPose(ModelPart partPose){copyFrom(partPose);} + //#endif + //spotless:on public void copyFrom(ModelPart modelPart) { this.xRot = modelPart.xRot; @@ -93,25 +72,6 @@ public void copyFrom(ModelPart modelPart) { this.z = modelPart.z; } - public ModelPart getChild(String string) { - ModelPart modelPart = this.children.get(string); - if (modelPart == null) - throw new NoSuchElementException("Can't find part " + string); - return modelPart; - } - - public void setPosition(float f, float g, float h) { - this.x = f; - this.y = g; - this.z = h; - } - - public void setRotation(float f, float g, float h) { - this.xRot = f; - this.yRot = g; - this.zRot = h; - } - public void render(PoseStack poseStack, VertexConsumer vertexConsumer, int i, int j) { render(null, poseStack, vertexConsumer, i, j, 1.0F, 1.0F, 1.0F, 1.0F); } @@ -130,8 +90,19 @@ public void render(ModelPart vanillaModel, PoseStack poseStack, VertexConsumer v public void translateAndRotate(PoseStack poseStack) { poseStack.translate(this.x / 16.0F, this.y / 16.0F, this.z / 16.0F); + // spotless:off + //#if MC >= 11903 if (this.xRot != 0.0F || this.yRot != 0.0F || this.zRot != 0.0F) poseStack.mulPose((new Quaternionf()).rotationZYX(this.zRot, this.yRot, this.xRot)); + //#else + //$$ if (this.zRot != 0.0F) + //$$ poseStack.mulPose(Vector3f.ZP.rotation(this.zRot)); + //$$ if (this.yRot != 0.0F) + //$$ poseStack.mulPose(Vector3f.YP.rotation(this.yRot)); + //$$ if (this.xRot != 0.0F) + //$$ poseStack.mulPose(Vector3f.XP.rotation(this.xRot)); + //#endif + //spotless:on } // render constants to reduce allocations @@ -152,9 +123,17 @@ private void compile(ModelPart vanillaModel, PoseStack.Pose pose, VertexConsumer // optional transformations for bending layers transformer.transform(vector3f, vector4f); + // spotless:off + //#if MC >= 11903 vector3f = matrix3f.transform(vector3f); for (int o = 0; o < 4; o++) { matrix4f.transform(vector4f[o]); + //#else + //$$ vector3f.transform(matrix3f); + //$$ for (int o = 0; o < 4; o++) { + //$$ vector4f[o].transform(matrix4f); + //#endif + //spotless:on vertexConsumer.vertex(vector4f[o].x(), vector4f[o].y(), vector4f[o].z(), red, green, blue, alpha, polygonData[id + 3 + (o * 5) + 3], polygonData[id + 3 + (o * 5) + 4], overlay, light, vector3f.x(), vector3f.y(), vector3f.z()); @@ -164,18 +143,32 @@ private void compile(ModelPart vanillaModel, PoseStack.Pose pose, VertexConsumer // other cubes for (Cube cube : this.cubes) { transformer.transform(cube); + // spotless:off + //#if MC >= 11700 cube.compile(pose, vertexConsumer, light, overlay, red, green, blue, alpha); - } - } + //#else + //$$ for (ModelPart.Polygon polygon : cube.polygons) { + //$$ Vector3f vector3f = polygon.normal.copy(); + //$$ vector3f.transform(matrix3f); + //$$ float l = vector3f.x(); + //$$ float m = vector3f.y(); + //$$ float n = vector3f.z(); + //$$ + //$$ for (int o = 0; o < 4; ++o) { + //$$ ModelPart.Vertex vertex = polygon.vertices[o]; + //$$ float p = vertex.pos.x() / 16.0F; + //$$ float q = vertex.pos.y() / 16.0F; + //$$ float r = vertex.pos.z() / 16.0F; + //$$ Vector4f vector4f = new Vector4f(p, q, r, 1.0F); + //$$ vector4f.transform(matrix4f); + //$$ vertexConsumer.vertex(vector4f.x(), vector4f.y(), vector4f.z(), red, green, blue, alpha, vertex.u, vertex.v, overlay, + //$$ light, l, m, n); + //$$ } + //$$ } + //#endif + //spotless:on - @Override - public void setVisible(boolean visible) { - this.visible = visible; - } - - @Override - public boolean isVisible() { - return visible; + } } } diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/render/PreviewHelper.java b/src/main/java/dev/tr7zw/skinlayers/render/PreviewHelper.java similarity index 99% rename from Shared/src/main/java/dev/tr7zw/skinlayers/render/PreviewHelper.java rename to src/main/java/dev/tr7zw/skinlayers/render/PreviewHelper.java index 5d673a3..6b6ed09 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/render/PreviewHelper.java +++ b/src/main/java/dev/tr7zw/skinlayers/render/PreviewHelper.java @@ -1,3 +1,4 @@ +//#if MC >= 12001 package dev.tr7zw.skinlayers.render; import org.jetbrains.annotations.Nullable; @@ -71,3 +72,4 @@ public static void renderEntityInInventory(GuiGraphics guiGraphics, int x, int y } } +//#endif \ No newline at end of file diff --git a/Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/BodyLayerFeatureRenderer.java b/src/main/java/dev/tr7zw/skinlayers/renderlayers/CustomLayerFeatureRenderer.java similarity index 70% rename from Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/BodyLayerFeatureRenderer.java rename to src/main/java/dev/tr7zw/skinlayers/renderlayers/CustomLayerFeatureRenderer.java index 97454e1..b830c97 100644 --- a/Shared/src/main/java/dev/tr7zw/skinlayers/renderlayers/BodyLayerFeatureRenderer.java +++ b/src/main/java/dev/tr7zw/skinlayers/renderlayers/CustomLayerFeatureRenderer.java @@ -2,9 +2,11 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; +import com.google.common.collect.Sets; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; @@ -14,7 +16,8 @@ import dev.tr7zw.skinlayers.accessor.PlayerSettings; import dev.tr7zw.skinlayers.api.LayerFeatureTransformerAPI; import dev.tr7zw.skinlayers.api.Mesh; -import dev.tr7zw.skinlayers.render.SolidPixelWrapper.Dimensions; +import dev.tr7zw.skinlayers.versionless.util.wrapper.SolidPixelWrapper.Dimensions; +import lombok.AllArgsConstructor; import net.minecraft.client.Minecraft; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.geom.ModelPart; @@ -24,31 +27,46 @@ import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.RenderLayerParent; import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.PlayerModelPart; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; -public class BodyLayerFeatureRenderer extends RenderLayer> { - public BodyLayerFeatureRenderer( +public class CustomLayerFeatureRenderer extends RenderLayer> { + + private static final Minecraft mc = Minecraft.getInstance(); + private final Set hideHeadLayers = Sets.newHashSet(Items.ZOMBIE_HEAD, Items.CREEPER_HEAD, Items.DRAGON_HEAD, + Items.SKELETON_SKULL, Items.WITHER_SKELETON_SKULL); + private final List bodyLayers = new ArrayList<>(); + private final boolean thinArms; + + public CustomLayerFeatureRenderer( RenderLayerParent> renderLayerParent) { super(renderLayerParent); thinArms = ((PlayerEntityModelAccessor) getParentModel()).hasThinArms(); + bodyLayers.add(new Layer(PlayerSettings::getHeadMesh, false, PlayerModelPart.HAT, Shape.HEAD, + () -> this.getParentModel().head, (player) -> { + ItemStack itemStack = player.getItemBySlot(EquipmentSlot.HEAD); + if (itemStack != null && hideHeadLayers.contains(itemStack.getItem())) { + return false; + } + return SkinLayersModBase.config.enableHat; + })); bodyLayers.add(new Layer(PlayerSettings::getLeftLegMesh, false, PlayerModelPart.LEFT_PANTS_LEG, Shape.LEGS, - () -> this.getParentModel().leftLeg, () -> SkinLayersModBase.config.enableLeftPants)); + () -> this.getParentModel().leftLeg, (player) -> SkinLayersModBase.config.enableLeftPants)); bodyLayers.add(new Layer(PlayerSettings::getRightLegMesh, false, PlayerModelPart.RIGHT_PANTS_LEG, Shape.LEGS, - () -> this.getParentModel().rightLeg, () -> SkinLayersModBase.config.enableRightPants)); + () -> this.getParentModel().rightLeg, (player) -> SkinLayersModBase.config.enableRightPants)); bodyLayers.add(new Layer(PlayerSettings::getLeftArmMesh, false, PlayerModelPart.LEFT_SLEEVE, thinArms ? Shape.ARMS_SLIM : Shape.ARMS, () -> this.getParentModel().leftArm, - () -> SkinLayersModBase.config.enableLeftSleeve)); + (player) -> SkinLayersModBase.config.enableLeftSleeve)); bodyLayers.add(new Layer(PlayerSettings::getRightArmMesh, true, PlayerModelPart.RIGHT_SLEEVE, thinArms ? Shape.ARMS_SLIM : Shape.ARMS, () -> this.getParentModel().rightArm, - () -> SkinLayersModBase.config.enableRightSleeve)); + (player) -> SkinLayersModBase.config.enableRightSleeve)); bodyLayers.add(new Layer(PlayerSettings::getTorsoMesh, false, PlayerModelPart.JACKET, Shape.BODY, - () -> this.getParentModel().body, () -> SkinLayersModBase.config.enableJacket)); + () -> this.getParentModel().body, (player) -> SkinLayersModBase.config.enableJacket)); } - private final boolean thinArms; - - private static final Minecraft mc = Minecraft.getInstance(); - public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, AbstractClientPlayer player, float f, float g, float h, float j, float k, float l) { if (player.isInvisible()) { @@ -66,34 +84,19 @@ public void render(PoseStack poseStack, MultiBufferSource multiBufferSource, int if (!SkinUtil.setup3dLayers(player, settings, thinArms, this.getParentModel())) { return; // no head layer setup and wasn't able to setup } - + // spotless:off + //#if MC >= 12002 VertexConsumer vertexConsumer = multiBufferSource .getBuffer(RenderType.entityTranslucent(player.getSkin().texture(), true)); + //#else + //$$ VertexConsumer vertexConsumer = multiBufferSource + //$$ .getBuffer(RenderType.entityTranslucent(player.getSkinTextureLocation(), true)); + //#endif + //spotless:on int m = LivingEntityRenderer.getOverlayCoords(player, 0.0f); renderLayers(player, settings, poseStack, vertexConsumer, i, m); } - private final List bodyLayers = new ArrayList<>(); - - private record Layer(Function meshGetter, boolean mirrored, PlayerModelPart modelPart, - Shape shape, Supplier vanillaGetter, Supplier configGetter) { - } - - private enum Shape { - HEAD(0, new Dimensions(8, 8, 8)), BODY(-0.2f, new Dimensions(8, 12, 4)), LEGS(-0.2f, new Dimensions(4, 14, 4)), - ARMS(-0.1f, new Dimensions(4, 14, 4)), ARMS_SLIM(-0.1f, new Dimensions(3, 14, 4)); - - private final float yOffsetMagicValue; - @SuppressWarnings("unused") - private final Dimensions dimensions; // unused, maybe useful to correct some deformations - - private Shape(float yOffsetMagicValue, Dimensions dimensions) { - this.dimensions = dimensions; - this.yOffsetMagicValue = yOffsetMagicValue; - } - - } - public void renderLayers(AbstractClientPlayer abstractClientPlayer, PlayerSettings settings, PoseStack matrixStack, VertexConsumer vertices, int light, int overlay) { float pixelScaling = SkinLayersModBase.config.baseVoxelSize; @@ -102,7 +105,7 @@ public void renderLayers(AbstractClientPlayer abstractClientPlayer, PlayerSettin for (Layer layer : bodyLayers) { Mesh mesh = layer.meshGetter.apply(settings); if (mesh != null && abstractClientPlayer.isModelPartShown(layer.modelPart) - && layer.vanillaGetter.get().visible && layer.configGetter.get()) { + && layer.vanillaGetter.get().visible && layer.configGetter.apply(abstractClientPlayer)) { matrixStack.pushPose(); LayerFeatureTransformerAPI.getTransformer().transform(abstractClientPlayer, matrixStack, layer.vanillaGetter.get()); @@ -132,4 +135,29 @@ public void renderLayers(AbstractClientPlayer abstractClientPlayer, PlayerSettin } + @AllArgsConstructor + private static class Layer { + private final Function meshGetter; + private final boolean mirrored; + private final PlayerModelPart modelPart; + private final Shape shape; + private final Supplier vanillaGetter; + private final Function configGetter; + } + + private enum Shape { + HEAD(0, new Dimensions(8, 8, 8)), BODY(-0.2f, new Dimensions(8, 12, 4)), LEGS(-0.2f, new Dimensions(4, 14, 4)), + ARMS(-0.1f, new Dimensions(4, 14, 4)), ARMS_SLIM(-0.1f, new Dimensions(3, 14, 4)); + + private final float yOffsetMagicValue; + @SuppressWarnings("unused") + private final Dimensions dimensions; // unused, maybe useful to correct some deformations + + private Shape(float yOffsetMagicValue, Dimensions dimensions) { + this.dimensions = dimensions; + this.yOffsetMagicValue = yOffsetMagicValue; + } + + } + } diff --git a/src/main/java/dev/tr7zw/skinlayers/util/NMSWrapper.java b/src/main/java/dev/tr7zw/skinlayers/util/NMSWrapper.java new file mode 100644 index 0000000..883146e --- /dev/null +++ b/src/main/java/dev/tr7zw/skinlayers/util/NMSWrapper.java @@ -0,0 +1,74 @@ +package dev.tr7zw.skinlayers.util; + +import com.mojang.authlib.GameProfile; +import com.mojang.blaze3d.platform.NativeImage; + +import dev.tr7zw.skinlayers.versionless.util.wrapper.SolidPixelWrapper.UV; +import dev.tr7zw.skinlayers.versionless.util.wrapper.TextureData; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.resources.ResourceLocation; +//spotless:off +//#if MC >= 12002 +import net.minecraft.client.resources.PlayerSkin; +//#else +//$$ import com.mojang.authlib.minecraft.MinecraftProfileTexture; +//$$ import java.util.Map; +//#endif +//spotless:on + +public class NMSWrapper { + + public static class WrappedNativeImage implements TextureData { + + private final NativeImage natImage; + + public WrappedNativeImage(NativeImage natImage) { + this.natImage = natImage; + } + + @Override + public boolean isPresent(UV onTextureUV) { + return natImage.getLuminanceOrAlpha(onTextureUV.u(), onTextureUV.v()) != 0; + } + + @Override + public boolean isSolid(UV onTextureUV) { + return natImage.getLuminanceOrAlpha(onTextureUV.u(), onTextureUV.v()) == -1; + } + + } + + public static ResourceLocation getPlayerSkin(AbstractClientPlayer player) { + // spotless:off + //#if MC >= 12002 + return player.getSkin().texture(); + //#else + //$$ return player.getSkinTextureLocation(); + //#endif + //spotless:on + } + + public static ResourceLocation getPlayerSkin(GameProfile gameprofile) { + // spotless:off + //#if MC >= 12002 + PlayerSkin playerSkin = Minecraft.getInstance().getSkinManager().getInsecureSkin(gameprofile); + if (playerSkin.textureUrl() == null) { + return null; + } + return playerSkin.texture(); + //#else + //$$ Map map = Minecraft.getInstance().getSkinManager() + //$$ .getInsecureSkinInformation(gameprofile); + //$$ MinecraftProfileTexture texture = map.get(MinecraftProfileTexture.Type.SKIN); + //$$ if (texture == null) { + //$$ return null; + //$$ } + //$$ ResourceLocation resourceLocation = Minecraft.getInstance().getSkinManager().registerTexture(texture, + //$$ MinecraftProfileTexture.Type.SKIN); + //$$ return resourceLocation; + //#endif + //spotless:on + } + +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/cs_cz.json b/src/main/resources/assets/skinlayers3d/lang/cs_cz.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/cs_cz.json rename to src/main/resources/assets/skinlayers3d/lang/cs_cz.json index 9393cfd..ba2623f 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/cs_cz.json +++ b/src/main/resources/assets/skinlayers3d/lang/cs_cz.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "Nastavení 3D Skin Layer", - "text.skinlayers.enable.hat": "3D pokrývka hlavy", "text.skinlayers.enable.jacket": "3D bunda", "text.skinlayers.enable.leftsleeve": "3D levý rukáv", diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/de_de.json b/src/main/resources/assets/skinlayers3d/lang/de_de.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/de_de.json rename to src/main/resources/assets/skinlayers3d/lang/de_de.json index f3d2dc0..b5c2fd2 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/de_de.json +++ b/src/main/resources/assets/skinlayers3d/lang/de_de.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "3D Skin Layer Einstellungen", - "text.skinlayers.enable.hat": "3D Hut", "text.skinlayers.enable.jacket": "3D Jacke", "text.skinlayers.enable.leftsleeve": "3D Linker Ärmel", @@ -17,4 +16,4 @@ "text.skinlayers.skulls.voxelsize": "Kopf Voxelgröße", "text.skinlayers.reset": "Standard", "text.skinlayers.fastrender.enable": "Schnelles Rendern" - } +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/en_us.json b/src/main/resources/assets/skinlayers3d/lang/en_us.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/en_us.json rename to src/main/resources/assets/skinlayers3d/lang/en_us.json index eb6390d..da944cf 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/en_us.json +++ b/src/main/resources/assets/skinlayers3d/lang/en_us.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "3D Skin Layer Settings", - "text.skinlayers.enable.hat": "3D Hat", "text.skinlayers.enable.hat.tooltip": "Render the player's hat layer as a 3D model", "text.skinlayers.enable.jacket": "3D Jacket", @@ -34,4 +33,4 @@ "text.skinlayers.fastrender.enable.tooltip": "Render the 3D models as fast as possible, this may cause some graphical glitches with transparency", "text.skinlayers.firstperson.voxelsize": "First Person Voxel Size", "text.skinlayers.firstperson.voxelsize.tooltip": "The size of the voxels used for the player's hand in first person" - } \ No newline at end of file +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/es_es.json b/src/main/resources/assets/skinlayers3d/lang/es_es.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/es_es.json rename to src/main/resources/assets/skinlayers3d/lang/es_es.json index dce1b0d..97bdba5 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/es_es.json +++ b/src/main/resources/assets/skinlayers3d/lang/es_es.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "Configuracion de 3D Skin Layer", - "text.skinlayers.enable.hat": "Sombrero 3D", "text.skinlayers.enable.hat.tooltip": "Renderiza la capa del sombrero del jugador como un modelo 3D", "text.skinlayers.enable.jacket": "Chaqueta 3D", diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/it_it.json b/src/main/resources/assets/skinlayers3d/lang/it_it.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/it_it.json rename to src/main/resources/assets/skinlayers3d/lang/it_it.json index 5575d68..b6d1d97 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/it_it.json +++ b/src/main/resources/assets/skinlayers3d/lang/it_it.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "Impostazioni di 3D Skin Layers", - "text.skinlayers.enable.hat": "Cappello 3D", "text.skinlayers.enable.jacket": "Giacca 3D", "text.skinlayers.enable.leftsleeve": "Mano sinistra 3D", @@ -18,4 +17,4 @@ "text.skinlayers.reset": "Predefinito", "text.skinlayers.fastrender.enable": "Fast Render", "text.skinlayers.firstperson.voxelsize": "Dimenisione del Voxel in prima persona" - } +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/ko_kr.json b/src/main/resources/assets/skinlayers3d/lang/ko_kr.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/ko_kr.json rename to src/main/resources/assets/skinlayers3d/lang/ko_kr.json index c6fda52..1d41a64 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/ko_kr.json +++ b/src/main/resources/assets/skinlayers3d/lang/ko_kr.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "3D Skin Layer 설정", - "text.skinlayers.enable.hat": "3D 모자", "text.skinlayers.enable.hat.tooltip": "플레이어의 모자 레이어를 3D 모델로 렌더합니다.", "text.skinlayers.enable.jacket": "3D 상의", diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/pt_br.json b/src/main/resources/assets/skinlayers3d/lang/pt_br.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/pt_br.json rename to src/main/resources/assets/skinlayers3d/lang/pt_br.json index 77ebc96..f9356b1 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/pt_br.json +++ b/src/main/resources/assets/skinlayers3d/lang/pt_br.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "Configurações do 3D Skin Layer", - "text.skinlayers.enable.hat": "Chapéu 3D", "text.skinlayers.enable.jacket": "Casaco 3D", "text.skinlayers.enable.leftsleeve": "Manga Esquerda 3D", @@ -18,4 +17,4 @@ "text.skinlayers.reset": "Restaurar", "text.skinlayers.fastrender.enable": "Renderização Rápida", "text.skinlayers.firstperson.voxelsize": "Tamanho do Voxel em Primeira Pessoa" - } \ No newline at end of file +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/pt_pt.json b/src/main/resources/assets/skinlayers3d/lang/pt_pt.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/pt_pt.json rename to src/main/resources/assets/skinlayers3d/lang/pt_pt.json index 77ebc96..f9356b1 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/pt_pt.json +++ b/src/main/resources/assets/skinlayers3d/lang/pt_pt.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "Configurações do 3D Skin Layer", - "text.skinlayers.enable.hat": "Chapéu 3D", "text.skinlayers.enable.jacket": "Casaco 3D", "text.skinlayers.enable.leftsleeve": "Manga Esquerda 3D", @@ -18,4 +17,4 @@ "text.skinlayers.reset": "Restaurar", "text.skinlayers.fastrender.enable": "Renderização Rápida", "text.skinlayers.firstperson.voxelsize": "Tamanho do Voxel em Primeira Pessoa" - } \ No newline at end of file +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/ru_ru.json b/src/main/resources/assets/skinlayers3d/lang/ru_ru.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/ru_ru.json rename to src/main/resources/assets/skinlayers3d/lang/ru_ru.json index 87145d0..b9558ff 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/ru_ru.json +++ b/src/main/resources/assets/skinlayers3d/lang/ru_ru.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "Настройки 3D Skin Layer", - "text.skinlayers.enable.hat": "Головной убор в 3D", "text.skinlayers.enable.hat.tooltip": "Отображение слоя головного убора игрока в виде 3D-модели", "text.skinlayers.enable.jacket": "Куртка в 3D", @@ -37,4 +36,3 @@ "modmenu.summaryTranslation.skinlayers": "Трёхмерное отображение слоёв скина игрока.", "modmenu.descriptionTranslation.skinlayers": "Замена плоским вторым слоям скинов игроков в виде их трёхмерных аналогов. Модель автоматически будет возвращаться к стандартному двухмерному виду на расстоянии для повышения производительности. Можно использовать полупрозрачные элементы, например, очки!" } - \ No newline at end of file diff --git a/src/main/resources/assets/skinlayers3d/lang/sv_se.json b/src/main/resources/assets/skinlayers3d/lang/sv_se.json new file mode 100644 index 0000000..9095cbc --- /dev/null +++ b/src/main/resources/assets/skinlayers3d/lang/sv_se.json @@ -0,0 +1,36 @@ +{ + "text.skinlayers.title": "Inställningar för 3D Skin Layers", + "text.skinlayers.enable.hat": "3D Hatt", + "text.skinlayers.enable.hat.tooltip": "Rendera spelarens hatt som en 3D-modell", + "text.skinlayers.enable.jacket": "3D Jacka", + "text.skinlayers.enable.jacket.tooltip": "Rendera spelarens jacka som en 3D-modell", + "text.skinlayers.enable.leftsleeve": "3D Vänster Ärm", + "text.skinlayers.enable.leftsleeve.tooltip": "Rendera spelarens vänstra ärm som en 3D-modell", + "text.skinlayers.enable.rightsleeve": "3D Höger Ärm", + "text.skinlayers.enable.rightsleeve.tooltip": "Rendera spelarens högra ärm som en 3D-modell", + "text.skinlayers.enable.leftpants": "3D Vänster Byxben", + "text.skinlayers.enable.leftpants.tooltip": "Rendera spelarens vänstra byxben som en 3D-modell", + "text.skinlayers.enable.rightpants": "3D Höger Byxben", + "text.skinlayers.enable.rightpants.tooltip": "Rendera spelarens högra byxben som en 3D-modell", + "text.skinlayers.renderdistancelod": "Detaljeringsnivå Avstånd", + "text.skinlayers.renderdistancelod.tooltip": "Avståndet från spelaren där modellen byter till en lägre nivå av detalj(vanilla 2d)", + "text.skinlayers.basevoxelsize": "Voxelstorlek", + "text.skinlayers.basevoxelsize.tooltip": "Storleken på voxlarna som används för spelare", + "text.skinlayers.headvoxelsize": "Huvud Voxelstorlek", + "text.skinlayers.headvoxelsize.tooltip": "Storleken på voxlarna som används för spelarens Huvud", + "text.skinlayers.bodyvoxelheightsize": "Kropp Voxelhöjd", + "text.skinlayers.bodyvoxelheightsize.tooltip": "Höjden på voxlarna som används för spelarens kropp(används för att förhindra att den fastnar i huudet/sticker ut ur armarna)", + "text.skinlayers.bodyvoxelwidthsize": "Överkropp Voxelbredd", + "text.skinlayers.bodyvoxelwidthsize.tooltip": "Bredden på voxlarna som används för spelarens överkropp(används för att förhindra att den fastnar i armarna)", + "text.skinlayers.skulls.enable": "3D Döskallar", + "text.skinlayers.skulls.enable.tooltip": "Rendera spelares huvuden(blocket) som en 3D-modell", + "text.skinlayers.skullsitems.enable": "3D Döskalleföremål", + "text.skinlayers.skullsitems.enable.tooltip": "Rendera spelares huvuden(föremålet) som en 3D-modell", + "text.skinlayers.skulls.voxelsize": "Döskalle Voxelstorlek", + "text.skinlayers.skulls.voxelsize.tooltip": "Storleken på voxlarna som används för spelares huvuden(blocket/föremålet)", + "text.skinlayers.reset": "Standard", + "text.skinlayers.fastrender.enable": "Snabb Rendering", + "text.skinlayers.fastrender.enable.tooltip": "Rendera 3D modellerna så fort som möjligt, det här kanske skapar några grafiska buggar med transperens", + "text.skinlayers.firstperson.voxelsize": "Första Person Voxel Storlek", + "text.skinlayers.firstperson.voxelsize.tooltip": "Storleken på voxlarna som används för spelarens hand i första person" +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/tr_tr.json b/src/main/resources/assets/skinlayers3d/lang/tr_tr.json similarity index 94% rename from Shared/src/main/resources/assets/3dskinlayers/lang/tr_tr.json rename to src/main/resources/assets/skinlayers3d/lang/tr_tr.json index 9b3ff32..61b505c 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/tr_tr.json +++ b/src/main/resources/assets/skinlayers3d/lang/tr_tr.json @@ -1,7 +1,6 @@ { - "__comment__": "Turkish translation by @alpeerkaraca", + "__comment__": "Turkish translation by @alpeerkaraca", "text.skinlayers.title": "3D Görünüm Ayarları", - "text.skinlayers.enable.hat": "3D Şapka", "text.skinlayers.enable.jacket": "3D Ceket", "text.skinlayers.enable.leftsleeve": "3D Sol Kol", @@ -18,4 +17,4 @@ "text.skinlayers.skulls.voxelsize": "Kafatası Voksel Boyutu", "text.skinlayers.reset": "Varsayılan", "text.skinlayers.fastrender.enable": "Hızlı Renderle" - } \ No newline at end of file +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/uk_ua.json b/src/main/resources/assets/skinlayers3d/lang/uk_ua.json similarity index 99% rename from Shared/src/main/resources/assets/3dskinlayers/lang/uk_ua.json rename to src/main/resources/assets/skinlayers3d/lang/uk_ua.json index 066229d..71b4d1f 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/uk_ua.json +++ b/src/main/resources/assets/skinlayers3d/lang/uk_ua.json @@ -1,6 +1,5 @@ { "text.skinlayers.title": "Параметри 3D Skin Layers", - "text.skinlayers.enable.hat": "3D-капелюх", "text.skinlayers.enable.jacket": "3D-куртка", "text.skinlayers.enable.leftsleeve": "3D-лівий рукав", @@ -17,4 +16,4 @@ "text.skinlayers.skulls.voxelsize": "Розмір вокселя черепа", "text.skinlayers.reset": "Скинути", "text.skinlayers.fastrender.enable": "Швидкий рендер" - } +} diff --git a/src/main/resources/assets/skinlayers3d/lang/zh_cn.json b/src/main/resources/assets/skinlayers3d/lang/zh_cn.json new file mode 100644 index 0000000..6f6e985 --- /dev/null +++ b/src/main/resources/assets/skinlayers3d/lang/zh_cn.json @@ -0,0 +1,19 @@ +{ + "text.skinlayers.title": "3D 双层皮肤 Mod 设置", + "text.skinlayers.enable.hat": "开启 3D 帽子", + "text.skinlayers.enable.jacket": "开启 3D 上衣", + "text.skinlayers.enable.leftsleeve": "开启 3D 左袖子", + "text.skinlayers.enable.rightsleeve": "开启 3D 右袖子", + "text.skinlayers.enable.leftpants": "开启 3D 左裤子", + "text.skinlayers.enable.rightpants": "开启 3D 右裤子", + "text.skinlayers.renderdistancelod": "3D 渲染距离", + "text.skinlayers.basevoxelsize": "像素块大小", + "text.skinlayers.headvoxelsize": "头部像素块大小", + "text.skinlayers.bodyvoxelheightsize": "身体像素块高度", + "text.skinlayers.bodyvoxelwidthsize": "身体像素块宽度", + "text.skinlayers.skulls.enable": "开启 3D 头颅", + "text.skinlayers.skullsitems.enable": "开启 3D 头颅物品", + "text.skinlayers.skulls.voxelsize": "头颅像素块大小", + "text.skinlayers.reset": "恢复为默认", + "text.skinlayers.fastrender.enable": "开启快速渲染" +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/lang/zh_tw.json b/src/main/resources/assets/skinlayers3d/lang/zh_tw.json similarity index 98% rename from Shared/src/main/resources/assets/3dskinlayers/lang/zh_tw.json rename to src/main/resources/assets/skinlayers3d/lang/zh_tw.json index 46db8f2..49050e7 100644 --- a/Shared/src/main/resources/assets/3dskinlayers/lang/zh_tw.json +++ b/src/main/resources/assets/skinlayers3d/lang/zh_tw.json @@ -1,37 +1,36 @@ -{ - "text.skinlayers.title": "3D Skin Layer 設定", - - "text.skinlayers.enable.hat": "3D 帽子", - "text.skinlayers.enable.hat.tooltip": "將玩家的帽子繪製為 3D 模型", - "text.skinlayers.enable.jacket": "3D 外套", - "text.skinlayers.enable.jacket.tooltip": "將玩家的外套繪製為 3D 模型", - "text.skinlayers.enable.leftsleeve": "3D 左衣袖", - "text.skinlayers.enable.leftsleeve.tooltip": "將玩家的左衣袖繪製為 3D 模型", - "text.skinlayers.enable.rightsleeve": "3D 右衣袖", - "text.skinlayers.enable.rightsleeve.tooltip": "將玩家的右衣袖繪製為 3D 模型", - "text.skinlayers.enable.leftpants": "3D 左褲管", - "text.skinlayers.enable.leftpants.tooltip": "將玩家的左褲管繪製為 3D 模型", - "text.skinlayers.enable.rightpants": "3D 右褲管", - "text.skinlayers.enable.rightpants.tooltip": "將玩家的右褲管繪製為 3D 模型", - "text.skinlayers.renderdistancelod": "細節層次距離", - "text.skinlayers.renderdistancelod.tooltip": "依據距離來切換顯示低細節層次模型(原版的 2D)", - "text.skinlayers.basevoxelsize": "像素大小", - "text.skinlayers.basevoxelsize.tooltip": "玩家所使用的像素大小", - "text.skinlayers.headvoxelsize": "頭部像素大小", - "text.skinlayers.headvoxelsize.tooltip": "玩家頭部所使用的像素大小", - "text.skinlayers.bodyvoxelheightsize": "身體像素高", - "text.skinlayers.bodyvoxelheightsize.tooltip": "玩家身體高所使用的像素大小(用於防止頭部與手臂穿透)", - "text.skinlayers.bodyvoxelwidthsize": "軀幹像素寬", - "text.skinlayers.bodyvoxelwidthsize.tooltip": "玩家軀幹寬所使用的像素大小(用於防止穿透到手臂)", - "text.skinlayers.skulls.enable": "3D 頭顱", - "text.skinlayers.skulls.enable.tooltip": "將玩家的頭顱與方塊頭顱繪製為 3D 模型", - "text.skinlayers.skullsitems.enable": "3D 頭顱物品", - "text.skinlayers.skullsitems.enable.tooltip": "將玩家的物品頭顱繪製為 3D 模型", - "text.skinlayers.skulls.voxelsize": "頭顱像素大小", - "text.skinlayers.skulls.voxelsize.tooltip": "玩家頭顱所使用的像素大小(方塊/物品)", - "text.skinlayers.reset": "預設", - "text.skinlayers.fastrender.enable": "快速繪製", - "text.skinlayers.fastrender.enable.tooltip": "以最快的速度繪製 3D 模型,這可能導致圖形的透明度錯誤", - "text.skinlayers.firstperson.voxelsize": "第一人稱像素大小", - "text.skinlayers.firstperson.voxelsize.tooltip": "第一人稱下玩家手部所使用的像素大小" -} +{ + "text.skinlayers.title": "3D Skin Layer 設定", + "text.skinlayers.enable.hat": "3D 帽子", + "text.skinlayers.enable.hat.tooltip": "將玩家的帽子繪製為 3D 模型", + "text.skinlayers.enable.jacket": "3D 外套", + "text.skinlayers.enable.jacket.tooltip": "將玩家的外套繪製為 3D 模型", + "text.skinlayers.enable.leftsleeve": "3D 左衣袖", + "text.skinlayers.enable.leftsleeve.tooltip": "將玩家的左衣袖繪製為 3D 模型", + "text.skinlayers.enable.rightsleeve": "3D 右衣袖", + "text.skinlayers.enable.rightsleeve.tooltip": "將玩家的右衣袖繪製為 3D 模型", + "text.skinlayers.enable.leftpants": "3D 左褲管", + "text.skinlayers.enable.leftpants.tooltip": "將玩家的左褲管繪製為 3D 模型", + "text.skinlayers.enable.rightpants": "3D 右褲管", + "text.skinlayers.enable.rightpants.tooltip": "將玩家的右褲管繪製為 3D 模型", + "text.skinlayers.renderdistancelod": "細節層次距離", + "text.skinlayers.renderdistancelod.tooltip": "依據距離來切換顯示低細節層次模型(原版的 2D)", + "text.skinlayers.basevoxelsize": "像素大小", + "text.skinlayers.basevoxelsize.tooltip": "玩家所使用的像素大小", + "text.skinlayers.headvoxelsize": "頭部像素大小", + "text.skinlayers.headvoxelsize.tooltip": "玩家頭部所使用的像素大小", + "text.skinlayers.bodyvoxelheightsize": "身體像素高", + "text.skinlayers.bodyvoxelheightsize.tooltip": "玩家身體高所使用的像素大小(用於防止頭部與手臂穿透)", + "text.skinlayers.bodyvoxelwidthsize": "軀幹像素寬", + "text.skinlayers.bodyvoxelwidthsize.tooltip": "玩家軀幹寬所使用的像素大小(用於防止穿透到手臂)", + "text.skinlayers.skulls.enable": "3D 頭顱", + "text.skinlayers.skulls.enable.tooltip": "將玩家的頭顱與方塊頭顱繪製為 3D 模型", + "text.skinlayers.skullsitems.enable": "3D 頭顱物品", + "text.skinlayers.skullsitems.enable.tooltip": "將玩家的物品頭顱繪製為 3D 模型", + "text.skinlayers.skulls.voxelsize": "頭顱像素大小", + "text.skinlayers.skulls.voxelsize.tooltip": "玩家頭顱所使用的像素大小(方塊/物品)", + "text.skinlayers.reset": "預設", + "text.skinlayers.fastrender.enable": "快速繪製", + "text.skinlayers.fastrender.enable.tooltip": "以最快的速度繪製 3D 模型,這可能導致圖形的透明度錯誤", + "text.skinlayers.firstperson.voxelsize": "第一人稱像素大小", + "text.skinlayers.firstperson.voxelsize.tooltip": "第一人稱下玩家手部所使用的像素大小" +} diff --git a/Shared/src/main/resources/assets/3dskinlayers/icon.png b/src/main/resources/icon.png similarity index 100% rename from Shared/src/main/resources/assets/3dskinlayers/icon.png rename to src/main/resources/icon.png diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..3848806 --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "Resources for ${mod_id}", + "pack_format": ${pack_format_number} + } +} diff --git a/src/main/resources/skinlayers3d.mixins.json b/src/main/resources/skinlayers3d.mixins.json new file mode 100644 index 0000000..2cae4c6 --- /dev/null +++ b/src/main/resources/skinlayers3d.mixins.json @@ -0,0 +1,22 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "dev.tr7zw.skinlayers.mixin", + "compatibilityLevel": "JAVA_16", + "refmap": "skinlayers3d.refmap.mixins.json", + "mixins": [], + "client": [ + "PlayerRendererMixin", + "PlayerMixin", + "PlayerModelMixin", + "SkullBlockEntityRendererMixin", + "SkullModelMixin", + "SkullBlockEntityMixin", + "BlockEntityWithoutLevelRendererMixin", + "CustomHeadLayerMixin", + "HttpTextureMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/versions/1.16.5-fabric/src/main/resources/skinlayers3d.accesswidener b/versions/1.16.5-fabric/src/main/resources/skinlayers3d.accesswidener new file mode 100644 index 0000000..940d835 --- /dev/null +++ b/versions/1.16.5-fabric/src/main/resources/skinlayers3d.accesswidener @@ -0,0 +1,5 @@ +accessWidener v1 named +accessible field net/minecraft/client/model/geom/ModelPart$Cube polygons [Lnet/minecraft/client/model/geom/ModelPart$Polygon; +accessible class net/minecraft/client/model/geom/ModelPart$Polygon +accessible class net/minecraft/client/model/geom/ModelPart$Vertex +accessible field net/minecraft/client/model/geom/ModelPart children Lit/unimi/dsi/fastutil/objects/ObjectList; \ No newline at end of file diff --git a/versions/1.16.5-forge/src/main/resources/META-INF/accesstransformer.cfg b/versions/1.16.5-forge/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000..260dbb9 --- /dev/null +++ b/versions/1.16.5-forge/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,4 @@ +public net.minecraft.client.renderer.model.ModelRenderer$ModelBox field_78254_i # polygons +public net.minecraft.client.renderer.model.ModelRenderer$TexturedQuad +public net.minecraft.client.renderer.model.ModelRenderer$PositionTextureVertex +public net.minecraft.client.renderer.model.ModelRenderer field_78805_m # children \ No newline at end of file diff --git a/versions/1.16.5-forge/src/main/resources/skinlayers3d.accesswidener b/versions/1.16.5-forge/src/main/resources/skinlayers3d.accesswidener new file mode 100644 index 0000000..940d835 --- /dev/null +++ b/versions/1.16.5-forge/src/main/resources/skinlayers3d.accesswidener @@ -0,0 +1,5 @@ +accessWidener v1 named +accessible field net/minecraft/client/model/geom/ModelPart$Cube polygons [Lnet/minecraft/client/model/geom/ModelPart$Polygon; +accessible class net/minecraft/client/model/geom/ModelPart$Polygon +accessible class net/minecraft/client/model/geom/ModelPart$Vertex +accessible field net/minecraft/client/model/geom/ModelPart children Lit/unimi/dsi/fastutil/objects/ObjectList; \ No newline at end of file diff --git a/versions/mainProject b/versions/mainProject new file mode 100644 index 0000000..66d55ba --- /dev/null +++ b/versions/mainProject @@ -0,0 +1 @@ +1.20.4-fabric \ No newline at end of file