Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add block display support. #1693

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/AbstractModelBlock.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package se.llbit.chunky.block;

import se.llbit.chunky.model.BlockModel;
import se.llbit.chunky.model.QuadModel;
import se.llbit.chunky.plugin.PluginApi;
import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.chunky.resources.Texture;
import se.llbit.math.Ray;
import se.llbit.math.Transform;
import se.llbit.math.Vector3;
import se.llbit.math.primitive.Primitive;

import java.util.Collection;
import java.util.Random;

@PluginApi
Expand Down Expand Up @@ -50,4 +54,9 @@ public boolean intersect(Ray ray, Scene scene) {
public boolean isBiomeDependant() {
return super.isBiomeDependant() || model.isBiomeDependant();
}

@Override
public Collection<Primitive> getPrimitives(Transform transform) {
return getModel().getPrimitives(transform);
}
}
6 changes: 6 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@
import se.llbit.json.JsonValue;
import se.llbit.math.AABB;
import se.llbit.math.Ray;
import se.llbit.math.Transform;
import se.llbit.math.Vector3;
import se.llbit.math.primitive.Primitive;
import se.llbit.nbt.CompoundTag;
import se.llbit.nbt.Tag;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;

Expand Down Expand Up @@ -153,4 +157,6 @@ public Tag getNewTagWithBlockEntity(Tag blockTag, CompoundTag entityTag) {
public boolean isBiomeDependant() {
return isWaterFilled();
}

public abstract Collection<Primitive> getPrimitives(Transform transform);
}
25 changes: 25 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/MinecraftBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

import se.llbit.chunky.resources.Texture;
import se.llbit.chunky.world.Material;
import se.llbit.math.Transform;
import se.llbit.math.Vector3;
import se.llbit.math.Vector4;
import se.llbit.math.primitive.Box;
import se.llbit.math.primitive.Primitive;

import java.util.Collection;
import java.util.LinkedList;

/**
* A simple opaque block with a single texture.
Expand All @@ -14,4 +22,21 @@ public MinecraftBlock(String name, Texture texture) {
opaque = true;
solid = true;
}

@Override
public Collection<Primitive> getPrimitives(Transform transform) {
// TODO check uv mapping and flip/rotate textures if needed
// TODO apply this block's material properties to the primitives

Collection<Primitive> primitives = new LinkedList<>();
Box box = new Box(0, 1, 0, 1, 0, 1);
box.transform(transform);
box.addFrontFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addBackFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addLeftFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addRightFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addTopFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addBottomFaces(primitives, texture, new Vector4(0, 1, 0, 1));
return primitives;
}
}
24 changes: 24 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/SolidNonOpaqueBlock.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package se.llbit.chunky.block;

import se.llbit.chunky.resources.Texture;
import se.llbit.math.Transform;
import se.llbit.math.Vector4;
import se.llbit.math.primitive.Box;
import se.llbit.math.primitive.Primitive;

import java.util.Collection;
import java.util.LinkedList;

public class SolidNonOpaqueBlock extends Block {

Expand All @@ -9,4 +16,21 @@ public SolidNonOpaqueBlock(String name, Texture texture) {
solid = true;
opaque = false;
}

@Override
public Collection<Primitive> getPrimitives(Transform transform) {
// TODO check uv mapping and flip/rotate textures if needed
// TODO apply this block's material properties to the primitives

Collection<Primitive> primitives = new LinkedList<>();
Box box = new Box(0, 1, 0, 1, 0, 1);
box.transform(transform);
box.addFrontFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addBackFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addLeftFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addRightFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addTopFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addBottomFaces(primitives, texture, new Vector4(0, 1, 0, 1));
return primitives;
}
}
24 changes: 24 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/UntintedLeaves.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package se.llbit.chunky.block;

import se.llbit.chunky.resources.Texture;
import se.llbit.math.Transform;
import se.llbit.math.Vector4;
import se.llbit.math.primitive.Box;
import se.llbit.math.primitive.Primitive;

import java.util.Collection;
import java.util.LinkedList;

public class UntintedLeaves extends Block {

Expand All @@ -9,4 +16,21 @@ public UntintedLeaves(String name, Texture texture) {
solid = false;
opaque = false;
}

@Override
public Collection<Primitive> getPrimitives(Transform transform) {
// TODO check uv mapping and flip/rotate textures if needed
// TODO apply this block's material properties to the primitives

Collection<Primitive> primitives = new LinkedList<>();
Box box = new Box(0, 1, 0, 1, 0, 1);
box.transform(transform);
box.addFrontFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addBackFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addLeftFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addRightFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addTopFaces(primitives, texture, new Vector4(0, 1, 0, 1));
box.addBottomFaces(primitives, texture, new Vector4(0, 1, 0, 1));
return primitives;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.log.Log;
import se.llbit.math.Ray;
import se.llbit.math.Transform;
import se.llbit.math.primitive.Primitive;
import se.llbit.nbt.CompoundTag;

import java.util.Collection;
import java.util.Collections;

/**
* A wrapper for legacy blocks (before the flattening in Minecraft 1.13) that have properties that
* depend on surrounding blocks (e.g. doors, snow covered grass or fences).
Expand Down Expand Up @@ -79,4 +84,9 @@ public Block getIncompleteBlock() {
* @param state Current finalization state
*/
public abstract void finalizeBlock(FinalizationState state);

@Override
public Collection<Primitive> getPrimitives(Transform transform) {
return Collections.emptyList();
}
}
10 changes: 10 additions & 0 deletions chunky/src/java/se/llbit/chunky/block/minecraft/SporeBlossom.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@

