Skip to content

Commit 2d41b57

Browse files
committed
Fixes #1515 for solid blocks and water
1 parent 50f6444 commit 2d41b57

File tree

6 files changed

+49
-16
lines changed

6 files changed

+49
-16
lines changed

chunky/src/java/se/llbit/chunky/block/minecraft/Air.java

+1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ private Air() {
2929
solid = false;
3030
opaque = false;
3131
invisible = true;
32+
refractive = true;
3233
}
3334
}

chunky/src/java/se/llbit/chunky/model/AnimatedQuadModel.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import se.llbit.chunky.plugin.PluginApi;
44
import se.llbit.chunky.renderer.scene.Scene;
55
import se.llbit.chunky.resources.AnimatedTexture;
6+
import se.llbit.chunky.world.Material;
67
import se.llbit.math.Quad;
78
import se.llbit.math.Ray;
89
import se.llbit.math.Vector3;
@@ -42,7 +43,7 @@ public boolean intersect(Ray ray, Scene scene) {
4243
Quad[] quads = getQuads();
4344
AnimatedTexture[] textures = getTextures();
4445
Tint[] tintedQuads = getTints();
45-
46+
Material mat = ray.getCurrentMaterial();
4647
// The animation frame to use
4748
int j = (int) (scene.getAnimationTime() * animationMode.framerate);
4849
if (animationMode.positional) {
@@ -58,11 +59,11 @@ public boolean intersect(Ray ray, Scene scene) {
5859
Quad quad = quads[i];
5960
if (quad.intersect(ray)) {
6061
float[] c = textures[i].getColor(ray.u, ray.v, j);
61-
if (c[3] > Ray.EPSILON) {
62+
if (c[3] > Ray.EPSILON || mat.refractive) {
6263
tint = tintedQuads == null ? Tint.NONE : tintedQuads[i];
6364
color = c;
6465
ray.t = ray.tNext;
65-
if (quad.doubleSided)
66+
if (quad.doubleSided || mat.refractive)
6667
ray.orientNormal(quad.n);
6768
else
6869
ray.setNormal(quad.n);

chunky/src/java/se/llbit/chunky/model/QuadModel.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import se.llbit.chunky.plugin.PluginApi;
2424
import se.llbit.chunky.renderer.scene.Scene;
2525
import se.llbit.chunky.resources.Texture;
26+
import se.llbit.chunky.world.Material;
2627
import se.llbit.math.Quad;
2728
import se.llbit.math.Ray;
2829
import se.llbit.math.Vector3;
@@ -112,18 +113,19 @@ public boolean intersect(Ray ray, Scene scene) {
112113
Quad[] quads = getQuads();
113114
Texture[] textures = getTextures();
114115
Tint[] tintedQuads = getTints();
116+
Material mat = ray.getCurrentMaterial();
115117

116118
float[] color = null;
117119
Tint tint = Tint.NONE;
118120
for (int i = 0; i < quads.length; ++i) {
119121
Quad quad = quads[i];
120122
if (quad.intersect(ray)) {
121123
float[] c = textures[i].getColor(ray.u, ray.v);
122-
if (c[3] > Ray.EPSILON) {
124+
if (c[3] > Ray.EPSILON || mat.refractive) {
123125
tint = tintedQuads == null ? Tint.NONE : tintedQuads[i];
124126
color = c;
125127
ray.t = ray.tNext;
126-
if (quad.doubleSided)
128+
if (quad.doubleSided || mat.refractive)
127129
ray.orientNormal(quad.n);
128130
else
129131
ray.setNormal(quad.n);

chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java

+11-5
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ public Scene() {
360360
branchCount = PersistentSettings.getBranchCountDefault();
361361

362362
palette = new BlockPalette();
363-
worldOctree = new Octree(octreeImplementation, 1);
364-
waterOctree = new Octree(octreeImplementation, 1);
363+
worldOctree = new Octree(octreeImplementation, 1, Octree.OctreeType.WORLD);
364+
waterOctree = new Octree(octreeImplementation, 1, Octree.OctreeType.WATER);
365365
emitterGrid = null;
366366
}
367367

@@ -744,7 +744,7 @@ private boolean worldIntersection(Ray ray) {
744744
} else {
745745
r = new Ray(start);
746746
r.setCurrentMaterial(start.getPrevMaterial(), start.getPrevData());
747-
if (waterOctree.enterBlock(this, r, palette) && r.distance < ray.t) {
747+
if (waterOctree.enterBlock(this, r, palette) && r.distance < ray.t + Ray.EPSILON) {
748748
ray.t = r.distance;
749749
ray.setNormal(r.getNormal());
750750
ray.color.set(r.color);
@@ -824,8 +824,8 @@ public synchronized void loadChunks(TaskTracker taskTracker, World world, Collec
824824

825825
// Create new octree to fit all chunks.
826826
palette = new BlockPalette();
827-
worldOctree = new Octree(octreeImplementation, requiredDepth);
828-
waterOctree = new Octree(octreeImplementation, requiredDepth);
827+
worldOctree = new Octree(octreeImplementation, requiredDepth, Octree.OctreeType.WORLD);
828+
waterOctree = new Octree(octreeImplementation, requiredDepth, Octree.OctreeType.WATER);
829829

830830
grassTexture = biomeStructureFactory.create();
831831
foliageTexture = biomeStructureFactory.create();
@@ -2227,6 +2227,12 @@ private synchronized boolean loadOctree(SceneIOProvider context, TaskTracker tas
22272227
// this dump is so old that it doesn't contain a water texture (Chunky 2.3.0, #691)
22282228
waterTexture = BiomeStructure.get(this.biomeStructureImplementation).create();
22292229
}
2230+
if (worldOctree.type == null) {
2231+
worldOctree.type = Octree.OctreeType.WORLD;
2232+
}
2233+
if (waterOctree.type == null) {
2234+
waterOctree.type = Octree.OctreeType.WATER;
2235+
}
22302236
palette = data.palette;
22312237
palette.applyMaterials();
22322238
Log.info("Octree loaded");

chunky/src/java/se/llbit/math/Octree.java

+27-4
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,26 @@ public int getData() {
244244
}
245245
}
246246

247+
/** The type of Octree, used to adjust intersection code based on contents*/
248+
public enum OctreeType {
249+
/**
250+
* Contains all world geometry excluding water, water is removed from water logged blocks
251+
* and full water blocks are replaced with air
252+
*/
253+
WORLD,
254+
/**
255+
* Contains all the water geometry only, other blocks are air
256+
*/
257+
WATER
258+
}
259+
247260
/**
248261
* Timestamp of last serialization.
249262
*/
250263
private long timestamp = 0;
251264

265+
public OctreeType type;
266+
252267
private OctreeImplementation implementation;
253268

254269
/**
@@ -257,9 +272,10 @@ public int getData() {
257272
*
258273
* @param octreeDepth The number of levels in the Octree.
259274
*/
260-
public Octree(String impl, int octreeDepth) {
275+
public Octree(String impl, int octreeDepth, OctreeType type) {
261276
Log.infof("Building new octree (%s)", impl);
262277
implementation = getImplementationFactory(impl).create(octreeDepth);
278+
this.type = type;
263279
}
264280

265281
protected Octree(OctreeImplementation impl) {
@@ -484,6 +500,8 @@ public boolean enterBlock(Scene scene, Ray ray, BlockPalette palette) {
484500
int depth = implementation.getDepth();
485501

486502
double distance = 0;
503+
//tread air as a null block depending on octreetype and were we are in the trace
504+
boolean includeAir = this.type == OctreeType.WORLD && !ray.getPrevMaterial().isWater();
487505

488506
// floating point division are slower than multiplication so we cache them
489507
// We also try to limit the number of time the ray origin is updated
@@ -539,9 +557,14 @@ public boolean enterBlock(Scene scene, Ray ray, BlockPalette palette) {
539557
ray.distance += distance;
540558
distance = 0;
541559
if (currentBlock.intersect(ray, scene)) {
542-
if (prevBlock != currentBlock)
560+
if (prevBlock != currentBlock) { //|| (currentBlock.refractive)) {
561+
//for things like glass panes coerce the current mat to be air or water
562+
// TODO testing
563+
if (currentBlock.refractive) {
564+
//ray.setCurrentMaterial(currentBlock.waterlogged ? Water.INSTANCE : Air.INSTANCE);
565+
}
543566
return true;
544-
567+
}
545568
ray.o.scaleAdd(Ray.OFFSET, ray.d);
546569
offsetX = -ray.o.x * invDx;
547570
offsetY = -ray.o.y * invDy;
@@ -556,7 +579,7 @@ public boolean enterBlock(Scene scene, Ray ray, BlockPalette palette) {
556579
offsetZ = -ray.o.z * invDz;
557580
continue;
558581
}
559-
} else if (!currentBlock.isSameMaterial(prevBlock) && currentBlock != Air.INSTANCE) {
582+
} else if (!currentBlock.isSameMaterial(prevBlock) && (currentBlock != Air.INSTANCE || includeAir)) {
560583
// Origin and distance of ray need to be updated
561584
ray.o.scaleAdd(distance, ray.d);
562585
ray.distance += distance;

chunky/src/java/se/llbit/math/Quad.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,14 @@ public void sample(Vector3 loc, Random rand) {
158158
*/
159159
public boolean intersect(Ray ray) {
160160
double u, v;
161-
161+
Material mat = ray.getCurrentMaterial();
162162
double ix = ray.o.x - QuickMath.floor(ray.o.x + ray.d.x * Ray.OFFSET);
163163
double iy = ray.o.y - QuickMath.floor(ray.o.y + ray.d.y * Ray.OFFSET);
164164
double iz = ray.o.z - QuickMath.floor(ray.o.z + ray.d.z * Ray.OFFSET);
165165

166166
// Test that the ray is heading toward the plane of this quad.
167167
double denom = ray.d.dot(n);
168-
if (denom < -Ray.EPSILON || (doubleSided && denom > Ray.EPSILON)) {
168+
if (denom < -Ray.EPSILON || ((doubleSided || mat.refractive) && denom > Ray.EPSILON)) {
169169

170170
// Test for intersection with the plane at origin.
171171
double t = -(ix * n.x + iy * n.y + iz * n.z + d) / denom;

0 commit comments

Comments
 (0)