Merge pull request #31 from saturnclientmc/rewrote-3d-cosmetic-rendering

Rewrote 3d cosmetic rendering #18
This commit is contained in:
2026-03-03 02:39:12 -08:00
committed by GitHub
37 changed files with 375 additions and 196 deletions
+7 -10
View File
@@ -47,11 +47,8 @@ repositories {
// Parchment mappings (if needed later)
maven { url 'https://maven.parchmentmc.org' }
// Special Model Loader
maven { name = "FelNull Maven"; url = "https://maven.felnull.dev" }
// Player Animation Library
maven { name = "KosmX Maven"; url = 'https://maven.kosmx.dev/' }
maven { name = "KoSmX Maven"; url = 'https://maven.kosmx.dev/' }
// Central repository
mavenCentral()
@@ -83,9 +80,9 @@ dependencies {
// Rendering / Model Libraries
// ─────────────────────────────────────────────
// Special Model Loader (included inside your mod jar)
modApi "dev.felnull:special-model-loader:1.4.0+pre.1"
include "dev.felnull:special-model-loader:1.4.0+pre.1"
// OBJ Reading Library
implementation "de.javagl:obj:0.4.0"
include "de.javagl:obj:0.4.0"
// SVG Rendering Library
include implementation("com.formdev:svgSalamander:1.1.4")
@@ -95,12 +92,12 @@ dependencies {
// Animation
// ─────────────────────────────────────────────
// Player Animation Library (bundled into your mod)
// Player Animation Library
include modImplementation(
"dev.kosmx.player-anim:player-animation-lib-fabric:${project.player_anim}"
)
// Optional: BendyLib (only if you directly use it)
// Optional: BendyLib
// include modRuntimeOnly(
// "io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendylib_version}"
// )
@@ -110,7 +107,7 @@ dependencies {
// External Libraries
// ─────────────────────────────────────────────
// Session Java (auth/session handling)
// Session Java (Saturn auth/session handling)
include implementation("com.github.selimaj-dev:session-java:0.1.6")
}
@@ -1,4 +1,4 @@
package org.saturnclient.saturnclient.cosmetics;
package org.saturnclient.cosmetics;
import java.util.ArrayList;
import java.util.List;
@@ -1,10 +1,9 @@
package org.saturnclient.saturnclient.cosmetics;
package org.saturnclient.cosmetics.cloak;
import java.util.Arrays;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.Config;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.RenderLayer;
@@ -24,6 +23,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentAsset;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.math.Vec3d;
/**
@@ -35,7 +35,7 @@ import net.minecraft.util.math.Vec3d;
*/
public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState, PlayerEntityModel> {
private final EquipmentModelLoader equipmentModelLoader;
private static final int PARTS = 16;
private static final int PARTS = 24;
private final float[] segmentValues = new float[PARTS];
private static final float TEX_W = 176f;
@@ -208,23 +208,23 @@ public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderStat
Vec3d innerBotRight = new Vec3d(x1, nextY, nextZ);
// Outer Vertices (Offset by the specific joint thickness)
Vec3d outerTopLeft = new Vec3d(x2, curY + thickYStart, curZ + thickZStart);
Vec3d outerTopRight = new Vec3d(x1, curY + thickYStart, curZ + thickZStart);
Vec3d outerBotLeft = new Vec3d(x2, nextY + thickYEnd, nextZ + thickZEnd);
Vec3d outerBotRight = new Vec3d(x1, nextY + thickYEnd, nextZ + thickZEnd);
Vec3d outerTopLeft = new Vec3d(x2, curY - thickYStart, curZ - thickZStart);
Vec3d outerTopRight = new Vec3d(x1, curY - thickYStart, curZ - thickZStart);
Vec3d outerBotLeft = new Vec3d(x2, nextY - thickYEnd, nextZ - thickZEnd);
Vec3d outerBotRight = new Vec3d(x1, nextY - thickYEnd, nextZ - thickZEnd);
// FRONT (Inner) - Changed winding/order to fix flipping
this.renderCapeQuad(vertexConsumer, matrixStack,
innerBotLeft, innerBotRight, innerTopRight, innerTopLeft,
frontU1, frontV1 + (frontPartV * i), frontU2, frontV1 + (frontPartV * (i + 1)),
light, overlay, 0, 0, -1, false);
// BACK (Outer)
// FRONT (facing camera)
this.renderCapeQuad(vertexConsumer, matrixStack,
outerBotRight, outerBotLeft, outerTopLeft, outerTopRight,
backU1, backV1 + (backPartV * i), backU2, backV1 + (backPartV * (i + 1)),
frontU2, frontV1 + (frontPartV * i), frontU1, frontV1 + (frontPartV * (i + 1)),
light, overlay, 0, 0, 1, false);
// BACK (Facing player)
this.renderCapeQuad(vertexConsumer, matrixStack,
innerBotLeft, innerBotRight, innerTopRight, innerTopLeft,
backU2, backV1 + (backPartV * i), backU1, backV1 + (backPartV * (i + 1)),
light, overlay, 0, 0, -1, false);
// LEFT EDGE
this.renderCapeQuad(vertexConsumer, matrixStack,
innerBotLeft, outerBotLeft, outerTopLeft, innerTopLeft,
@@ -300,16 +300,25 @@ public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderStat
matrixStack.push();
matrixStack.translate(0.0f, 0.0f, 0.19f);
matrixStack.translate(0.0f, 0.0f, 0.12f);
if (this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.HUMANOID)) {
matrixStack.translate(0.0F, -0.053125F, 0.06875F);
}
if (playerEntityRenderState.isInSneakingPose) {
matrixStack.translate(0, 0.16f, 0.0f);
matrixStack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(29.0f));
}
long now = System.currentTimeMillis();
if (now - lastUpdate >= 20) {
float value = Math.min(1.0f, playerEntityRenderState.field_53537 / 108.0f)
+ (Math.max(0, playerEntityRenderState.field_53536) / 16);
float velX = Math.min(1.0f, playerEntityRenderState.field_53537 / 108.0f);
float rawVelY = playerEntityRenderState.field_53536;
float velY = (rawVelY > 4.0f ? rawVelY : 0.0f) / 16;
float value = playerEntityRenderState.isSwimming ? 0.0f : velX + velY;
if (Config.cloakPhysics.value) {
updateSegmentValues(value);
} else {
@@ -1,11 +1,9 @@
package org.saturnclient.saturnclient.cosmetics.cloaks;
package org.saturnclient.cosmetics.cloak;
import net.minecraft.util.Identifier;
import org.saturnclient.saturnclient.client.ServiceClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.cosmetics.cloaks.utils.AnimatedCloakData;
import org.saturnclient.saturnclient.cosmetics.cloaks.utils.IdentifierUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
@@ -17,6 +15,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.saturnclient.cosmetics.cloak.utils.AnimatedCloakData;
import org.saturnclient.cosmetics.cloak.utils.IdentifierUtils;
import org.saturnclient.saturnclient.SaturnClient;
/**
@@ -1,4 +1,4 @@
package org.saturnclient.saturnclient.cosmetics.cloaks;
package org.saturnclient.cosmetics.cloak;
import java.awt.*;
import java.awt.image.BufferedImage;
@@ -1,4 +1,4 @@
package org.saturnclient.saturnclient.cosmetics.cloaks.utils;
package org.saturnclient.cosmetics.cloak.utils;
import net.minecraft.util.Identifier;
@@ -1,4 +1,4 @@
package org.saturnclient.saturnclient.cosmetics.cloaks.utils;
package org.saturnclient.cosmetics.cloak.utils;
import org.saturnclient.saturnclient.SaturnClient;
import net.minecraft.client.texture.NativeImage;
@@ -1,4 +1,4 @@
package org.saturnclient.saturnclient.cosmetics.cloaks.utils;
package org.saturnclient.cosmetics.cloak.utils;
import java.util.Random;
@@ -0,0 +1,39 @@
package org.saturnclient.cosmetics.hat;
import org.saturnclient.cosmetics.obj.MtlLoader;
import org.saturnclient.cosmetics.obj.ObjModel;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.PlayerEntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState, PlayerEntityModel> {
public HatFeatureRenderer(FeatureRendererContext<PlayerEntityRenderState, PlayerEntityModel> context) {
super(context);
}
@Override
public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light,
PlayerEntityRenderState state, float limbAngle, float limbDistance) {
SaturnPlayer player = SaturnPlayer.get(state.name);
if (state.invisible || player == null || player.hat.isEmpty()) {
return;
}
matrices.push();
this.getContextModel().head.rotate(matrices);
ObjModel.cosmetic("hat", player.hat).render(MtlLoader.cosmetic(player.hat),
matrices, vertexConsumers, light,
OverlayTexture.DEFAULT_UV);
matrices.pop();
}
}
@@ -1,4 +1,4 @@
package org.saturnclient.saturnclient.cosmetics;
package org.saturnclient.cosmetics.hat;
import java.util.ArrayList;
import java.util.List;
@@ -0,0 +1,57 @@
package org.saturnclient.cosmetics.obj;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.javagl.obj.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.Identifier;
public class MtlLoader {
static Map<Identifier, Map<String, Mtl>> loadedMtls = new HashMap<>();
static Map<String, Mtl> loadMtl(Identifier mtlId) throws IOException {
try (InputStream is = MinecraftClient.getInstance().getResourceManager()
.getResource(mtlId).get().getInputStream()) {
List<Mtl> mtlList = MtlReader.read(is);
Map<String, Mtl> mtlMap = new java.util.LinkedHashMap<>();
for (Mtl mtl : mtlList) {
mtlMap.put(mtl.getName(), mtl);
}
return mtlMap;
}
}
public static Map<String, Mtl> of(Identifier mtlId) {
System.out.println(mtlId);
if (loadedMtls.containsKey(mtlId))
return loadedMtls.get(mtlId);
try {
Map<String, Mtl> mtl = loadMtl(mtlId);
loadedMtls.put(mtlId, mtl);
return mtl;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static Map<String, Mtl> cosmetic(String cosmeticId) {
int index = cosmeticId.indexOf('_');
String mtlId = (index == -1) ? "" : cosmeticId.substring(index + 1);
if (mtlId.isEmpty())
mtlId = "white";
return of(Identifier.of("saturnclient", "models/cosmetic/materials/" + mtlId + ".mtl"));
}
}
@@ -0,0 +1,102 @@
package org.saturnclient.cosmetics.obj;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.javagl.obj.Mtl;
import de.javagl.obj.Obj;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
public class ObjModel {
private static final ObjectMapper MAPPER = new ObjectMapper();
public static final Map<Identifier, ObjModel> loadedObjModels = new HashMap<>();
public record Config(
@JsonProperty("translate") Vec3d transform,
@JsonProperty("scale") Vec3d scale,
@JsonProperty("rotation") Vec3d rotation) {
public Config {
transform = transform == null ? new Vec3d(0, 0, 0) : transform;
scale = scale == null ? new Vec3d(1, 1, 1) : scale;
rotation = rotation == null ? new Vec3d(0, 0, 0) : rotation;
}
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
public record Vec3d(float x, float y, float z) {
}
}
Obj obj;
Config config;
public static ObjModel cosmetic(String cosmeticKind, String id) {
return of(Identifier.of("saturnclient", "models/cosmetic/" + cosmeticKind + "/" + id.split("_")[0] + "/model"));
}
public static ObjModel of(Identifier obj) {
if (loadedObjModels.containsKey(obj))
return loadedObjModels.get(obj);
ObjModel o = new ObjModel(obj);
loadedObjModels.put(obj, o);
return o;
}
ObjModel(Identifier identifier) {
Identifier objId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".obj");
Identifier jsonId = Identifier.of(identifier.getNamespace(), identifier.getPath() + ".json");
try {
this.obj = ObjRenderer.loadObj(objId);
} catch (IOException e) {
e.printStackTrace();
}
// Try loading JSON config if it exists
ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager();
Optional<Resource> resource = resourceManager.getResource(jsonId);
if (resource.isPresent()) {
try (InputStream stream = resource.get().getInputStream()) {
this.config = MAPPER.readValue(stream, Config.class);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void render(Map<String, Mtl> mtlMap, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light,
int overlay) {
matrices.push();
matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f));
matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f));
if (this.config != null) {
matrices.translate(config.transform.x, config.transform.y, config.transform.z);
matrices.scale(config.scale.x, config.scale.y, config.scale.z);
matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(config.rotation.x));
matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(config.rotation.y));
matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotationDegrees(config.rotation.z));
}
ObjRenderer.renderObj(this.obj, mtlMap, matrices, vertexConsumers, light, overlay);
matrices.pop();
}
}
@@ -0,0 +1,111 @@
package org.saturnclient.cosmetics.obj;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import de.javagl.obj.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
public class ObjRenderer {
public static Obj loadObj(Identifier objId) throws IOException {
try (InputStream is = MinecraftClient.getInstance().getResourceManager()
.getResource(objId).get().getInputStream()) {
return ObjReader.read(is);
}
}
public static void renderObj(Obj obj, Map<String, Mtl> mtlMap, MatrixStack matrices,
VertexConsumerProvider vertexConsumers, int light, int overlay) {
MatrixStack.Entry entry = matrices.peek();
Map<String, Obj> materialGroups = ObjSplitting.splitByMaterialGroups(obj);
for (Map.Entry<String, Obj> group : materialGroups.entrySet()) {
String materialName = group.getKey();
Obj groupObj = group.getValue();
Mtl mtl = mtlMap != null ? mtlMap.get(materialName) : null;
// Resolve texture identifier using same logic as ObjUnbakedModelModel
Identifier texture = Identifier.of("minecraft:textures/misc/white.png");
if (mtl != null) {
String mapKd = mtl.getMapKd();
if (mapKd != null) {
// "#key" references are not resolvable at runtime without a texture map,
// so we only support direct resource location strings here
if (!mapKd.startsWith("#")) {
texture = Identifier.of(mapKd);
}
}
}
// Diffuse color (Kd)
float r = 1f, g = 1f, b = 1f;
if (mtl != null) {
FloatTuple kd = mtl.getKd();
if (kd != null) {
r = kd.getX();
g = kd.getY();
b = kd.getZ();
}
}
VertexConsumer consumer = vertexConsumers.getBuffer(RenderLayer.getEntityAlpha(texture));
int faces = groupObj.getNumFaces();
final float fr = r, fg = g, fb = b;
for (int f = 0; f < faces; f++) {
ObjFace face = groupObj.getFace(f);
int verts = face.getNumVertices();
// Your original winding order logic, untouched
for (int i = verts - 1; i >= 0; i--) {
writeVertex(groupObj, face, i, consumer, entry, light, overlay, fr, fg, fb);
}
}
}
}
private static void writeVertex(Obj obj, ObjFace face, int index, VertexConsumer consumer,
MatrixStack.Entry matrix, int light, int overlay,
float r, float g, float b) {
FloatTuple pos = obj.getVertex(face.getVertexIndex(index));
float x = pos.getX();
float y = pos.getY();
float z = pos.getZ();
float nx = 0f, ny = 1f, nz = 0f;
int normalIndex = face.getNormalIndex(index);
if (normalIndex >= 0) {
FloatTuple n = obj.getNormal(normalIndex);
nx = n.getX();
ny = n.getY();
nz = n.getZ();
}
float u = 0f, v = 0f;
int texIndex = face.getTexCoordIndex(index);
if (texIndex >= 0) {
FloatTuple tc = obj.getTexCoord(texIndex);
u = tc.getX();
v = 1f - tc.getY(); // Flip V: OBJ bottom-left origin -> Minecraft top-left
}
consumer.vertex(matrix, x, y, z)
.color(r, g, b, 1f)
.texture(u, v)
.overlay(overlay)
.light(light)
.normal(matrix, nx, ny, nz);
}
}
@@ -6,13 +6,13 @@ import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.util.math.MatrixStack;
import org.saturnclient.cosmetics.Emotes;
import org.saturnclient.cosmetics.cloak.Cloaks;
import org.saturnclient.cosmetics.hat.Hats;
import org.saturnclient.modules.ModManager;
import org.saturnclient.saturnclient.client.ServiceClient;
import org.saturnclient.saturnclient.config.Config;
import org.saturnclient.saturnclient.config.manager.ConfigManager;
import org.saturnclient.saturnclient.cosmetics.Emotes;
import org.saturnclient.saturnclient.cosmetics.Hats;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
import org.saturnclient.saturnclient.event.KeyInputHandler;
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
import org.saturnclient.ui2.RenderScope;
@@ -23,8 +23,6 @@ import org.saturnclient.ui2.screens.TitleMenu;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import dev.felnull.specialmodelloader.api.event.SpecialModelLoaderEvents;
/**
* Main class for the Saturn Client mod.
*/
@@ -47,10 +45,6 @@ public class SaturnClient implements ModInitializer {
ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> ConfigManager.save());
SpecialModelLoaderEvents.LOAD_SCOPE.register(() -> {
return (resourceManager, location) -> MOD_ID.equals(location.getNamespace());
});
ScreenEvents.AFTER_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (screen != null && !(screen instanceof TitleMenu)) {
if (screen instanceof SaturnScreen) {
@@ -3,10 +3,10 @@ package org.saturnclient.saturnclient.client;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.saturnclient.cosmetics.cloak.Cloaks;
import org.saturnclient.cosmetics.hat.Hats;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.cosmetics.Hats;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
import dev.kosmx.playerAnim.api.layered.AnimationStack;
import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess;
@@ -1,62 +0,0 @@
package org.saturnclient.saturnclient.cosmetics;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.SaturnClient;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.PlayerEntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.EquippableComponent;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.ModelTransformationMode;
import net.minecraft.util.Identifier;
public class HatFeatureRenderer extends FeatureRenderer<PlayerEntityRenderState, PlayerEntityModel> {
public HatFeatureRenderer(FeatureRendererContext<PlayerEntityRenderState, PlayerEntityModel> context) {
super(context);
}
@Override
public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light,
PlayerEntityRenderState state, float limbAngle, float limbDistance) {
ItemStack headItem = state.equippedHeadStack;
SaturnPlayer player = SaturnPlayer.get(state.name);
if (!headItem.isEmpty() || state.invisible || player == null || player.hat.isEmpty()) {
return;
}
matrices.push();
this.getContextModel().head.rotate(matrices);
matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_X.rotationDegrees(180.0f));
matrices.multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Y.rotationDegrees(180.0f));
ItemStack customHat = new ItemStack(Items.STICK);
customHat.set(DataComponentTypes.ITEM_MODEL,
Identifier.of("saturnclient:hat_" + player.hat));
customHat.set(DataComponentTypes.EQUIPPABLE,
EquippableComponent.builder(EquipmentSlot.HEAD).build());
ItemRenderer itemRenderer = SaturnClient.client.getItemRenderer();
itemRenderer.renderItem(
customHat,
ModelTransformationMode.THIRD_PERSON_RIGHT_HAND,
light,
OverlayTexture.DEFAULT_UV,
matrices,
vertexConsumers,
null,
0);
matrices.pop();
}
}
@@ -7,8 +7,8 @@ import net.minecraft.client.render.entity.model.PlayerEntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.entity.player.PlayerEntity;
import org.saturnclient.saturnclient.cosmetics.CloakFeatureRenderer;
import org.saturnclient.saturnclient.cosmetics.HatFeatureRenderer;
import org.saturnclient.cosmetics.cloak.CloakFeatureRenderer;
import org.saturnclient.cosmetics.hat.HatFeatureRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -11,7 +11,7 @@ import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGUniverse;
import org.jetbrains.annotations.Nullable;
import org.saturnclient.saturnclient.cosmetics.cloaks.utils.IdentifierUtils;
import org.saturnclient.cosmetics.cloak.utils.IdentifierUtils;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.Identifier;
@@ -1,10 +1,10 @@
package org.saturnclient.ui2.screens;
import org.saturnclient.cosmetics.Emotes;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.ServiceClient;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.config.Config;
import org.saturnclient.saturnclient.cosmetics.Emotes;
import org.saturnclient.ui2.SaturnScreen;
import org.saturnclient.ui2.Utils;
import org.saturnclient.ui2.anim.Fade;
@@ -1,9 +1,9 @@
package org.saturnclient.ui2.screens.cosmetics;
import org.saturnclient.cosmetics.cloak.Cloaks;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
import org.saturnclient.ui2.resources.Textures;
import org.saturnclient.ui2.SaturnScreen;
import org.saturnclient.ui2.anim.Fade;
@@ -1,9 +1,9 @@
package org.saturnclient.ui2.screens.cosmetics;
import org.saturnclient.cosmetics.hat.Hats;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.cosmetics.Hats;
import org.saturnclient.ui2.resources.Textures;
import org.saturnclient.ui2.SaturnScreen;
import org.saturnclient.ui2.anim.Fade;
@@ -1,11 +1,11 @@
package org.saturnclient.ui2.screens.store;
import org.saturnclient.cosmetics.cloak.Cloaks;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.ServiceClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.config.Theme;
import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks;
import org.saturnclient.ui2.SaturnScreen;
import org.saturnclient.ui2.Utils;
import org.saturnclient.ui2.anim.Fade;
@@ -1,11 +1,11 @@
package org.saturnclient.ui2.screens.store;
import org.saturnclient.cosmetics.hat.Hats;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.client.ServiceClient;
import org.saturnclient.saturnclient.client.player.SaturnPlayer;
import org.saturnclient.saturnclient.config.AnimationConfig;
import org.saturnclient.saturnclient.config.Theme;
import org.saturnclient.saturnclient.cosmetics.Hats;
import org.saturnclient.ui2.SaturnScreen;
import org.saturnclient.ui2.Utils;
import org.saturnclient.ui2.anim.Fade;
@@ -1,6 +0,0 @@
{
"model": {
"type": "minecraft:model",
"model": "saturnclient:item/halo/white"
}
}
@@ -1,6 +0,0 @@
{
"model": {
"type": "minecraft:model",
"model": "saturnclient:item/halo/black"
}
}
@@ -1,6 +0,0 @@
{
"model": {
"type": "minecraft:model",
"model": "saturnclient:item/horns/black"
}
}
@@ -1,6 +0,0 @@
{
"model": {
"type": "minecraft:model",
"model": "saturnclient:item/horns/white"
}
}
@@ -0,0 +1,4 @@
{
"translate": [0.0, 0.62, 0.0],
"scale": [0.2, 0.1, 0.2]
}
@@ -0,0 +1,4 @@
{
"translate": [0.0, 0.25, 0.0],
"scale": [0.25, 0.25, 0.25]
}
@@ -10,4 +10,4 @@ Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Kd saturnclient:item/halo_black
map_Kd saturnclient:textures/item/halo_black.png
@@ -10,4 +10,4 @@ Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Kd saturnclient:item/halo
map_Kd saturnclient:textures/item/halo.png
@@ -1,13 +0,0 @@
{
"parent": "special-model-loader:builtin/obj",
"model": "saturnclient:models/item/halo/halo.obj",
"mtl_override": "saturnclient:models/item/black.mtl",
"flip_v": true,
"display": {
"thirdperson_righthand": {
"rotation": [0, 0, 0],
"translation": [1.5, 12, 1.5],
"scale": [0.2, 0.2, 0.2]
}
}
}
@@ -1,13 +0,0 @@
{
"parent": "special-model-loader:builtin/obj",
"model": "saturnclient:models/item/halo/halo.obj",
"mtl_override": "saturnclient:models/item/white.mtl",
"flip_v": true,
"display": {
"thirdperson_righthand": {
"rotation": [0, 0, 0],
"translation": [1.5, 12, 1.5],
"scale": [0.2, 0.2, 0.2]
}
}
}
@@ -1,13 +0,0 @@
{
"parent": "special-model-loader:builtin/obj",
"model": "saturnclient:models/item/horns/horns.obj",
"mtl_override": "saturnclient:models/item/black.mtl",
"flip_v": true,
"display": {
"thirdperson_righthand": {
"rotation": [0, 0, 0],
"translation": [2, 6, 2],
"scale": [0.25, 0.25, 0.25]
}
}
}
@@ -1,13 +0,0 @@
{
"parent": "special-model-loader:builtin/obj",
"model": "saturnclient:models/item/horns/horns.obj",
"mtl_override": "saturnclient:models/item/white.mtl",
"flip_v": true,
"display": {
"thirdperson_righthand": {
"rotation": [0, 0, 0],
"translation": [2, 6, 2],
"scale": [0.25, 0.25, 0.25]
}
}
}