Skip to content

Commit cab971d

Browse files
committed
Fix lit campfire height by making it an entity. Only emit light from the flame.
1 parent 2807fc5 commit cab971d

File tree

3 files changed

+323
-3
lines changed

3 files changed

+323
-3
lines changed
Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,38 @@
11
package se.llbit.chunky.block;
22

3+
import se.llbit.chunky.entity.Entity;
34
import se.llbit.chunky.model.CampfireModel;
4-
import se.llbit.chunky.model.StonecutterModel;
55
import se.llbit.chunky.renderer.scene.Scene;
66
import se.llbit.chunky.resources.Texture;
77
import se.llbit.math.Ray;
8+
import se.llbit.math.Vector3;
9+
import se.llbit.nbt.CompoundTag;
810

911
public class Campfire extends MinecraftBlockTranslucent {
1012
private final String facing;
1113
public final boolean isLit;
1214

1315
public Campfire(String facing, boolean lit) {
1416
super("campfire", Texture.campfireLog);
17+
invisible = true;
18+
opaque = false;
1519
localIntersect = true;
1620
this.facing = facing;
1721
this.isLit = lit;
18-
// TODO the fire is 1/16th higher than a block, so this must be an entity
1922
}
2023

2124
@Override
2225
public boolean intersect(Ray ray, Scene scene) {
23-
return CampfireModel.intersect(ray, facing, isLit);
26+
return false;
27+
}
28+
29+
@Override
30+
public boolean isBlockEntity() {
31+
return true;
32+
}
33+
34+
@Override
35+
public Entity toBlockEntity(Vector3 position, CompoundTag entityTag) {
36+
return new se.llbit.chunky.entity.Campfire(position, this.facing, this.isLit);
2437
}
2538
}
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
package se.llbit.chunky.entity;
2+
3+
import se.llbit.chunky.model.Model;
4+
import se.llbit.chunky.resources.Texture;
5+
import se.llbit.chunky.world.Material;
6+
import se.llbit.chunky.world.material.TextureMaterial;
7+
import se.llbit.json.JsonObject;
8+
import se.llbit.json.JsonValue;
9+
import se.llbit.math.Quad;
10+
import se.llbit.math.Transform;
11+
import se.llbit.math.Vector3;
12+
import se.llbit.math.Vector4;
13+
import se.llbit.math.primitive.Primitive;
14+
import se.llbit.nbt.CompoundTag;
15+
import se.llbit.util.JsonUtil;
16+
17+
import java.util.Collection;
18+
import java.util.LinkedList;
19+
20+
public class Campfire extends Entity {
21+
private static final Texture log = Texture.campfireLog;
22+
private static final Texture litlog = Texture.campfireLogLit;
23+
private static final Texture fire = Texture.campfireFire;
24+
25+
private static final Texture[] tex = new Texture[]{
26+
log, log, log, log, log, log, log, log, log, log, log, log, log, log, log,
27+
log, log, log, log, log, log, log, log, log, log, log, log, log,
28+
};
29+
30+
private static final Texture[] texLit = new Texture[]{
31+
log, log, log, litlog, log, log, log, litlog, log, log, litlog, litlog, log, log, litlog,
32+
log, log, log, log, litlog, log, log, litlog, litlog, litlog, log, log, log, fire, fire, fire, fire
33+
};
34+
35+
private static final Quad[] quads = new Quad[]{
36+
new Quad(
37+
new Vector3(5 / 16.0, 4 / 16.0, 16 / 16.0),
38+
new Vector3(5 / 16.0, 4 / 16.0, 0 / 16.0),
39+
new Vector3(1 / 16.0, 4 / 16.0, 16 / 16.0),
40+
new Vector4(0 / 16.0, 16 / 16.0, 12 / 16.0, 16 / 16.0)
41+
),
42+
new Quad(
43+
new Vector3(5 / 16.0, 0 / 16.0, 0 / 16.0),
44+
new Vector3(5 / 16.0, 0 / 16.0, 16 / 16.0),
45+
new Vector3(1 / 16.0, 0 / 16.0, 0 / 16.0),
46+
new Vector4(0 / 16.0, 16 / 16.0, 12 / 16.0, 16 / 16.0)
47+
),
48+
new Quad(
49+
new Vector3(1 / 16.0, 4 / 16.0, 16 / 16.0),
50+
new Vector3(1 / 16.0, 4 / 16.0, 0 / 16.0),
51+
new Vector3(1 / 16.0, 0 / 16.0, 16 / 16.0),
52+
new Vector4(0 / 16.0, 16 / 16.0, 16 / 16.0, 12 / 16.0)
53+
),
54+
new Quad(
55+
new Vector3(5 / 16.0, 4 / 16.0, 0 / 16.0),
56+
new Vector3(5 / 16.0, 4 / 16.0, 16 / 16.0),
57+
new Vector3(5 / 16.0, 0 / 16.0, 0 / 16.0),
58+
new Vector4(16 / 16.0, 0 / 16.0, 15 / 16.0, 11 / 16.0)
59+
),
60+
new Quad(
61+
new Vector3(1 / 16.0, 4 / 16.0, 0 / 16.0),
62+
new Vector3(5 / 16.0, 4 / 16.0, 0 / 16.0),
63+
new Vector3(1 / 16.0, 0 / 16.0, 0 / 16.0),
64+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
65+
),
66+
new Quad(
67+
new Vector3(5 / 16.0, 4 / 16.0, 16 / 16.0),
68+
new Vector3(1 / 16.0, 4 / 16.0, 16 / 16.0),
69+
new Vector3(5 / 16.0, 0 / 16.0, 16 / 16.0),
70+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
71+
),
72+
new Quad(
73+
new Vector3(16 / 16.0, 7 / 16.0, 11 / 16.0),
74+
new Vector3(0 / 16.0, 7 / 16.0, 11 / 16.0),
75+
new Vector3(16 / 16.0, 7 / 16.0, 15 / 16.0),
76+
new Vector4(0 / 16.0, 16 / 16.0, 12 / 16.0, 16 / 16.0)
77+
),
78+
new Quad(
79+
new Vector3(0 / 16.0, 3 / 16.0, 11 / 16.0),
80+
new Vector3(16 / 16.0, 3 / 16.0, 11 / 16.0),
81+
new Vector3(0 / 16.0, 3 / 16.0, 15 / 16.0),
82+
new Vector4(0 / 16.0, 16 / 16.0, 8 / 16.0, 12 / 16.0)
83+
),
84+
new Quad(
85+
new Vector3(0 / 16.0, 7 / 16.0, 15 / 16.0),
86+
new Vector3(0 / 16.0, 7 / 16.0, 11 / 16.0),
87+
new Vector3(0 / 16.0, 3 / 16.0, 15 / 16.0),
88+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
89+
),
90+
new Quad(
91+
new Vector3(16 / 16.0, 7 / 16.0, 11 / 16.0),
92+
new Vector3(16 / 16.0, 7 / 16.0, 15 / 16.0),
93+
new Vector3(16 / 16.0, 3 / 16.0, 11 / 16.0),
94+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
95+
),
96+
new Quad(
97+
new Vector3(0 / 16.0, 7 / 16.0, 11 / 16.0),
98+
new Vector3(16 / 16.0, 7 / 16.0, 11 / 16.0),
99+
new Vector3(0 / 16.0, 3 / 16.0, 11 / 16.0),
100+
new Vector4(0 / 16.0, 16 / 16.0, 16 / 16.0, 12 / 16.0)
101+
),
102+
new Quad(
103+
new Vector3(16 / 16.0, 7 / 16.0, 15 / 16.0),
104+
new Vector3(0 / 16.0, 7 / 16.0, 15 / 16.0),
105+
new Vector3(16 / 16.0, 3 / 16.0, 15 / 16.0),
106+
new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 12 / 16.0)
107+
),
108+
new Quad(
109+
new Vector3(15 / 16.0, 4 / 16.0, 16 / 16.0),
110+
new Vector3(15 / 16.0, 4 / 16.0, 0 / 16.0),
111+
new Vector3(11 / 16.0, 4 / 16.0, 16 / 16.0),
112+
new Vector4(0 / 16.0, 16 / 16.0, 12 / 16.0, 16 / 16.0)
113+
),
114+
new Quad(
115+
new Vector3(15 / 16.0, 0 / 16.0, 0 / 16.0),
116+
new Vector3(15 / 16.0, 0 / 16.0, 16 / 16.0),
117+
new Vector3(11 / 16.0, 0 / 16.0, 0 / 16.0),
118+
new Vector4(0 / 16.0, 16 / 16.0, 12 / 16.0, 16 / 16.0)
119+
),
120+
new Quad(
121+
new Vector3(11 / 16.0, 4 / 16.0, 16 / 16.0),
122+
new Vector3(11 / 16.0, 4 / 16.0, 0 / 16.0),
123+
new Vector3(11 / 16.0, 0 / 16.0, 16 / 16.0),
124+
new Vector4(0 / 16.0, 16 / 16.0, 15 / 16.0, 11 / 16.0)
125+
),
126+
new Quad(
127+
new Vector3(15 / 16.0, 4 / 16.0, 0 / 16.0),
128+
new Vector3(15 / 16.0, 4 / 16.0, 16 / 16.0),
129+
new Vector3(15 / 16.0, 0 / 16.0, 0 / 16.0),
130+
new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 12 / 16.0)
131+
),
132+
new Quad(
133+
new Vector3(11 / 16.0, 4 / 16.0, 0 / 16.0),
134+
new Vector3(15 / 16.0, 4 / 16.0, 0 / 16.0),
135+
new Vector3(11 / 16.0, 0 / 16.0, 0 / 16.0),
136+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
137+
),
138+
new Quad(
139+
new Vector3(15 / 16.0, 4 / 16.0, 16 / 16.0),
140+
new Vector3(11 / 16.0, 4 / 16.0, 16 / 16.0),
141+
new Vector3(15 / 16.0, 0 / 16.0, 16 / 16.0),
142+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
143+
),
144+
new Quad(
145+
new Vector3(16 / 16.0, 7 / 16.0, 1 / 16.0),
146+
new Vector3(0 / 16.0, 7 / 16.0, 1 / 16.0),
147+
new Vector3(16 / 16.0, 7 / 16.0, 5 / 16.0),
148+
new Vector4(0 / 16.0, 16 / 16.0, 12 / 16.0, 16 / 16.0)
149+
),
150+
new Quad(
151+
new Vector3(0 / 16.0, 3 / 16.0, 1 / 16.0),
152+
new Vector3(16 / 16.0, 3 / 16.0, 1 / 16.0),
153+
new Vector3(0 / 16.0, 3 / 16.0, 5 / 16.0),
154+
new Vector4(0 / 16.0, 16 / 16.0, 8 / 16.0, 12 / 16.0)
155+
),
156+
new Quad(
157+
new Vector3(0 / 16.0, 7 / 16.0, 5 / 16.0),
158+
new Vector3(0 / 16.0, 7 / 16.0, 1 / 16.0),
159+
new Vector3(0 / 16.0, 3 / 16.0, 5 / 16.0),
160+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
161+
),
162+
new Quad(
163+
new Vector3(16 / 16.0, 7 / 16.0, 1 / 16.0),
164+
new Vector3(16 / 16.0, 7 / 16.0, 5 / 16.0),
165+
new Vector3(16 / 16.0, 3 / 16.0, 1 / 16.0),
166+
new Vector4(4 / 16.0, 0 / 16.0, 12 / 16.0, 8 / 16.0)
167+
),
168+
new Quad(
169+
new Vector3(0 / 16.0, 7 / 16.0, 1 / 16.0),
170+
new Vector3(16 / 16.0, 7 / 16.0, 1 / 16.0),
171+
new Vector3(0 / 16.0, 3 / 16.0, 1 / 16.0),
172+
new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 12 / 16.0)
173+
),
174+
new Quad(
175+
new Vector3(16 / 16.0, 7 / 16.0, 5 / 16.0),
176+
new Vector3(0 / 16.0, 7 / 16.0, 5 / 16.0),
177+
new Vector3(16 / 16.0, 3 / 16.0, 5 / 16.0),
178+
new Vector4(0 / 16.0, 16 / 16.0, 16 / 16.0, 12 / 16.0)
179+
),
180+
new Quad(
181+
new Vector3(11 / 16.0, 1 / 16.0, 16 / 16.0),
182+
new Vector3(11 / 16.0, 1 / 16.0, 0 / 16.0),
183+
new Vector3(5 / 16.0, 1 / 16.0, 16 / 16.0),
184+
new Vector4(0 / 16.0, 16 / 16.0, 2 / 16.0, 8 / 16.0)
185+
),
186+
new Quad(
187+
new Vector3(11 / 16.0, 0 / 16.0, 0 / 16.0),
188+
new Vector3(11 / 16.0, 0 / 16.0, 16 / 16.0),
189+
new Vector3(5 / 16.0, 0 / 16.0, 0 / 16.0),
190+
new Vector4(0 / 16.0, 16 / 16.0, 2 / 16.0, 8 / 16.0)
191+
),
192+
new Quad(
193+
new Vector3(5 / 16.0, 1 / 16.0, 0 / 16.0),
194+
new Vector3(11 / 16.0, 1 / 16.0, 0 / 16.0),
195+
new Vector3(5 / 16.0, 0 / 16.0, 0 / 16.0),
196+
new Vector4(6 / 16.0, 0 / 16.0, 1 / 16.0, 0 / 16.0)
197+
),
198+
new Quad(
199+
new Vector3(11 / 16.0, 1 / 16.0, 16 / 16.0),
200+
new Vector3(5 / 16.0, 1 / 16.0, 16 / 16.0),
201+
new Vector3(11 / 16.0, 0 / 16.0, 16 / 16.0),
202+
new Vector4(16 / 16.0, 10 / 16.0, 1 / 16.0, 0 / 16.0)
203+
),
204+
rotateFire(new Quad(
205+
new Vector3(0.8 / 16.0, 17 / 16.0, 8 / 16.0),
206+
new Vector3(15.2 / 16.0, 17 / 16.0, 8 / 16.0),
207+
new Vector3(0.8 / 16.0, 1 / 16.0, 8 / 16.0),
208+
new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0)
209+
)),
210+
rotateFire(new Quad(
211+
new Vector3(15.2 / 16.0, 17 / 16.0, 8 / 16.0),
212+
new Vector3(0.8 / 16.0, 17 / 16.0, 8 / 16.0),
213+
new Vector3(15.2 / 16.0, 1 / 16.0, 8 / 16.0),
214+
new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0)
215+
)),
216+
rotateFire(new Quad(
217+
new Vector3(8 / 16.0, 17 / 16.0, 15.2 / 16.0),
218+
new Vector3(8 / 16.0, 17 / 16.0, 0.8 / 16.0),
219+
new Vector3(8 / 16.0, 1 / 16.0, 15.2 / 16.0),
220+
new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0)
221+
)),
222+
rotateFire(new Quad(
223+
new Vector3(8 / 16.0, 17 / 16.0, 0.8 / 16.0),
224+
new Vector3(8 / 16.0, 17 / 16.0, 15.2 / 16.0),
225+
new Vector3(8 / 16.0, 1 / 16.0, 0.8 / 16.0),
226+
new Vector4(16 / 16.0, 0 / 16.0, 16 / 16.0, 0 / 16.0)
227+
))
228+
};
229+
230+
static final Quad[][] orientedQuads = new Quad[4][];
231+
232+
static {
233+
orientedQuads[0] = quads;
234+
orientedQuads[1] = Model.rotateY(orientedQuads[0]);
235+
orientedQuads[2] = Model.rotateY(orientedQuads[1]);
236+
orientedQuads[3] = Model.rotateY(orientedQuads[2]);
237+
}
238+
239+
private static Quad rotateFire(Quad quad) {
240+
double rotatedWidth = 14.4 * Math.cos(Math.toRadians(45));
241+
return new Quad(quad, Transform.NONE.rotateY(Math.toRadians(45)));
242+
}
243+
244+
private final String facing;
245+
private final boolean isLit;
246+
247+
public Campfire(Vector3 position, String facing, boolean lit) {
248+
super(position);
249+
this.facing = facing;
250+
this.isLit = lit;
251+
}
252+
253+
public Campfire(JsonObject json) {
254+
super(JsonUtil.vec3FromJsonObject(json.get("position")));
255+
this.facing = json.get("facing").stringValue("north");
256+
this.isLit = json.get("lit").boolValue(true);
257+
}
258+
259+
@Override
260+
public Collection<Primitive> primitives(Vector3 offset) {
261+
Collection<Primitive> faces = new LinkedList<>();
262+
Transform transform = Transform.NONE
263+
.translate(position.x + offset.x, position.y + offset.y, position.z + offset.z);
264+
int facing = getOrientationIndex(this.facing);
265+
int n = isLit ? orientedQuads[facing].length : orientedQuads[facing].length - 4;
266+
Texture[] textures = isLit ? texLit : tex;
267+
for (int i = 0; i < n; i++) {
268+
Material material = new TextureMaterial(textures[i]);
269+
if (isLit && i >= n - 4) {
270+
material.emittance = 1.0f;
271+
}
272+
orientedQuads[facing][i].addTriangles(faces, material, transform);
273+
}
274+
return faces;
275+
}
276+
277+
@Override
278+
public JsonValue toJson() {
279+
JsonObject json = new JsonObject();
280+
json.add("kind", "campfire");
281+
json.add("position", position.toJson());
282+
json.add("facing", facing);
283+
json.add("lit", isLit);
284+
return json;
285+
}
286+
287+
public static Entity fromJson(JsonObject json) {
288+
return new Campfire(json);
289+
}
290+
291+
private static int getOrientationIndex(String facing) {
292+
switch (facing) {
293+
case "north":
294+
return 0;
295+
case "east":
296+
return 1;
297+
case "south":
298+
return 2;
299+
case "west":
300+
return 3;
301+
default:
302+
return 0;
303+
}
304+
}
305+
}

chunky/src/java/se/llbit/chunky/entity/Entity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public static Entity fromJson(JsonObject json) {
7979
return WallCoralFanEntity.fromJson(json);
8080
case "lectern":
8181
return Lectern.fromJson(json);
82+
case "campfire":
83+
return Campfire.fromJson(json);
8284
}
8385
return null;
8486
}

0 commit comments

Comments
 (0)