Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package twilightforest.block.entity;

import com.google.common.base.MoreObjects;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag;
Expand All @@ -17,6 +18,8 @@
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.neoforged.neoforge.model.data.ModelData;
import net.neoforged.neoforge.model.data.ModelProperty;
import org.joml.Vector3f;
import twilightforest.init.TFBlockEntities;

Expand All @@ -30,6 +33,7 @@ public class ReactorDebrisBlockEntity extends BlockEntity {
Identifier.withDefaultNamespace("block/nether_portal"),
Identifier.withDefaultNamespace("block/obsidian"),
};
public static final ModelProperty<Identifier> TEXTURE_FOR_PARTICLE = new ModelProperty<>();
public static final Identifier DEFAULT_TEXTURE = TEXTURES[0];
private static final float Z_FIGHTING_MIN = 0.008F;
private static final float Z_FIGHTING_MAX = 1 - 0.008F;
Expand Down Expand Up @@ -153,4 +157,12 @@ public ClientboundBlockEntityDataPacket getUpdatePacket() {
public CompoundTag getUpdateTag(HolderLookup.Provider registries) {
return this.saveCustomOnly(registries);
}

@Override
public ModelData getModelData() {
if (!(this.level instanceof ClientLevel clientLevel))
return ModelData.EMPTY.derive().with(TEXTURE_FOR_PARTICLE, ReactorDebrisBlockEntity.DEFAULT_TEXTURE).build();
final Identifier textureForParticle = this.textures[clientLevel.getRandom().nextInt(this.textures.length)];
return ModelData.EMPTY.derive().with(TEXTURE_FOR_PARTICLE, textureForParticle).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.client.model.geom.builders.*;
import net.minecraft.client.renderer.entity.state.HumanoidRenderState;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import org.joml.Vector3f;
Expand All @@ -15,10 +16,9 @@
import twilightforest.init.TFDataAttachments;
import twilightforest.util.TFMathUtil;

import java.util.Collections;
import java.util.List;

public class TravellersWingsModel extends HumanoidModel<LivingEntity> {
public class TravellersWingsModel extends HumanoidModel<HumanoidRenderState> {
private static final double TAU = 4; // Time (in ticks) in which distance reduces in e times
private static final float ANGLE_10_DEG = Mth.PI / 18;
private static final Vector3f SMALL_SWING = new Vector3f(8.0F, 8.0F, 8.0F);
Expand Down Expand Up @@ -167,9 +167,21 @@ protected static void createBelt(PartDefinition root, float deformation) {
);
}

public void setupModelAnimations(LivingEntity entity, float f, float f1, double ageInTicks, float netHeadYaw, float headPitch) {
// [VanillaCopy] this method should be removed when IClientItemExtensions fully switches to HumanoidRenderState
private HumanoidRenderState createRendererState(LivingEntity entity, float walkAnimationPos, float walkAnimationSpeed, double ageInTicks, float netHeadYaw, float headPitch) {
HumanoidRenderState state = new HumanoidRenderState();
state.entityType = entity.getType();
state.walkAnimationPos = walkAnimationPos;
state.walkAnimationSpeed = walkAnimationSpeed;
state.ageInTicks = (float) ageInTicks;
state.yRot = netHeadYaw;
state.xRot = headPitch;
return state;
}

public void setupModelAnimations(LivingEntity entity, float walkAnimationPos, float walkAnimationSpeed, double ageInTicks, float netHeadYaw, float headPitch) {
this.bodyParts().forEach(modelPart -> modelPart.getAllParts().forEach(ModelPart::resetPose));
super.setupAnim(entity, f, f1, (float) ageInTicks, netHeadYaw, headPitch);
super.setupAnim(createRendererState(entity, walkAnimationPos, walkAnimationSpeed, ageInTicks, netHeadYaw, headPitch));
TravellersWingsAnimAttachment animAttachment = entity.getData(TFDataAttachments.TRAVELLERS_WINGS_ANIM);
TravellersWingsAttachment attachment = entity.getData(TFDataAttachments.TRAVELLERS_WINGS);

Expand Down Expand Up @@ -220,7 +232,7 @@ public void setupModelAnimations(LivingEntity entity, float f, float f1, double
animAttachment.zRotOld = this.wingBaseRight.zRot;

// If the wing model keeps a non-changing offset then looking at it with a spyglass even 4 chunks away will reveal Z-fighting.
float distance = (float) (Math.sqrt(entity.distanceToSqr(this.mainCamera.getPosition())) * PART_OFFSET);
float distance = (float) (Math.sqrt(entity.distanceToSqr(this.mainCamera.position())) * PART_OFFSET);
// The below solution is to animate its offset based off of camera distance. The animation is not time-based.
int partCount = Math.min(this.wingPartsLeft.size(), this.wingPartsRight.size());
for (int partIndex = 0; partIndex < partCount; partIndex++) {
Expand All @@ -240,12 +252,6 @@ private Vector3f calculateRotations(TravellersWingsAnimAttachment attachment, do
);
}

@Override
protected Iterable<ModelPart> headParts() {
return Collections.emptyList();
}

@Override
protected Iterable<ModelPart> bodyParts() {
return ImmutableList.of(body, leftLeg, rightLeg);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import net.minecraft.core.Direction;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.tags.TagKey;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.level.block.Block;
Expand Down Expand Up @@ -75,14 +75,14 @@ private List<Block> parseConnnectableBlocks(JsonObject object) {

for (JsonElement element : object.getAsJsonArray("connectable_blocks")) {
if (element.getAsString().startsWith("#")) {
ResourceLocation tag = ResourceLocation.tryParse(element.getAsString().substring(1));
Identifier tag = Identifier.tryParse(element.getAsString().substring(1));
if (tag != null) {
BuiltInRegistries.BLOCK.getTagOrEmpty(TagKey.create(Registries.BLOCK, tag)).forEach(blockHolder -> blocks.add(blockHolder.value()));
} else {
throw new JsonParseException("Invalid block tag: " + element.getAsString());
}
} else {
Block block = BuiltInRegistries.BLOCK.getValue(ResourceLocation.tryParse(element.getAsString()));
Block block = BuiltInRegistries.BLOCK.getValue(Identifier.tryParse(element.getAsString()));
if (block == Blocks.AIR) {
throw new JsonParseException("Invalid block: " + element.getAsString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.block.model.BlockElement;
import net.minecraft.client.renderer.block.model.BlockElementFace;
import net.minecraft.client.renderer.block.model.BlockElementRotation;
import net.minecraft.client.renderer.block.model.BlockFaceUV;
import com.mojang.math.Quadrant;
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
import net.minecraft.client.resources.model.cuboid.CuboidFace;
import net.minecraft.client.resources.model.cuboid.CuboidModelElement;
import net.minecraft.client.resources.model.cuboid.CuboidRotation;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.resources.Identifier;
import net.minecraft.util.Mth;
import net.neoforged.neoforge.client.model.ExtraFaceData;
import net.neoforged.neoforge.client.model.generators.template.CustomLoaderBuilder;
import org.apache.commons.lang3.mutable.MutableObject;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector3f;
import org.joml.Vector3fc;
import twilightforest.TwilightForestMod;
import twilightforest.client.model.block.forcefield.ForceFieldModel.ExtraDirection;
import twilightforest.util.UnbakedGeometryUtil;

import java.util.*;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -81,7 +83,7 @@ public JsonObject toJson(JsonObject json) {
if (!this.elements.isEmpty()) {
JsonArray elements = new JsonArray();
this.elements.forEach(forceFieldElementBuilder -> {
BlockElement part = forceFieldElementBuilder.build();
CuboidModelElement part = forceFieldElementBuilder.build();
JsonObject partObj = new JsonObject();

if (forceFieldElementBuilder.condition != null) {
Expand All @@ -98,50 +100,50 @@ public JsonObject toJson(JsonObject json) {
partObj.add("condition", condition);
}

partObj.add("from", serializeVector3f(part.from));
partObj.add("to", serializeVector3f(part.to));
partObj.add("from", serializeVector3fc(part.from()));
partObj.add("to", serializeVector3fc(part.to()));

if (part.rotation != null) {
if (part.rotation() != null) {
JsonObject rotation = new JsonObject();
rotation.add("origin", serializeVector3f(part.rotation.origin()));
rotation.add("origin", serializeVector3fc(part.rotation().origin()));
rotation.addProperty("axis", part.rotation.axis().getSerializedName());
rotation.addProperty("angle", part.rotation.angle());
if (part.rotation.rescale()) {
if (part.rotation().rescale()) {
rotation.addProperty("rescale", true);
}
partObj.add("rotation", rotation);
}

if (!part.shade) {
partObj.addProperty("shade", part.shade);
if (!part.shade()) {
partObj.addProperty("shade", part.shade());
}

if (part.lightEmission != 0) {
partObj.addProperty("light_emission", part.lightEmission);
if (part.lightEmission() != 0) {
partObj.addProperty("light_emission", part.lightEmission());
}

JsonObject faces = new JsonObject();
for (Direction dir : Direction.values()) {
BlockElementFace face = part.faces.get(dir);
CuboidFace face = part.faces().get(dir);
if (face == null) continue;

JsonObject faceObj = new JsonObject();
faceObj.addProperty("texture", serializeLocOrKey(face.texture()));
if (!Arrays.equals(face.uv().uvs, part.uvsByFace(dir))) {
faceObj.add("uv", new Gson().toJsonTree(face.uv().uvs));
if (!UnbakedGeometryUtil.areUVsEqual(face.uvs(), UnbakedGeometryUtil.uvsByFace(dir, part))) {
faceObj.add("uv", new Gson().toJsonTree(face.uvs()));
}
if (face.cullForDirection() != null) {
faceObj.addProperty("cullface", face.cullForDirection().getSerializedName());
}
if (face.uv().rotation != 0) {
faceObj.addProperty("rotation", face.uv().rotation);
if (face.rotation() != Quadrant.R0) {
faceObj.addProperty("rotation", UnbakedGeometryUtil.angleFromQuadrant(face.rotation()));
}
if (face.tintIndex() != -1) {
faceObj.addProperty("tintindex", face.tintIndex());
}
faces.add(dir.getSerializedName(), faceObj);
}
if (!part.faces.isEmpty()) {
if (!part.faces().isEmpty()) {
partObj.add("faces", faces);
}
elements.add(partObj);
Expand All @@ -155,10 +157,10 @@ private static String serializeLocOrKey(String tex) {
if (tex.charAt(0) == '#') {
return tex;
}
return ResourceLocation.parse(tex).toString();
return Identifier.parse(tex).toString();
}

private static JsonArray serializeVector3f(Vector3f vec) {
private static JsonArray serializeVector3fc(Vector3fc vec) {
JsonArray ret = new JsonArray();
ret.add(serializeFloat(vec.x()));
ret.add(serializeFloat(vec.y()));
Expand Down Expand Up @@ -288,12 +290,12 @@ private BiConsumer<Direction, ForceFieldElementBuilder.FaceBuilder> addTexture(S
return (direction, builder) -> builder.texture(texture);
}

BlockElement build() {
Map<Direction, BlockElementFace> faces = this.faces.entrySet().stream()
CuboidModelElement build() {
Map<Direction, CuboidFace> faces = this.faces.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().build(), (direction, face) -> {
throw new IllegalArgumentException();
}, LinkedHashMap::new));
return new BlockElement(this.from, this.to, faces, this.rotation == null ? null : this.rotation.build(), this.shade, this.light, ExtraFaceData.DEFAULT);
return new CuboidModelElement(this.from, this.to, faces, this.rotation == null ? null : this.rotation.build(), this.shade, this.light, ExtraFaceData.DEFAULT);
}

public ForceFieldModelBuilder end() {
Expand Down Expand Up @@ -340,11 +342,11 @@ public ForceFieldElementBuilder.FaceBuilder rotation(FaceRotation rot) {
return this;
}

BlockElementFace build() {
CuboidFace build() {
if (this.texture == null) {
throw new IllegalStateException("A model face must have a texture");
}
return new BlockElementFace(this.cullface, this.tintindex, this.texture, new BlockFaceUV(this.uvs, this.rotation.rotation), ExtraFaceData.DEFAULT, new MutableObject<>());
return new CuboidFace(this.cullface, this.tintindex, this.texture, this.uvs == null ? new CuboidFace.UVs(0, 0, 16, 16) : UnbakedGeometryUtil.uvsFromArray(this.uvs), UnbakedGeometryUtil.quadrantFromAngle(this.rotation.rotation), ExtraFaceData.DEFAULT, new MutableObject<>());
}

public ForceFieldElementBuilder end() {
Expand Down Expand Up @@ -384,10 +386,10 @@ public ForceFieldElementBuilder.RotationBuilder rescale(boolean rescale) {
return this;
}

BlockElementRotation build() {
CuboidRotation build() {
Preconditions.checkNotNull(this.origin, "No origin specified");
Preconditions.checkNotNull(this.axis, "No axis specified");
return new BlockElementRotation(this.origin, this.axis, this.angle, this.rescale);
return new CuboidRotation(this.origin, new CuboidRotation.SingleAxisRotation(this.axis, this.angle), this.rescale);
}

public ForceFieldElementBuilder end() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import net.minecraft.client.renderer.block.model.BlockElement;
import net.minecraft.client.resources.model.cuboid.CuboidModelElement;
import net.minecraft.util.GsonHelper;
import net.neoforged.neoforge.client.model.NeoForgeModelProperties;
import net.neoforged.neoforge.client.model.StandardModelParameters;
import net.neoforged.neoforge.client.model.UnbakedModelLoader;
import org.jetbrains.annotations.Nullable;
Expand All @@ -24,7 +23,7 @@ public class ForceFieldModelLoader implements UnbakedModelLoader<UnbakedForceFie
@SuppressWarnings("ConstantConditions")
public UnbakedForceFieldModel read(JsonObject json, JsonDeserializationContext context) throws JsonParseException {

Map<BlockElement, Condition> elementsAndConditions = new HashMap<>();
Map<CuboidModelElement, Condition> elementsAndConditions = new HashMap<>();

if (json.has("elements")) {
for (JsonElement jsonElement : GsonHelper.getAsJsonArray(json, "elements")) {
Expand All @@ -41,7 +40,7 @@ public UnbakedForceFieldModel read(JsonObject json, JsonDeserializationContext c
}
}
}
elementsAndConditions.put(context.deserialize(jsonElement, BlockElement.class), new Condition(direction, b, parents));
elementsAndConditions.put(context.deserialize(jsonElement, CuboidModelElement.class), new Condition(direction, b, parents));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package twilightforest.client.model.block.forcefield;

import net.minecraft.client.renderer.block.model.BlockElement;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.renderer.block.model.TextureSlots;
import net.minecraft.client.resources.model.*;
import net.minecraft.client.resources.model.cuboid.CuboidModelElement;
import net.minecraft.util.context.ContextMap;
import net.neoforged.neoforge.client.RenderTypeGroup;
import net.neoforged.neoforge.client.model.AbstractUnbakedModel;
import net.neoforged.neoforge.client.model.ExtendedUnbakedModel;
import net.neoforged.neoforge.client.model.StandardModelParameters;

import java.util.Map;

public class UnbakedForceFieldModel extends AbstractUnbakedModel {

private final Map<BlockElement, ForceFieldModelLoader.Condition> elementsAndConditions;
private final Map<CuboidModelElement, ForceFieldModelLoader.Condition> elementsAndConditions;

public UnbakedForceFieldModel(Map<BlockElement, ForceFieldModelLoader.Condition> elementsAndConditions, StandardModelParameters parameters) {
public UnbakedForceFieldModel(Map<CuboidModelElement, ForceFieldModelLoader.Condition> elementsAndConditions, StandardModelParameters parameters) {
super(parameters);
this.elementsAndConditions = elementsAndConditions;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package twilightforest.client.model.block.patch;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.neoforged.neoforge.client.model.generators.template.CustomLoaderBuilder;
import twilightforest.TwilightForestMod;
Expand Down
Loading
Loading