added full support for random models and fixed some issues with the previously implemented permutations
This commit is contained in:
parent
55b8e55015
commit
6e08148733
@ -32,14 +32,14 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
this.wrapped = baseModel; //field from the superclass; vanilla getQuads etc. will delegate through to this
|
||||
|
||||
this.tam = tam;
|
||||
this.facePermutation = MeshTransformUtil.facePermutation(settings);
|
||||
// this.facePermutation = MeshTransformUtil.facePermutation(settings);
|
||||
this.uvlock = settings.isUvLocked();
|
||||
this.itemModelState = itemModelState;
|
||||
this.ao = ao;
|
||||
}
|
||||
|
||||
protected final TemplateAppearanceManager tam;
|
||||
protected final Map<Direction, Direction> facePermutation; //immutable
|
||||
// protected final Map<Direction, Direction> facePermutation;
|
||||
protected final boolean uvlock;
|
||||
protected final BlockState itemModelState;
|
||||
protected final boolean ao;
|
||||
@ -75,20 +75,26 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
}
|
||||
if(theme.getBlock() == Blocks.BARRIER) return;
|
||||
|
||||
TemplateAppearance ta = tam.getTemplateAppearance(theme);
|
||||
TemplateAppearance template_appearance = tam.getTemplateAppearance(theme);
|
||||
long seed = theme.getRenderingSeed(pos);
|
||||
int model_id = 0;
|
||||
if (ta instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
|
||||
if (template_appearance instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
|
||||
|
||||
int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, blockView, pos, 0);
|
||||
Mesh untintedMesh = getUntintedRetexturedMesh(new MeshCacheKey(state, new TransformCacheKey(ta, model_id)), seed);
|
||||
Mesh untintedMesh = getUntintedRetexturedMesh(
|
||||
new MeshCacheKey(
|
||||
state,
|
||||
new TransformCacheKey(template_appearance, model_id)
|
||||
),
|
||||
seed
|
||||
);
|
||||
|
||||
//The specific tint might vary a lot; imagine grass color smoothly changing. Trying to bake the tint into
|
||||
//the cached mesh will pollute it with a ton of single-use meshes with only slightly different colors.
|
||||
if(tint == 0xFFFFFFFF) {
|
||||
untintedMesh.outputTo(quad_emitter);
|
||||
} else {
|
||||
context.pushTransform(new TintingTransformer(ta, tint, seed));
|
||||
context.pushTransform(new TintingTransformer(template_appearance, tint, seed));
|
||||
untintedMesh.outputTo(quad_emitter);
|
||||
context.popTransform();
|
||||
}
|
||||
@ -147,7 +153,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
if(tag == 0) return true; //Pass the quad through unmodified.
|
||||
|
||||
//The quad tag numbers were selected so this magic trick works:
|
||||
Direction direction = facePermutation.get(DIRECTIONS[quad.tag() - 1]);
|
||||
Direction direction = quad.nominalFace(); // facePermutation.get(quad.nominalFace());
|
||||
quad.spriteBake(ta.getSprite(direction, seed), MutableQuadView.BAKE_NORMALIZED | ta.getBakeFlags(direction, seed) | (uvlock ? MutableQuadView.BAKE_LOCK_UV : 0));
|
||||
return true;
|
||||
}
|
||||
@ -169,8 +175,8 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
int tag = quad.tag();
|
||||
if(tag == 0) return true;
|
||||
|
||||
Direction dir = facePermutation.get(DIRECTIONS[quad.tag() - 1]);
|
||||
if(ta.hasColor(dir, seed)) quad.color(tint, tint, tint, tint);
|
||||
// Direction dir = facePermutation.get(DIRECTIONS[quad.tag() - 1]);
|
||||
if(ta.hasColor(quad.nominalFace(), seed)) quad.color(tint, tint, tint, tint);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -87,9 +87,9 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel, TemplatesClient
|
||||
|
||||
Random rand = Random.create(42);
|
||||
|
||||
for(Direction cullFace : DIRECTIONS_AND_NULL) {
|
||||
for(BakedQuad quad : wrapped.getQuads(state, cullFace, rand)) {
|
||||
emitter.fromVanilla(quad, mat, cullFace);
|
||||
for(Direction direction : DIRECTIONS_AND_NULL) {
|
||||
for(BakedQuad quad : wrapped.getQuads(state, direction, rand)) {
|
||||
emitter.fromVanilla(quad, mat, direction);
|
||||
QuadUvBounds.read(emitter).normalizeUv(emitter, quad.getSprite());
|
||||
emitter.tag(emitter.lightFace().ordinal() + 1);
|
||||
emitter.emit();
|
||||
|
@ -72,10 +72,6 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel, TemplatesClient
|
||||
}
|
||||
|
||||
BakedModel model = baker.bake(parent, modelBakeSettings);
|
||||
if (model instanceof WeightedBakedModel weighted_model) {
|
||||
System.out.println("weighted model");
|
||||
((WeightedBakedModelAccessor) weighted_model).getModels();
|
||||
}
|
||||
|
||||
return new RetexturingBakedModel(
|
||||
model,
|
||||
|
@ -126,6 +126,7 @@ public class TemplateAppearanceManager {
|
||||
int[] flags = new int[6];
|
||||
byte[] color_mask = {0b000000};
|
||||
|
||||
System.out.println("new mesh"); // TODO remove
|
||||
//Read quads off the model by their `cullface`
|
||||
Arrays.stream(Direction.values()).forEach(direction -> {
|
||||
List<BakedQuad> quads = model.getQuads(null, direction, random);
|
||||
@ -154,17 +155,58 @@ public class TemplateAppearanceManager {
|
||||
//are looked up with a simple table.
|
||||
quad_emitter.fromVanilla(quad, material, direction);
|
||||
|
||||
float spriteUAvg = (sprite.getMinU() + sprite.getMaxU()) / 2;
|
||||
float spriteVAvg = (sprite.getMinV() + sprite.getMaxV()) / 2;
|
||||
|
||||
flags[direction.ordinal()] = MAGIC_BAKEFLAGS_SBOX[
|
||||
(quad_emitter.u(0) < spriteUAvg ? 8 : 0) |
|
||||
(quad_emitter.v(0) < spriteVAvg ? 4 : 0) |
|
||||
(quad_emitter.u(1) < spriteUAvg ? 2 : 0) |
|
||||
(quad_emitter.v(1) < spriteVAvg ? 1 : 0)
|
||||
];
|
||||
flags[direction.ordinal()] = getBakeFlags(quad_emitter, sprite);
|
||||
});
|
||||
|
||||
return new Appearance(sprites, flags, color_mask[0]);
|
||||
}
|
||||
|
||||
private static int getBakeFlags(QuadEmitter emitter, Sprite sprite) { // TODO can probably receive tons of improvements
|
||||
boolean[][] order_matrix = getOrderMatrix(emitter, sprite);
|
||||
int flag = 0;
|
||||
if (!isClockwise(order_matrix)) { // check if quad has been mirrored on model
|
||||
// check which mirroring is more efficient in terms of rotations
|
||||
int rotation_u = getRotation(flipOrderMatrix(order_matrix, MutableQuadView.BAKE_FLIP_U));
|
||||
int rotation_v = getRotation(flipOrderMatrix(order_matrix, MutableQuadView.BAKE_FLIP_V));
|
||||
if (rotation_u < rotation_v) flag = MutableQuadView.BAKE_FLIP_U | rotation_u;
|
||||
else flag = MutableQuadView.BAKE_FLIP_V | rotation_v;
|
||||
} else flag |= getRotation(order_matrix);
|
||||
return flag;
|
||||
}
|
||||
|
||||
private static int getRotation(boolean[][] order_matrix) {
|
||||
int rotations = MutableQuadView.BAKE_ROTATE_NONE;
|
||||
rotations |= order_matrix[0][0] && !order_matrix[0][1] ? MutableQuadView.BAKE_ROTATE_90 : 0;
|
||||
rotations |= !order_matrix[0][0] && !order_matrix[0][1] ? MutableQuadView.BAKE_ROTATE_180 : 0;
|
||||
rotations |= !order_matrix[0][0] && order_matrix[0][1] ? MutableQuadView.BAKE_ROTATE_270 : 0;
|
||||
return rotations;
|
||||
}
|
||||
|
||||
private static boolean isClockwise(boolean[][] rotation_matrix) {
|
||||
for (int i = 1; i < rotation_matrix.length; i++) {
|
||||
if (rotation_matrix[i][0] != rotation_matrix[i-1][1] && rotation_matrix[i][0] != rotation_matrix[i][1])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean[][] flipOrderMatrix(boolean[][] order_matrix, int flag) {
|
||||
boolean[][] new_matrix = new boolean[4][2];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
new_matrix[i][0] = (flag == MutableQuadView.BAKE_FLIP_U) != order_matrix[i][0];
|
||||
new_matrix[i][1] = (flag == MutableQuadView.BAKE_FLIP_V) != order_matrix[i][1];
|
||||
}
|
||||
return new_matrix;
|
||||
}
|
||||
|
||||
private static boolean[][] getOrderMatrix(QuadEmitter emitter, Sprite sprite) {
|
||||
float u_center = (sprite.getMinU() + sprite.getMaxU()) / 2;
|
||||
float v_center = (sprite.getMinV() + sprite.getMaxV()) / 2;
|
||||
boolean[][] order_matrix = new boolean[4][2];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
order_matrix[i][0] = emitter.u(i) < u_center;
|
||||
order_matrix[i][1] = emitter.v(i) < v_center;
|
||||
}
|
||||
return order_matrix;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user