import se.llbit.chunky.block.Block;
import se.llbit.chunky.entity.Entity;
import se.llbit.chunky.model.minecraft.SporeBlossomModel;
import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.chunky.resources.Texture;
import se.llbit.math.Ray;
import se.llbit.math.Transform;
import se.llbit.math.Vector3;
import se.llbit.math.primitive.Primitive;

import java.util.Collection;

public class SporeBlossom extends Block {

Expand All @@ -48,4 +53,9 @@ public boolean isEntity() {
public Entity toEntity(Vector3 position) {
return new se.llbit.chunky.entity.SporeBlossom(position);
}

@Override
public Collection<Primitive> getPrimitives(Transform transform) {
return SporeBlossomModel.primitives(transform);
}
}
71 changes: 71 additions & 0 deletions chunky/src/java/se/llbit/chunky/entity/BlockDisplayEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package se.llbit.chunky.entity;

import se.llbit.chunky.block.Block;
import se.llbit.json.JsonObject;
import se.llbit.json.JsonValue;
import se.llbit.math.Transform;
import se.llbit.math.Vector3;
import se.llbit.math.Vector4;
import se.llbit.math.primitive.Primitive;
import se.llbit.nbt.CompoundTag;
import se.llbit.nbt.Tag;

import java.util.Collection;

public class BlockDisplayEntity extends Entity {
private final Block block;
private final CompoundTag tag;

public BlockDisplayEntity(Vector3 position, Block block, CompoundTag tag) {
super(position);
this.block = block;
this.tag = tag;
}

@Override
public Collection<Primitive> primitives(Vector3 offset) {
// TODO add support for matrix form (ie. 16 values in row-major order)

Transform transform = getTransform(tag.get("transformation"))
.translate(position)
.translate(offset);

return block.getPrimitives(transform);
}

private Transform getTransform(Tag transformation) {
return Transform.NONE
.rotateQuaternion( // TODO support axis-angle form (ie. angle of rotation and axis vector)
new Vector4(
transformation.get("right_rotation").get(1).floatValue(),
transformation.get("right_rotation").get(2).floatValue(),
-transformation.get("right_rotation").get(3).floatValue(), // fix rotation direction
-transformation.get("right_rotation").get(0).floatValue() // fix rotation direction
)
)
.scale(
transformation.get("scale").get(0).floatValue(1),
transformation.get("scale").get(1).floatValue(1),
transformation.get("scale").get(2).floatValue(1)
)
.rotateQuaternion( // TODO support axis-angle form (ie. angle of rotation and axis vector)
new Vector4(
transformation.get("left_rotation").get(1).floatValue(),
transformation.get("left_rotation").get(2).floatValue(),
-transformation.get("left_rotation").get(3).floatValue(), // fix rotation direction
-transformation.get("left_rotation").get(0).floatValue() // fix rotation direction
)
)
.translate(
transformation.get("translation").get(0).floatValue(0),
transformation.get("translation").get(1).floatValue(0),
transformation.get("translation").get(2).floatValue(0)
);
}

@Override
public JsonValue toJson() {
// TODO can we even serialize this or do we put the tag into a block palette?
return new JsonObject();
}
}
47 changes: 39 additions & 8 deletions chunky/src/java/se/llbit/chunky/model/AABBModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
import se.llbit.chunky.plugin.PluginApi;
import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.chunky.resources.Texture;
import se.llbit.math.AABB;
import se.llbit.math.Ray;
import se.llbit.math.Vector3;
import se.llbit.math.*;
import se.llbit.math.primitive.Box;
import se.llbit.math.primitive.Primitive;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.*;

/**
* A block model that is made out of textured AABBs.
Expand Down Expand Up @@ -186,12 +183,46 @@ 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)
.filter(Objects::nonNull)
.flatMap(Arrays::stream)
.anyMatch(Tint::isBiomeTint);
}

@Override
public Collection<Primitive> getPrimitives(Transform transform) {
List<Primitive> primitives = new ArrayList<>();

AABB[] boxes = getBoxes();
Texture[][] textures = getTextures();

for (int i = 0; i < boxes.length; ++i) {
AABB aabb = boxes[i];
Box box = new Box(aabb.xmin, aabb.xmax, aabb.ymin, aabb.ymax, aabb.zmin, aabb.zmax);
box.transform(transform);
if (textures[i][0] != null) {
box.addFrontFaces(primitives, textures[i][0], new Vector4(0, 1, 0, 1)); // TODO
}
if (textures[i][1] != null) {
box.addBackFaces(primitives, textures[i][1], new Vector4(0, 1, 0, 1)); // TODO
}
if (textures[i][2] != null) {
box.addLeftFaces(primitives, textures[i][2], new Vector4(0, 1, 0, 1)); // TODO
}
if (textures[i][3] != null) {
box.addRightFaces(primitives, textures[i][3], new Vector4(0, 1, 0, 1)); // TODO
}
if (textures[i][4] != null) {
box.addTopFaces(primitives, textures[i][4], new Vector4(0, 1, 0, 1));
}
if (textures[i][5] != null) {
box.addBottomFaces(primitives, textures[i][5], new Vector4(0, 1, 0, 1));
}
}
// TODO apply correct texture index, tint and uv-mapping, material properties
return primitives;
}
}
5 changes: 5 additions & 0 deletions chunky/src/java/se/llbit/chunky/model/BlockModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import se.llbit.chunky.plugin.PluginApi;
import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.math.Ray;
import se.llbit.math.Transform;
import se.llbit.math.Vector3;
import se.llbit.math.primitive.Primitive;

import java.util.Collection;
import java.util.List;
import java.util.Random;

Expand All @@ -20,4 +23,6 @@ public interface BlockModel {
double faceSurfaceArea(int face);

boolean isBiomeDependant();

Collection<Primitive> getPrimitives(Transform transform);
}