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)