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.wrapped = baseModel; //field from the superclass; vanilla getQuads etc. will delegate through to this
|
||||||
|
|
||||||
this.tam = tam;
|
this.tam = tam;
|
||||||
this.facePermutation = MeshTransformUtil.facePermutation(settings);
|
// this.facePermutation = MeshTransformUtil.facePermutation(settings);
|
||||||
this.uvlock = settings.isUvLocked();
|
this.uvlock = settings.isUvLocked();
|
||||||
this.itemModelState = itemModelState;
|
this.itemModelState = itemModelState;
|
||||||
this.ao = ao;
|
this.ao = ao;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final TemplateAppearanceManager tam;
|
protected final TemplateAppearanceManager tam;
|
||||||
protected final Map<Direction, Direction> facePermutation; //immutable
|
// protected final Map<Direction, Direction> facePermutation;
|
||||||
protected final boolean uvlock;
|
protected final boolean uvlock;
|
||||||
protected final BlockState itemModelState;
|
protected final BlockState itemModelState;
|
||||||
protected final boolean ao;
|
protected final boolean ao;
|
||||||
@ -75,20 +75,26 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
}
|
}
|
||||||
if(theme.getBlock() == Blocks.BARRIER) return;
|
if(theme.getBlock() == Blocks.BARRIER) return;
|
||||||
|
|
||||||
TemplateAppearance ta = tam.getTemplateAppearance(theme);
|
TemplateAppearance template_appearance = tam.getTemplateAppearance(theme);
|
||||||
long seed = theme.getRenderingSeed(pos);
|
long seed = theme.getRenderingSeed(pos);
|
||||||
int model_id = 0;
|
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);
|
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 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.
|
//the cached mesh will pollute it with a ton of single-use meshes with only slightly different colors.
|
||||||
if(tint == 0xFFFFFFFF) {
|
if(tint == 0xFFFFFFFF) {
|
||||||
untintedMesh.outputTo(quad_emitter);
|
untintedMesh.outputTo(quad_emitter);
|
||||||
} else {
|
} else {
|
||||||
context.pushTransform(new TintingTransformer(ta, tint, seed));
|
context.pushTransform(new TintingTransformer(template_appearance, tint, seed));
|
||||||
untintedMesh.outputTo(quad_emitter);
|
untintedMesh.outputTo(quad_emitter);
|
||||||
context.popTransform();
|
context.popTransform();
|
||||||
}
|
}
|
||||||
@ -147,7 +153,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
if(tag == 0) return true; //Pass the quad through unmodified.
|
if(tag == 0) return true; //Pass the quad through unmodified.
|
||||||
|
|
||||||
//The quad tag numbers were selected so this magic trick works:
|
//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));
|
quad.spriteBake(ta.getSprite(direction, seed), MutableQuadView.BAKE_NORMALIZED | ta.getBakeFlags(direction, seed) | (uvlock ? MutableQuadView.BAKE_LOCK_UV : 0));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -168,9 +174,9 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
|||||||
public boolean transform(MutableQuadView quad) {
|
public boolean transform(MutableQuadView quad) {
|
||||||
int tag = quad.tag();
|
int tag = quad.tag();
|
||||||
if(tag == 0) return true;
|
if(tag == 0) return true;
|
||||||
|
|
||||||
Direction dir = facePermutation.get(DIRECTIONS[quad.tag() - 1]);
|
// Direction dir = facePermutation.get(DIRECTIONS[quad.tag() - 1]);
|
||||||
if(ta.hasColor(dir, seed)) quad.color(tint, tint, tint, tint);
|
if(ta.hasColor(quad.nominalFace(), seed)) quad.color(tint, tint, tint, tint);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -86,10 +86,10 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel, TemplatesClient
|
|||||||
RenderMaterial mat = tam.getCachedMaterial(state, false);
|
RenderMaterial mat = tam.getCachedMaterial(state, false);
|
||||||
|
|
||||||
Random rand = Random.create(42);
|
Random rand = Random.create(42);
|
||||||
|
|
||||||
for(Direction cullFace : DIRECTIONS_AND_NULL) {
|
for(Direction direction : DIRECTIONS_AND_NULL) {
|
||||||
for(BakedQuad quad : wrapped.getQuads(state, cullFace, rand)) {
|
for(BakedQuad quad : wrapped.getQuads(state, direction, rand)) {
|
||||||
emitter.fromVanilla(quad, mat, cullFace);
|
emitter.fromVanilla(quad, mat, direction);
|
||||||
QuadUvBounds.read(emitter).normalizeUv(emitter, quad.getSprite());
|
QuadUvBounds.read(emitter).normalizeUv(emitter, quad.getSprite());
|
||||||
emitter.tag(emitter.lightFace().ordinal() + 1);
|
emitter.tag(emitter.lightFace().ordinal() + 1);
|
||||||
emitter.emit();
|
emitter.emit();
|
||||||
|
@ -72,10 +72,6 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel, TemplatesClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
BakedModel model = baker.bake(parent, modelBakeSettings);
|
BakedModel model = baker.bake(parent, modelBakeSettings);
|
||||||
if (model instanceof WeightedBakedModel weighted_model) {
|
|
||||||
System.out.println("weighted model");
|
|
||||||
((WeightedBakedModelAccessor) weighted_model).getModels();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RetexturingBakedModel(
|
return new RetexturingBakedModel(
|
||||||
model,
|
model,
|
||||||
|
@ -126,6 +126,7 @@ public class TemplateAppearanceManager {
|
|||||||
int[] flags = new int[6];
|
int[] flags = new int[6];
|
||||||
byte[] color_mask = {0b000000};
|
byte[] color_mask = {0b000000};
|
||||||
|
|
||||||
|
System.out.println("new mesh"); // TODO remove
|
||||||
//Read quads off the model by their `cullface`
|
//Read quads off the model by their `cullface`
|
||||||
Arrays.stream(Direction.values()).forEach(direction -> {
|
Arrays.stream(Direction.values()).forEach(direction -> {
|
||||||
List<BakedQuad> quads = model.getQuads(null, direction, random);
|
List<BakedQuad> quads = model.getQuads(null, direction, random);
|
||||||
@ -154,17 +155,58 @@ public class TemplateAppearanceManager {
|
|||||||
//are looked up with a simple table.
|
//are looked up with a simple table.
|
||||||
quad_emitter.fromVanilla(quad, material, direction);
|
quad_emitter.fromVanilla(quad, material, direction);
|
||||||
|
|
||||||
float spriteUAvg = (sprite.getMinU() + sprite.getMaxU()) / 2;
|
flags[direction.ordinal()] = getBakeFlags(quad_emitter, sprite);
|
||||||
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)
|
|
||||||
];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Appearance(sprites, flags, color_mask[0]);
|
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