Compare commits
5 commits
master
...
kapri-scen
Author | SHA1 | Date | |
---|---|---|---|
![]() |
53958e9b97 | ||
![]() |
96fd7e4339 | ||
![]() |
110e85827e | ||
![]() |
edf8d251ed | ||
![]() |
b3f073e2be |
BIN
resources/obomba.jpg
Normal file
BIN
resources/obomba.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
|
@ -1,10 +1,26 @@
|
||||||
package xyz.marsavic.gfxlab.graphics3d;
|
package xyz.marsavic.gfxlab.graphics3d;
|
||||||
|
|
||||||
|
import xyz.marsavic.geometry.Vector;
|
||||||
import xyz.marsavic.gfxlab.Color;
|
import xyz.marsavic.gfxlab.Color;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
public record Material(
|
public record Material(
|
||||||
Color diffuse
|
Color diffuse
|
||||||
) {
|
) {
|
||||||
|
public static Material diffuseImage(BufferedImage img, Vector uv) {
|
||||||
|
int x = (int) (uv.x()*img.getWidth()) % img.getWidth();
|
||||||
|
if (x < 0) {
|
||||||
|
x += img.getWidth(); // adding in case of negative modulo
|
||||||
|
}
|
||||||
|
|
||||||
|
int y = (int) (uv.y()*img.getWidth()) % img.getWidth();
|
||||||
|
if (y < 0) {
|
||||||
|
y += img.getHeight();
|
||||||
|
}
|
||||||
|
y = img.getHeight()-y-1; // inverting y, BufferedImage is encoded from top to bottom, and uv mapping is bottom to top
|
||||||
|
return new Material(Color.code(img.getRGB(x, y)));
|
||||||
|
}
|
||||||
public Material diffuse(Color diffuse) { return new Material(diffuse); }
|
public Material diffuse(Color diffuse) { return new Material(diffuse); }
|
||||||
|
|
||||||
public static final Material BLACK = new Material(Color.BLACK);
|
public static final Material BLACK = new Material(Color.BLACK);
|
||||||
|
|
|
@ -22,8 +22,12 @@ public abstract class RayTracer implements ColorFunctionT {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color at(double t, Vector p) {
|
public Color at(double t, Vector p) {
|
||||||
Ray ray = Ray.pd(Vec3.xyz(0, 0, -2.6), Vec3.zp(1.6, p));
|
Ray ray = Ray.pd(Vec3.xyz(0, 0, -15), Vec3.zp(1.6, p));
|
||||||
return sample(ray);
|
return sample(ray);
|
||||||
}
|
}
|
||||||
|
// @Override
|
||||||
|
// public Color at(double t, Vector p) {
|
||||||
|
// Ray ray = Ray.pd(Vec3.xyz(0, 20, -20), Vec3.xyz(0, -1, 1).add(Vec3.xyz(p.x(), p.y(), p.y())));
|
||||||
|
// return sample(ray);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,11 @@ public class RayTracerSimple extends RayTracer {
|
||||||
|
|
||||||
for (Light light : scene.lights()) {
|
for (Light light : scene.lights()) {
|
||||||
Vec3 l = light.p().sub(p); // Vector from p to the light;
|
Vec3 l = light.p().sub(p); // Vector from p to the light;
|
||||||
|
Ray lRay = new Ray(light.p(), l.inverse()); // Project a Ray from light source to object
|
||||||
|
Hit lHit = scene.solid().firstHit(lRay);
|
||||||
|
double epsilon = 0.000001;
|
||||||
|
if (lRay.at(Hit.t(lHit)).sub(p).lengthSquared() >= epsilon)
|
||||||
|
continue; // if it strikes an object before our point, a shadow is cast, no light is added
|
||||||
double lLSqr = l.lengthSquared(); // Distance from p to the light squared
|
double lLSqr = l.lengthSquared(); // Distance from p to the light squared
|
||||||
double lL = Math.sqrt(lLSqr); // Distance from p to the light
|
double lL = Math.sqrt(lLSqr); // Distance from p to the light
|
||||||
double cosLN = n_.dot(l) / lL; // Cosine of the angle between l and n_
|
double cosLN = n_.dot(l) / lL; // Cosine of the angle between l and n_
|
||||||
|
|
101
src/xyz/marsavic/gfxlab/graphics3d/scene/Obamaborea.java
Normal file
101
src/xyz/marsavic/gfxlab/graphics3d/scene/Obamaborea.java
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package xyz.marsavic.gfxlab.graphics3d.scene;
|
||||||
|
|
||||||
|
import xyz.marsavic.gfxlab.Color;
|
||||||
|
import xyz.marsavic.gfxlab.Vec3;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Light;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Material;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Scene;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Solid;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.solids.Group;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.solids.HalfSpace;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.solids.Parallelepiped;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class Obamaborea extends Scene.Base {
|
||||||
|
BufferedImage obomba;
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
obomba = ImageIO.read(new File("resources/obomba.jpg"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Couldn't load Obomba, exiting");
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Obamaborea(int width, int floors) {
|
||||||
|
double pillarHeight = 5;
|
||||||
|
double pillarSpace = 5;
|
||||||
|
Solid floor = HalfSpace.pn(Vec3.xyz(0, -1, 0), Vec3.xyz(0, 0.1, 0),
|
||||||
|
uv -> Material.diffuseImage(obomba, uv)
|
||||||
|
);
|
||||||
|
Parallelepiped[][][] pillars = new Parallelepiped[floors][width][width];
|
||||||
|
|
||||||
|
for (int i = 0; i < floors; i++) {
|
||||||
|
for (int j = 0; j < width; j++) {
|
||||||
|
for (int k = 0; k < width; k++) {
|
||||||
|
pillars[i][j][k] =
|
||||||
|
Parallelepiped.cxyz(
|
||||||
|
Vec3.xyz((k+0.5-width/2.0)*pillarSpace,
|
||||||
|
(i*1.5)*pillarHeight,
|
||||||
|
(j+0.5-width/2.0)*pillarSpace),
|
||||||
|
1, pillarHeight, 1,
|
||||||
|
uv -> Material.diffuseImage(obomba, uv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Solid> objects = Arrays.stream(pillars).flatMap(Arrays::stream).flatMap(Arrays::stream)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
objects.add(floor);
|
||||||
|
solid = Group.of(objects);
|
||||||
|
|
||||||
|
// Light[][][] ls = new Light[floors+1][width+1][width+1];
|
||||||
|
//
|
||||||
|
// for (int i = 0; i < floors+1; i++) {
|
||||||
|
// for (int j = 0; j < width+1; j++) {
|
||||||
|
// for (int k = 0; k < width+1; k++) {
|
||||||
|
// ls[i][j][k] = Light.pc(Vec3.xyz(((double) k - width / 2.0) * pillarSpace,
|
||||||
|
// (i + 0.5) * pillarHeight,
|
||||||
|
// ((double) j - width / 2.0) * pillarSpace), Color.gray(10));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// Light [] lsFlat = Arrays.stream(ls).flatMap(Arrays::stream).flatMap(Arrays::stream).collect(Collectors.toList()).toArray(new Light[0]);
|
||||||
|
Collections.addAll(lights, Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
|
||||||
|
0.5*pillarHeight,
|
||||||
|
(-width/2.0) * pillarSpace), Color.gray(30)),
|
||||||
|
Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
|
||||||
|
0.5*pillarHeight,
|
||||||
|
(-width/2.0) * pillarSpace), Color.gray(30)),
|
||||||
|
Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
|
||||||
|
0.5*pillarHeight,
|
||||||
|
(width/2.0) * pillarSpace), Color.gray(30)),
|
||||||
|
Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
|
||||||
|
0.5*pillarHeight,
|
||||||
|
(width/2.0) * pillarSpace), Color.gray(30)),
|
||||||
|
Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
|
||||||
|
(width+0.5)*pillarHeight,
|
||||||
|
(-width/2.0) * pillarSpace), Color.gray(30)),
|
||||||
|
Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
|
||||||
|
(width+0.5)*pillarHeight,
|
||||||
|
(-width/2.0) * pillarSpace), Color.gray(30)),
|
||||||
|
Light.pc(Vec3.xyz((-width/2.0) * pillarSpace,
|
||||||
|
(width+0.5)*pillarHeight,
|
||||||
|
(width/2.0) * pillarSpace), Color.gray(30)),
|
||||||
|
Light.pc(Vec3.xyz((width/2.0) * pillarSpace,
|
||||||
|
(width+0.5)*pillarHeight,
|
||||||
|
(width/2.0) * pillarSpace), Color.gray(30))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,21 +9,33 @@ import xyz.marsavic.gfxlab.graphics3d.solids.Ball;
|
||||||
import xyz.marsavic.gfxlab.graphics3d.solids.Group;
|
import xyz.marsavic.gfxlab.graphics3d.solids.Group;
|
||||||
import xyz.marsavic.gfxlab.graphics3d.solids.HalfSpace;
|
import xyz.marsavic.gfxlab.graphics3d.solids.HalfSpace;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
|
||||||
public class SceneTest1 extends Scene.Base{
|
public class SceneTest1 extends Scene.Base{
|
||||||
|
BufferedImage obomba;
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
obomba = ImageIO.read(new File("resources/obomba.jpg"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Couldn't load Obomba, exiting");
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SceneTest1() {
|
public SceneTest1() {
|
||||||
solid = Group.of(
|
solid = Group.of(
|
||||||
Ball.cr(Vec3.xyz(0, 0, 0), 1,
|
Ball.cr(Vec3.xyz(0, 0, 0), 1,
|
||||||
uv -> new Material(Color.hsb(uv.x() * 6, 0.8, uv.y()))
|
uv -> Material.diffuseImage(obomba, uv)
|
||||||
),
|
),
|
||||||
HalfSpace.pn(Vec3.xyz(0, -1, 0), Vec3.xyz(0, 1, 0),
|
HalfSpace.pn(Vec3.xyz(0, -1, 0), Vec3.xyz(0, 1, 0),
|
||||||
uv -> new Material(Color.hsb(uv.x(), 0.8, 0.8))
|
uv -> Material.diffuseImage(obomba, uv)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Collections.addAll(lights,
|
Collections.addAll(lights,
|
||||||
Light.pc(Vec3.xyz(-1, 1, -1), Color.hsb(0.0, 1.0, 0.6)),
|
Light.pc(Vec3.xyz(-1, 1, -1), Color.hsb(0.0, 1.0, 0.6)),
|
||||||
Light.pc(Vec3.xyz( 2, 0, 0), Color.gray(0.6)),
|
Light.pc(Vec3.xyz( 2, 0, 0), Color.gray(0.6)),
|
||||||
|
|
107
src/xyz/marsavic/gfxlab/graphics3d/solids/Cylinder.java
Normal file
107
src/xyz/marsavic/gfxlab/graphics3d/solids/Cylinder.java
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
package xyz.marsavic.gfxlab.graphics3d.solids;
|
||||||
|
|
||||||
|
import xyz.marsavic.functions.interfaces.F1;
|
||||||
|
import xyz.marsavic.geometry.Vector;
|
||||||
|
import xyz.marsavic.gfxlab.Vec3;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Hit;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Material;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Ray;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Solid;
|
||||||
|
import xyz.marsavic.utils.Numeric;
|
||||||
|
|
||||||
|
public class Cylinder implements Solid {
|
||||||
|
|
||||||
|
private final Vec3 p;
|
||||||
|
private final double r;
|
||||||
|
private final Vec3 d; // directional vector, for a finite cylinder it also represents the height
|
||||||
|
private final F1<Material, Vector> mapMaterial;
|
||||||
|
|
||||||
|
// transient
|
||||||
|
private final double rSqr;
|
||||||
|
private final boolean finite;
|
||||||
|
|
||||||
|
|
||||||
|
private Cylinder(Vec3 p, double r, Vec3 d, F1<Material, Vector> mapMaterial, boolean finite) {
|
||||||
|
this.p = p;
|
||||||
|
this.r = r;
|
||||||
|
this.d = d;
|
||||||
|
rSqr = r * r;
|
||||||
|
this.mapMaterial = mapMaterial;
|
||||||
|
this.finite = finite;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Cylinder prdi(Vec3 p, double r, Vec3 d, F1<Material, Vector> mapMaterial) {
|
||||||
|
return new Cylinder(p, r, d, mapMaterial, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cylinder prd(Vec3 p, double r, Vec3 d, F1<Material, Vector> mapMaterial) {
|
||||||
|
return new Cylinder(p, r, d, mapMaterial, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Cylinder crd(Vec3 c, double r, Vec3 d, F1<Material, Vector> mapMaterial) {
|
||||||
|
return new Cylinder(c.sub(d.div(2)), r, d, mapMaterial, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 c() {
|
||||||
|
return p.add(d.div(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 p() { return p; }
|
||||||
|
public double r() {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
public Vec3 d() {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cylinder.HitCylinder firstHit(Ray ray, double afterTime) {
|
||||||
|
Vec3 e = c().sub(ray.p()); // Vector from the ray origin to the Cylinder start point
|
||||||
|
|
||||||
|
double dSqr = ray.d().lengthSquared();
|
||||||
|
double l = e.dot(ray.d()) / dSqr;
|
||||||
|
double mSqr = l * l - (e.lengthSquared() - rSqr) / dSqr;
|
||||||
|
|
||||||
|
if (mSqr > 0) {
|
||||||
|
double m = Math.sqrt(mSqr);
|
||||||
|
if (l - m > afterTime) return new Cylinder.HitCylinder(ray, l - m);
|
||||||
|
if (l + m > afterTime) return new Cylinder.HitCylinder(ray, l + m);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class HitCylinder extends Hit.RayT {
|
||||||
|
|
||||||
|
protected HitCylinder(Ray ray, double t) {
|
||||||
|
super(ray, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3 n() {
|
||||||
|
return ray().at(t()).sub(c());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Material material() {
|
||||||
|
return Cylinder.this.mapMaterial.at(uv());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector uv() {
|
||||||
|
Vec3 n = n();
|
||||||
|
return Vector.xy(
|
||||||
|
Numeric.atan2T(n.z(), n.x()),
|
||||||
|
-2 * Numeric.asinT(n.y() / r) + 0.5
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec3 n_() {
|
||||||
|
return n().div(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
129
src/xyz/marsavic/gfxlab/graphics3d/solids/Parallelepiped.java
Normal file
129
src/xyz/marsavic/gfxlab/graphics3d/solids/Parallelepiped.java
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
package xyz.marsavic.gfxlab.graphics3d.solids;
|
||||||
|
|
||||||
|
import xyz.marsavic.functions.interfaces.F1;
|
||||||
|
import xyz.marsavic.geometry.Vector;
|
||||||
|
import xyz.marsavic.gfxlab.Vec3;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Hit;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Material;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Ray;
|
||||||
|
import xyz.marsavic.gfxlab.graphics3d.Solid;
|
||||||
|
|
||||||
|
public class Parallelepiped implements Solid {
|
||||||
|
|
||||||
|
private final Vec3 p; // starting vertex
|
||||||
|
private final Vec3[][][] vertices;
|
||||||
|
HalfSpace [] sides;
|
||||||
|
private final F1<Material, Vector> mapMaterial;
|
||||||
|
|
||||||
|
private final Vec3 a, b, c;
|
||||||
|
|
||||||
|
private Parallelepiped(Vec3 point, Vec3 aEdge, Vec3 bEdge, Vec3 cEdge, F1<Material, Vector> mapMaterial) {
|
||||||
|
this.mapMaterial = mapMaterial;
|
||||||
|
|
||||||
|
this.p = point;
|
||||||
|
this.a = aEdge;
|
||||||
|
this.b = bEdge;
|
||||||
|
this.c = cEdge;
|
||||||
|
|
||||||
|
vertices = new Vec3[][][]
|
||||||
|
{{{p, p.add(c)}, {p.add(b), p.add(b).add(c)}},
|
||||||
|
{{p.add(a), p.add(a).add(c)}, {p.add(a).add(b), p.add(a).add(b).add(c)}}};
|
||||||
|
sides = new HalfSpace[6];
|
||||||
|
sides[0] = HalfSpace.pef(p, b, a, mapMaterial);
|
||||||
|
sides[1] = HalfSpace.pef(p.add(c), a, b, mapMaterial);
|
||||||
|
sides[2] = HalfSpace.pef(p, a, c, mapMaterial);
|
||||||
|
sides[3] = HalfSpace.pef(p.add(b), c, a, mapMaterial);
|
||||||
|
sides[4] = HalfSpace.pef(p, c, b, mapMaterial);
|
||||||
|
sides[5] = HalfSpace.pef(p.add(a), b, c, mapMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Parallelepiped pabc(Vec3 p, Vec3 a, Vec3 b, Vec3 c, F1<Material, Vector> mapMaterial) {
|
||||||
|
return new Parallelepiped(p, a, b, c, mapMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parallelepiped cabc(Vec3 center, Vec3 a, Vec3 b, Vec3 c, F1<Material, Vector> mapMaterial) {
|
||||||
|
return new Parallelepiped(center.sub(a.div(2)).sub(b.div(2)).sub(c.div(2)),
|
||||||
|
a, b, c, mapMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parallelepiped pxyz(Vec3 p, double x, double y, double z, F1<Material, Vector> mapMaterial) {
|
||||||
|
return new Parallelepiped(p,
|
||||||
|
Vec3.xyz(x, 0, 0), Vec3.xyz(0, y, 0), Vec3.xyz(0, 0, z),
|
||||||
|
mapMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parallelepiped cxyz(Vec3 center, double x, double y, double z, F1<Material, Vector> mapMaterial) {
|
||||||
|
return new Parallelepiped(center.sub(Vec3.xyz(x/2, y/2, z/2)),
|
||||||
|
Vec3.xyz(x, 0, 0), Vec3.xyz(0, y, 0), Vec3.xyz(0, 0, z),
|
||||||
|
mapMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 p() {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 center() { return p.add(a.div(2)).add(b.div(2)).add(c.div(2)); }
|
||||||
|
|
||||||
|
public Vec3 a() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 b() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3 c() {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3[][][] vertices() {
|
||||||
|
return vertices.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean pointOnParallelogram(Vec3 p, Vec3 e, Vec3 f) {
|
||||||
|
// we solve p as a linear combination of a*e+b*f, then check if this combination is in
|
||||||
|
// 0<=a<=1 and 0<=b<=1
|
||||||
|
double D = e.lengthSquared() * f.lengthSquared() - e.dot(f)*e.dot(f);
|
||||||
|
if (D == 0)
|
||||||
|
return false;
|
||||||
|
// System determinant
|
||||||
|
double Da = p.dot(e)*f.lengthSquared() - p.dot(f)*e.dot(f);
|
||||||
|
// a's determinant
|
||||||
|
double Db = e.lengthSquared()*p.dot(f) - e.dot(f)*p.dot(e);
|
||||||
|
double a = Da/D;
|
||||||
|
// a's determinant
|
||||||
|
double b = Db/D;
|
||||||
|
// b's determinant
|
||||||
|
return a >= 0 && a <= 1 && b >= 0 && b <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Hit firstHit(Ray ray, double afterTime) {
|
||||||
|
Hit[] planeHits = new Hit[6];
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
planeHits[i] = sides[i].firstHit(ray, afterTime);
|
||||||
|
if (planeHits[i] == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Vec3 rayPlaneIntersect = ray.at(planeHits[i].t());
|
||||||
|
if (!pointOnParallelogram(rayPlaneIntersect.sub(sides[i].p()), sides[i].e(), sides[i].f())) {
|
||||||
|
planeHits[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double minT = Hit.t(null); // Positive infinity
|
||||||
|
int minI = 0;
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
if (Hit.t(planeHits[i]) < minT) {
|
||||||
|
minT = Hit.t(planeHits[i]);
|
||||||
|
minI = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return planeHits[minI];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import xyz.marsavic.functions.interfaces.F1;
|
||||||
import xyz.marsavic.gfxlab.*;
|
import xyz.marsavic.gfxlab.*;
|
||||||
import xyz.marsavic.gfxlab.elements.Output;
|
import xyz.marsavic.gfxlab.elements.Output;
|
||||||
import xyz.marsavic.gfxlab.graphics3d.raytracers.RayTracerSimple;
|
import xyz.marsavic.gfxlab.graphics3d.raytracers.RayTracerSimple;
|
||||||
import xyz.marsavic.gfxlab.graphics3d.scene.SceneTest1;
|
import xyz.marsavic.gfxlab.graphics3d.scene.Obamaborea;
|
||||||
import xyz.marsavic.gfxlab.gui.UtilsGL;
|
import xyz.marsavic.gfxlab.gui.UtilsGL;
|
||||||
import xyz.marsavic.gfxlab.tonemapping.ColorTransform;
|
import xyz.marsavic.gfxlab.tonemapping.ColorTransform;
|
||||||
import xyz.marsavic.gfxlab.tonemapping.ToneMapping;
|
import xyz.marsavic.gfxlab.tonemapping.ToneMapping;
|
||||||
|
@ -30,7 +30,7 @@ public class GfxLab {
|
||||||
e(Fs::transformedColorFunction,
|
e(Fs::transformedColorFunction,
|
||||||
// e(Blobs::new, val(5), val(0.1), val(0.2)),
|
// e(Blobs::new, val(5), val(0.1), val(0.2)),
|
||||||
e(RayTracerSimple::new,
|
e(RayTracerSimple::new,
|
||||||
e(SceneTest1::new)
|
e(Obamaborea::new, val(3), val(3))
|
||||||
),
|
),
|
||||||
e(TransformationsFromSize.toGeometric, eSize)
|
e(TransformationsFromSize.toGeometric, eSize)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue