diff --git a/chunky/src/java/se/llbit/chunky/model/AABBModel.java b/chunky/src/java/se/llbit/chunky/model/AABBModel.java index 90ca47f55..74930686f 100644 --- a/chunky/src/java/se/llbit/chunky/model/AABBModel.java +++ b/chunky/src/java/se/llbit/chunky/model/AABBModel.java @@ -8,47 +8,76 @@ import se.llbit.math.Vector3; import java.util.Arrays; -import java.util.List; import java.util.Objects; import java.util.Random; /** - * A block model that is made out of textured AABBs. + * A block model that is made out of textured axis-aligned bounding boxes (AABBs). */ @PluginApi public abstract class AABBModel implements BlockModel { /** * Different UV mapping methods. - * - None: No change in mapping - * - ROTATE_90: Rotate 90 degrees clockwise - * - ROTATE_180: Rotate 180 degrees - * - ROTATE_270: Rotate 270 degrees clockwise (90 degrees counterclockwise) - * - FLIP_U: Flip along the X axis (u = 1 - u) - * - FLIP_V: Flip along the Y axis (v = 1 - v) - *

- * Note: a value of {@code null} is equivalent to {@code NONE} */ public enum UVMapping { + /** + * No change in mapping. + */ NONE, + /** + * Rotate by 90 degrees clockwise. + */ ROTATE_90, + /** + * Rotate by 180 degrees. + */ ROTATE_180, + /** + * Rotate 270 degrees clockwise (90 degrees counter clockwise). + */ ROTATE_270, + /** + * Mirror horizontally (u = 1 - u). + */ FLIP_U, + /** + * Mirror vertically (v = 1 - v). + */ FLIP_V } + /** + * Get the boxes for this model. + * + * @return An array of boxes. + */ @PluginApi public abstract AABB[] getBoxes(); + /** + * Get textures for the boxes. + * + * @return An array of textures for the boxes, each in north, east, south, west, top, bottom order. + */ @PluginApi public abstract Texture[][] getTextures(); + /** + * Get tints for the boxes. If an entry is null or this method returns null, it is equivalent to {@link Tint#NONE}. + * + * @return An array of tints for the boxes, each in north, east, south, west, top, bottom order. + */ @PluginApi public Tint[][] getTints() { return null; } + /** + * Get UV mappings for the boxes. If an entry is null or this method returns null, it is equivalent to {@link UVMapping#NONE}. + * + * @return An array of UV mappings for the boxes, each in north, east, south, west, top, bottom order. + */ @PluginApi public UVMapping[][] getUVMapping() { return null; @@ -81,45 +110,47 @@ public boolean intersect(Ray ray, Scene scene) { ray.t = Double.POSITIVE_INFINITY; for (int i = 0; i < boxes.length; ++i) { if (boxes[i].intersect(ray)) { + Texture[] texturesBox = textures[i]; Tint[] tintedFacesBox = tintedFaces != null ? tintedFaces[i] : null; + UVMapping[] mappingBox = mapping != null ? mapping[i] : null; Vector3 n = ray.getNormal(); if (n.y > 0) { // top ray.v = 1 - ray.v; - if (intersectFace(ray, scene, textures[i][4], - mapping != null ? mapping[i][4] : null + if (intersectFace(ray, texturesBox[4], + mappingBox != null ? mappingBox[4] : null )) { tint = tintedFacesBox != null ? tintedFacesBox[4] : Tint.NONE; hit = true; } } else if (n.y < 0) { // bottom - if (intersectFace(ray, scene, textures[i][5], - mapping != null ? mapping[i][5] : null)) { + if (intersectFace(ray, texturesBox[5], + mappingBox != null ? mappingBox[5] : null)) { hit = true; tint = tintedFacesBox != null ? tintedFacesBox[5] : Tint.NONE; } } else if (n.z < 0) { // north - if (intersectFace(ray, scene, textures[i][0], - mapping != null ? mapping[i][0] : null + if (intersectFace(ray, texturesBox[0], + mappingBox != null ? mappingBox[0] : null )) { hit = true; tint = tintedFacesBox != null ? tintedFacesBox[0] : Tint.NONE; } } else if (n.z > 0) { // south - if (intersectFace(ray, scene, textures[i][2], - mapping != null ? mapping[i][2] : null + if (intersectFace(ray, texturesBox[2], + mappingBox != null ? mappingBox[2] : null )) { hit = true; tint = tintedFacesBox != null ? tintedFacesBox[2] : Tint.NONE; } } else if (n.x < 0) { // west - if (intersectFace(ray, scene, textures[i][3], - mapping != null ? mapping[i][3] : null)) { + if (intersectFace(ray, texturesBox[3], + mappingBox != null ? mappingBox[3] : null)) { hit = true; tint = tintedFacesBox != null ? tintedFacesBox[3] : Tint.NONE; } } else if (n.x > 0) { // east - if (intersectFace(ray, scene, textures[i][1], - mapping != null ? mapping[i][1] : null)) { + if (intersectFace(ray, texturesBox[1], + mappingBox != null ? mappingBox[1] : null)) { hit = true; tint = tintedFacesBox != null ? tintedFacesBox[1] : Tint.NONE; } @@ -141,7 +172,7 @@ public boolean intersect(Ray ray, Scene scene) { return hit; } - private boolean intersectFace(Ray ray, Scene scene, Texture texture, UVMapping mapping) { + private boolean intersectFace(Ray ray, Texture texture, UVMapping mapping) { // This is the method that handles intersecting faces of all AABB-based models. // Do normal mapping, parallax occlusion mapping, specular maps and all the good stuff here! @@ -186,7 +217,7 @@ private boolean intersectFace(Ray ray, Scene scene, Texture texture, UVMapping m @Override public boolean isBiomeDependant() { Tint[][] tints = getTints(); - if(tints == null) + if (tints == null) return false; return Arrays.stream(tints)