use of com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace.ModelFaceSide in project InteractiveChat-DiscordSRV-Addon by LOOHP.
the class ModelManager method loadDirectory.
@Override
protected void loadDirectory(String namespace, ResourcePackFile root) {
if (!root.exists() || !root.isDirectory()) {
throw new IllegalArgumentException(root.getAbsolutePath() + " is not a directory.");
}
JSONParser parser = new JSONParser();
Map<String, BlockModel> models = new HashMap<>();
Collection<ResourcePackFile> files = root.listFilesRecursively(new String[] { "json" });
for (ResourcePackFile file : files) {
try {
String key = namespace + ":" + file.getRelativePathFrom(root);
key = key.substring(0, key.lastIndexOf("."));
InputStreamReader reader = new InputStreamReader(new BOMInputStream(file.getInputStream()), StandardCharsets.UTF_8);
JSONObject rootJson = (JSONObject) parser.parse(reader);
reader.close();
String parent = (String) rootJson.getOrDefault("parent", null);
boolean ambientocclusion = (boolean) rootJson.getOrDefault("ambientocclusion", true);
ModelGUILight guiLight = rootJson.containsKey("gui_light") ? ModelGUILight.fromKey((String) rootJson.get("gui_light")) : null;
Map<ModelDisplayPosition, ModelDisplay> display = new EnumMap<>(ModelDisplayPosition.class);
JSONObject displayJson = (JSONObject) rootJson.get("display");
if (displayJson != null) {
for (Object obj : displayJson.keySet()) {
String displayKey = obj.toString();
JSONArray rotationArray = (JSONArray) ((JSONObject) displayJson.get(displayKey)).get("rotation");
JSONArray translationArray = (JSONArray) ((JSONObject) displayJson.get(displayKey)).get("translation");
JSONArray scaleArray = (JSONArray) ((JSONObject) displayJson.get(displayKey)).get("scale");
Coordinates3D rotation;
if (rotationArray == null) {
rotation = new Coordinates3D(0, 0, 0);
} else {
rotation = new Coordinates3D(((Number) rotationArray.get(0)).doubleValue(), ((Number) rotationArray.get(1)).doubleValue(), ((Number) rotationArray.get(2)).doubleValue());
}
Coordinates3D translation;
if (translationArray == null) {
translation = new Coordinates3D(0, 0, 0);
} else {
translation = new Coordinates3D(((Number) translationArray.get(0)).doubleValue(), ((Number) translationArray.get(1)).doubleValue(), ((Number) translationArray.get(2)).doubleValue());
}
Coordinates3D scale;
if (scaleArray == null) {
scale = new Coordinates3D(1, 1, 1);
} else {
scale = new Coordinates3D(((Number) scaleArray.get(0)).doubleValue(), ((Number) scaleArray.get(1)).doubleValue(), ((Number) scaleArray.get(2)).doubleValue());
}
ModelDisplayPosition displayPos = ModelDisplayPosition.fromKey(displayKey);
display.put(displayPos, new ModelDisplay(displayPos, rotation, translation, scale));
}
}
Map<String, String> texture = new HashMap<>();
JSONObject textureJson = (JSONObject) rootJson.get("textures");
if (textureJson != null) {
for (Object obj : textureJson.keySet()) {
String textureKey = obj.toString();
texture.put(textureKey, textureJson.get(textureKey).toString());
}
}
List<ModelElement> elements = new ArrayList<>();
JSONArray elementsArray = (JSONArray) rootJson.get("elements");
if (elementsArray != null) {
for (Object obj : elementsArray) {
JSONObject elementJson = (JSONObject) obj;
JSONArray fromArray = (JSONArray) elementJson.get("from");
JSONArray toArray = (JSONArray) elementJson.get("to");
Coordinates3D from = new Coordinates3D(((Number) fromArray.get(0)).doubleValue(), ((Number) fromArray.get(1)).doubleValue(), ((Number) fromArray.get(2)).doubleValue());
Coordinates3D to = new Coordinates3D(((Number) toArray.get(0)).doubleValue(), ((Number) toArray.get(1)).doubleValue(), ((Number) toArray.get(2)).doubleValue());
ModelElementRotation rotation;
JSONObject rotationJson = (JSONObject) elementJson.get("rotation");
if (rotationJson == null) {
rotation = null;
} else {
Coordinates3D origin;
JSONArray originArray = (JSONArray) rotationJson.get("origin");
if (originArray == null) {
origin = new Coordinates3D(0, 0, 0);
} else {
origin = new Coordinates3D(((Number) originArray.get(0)).doubleValue(), ((Number) originArray.get(1)).doubleValue(), ((Number) originArray.get(2)).doubleValue());
}
ModelAxis axis = ModelAxis.valueOf(rotationJson.get("axis").toString().toUpperCase());
double angle = ((Number) rotationJson.get("angle")).doubleValue();
boolean rescale = (boolean) rotationJson.getOrDefault("rescale", false);
rotation = new ModelElementRotation(origin, axis, angle, rescale);
}
boolean shade = (boolean) elementJson.getOrDefault("shade", true);
Map<ModelFaceSide, ModelFace> face = new EnumMap<>(ModelFaceSide.class);
JSONObject facesJson = (JSONObject) elementJson.get("faces");
if (facesJson != null) {
for (Object obj1 : facesJson.keySet()) {
String faceKey = obj1.toString();
ModelFaceSide side = ModelFaceSide.fromKey(faceKey);
JSONObject faceJson = (JSONObject) facesJson.get(faceKey);
TextureUV uv;
JSONArray uvArray = (JSONArray) faceJson.get("uv");
if (uvArray == null) {
uv = null;
} else {
uv = new TextureUV(((Number) uvArray.get(0)).doubleValue(), ((Number) uvArray.get(1)).doubleValue(), ((Number) uvArray.get(2)).doubleValue(), ((Number) uvArray.get(3)).doubleValue());
}
String faceTexture = (String) faceJson.get("texture");
Object cullfaceObj = faceJson.get("cullface");
ModelFaceSide cullface = null;
if (cullfaceObj != null && cullfaceObj instanceof String) {
cullface = ModelFaceSide.fromKey((String) cullfaceObj);
}
if (cullface == null) {
cullface = side;
}
int faceRotation = ((Number) faceJson.getOrDefault("rotation", 0)).intValue();
int faceTintindex = ((Number) faceJson.getOrDefault("tintindex", -1)).intValue();
face.put(side, new ModelFace(side, uv, faceTexture, cullface, faceRotation, faceTintindex));
}
}
elements.add(new ModelElement(from, to, rotation, shade, face));
}
}
List<ModelOverride> overrides = new ArrayList<>();
JSONArray overridesArray = (JSONArray) rootJson.get("overrides");
if (overridesArray != null) {
for (Object obj : overridesArray) {
JSONObject overrideJson = (JSONObject) obj;
JSONObject predicateJson = (JSONObject) overrideJson.get("predicate");
Map<ModelOverrideType, Float> predicates = new EnumMap<>(ModelOverrideType.class);
for (Object obj1 : predicateJson.keySet()) {
String predicateTypeKey = obj1.toString();
ModelOverrideType type = ModelOverrideType.fromKey(predicateTypeKey);
Object value = predicateJson.get(predicateTypeKey);
predicates.put(type, ((Number) value).floatValue());
}
String model = (String) overrideJson.get("model");
overrides.add(new ModelOverride(predicates, model));
}
}
Collections.reverse(overrides);
models.put(key, new BlockModel(this, parent, ambientocclusion, guiLight, display, texture, elements, overrides));
} catch (Exception e) {
new ResourceLoadingException("Unable to load block model " + file.getAbsolutePath(), e).printStackTrace();
}
}
this.models.putAll(models);
}
use of com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace.ModelFaceSide in project InteractiveChat-DiscordSRV-Addon by LOOHP.
the class ModelRenderer method generateStandardRenderModel.
@SuppressWarnings("SuspiciousNameCombination")
private Model generateStandardRenderModel(BlockModel blockModel, ResourceManager manager, Map<String, TextureResource> providedTextures, TintIndexData tintIndexData, boolean enchanted, boolean skin) {
Map<String, BufferedImage> cachedResize = new ConcurrentHashMap<>();
List<ModelElement> elements = new ArrayList<>(blockModel.getElements());
List<Hexahedron> hexahedrons = new ArrayList<>(elements.size());
Queue<Future<Hexahedron>> tasks = new ConcurrentLinkedQueue<>();
Iterator<ModelElement> itr = elements.iterator();
while (itr.hasNext()) {
ModelElement element = itr.next();
tasks.add(modelResolvingService.submit(() -> {
ModelElementRotation rotation = element.getRotation();
boolean ignoreZFight = false;
if (rotation != null) {
ignoreZFight = rotation.isRescale();
}
Hexahedron hexahedron = Hexahedron.fromCorners(new Point3D(element.getFrom().getX(), element.getFrom().getY(), element.getFrom().getZ()), new Point3D(element.getTo().getX(), element.getTo().getY(), element.getTo().getZ()), ignoreZFight, new BufferedImage[6]);
BufferedImage[] images = new BufferedImage[6];
BufferedImage[] overlayImages = new BufferedImage[6];
int i = 0;
for (ModelFaceSide side : ModelFaceSide.values()) {
ModelFace faceData = element.getFace(side);
if (faceData == null) {
images[i] = null;
} else {
TextureUV uv = faceData.getUV();
TextureResource resource = providedTextures.get(faceData.getTexture());
if (resource == null) {
resource = manager.getTextureManager().getTexture(faceData.getTexture(), false);
}
if (resource == null || !resource.isTexture()) {
images[i] = null;
} else if (uv != null && (uv.getXDiff() == 0 || uv.getYDiff() == 0)) {
images[i] = null;
} else {
BufferedImage cached = cachedResize.get(faceData.getTexture());
if (cached == null) {
cached = resource.getTexture();
if (resource.hasTextureMeta()) {
TextureMeta meta = resource.getTextureMeta();
if (meta.hasProperties()) {
TextureProperties properties = meta.getProperties();
if (properties.isBlur()) {
cached = ImageUtils.applyGaussianBlur(cached);
}
}
if (meta.hasAnimation()) {
TextureAnimation animation = meta.getAnimation();
if (animation.hasWidth() && animation.hasHeight()) {
cached = ImageUtils.copyAndGetSubImage(cached, 0, 0, animation.getWidth(), animation.getHeight());
} else {
cached = ImageUtils.copyAndGetSubImage(cached, 0, 0, cached.getWidth(), cached.getWidth());
}
}
}
if (cached.getWidth() > cached.getHeight()) {
cached = ImageUtils.resizeImageFillWidth(cached, skin ? SKIN_RESOLUTION : TEXTURE_RESOLUTION);
} else {
cached = ImageUtils.resizeImageFillHeight(cached, skin ? SKIN_RESOLUTION : TEXTURE_RESOLUTION);
}
cachedResize.put(faceData.getTexture(), cached);
}
images[i] = ImageUtils.copyImage(cached);
if (uv == null) {
Point3D[] points;
switch(side) {
case DOWN:
points = hexahedron.getDownFace().getPoints();
break;
case EAST:
points = hexahedron.getEastFace().getPoints();
break;
case NORTH:
points = hexahedron.getNorthFace().getPoints();
break;
case SOUTH:
points = hexahedron.getSouthFace().getPoints();
break;
case UP:
points = hexahedron.getUpFace().getPoints();
break;
case WEST:
default:
points = hexahedron.getWestFace().getPoints();
break;
}
double x1;
double y1;
double x2;
double y2;
if (points[0].x == points[2].x) {
x1 = points[0].y;
y1 = points[0].z;
x2 = points[2].y;
y2 = points[2].z;
} else if (points[0].y == points[2].y) {
x1 = points[0].z;
y1 = points[0].x;
x2 = points[2].z;
y2 = points[2].x;
} else {
x1 = points[0].y;
y1 = points[0].x;
x2 = points[2].y;
y2 = points[2].x;
}
uv = new TextureUV(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2));
}
uv = uv.getScaled(1, (double) images[i].getHeight() / (double) images[i].getWidth());
uv = uv.getScaled((double) images[i].getWidth() / 16.0);
int x1 = (int) Math.ceil(uv.getX1());
int y1 = (int) Math.ceil(uv.getY1());
int dX = Math.abs((int) Math.floor(uv.getX2()) - x1);
int dY = Math.abs((int) Math.floor(uv.getY2()) - y1);
if (uv.isVerticallyFlipped()) {
images[i] = ImageUtils.flipVertically(images[i]);
y1 = images[i].getHeight() - y1;
}
if (uv.isHorizontallyFlipped()) {
images[i] = ImageUtils.flipHorizontal(images[i]);
x1 = images[i].getWidth() - x1;
}
images[i] = ImageUtils.copyAndGetSubImage(images[i], x1, y1, Math.max(1, dX), Math.max(1, dY));
int rotationAngle = faceData.getRotation();
if (rotationAngle % 360 != 0) {
images[i] = ImageUtils.rotateImageByDegrees(images[i], rotationAngle);
}
images[i] = tintIndexData.applyTint(images[i], faceData.getTintindex());
if (enchanted) {
overlayImages[i] = rawEnchantmentGlintProvider.apply(images[i]);
}
}
}
i++;
}
hexahedron.setImage(images);
hexahedron.setOverlay(overlayImages);
hexahedron.setOverlayAdditionFactor(OVERLAY_ADDITION_FACTORS);
if (rotation != null) {
hexahedron.translate(-rotation.getOrigin().getX(), -rotation.getOrigin().getY(), -rotation.getOrigin().getZ());
switch(rotation.getAxis()) {
case X:
hexahedron.rotate(rotation.getAngle(), 0, 0, false);
break;
case Y:
hexahedron.rotate(0, rotation.getAngle(), 0, false);
break;
case Z:
default:
hexahedron.rotate(0, 0, rotation.getAngle(), false);
break;
}
hexahedron.translate(rotation.getOrigin().getX(), rotation.getOrigin().getY(), rotation.getOrigin().getZ());
}
return hexahedron;
}));
itr.remove();
}
while (!tasks.isEmpty() || !elements.isEmpty()) {
Future<Hexahedron> task = tasks.poll();
if (task == null) {
try {
TimeUnit.MILLISECONDS.sleep(1);
} catch (InterruptedException e) {
}
} else {
try {
hexahedrons.add(task.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
return new Model(hexahedrons);
}
Aggregations