Rewrite villager rendering and fix saddlebags not appearing correctly. Should fix #134

This commit is contained in:
Sollace 2019-10-04 21:31:48 +02:00
parent 27a0ebeeb5
commit cc560615c9
33 changed files with 244 additions and 183 deletions

View file

@ -16,11 +16,14 @@ public class ModelVillagerPony<T extends LivingEntity & VillagerDataContainer> e
public PlaneRenderer apron;
public PlaneRenderer trinket;
private VillagerProfession profession;
public boolean special;
public boolean special2;
public boolean hatVisible;
@Override
protected void shakeBody(float move, float swing, float bodySwing, float ticks) {
super.shakeBody(move, swing, bodySwing, ticks);
@ -51,16 +54,22 @@ public class ModelVillagerPony<T extends LivingEntity & VillagerDataContainer> e
@Override
public boolean isWearing(Wearable wearable) {
if (wearable == Wearable.SADDLE_BAGS) {
return !special && profession != VillagerProfession.NONE && (
profession == VillagerProfession.FARMER
profession == VillagerProfession.CARTOGRAPHER
|| profession == VillagerProfession.FARMER
|| profession == VillagerProfession.FISHERMAN
|| profession == VillagerProfession.LIBRARIAN
|| profession == VillagerProfession.SHEPHERD);
}
if (wearable == Wearable.MUFFIN) {
return special2;
}
if (wearable == Wearable.VILLAGER) {
return hatVisible;
}
return super.isWearing(wearable);
}
@ -81,7 +90,7 @@ public class ModelVillagerPony<T extends LivingEntity & VillagerDataContainer> e
@Override
public void setHatVisible(boolean visible) {
hatVisible = visible;
}
@Override

View file

@ -1,11 +1,6 @@
package com.minelittlepony.client.model.gear;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.model.Model;
import net.minecraft.client.texture.TextureManager;
import net.minecraft.entity.Entity;
import org.lwjgl.opengl.GL11;
import com.minelittlepony.model.gear.IGear;
@ -17,16 +12,4 @@ public abstract class AbstractGear extends Model implements IGear {
init(0, 0);
}
@Override
public void renderSeparately(Entity entity, float scale) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
TextureManager tex = MinecraftClient.getInstance().getEntityRenderManager().textureManager;
tex.bindTexture(getTexture(entity));
renderPart(scale, entity.getUuid());
GL11.glPopAttrib();
}
}

View file

@ -82,7 +82,7 @@ public class ChristmasHat extends AbstractGear {
}
@Override
public Identifier getTexture(Entity entity) {
public <T extends Entity> Identifier getTexture(T entity, IGearRenderContext<T> context) {
return TEXTURE;
}

View file

@ -0,0 +1,13 @@
package com.minelittlepony.client.model.gear;
import net.minecraft.entity.Entity;
import net.minecraft.util.Identifier;
import com.minelittlepony.model.gear.IGear;
public interface IGearRenderContext<T extends Entity> {
IGearRenderContext<?> NULL = (e, g) -> null;
Identifier getDefaultTexture(T entity, IGear gear);
}

View file

@ -44,7 +44,7 @@ public class Muffin extends AbstractGear implements IStackable {
}
@Override
public Identifier getTexture(Entity entity) {
public <T extends Entity> Identifier getTexture(T entity, IGearRenderContext<T> context) {
return TEXTURE;
}

View file

@ -136,9 +136,8 @@ public class SaddleBags extends AbstractGear {
}
@Override
public Identifier getTexture(Entity entity) {
// use the default
return null;
public <T extends Entity> Identifier getTexture(T entity, IGearRenderContext<T> context) {
return context.getDefaultTexture(entity, this);
}
}

View file

@ -39,7 +39,7 @@ public class Stetson extends AbstractGear implements IStackable {
}
@Override
public Identifier getTexture(Entity entity) {
public <T extends Entity> Identifier getTexture(T entity, IGearRenderContext<T> context) {
return TEXTURE;
}

View file

@ -0,0 +1,51 @@
package com.minelittlepony.client.model.gear;
import net.minecraft.entity.Entity;
import net.minecraft.util.Identifier;
import net.minecraft.village.VillagerDataContainer;
import com.minelittlepony.client.util.render.PonyRenderer;
import com.minelittlepony.model.BodyPart;
import com.minelittlepony.model.IModel;
import com.minelittlepony.pony.meta.Wearable;
import java.util.UUID;
public class VillagerHat extends AbstractGear {
private static final Identifier TEXTURE = new Identifier("minelittlepony", "textures/models/antlers.png");
private PonyRenderer hat;
@Override
public void init(float yOffset, float stretch) {
hat = new PonyRenderer(this, 30, 47)
.around(0, 0, 0)
.box(-8, -8, -6, 16, 16, 1, stretch);
hat.pitch = -1.5707964F;
}
@Override
public boolean canRender(IModel model, Entity entity) {
return model.isWearing(Wearable.VILLAGER);
}
@Override
public BodyPart getGearLocation() {
return BodyPart.HEAD;
}
@Override
public <T extends Entity> Identifier getTexture(T entity, IGearRenderContext<T> context) {
if (entity instanceof VillagerDataContainer) {
return context.getDefaultTexture(entity, this);
}
return TEXTURE;
}
@Override
public void renderPart(float scale, UUID interpolatorId) {
hat.render(scale);
}
}

View file

@ -50,7 +50,7 @@ public class WitchHat extends AbstractGear implements IStackable {
}
@Override
public Identifier getTexture(Entity entity) {
public <T extends Entity> Identifier getTexture(T entity, IGearRenderContext<T> context) {
return WITCH_TEXTURES;
}

View file

@ -2,8 +2,10 @@ package com.minelittlepony.client.render;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.client.model.ModelWrapper;
import com.minelittlepony.client.model.gear.IGearRenderContext;
import com.minelittlepony.model.BodyPart;
import com.minelittlepony.model.PonyModelConstants;
import com.minelittlepony.model.gear.IGear;
import com.minelittlepony.pony.IPony;
import com.minelittlepony.util.math.MathUtil;
@ -11,7 +13,7 @@ import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
public interface IPonyRender<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends PonyModelConstants {
public interface IPonyRender<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends PonyModelConstants, IGearRenderContext<T> {
/**
* Gets the wrapped pony model for this renderer.
@ -24,6 +26,11 @@ public interface IPonyRender<T extends LivingEntity, M extends EntityModel<T> &
Identifier findTexture(T entity);
@Override
default Identifier getDefaultTexture(T entity, IGear gear) {
return findTexture(entity);
}
/**
* Called by riders to have their transportation adjust their position.
*/

View file

@ -15,6 +15,7 @@ import net.minecraft.client.render.VisibleRegion;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
public class RenderPony<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> {
@ -134,6 +135,11 @@ public class RenderPony<T extends LivingEntity, M extends EntityModel<T> & IPony
return getModel();
}
public void updateMetadata(Identifier texture) {
pony = MineLittlePony.getInstance().getManager().getPony(texture);
playerModel.apply(pony.getMetadata());
}
public void updateModel(T entity) {
pony = renderer.getEntityPony(entity);
playerModel.apply(pony.getMetadata());

View file

@ -1,30 +1,21 @@
package com.minelittlepony.client.render.entities;
import com.minelittlepony.client.model.entities.ModelVillagerPony;
import com.minelittlepony.client.render.layer.LayerVillagerClothing;
import com.minelittlepony.util.resources.FormattedTextureSupplier;
import com.minelittlepony.client.render.entities.villager.AbstractVillagerRenderer;
import com.minelittlepony.util.resources.ITextureSupplier;
import com.mojang.blaze3d.platform.GlStateManager;
import net.fabricmc.fabric.api.client.render.EntityRendererRegistry;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.util.Identifier;
public class RenderPonyVillager extends RenderPonyMob.Caster<VillagerEntity, ModelVillagerPony<VillagerEntity>> {
public class RenderPonyVillager extends AbstractVillagerRenderer<VillagerEntity, ModelVillagerPony<VillagerEntity>> {
private static final ITextureSupplier<String> FORMATTER = new FormattedTextureSupplier("minelittlepony", "textures/entity/villager/%s.png");
private static final ITextureSupplier<VillagerEntity> PROFESSIONS = new VillagerProfessionTextureCache<>(FORMATTER);
private static final String TYPE = "villager";
private static final ITextureSupplier<String> FORMATTER = ITextureSupplier.formatted("minelittlepony", "textures/entity/villager/%s.png");
public RenderPonyVillager(EntityRenderDispatcher manager, EntityRendererRegistry.Context context) {
super(manager, new ModelVillagerPony<>());
}
@Override
protected void addLayers() {
super.addLayers();
addFeature(new LayerVillagerClothing<>(this, "villager"));
super(manager, new ModelVillagerPony<>(), TYPE, FORMATTER);
}
@Override
@ -33,8 +24,4 @@ public class RenderPonyVillager extends RenderPonyMob.Caster<VillagerEntity, Mod
GlStateManager.scalef(BASE_MODEL_SCALE, BASE_MODEL_SCALE, BASE_MODEL_SCALE);
}
@Override
public Identifier findTexture(VillagerEntity entity) {
return PROFESSIONS.supplyTexture(entity);
}
}

View file

@ -1,34 +1,20 @@
package com.minelittlepony.client.render.entities;
import com.minelittlepony.client.model.entities.ModelZombieVillagerPony;
import com.minelittlepony.client.render.layer.LayerVillagerClothing;
import com.minelittlepony.util.resources.FormattedTextureSupplier;
import com.minelittlepony.client.render.entities.villager.AbstractVillagerRenderer;
import com.minelittlepony.util.resources.ITextureSupplier;
import net.fabricmc.fabric.api.client.render.EntityRendererRegistry;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.entity.mob.ZombieVillagerEntity;
import net.minecraft.util.Identifier;
public class RenderPonyZombieVillager extends RenderPonyMob.Caster<ZombieVillagerEntity, ModelZombieVillagerPony> {
public class RenderPonyZombieVillager extends AbstractVillagerRenderer<ZombieVillagerEntity, ModelZombieVillagerPony> {
private static final ITextureSupplier<String> FORMATTER = new FormattedTextureSupplier("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png");
private static final ITextureSupplier<ZombieVillagerEntity> PROFESSIONS = new VillagerProfessionTextureCache<>(FORMATTER);
private static final String TYPE = "zombie_villager";
private static final ITextureSupplier<String> FORMATTER = ITextureSupplier.formatted("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png");
public RenderPonyZombieVillager(EntityRenderDispatcher manager, EntityRendererRegistry.Context context) {
super(manager, new ModelZombieVillagerPony());
}
@Override
protected void addLayers() {
super.addLayers();
addFeature(new LayerVillagerClothing<>(this, "zombie_villager"));
}
@Override
public Identifier findTexture(ZombieVillagerEntity entity) {
return PROFESSIONS.supplyTexture(entity);
super(manager, new ModelZombieVillagerPony(), TYPE, FORMATTER);
}
@Override

View file

@ -0,0 +1,48 @@
package com.minelittlepony.client.render.entities.villager;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.model.ModelWithHat;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.util.Identifier;
import net.minecraft.village.VillagerDataContainer;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.entities.RenderPonyMob;
import com.minelittlepony.client.render.layer.LayerGear;
import com.minelittlepony.client.util.render.PonyRenderer;
import com.minelittlepony.model.IUnicorn;
import com.minelittlepony.model.gear.IGear;
import com.minelittlepony.util.resources.ITextureSupplier;
public abstract class AbstractVillagerRenderer<
T extends MobEntity & VillagerDataContainer,
M extends ClientPonyModel<T> & IUnicorn<PonyRenderer> & ModelWithHat> extends RenderPonyMob.Caster<T, M> {
private final ITextureSupplier<T> professions;
private final String entityType;
public AbstractVillagerRenderer(EntityRenderDispatcher manager, M model, String type, ITextureSupplier<String> formatter) {
super(manager, model);
entityType = type;
professions = new PonyTextures<>(formatter);
addFeature(new ClothingLayer<>(this, entityType));
}
@Override
public Identifier getDefaultTexture(T villager, IGear gear) {
if (gear == LayerGear.SADDLE_BAGS) {
return ClothingLayer.getClothingTexture(villager, entityType);
}
if (gear == LayerGear.VILLAGER_HAT) {
return ClothingLayer.getHatTexture(villager, entityType);
}
return super.getDefaultTexture(villager, gear);
}
@Override
public Identifier findTexture(T villager) {
return professions.supplyTexture(villager);
}
}

View file

@ -0,0 +1,62 @@
package com.minelittlepony.client.render.entities.villager;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.feature.VillagerClothingFeatureRenderer;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.model.ModelWithHat;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.entity.LivingEntity;
import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.village.VillagerDataContainer;
import net.minecraft.village.VillagerProfession;
import net.minecraft.village.VillagerType;
import com.minelittlepony.client.model.IPonyModel;
import com.minelittlepony.client.render.IPonyRender;
import com.minelittlepony.client.render.RenderPony;
public class ClothingLayer<
T extends LivingEntity & VillagerDataContainer,
M extends EntityModel<T> & IPonyModel<T> & ModelWithHat,
C extends FeatureRendererContext<T, M> & IPonyRender<T, M>> extends VillagerClothingFeatureRenderer<T, M> {
private final RenderPony<T, M> renderer;
public ClothingLayer(C context, String type) {
super(context, (ReloadableResourceManager)MinecraftClient.getInstance().getResourceManager(), type);
renderer = context.getInternalRenderer();
}
public static Identifier getClothingTexture(VillagerDataContainer entity, String entityType) {
VillagerProfession profession = entity.getVillagerData().getProfession();
return createTexture("minelittlepony", "profession", entityType, Registry.VILLAGER_PROFESSION.getId(profession));
}
public static Identifier getHatTexture(VillagerDataContainer entity, String entityType) {
VillagerType villagerType = entity.getVillagerData().getType();
return createTexture("minecraft", "type", entityType, Registry.VILLAGER_TYPE.getId(villagerType));
}
public static Identifier createTexture(String namespace, String type, String entityType, Identifier profession) {
return new Identifier(namespace, String.format("textures/entity/%s/%s/%s.png", entityType, type, profession.getPath()));
}
@Override
public void bindTexture(Identifier texture) {
if (texture != SpriteAtlasTexture.BLOCK_ATLAS_TEX) {
if (!"minelittlepony".contentEquals(texture.getNamespace())) {
texture = new Identifier("minelittlepony", texture.getPath());
}
}
renderer.updateMetadata(texture);
super.bindTexture(texture);
}
}

View file

@ -1,7 +1,8 @@
package com.minelittlepony.client.render.entities;
package com.minelittlepony.client.render.entities.villager;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.util.Identifier;
import net.minecraft.village.VillagerData;
import net.minecraft.village.VillagerDataContainer;
@ -18,7 +19,7 @@ import java.util.Optional;
/**
* Cached pool of villager textures.
*/
class VillagerProfessionTextureCache<T extends LivingEntity & VillagerDataContainer> implements ITextureSupplier<T> {
class PonyTextures<T extends LivingEntity & VillagerDataContainer> implements ITextureSupplier<T> {
private final ITextureSupplier<String> formatter;
@ -36,7 +37,7 @@ class VillagerProfessionTextureCache<T extends LivingEntity & VillagerDataContai
* @param keyMapper Mapper to convert integer ids into a string value for format insertion
* @param fallback The default if any generated textures fail to load. This is stored in place of failing textures.
*/
public VillagerProfessionTextureCache(ITextureSupplier<String> formatter) {
public PonyTextures(ITextureSupplier<String> formatter) {
this.formatter = formatter;
this.fallback = formatter.supplyTexture("villager_pony");
this.egg = formatter.supplyTexture("silly_pony");
@ -55,6 +56,9 @@ class VillagerProfessionTextureCache<T extends LivingEntity & VillagerDataContai
}
}
if (entity instanceof VillagerEntity) {
((VillagerEntity)entity).setVillagerData(entity.getVillagerData().withProfession(VillagerProfession.LIBRARIAN));
}
VillagerData t = entity.getVillagerData();
return getTexture(t.getType(), t.getProfession());

View file

@ -2,7 +2,6 @@ package com.minelittlepony.client.render.layer;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
import org.lwjgl.opengl.GL11;
@ -12,6 +11,7 @@ import com.minelittlepony.client.model.gear.ChristmasHat;
import com.minelittlepony.client.model.gear.Muffin;
import com.minelittlepony.client.model.gear.SaddleBags;
import com.minelittlepony.client.model.gear.Stetson;
import com.minelittlepony.client.model.gear.VillagerHat;
import com.minelittlepony.client.model.gear.WitchHat;
import com.minelittlepony.client.render.IPonyRender;
import com.minelittlepony.model.BodyPart;
@ -25,12 +25,20 @@ import java.util.Map;
public class LayerGear<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyLayer<T, M> {
public static final IGear SADDLE_BAGS = new SaddleBags();
public static final IGear WITCH_HAT = new WitchHat();
public static final IGear MUFFIN = new Muffin();
public static final IGear STETSON = new Stetson();
public static final IGear ANTLERS = new ChristmasHat();
public static final IGear VILLAGER_HAT = new VillagerHat();
private static List<IGear> gears = Lists.newArrayList(
new SaddleBags(),
new WitchHat(),
new Muffin(),
new Stetson(),
new ChristmasHat()
SADDLE_BAGS,
WITCH_HAT,
MUFFIN,
STETSON,
ANTLERS,
VILLAGER_HAT
);
public LayerGear(IPonyRender<T, M> renderer) {
@ -75,12 +83,7 @@ public class LayerGear<T extends LivingEntity, M extends EntityModel<T> & IPonyM
private void renderGear(M model, T entity, IGear gear, float move, float swing, float scale, float ticks) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
Identifier texture = gear.getTexture(entity);
if (texture == null) {
texture = getContext().findTexture(entity);
}
getContext().bindTexture(texture);
getContext().bindTexture(gear.getTexture(entity, getContext()));
gear.setLivingAnimations(model, entity);
gear.setRotationAndAngles(model.getAttributes().isGoingFast, entity.getUuid(), move, swing, model.getWobbleAmount(), ticks);

View file

@ -1,31 +0,0 @@
package com.minelittlepony.client.render.layer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.feature.VillagerClothingFeatureRenderer;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.model.ModelWithHat;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.entity.LivingEntity;
import net.minecraft.resource.ReloadableResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.village.VillagerDataContainer;
public class LayerVillagerClothing<T extends LivingEntity & VillagerDataContainer, M extends EntityModel<T> & ModelWithHat> extends VillagerClothingFeatureRenderer<T, M> {
public LayerVillagerClothing(FeatureRendererContext<T, M> context, String type) {
super(context, (ReloadableResourceManager)MinecraftClient.getInstance().getResourceManager(), type);
}
@Override
public void bindTexture(Identifier texture) {
if (texture != SpriteAtlasTexture.BLOCK_ATLAS_TEX) {
if (!"minelittlepony".contentEquals(texture.getNamespace())) {
texture = new Identifier("minelittlepony", texture.getPath());
}
}
super.bindTexture(texture);
}
}

View file

@ -3,12 +3,11 @@ package com.minelittlepony.model.gear;
import net.minecraft.entity.Entity;
import net.minecraft.util.Identifier;
import com.minelittlepony.client.model.gear.IGearRenderContext;
import com.minelittlepony.model.BodyPart;
import com.minelittlepony.model.IModel;
import com.minelittlepony.model.IPart;
import javax.annotation.Nullable;
public interface IGear extends IPart {
/**
@ -30,8 +29,7 @@ public interface IGear extends IPart {
* Gets the texture to use for this wearable.
* Return null to use the same as the primary model.
*/
@Nullable
Identifier getTexture(Entity entity);
<T extends Entity> Identifier getTexture(T entity, IGearRenderContext<T> context);
/**
* Orients this wearable.
@ -39,9 +37,4 @@ public interface IGear extends IPart {
default void setLivingAnimations(IModel model, Entity entity) {
}
/**
* Renders this wearable separately. (used outside of the gear render layer)
*/
void renderSeparately(Entity entity, float scale);
}

View file

@ -11,6 +11,7 @@ public enum Wearable implements ITriggerPixelMapped<Wearable> {
HAT (0x64),
ANTLERS (0x96),
SADDLE_BAGS (0xC8),
VILLAGER (0x11),
STETSON (0xFA);
private int triggerValue;

View file

@ -1,22 +0,0 @@
package com.minelittlepony.util.resources;
import net.minecraft.util.Identifier;
/**
* Supplies new resource locations based on a pre-defined domain and formatted path.
*/
public class FormattedTextureSupplier implements ITextureSupplier<String> {
private final String domain;
private final String path;
public FormattedTextureSupplier(String domain, String path) {
this.domain = domain;
this.path = path;
}
@Override
public Identifier supplyTexture(String key) {
return new Identifier(domain, String.format(path, key));
}
}

View file

@ -11,4 +11,8 @@ public interface ITextureSupplier<T> {
* Supplies a new texture. May be generated for returned from a pool indexed by the given key.
*/
Identifier supplyTexture(T key);
static ITextureSupplier<String> formatted(String domain, String path) {
return key -> new Identifier(domain, String.format(path, key));
}
}

View file

@ -1,42 +0,0 @@
package com.minelittlepony.util.resources;
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
/**
* Simple mapping from an integer index to a pre-defined set of strings.
* Returns the string representation of the index if no value was found.
*/
public class IntStringMapper implements Function<Integer, String> {
private final HashMap<Integer, String> values = Maps.newHashMap();
/**
* Creates a new string mapper pre-populated with the provided values by index.
*/
public IntStringMapper(String...values) {
for (int i = 0; i < values.length; i++) {
this.values.put(i, Objects.requireNonNull(values[i]));
}
}
/**
* Return the values. So you can actually modify it.
* I mean, if you want to @modders...
*/
public Map<Integer, String> getValues() {
return values;
}
@Override
public String apply(Integer t) {
if (values.containsKey(t)) {
return values.get(t);
}
return String.valueOf(t);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB