joonsrenderer 1.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +53 -0
- data/.mvn/extensions.xml +8 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +6 -0
- data/LICENSE +674 -0
- data/README.md +2 -0
- data/Rakefile +43 -0
- data/docs/.gitignore +6 -0
- data/docs/_config.yml +20 -0
- data/docs/_includes/footer.html +38 -0
- data/docs/_includes/head.html +15 -0
- data/docs/_includes/header.html +27 -0
- data/docs/_includes/icon-github.html +1 -0
- data/docs/_includes/icon-github.svg +1 -0
- data/docs/_includes/icon-twitter.html +1 -0
- data/docs/_includes/icon-twitter.svg +1 -0
- data/docs/_layouts/default.html +20 -0
- data/docs/_layouts/page.html +14 -0
- data/docs/_layouts/post.html +15 -0
- data/docs/_posts/2017-01-08-animated_ray_tracing.md +72 -0
- data/docs/_posts/2017-01-08-welcome.md +78 -0
- data/docs/_sass/_base.scss +206 -0
- data/docs/_sass/_layout.scss +242 -0
- data/docs/_sass/_syntax-highlighting.scss +71 -0
- data/docs/about.md +12 -0
- data/docs/assets/Animation.ogv +0 -0
- data/docs/assets/Animation.png +0 -0
- data/docs/assets/basic.png +0 -0
- data/docs/assets/basic_traced.png +0 -0
- data/docs/css/main.scss +38 -0
- data/docs/favicon.ico +0 -0
- data/docs/feed.xml +30 -0
- data/docs/index.html +38 -0
- data/joonsrenderer.gemspec +23 -0
- data/lib/joonsrenderer.rb +12 -0
- data/lib/joonsrenderer/version.rb +3 -0
- data/pom.rb +75 -0
- data/pom.xml +163 -0
- data/src/main/java/SunflowGUI.java +1354 -0
- data/src/main/java/joons/JRFiller.java +79 -0
- data/src/main/java/joons/JRImagePanel.java +141 -0
- data/src/main/java/joons/JRRecorder.java +183 -0
- data/src/main/java/joons/JRStatics.java +199 -0
- data/src/main/java/joons/JoonsRenderer.java +837 -0
- data/src/main/java/org/sunflow/AsciiFileSunflowAPI.java +98 -0
- data/src/main/java/org/sunflow/Benchmark.java +313 -0
- data/src/main/java/org/sunflow/BinaryFileSunflowAPI.java +228 -0
- data/src/main/java/org/sunflow/FileSunflowAPI.java +354 -0
- data/src/main/java/org/sunflow/PluginRegistry.java +322 -0
- data/src/main/java/org/sunflow/RealtimeBenchmark.java +125 -0
- data/src/main/java/org/sunflow/RenderObjectMap.java +344 -0
- data/src/main/java/org/sunflow/SunflowAPI.java +762 -0
- data/src/main/java/org/sunflow/SunflowAPIInterface.java +277 -0
- data/src/main/java/org/sunflow/core/AccelerationStructure.java +20 -0
- data/src/main/java/org/sunflow/core/AccelerationStructureFactory.java +36 -0
- data/src/main/java/org/sunflow/core/BucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/Camera.java +125 -0
- data/src/main/java/org/sunflow/core/CameraLens.java +29 -0
- data/src/main/java/org/sunflow/core/CausticPhotonMapInterface.java +15 -0
- data/src/main/java/org/sunflow/core/Display.java +78 -0
- data/src/main/java/org/sunflow/core/Filter.java +27 -0
- data/src/main/java/org/sunflow/core/GIEngine.java +42 -0
- data/src/main/java/org/sunflow/core/Geometry.java +157 -0
- data/src/main/java/org/sunflow/core/GlobalPhotonMapInterface.java +21 -0
- data/src/main/java/org/sunflow/core/ImageSampler.java +26 -0
- data/src/main/java/org/sunflow/core/Instance.java +224 -0
- data/src/main/java/org/sunflow/core/InstanceList.java +83 -0
- data/src/main/java/org/sunflow/core/IntersectionState.java +120 -0
- data/src/main/java/org/sunflow/core/LightSample.java +104 -0
- data/src/main/java/org/sunflow/core/LightServer.java +382 -0
- data/src/main/java/org/sunflow/core/LightSource.java +67 -0
- data/src/main/java/org/sunflow/core/Modifier.java +16 -0
- data/src/main/java/org/sunflow/core/Options.java +20 -0
- data/src/main/java/org/sunflow/core/ParameterList.java +758 -0
- data/src/main/java/org/sunflow/core/PhotonStore.java +62 -0
- data/src/main/java/org/sunflow/core/PrimitiveList.java +70 -0
- data/src/main/java/org/sunflow/core/Ray.java +219 -0
- data/src/main/java/org/sunflow/core/RenderObject.java +25 -0
- data/src/main/java/org/sunflow/core/Scene.java +377 -0
- data/src/main/java/org/sunflow/core/SceneParser.java +58 -0
- data/src/main/java/org/sunflow/core/Shader.java +30 -0
- data/src/main/java/org/sunflow/core/ShadingCache.java +84 -0
- data/src/main/java/org/sunflow/core/ShadingState.java +939 -0
- data/src/main/java/org/sunflow/core/Statistics.java +85 -0
- data/src/main/java/org/sunflow/core/Tesselatable.java +36 -0
- data/src/main/java/org/sunflow/core/Texture.java +128 -0
- data/src/main/java/org/sunflow/core/TextureCache.java +48 -0
- data/src/main/java/org/sunflow/core/accel/BoundingIntervalHierarchy.java +652 -0
- data/src/main/java/org/sunflow/core/accel/KDTree.java +833 -0
- data/src/main/java/org/sunflow/core/accel/NullAccelerator.java +30 -0
- data/src/main/java/org/sunflow/core/accel/UniformGrid.java +329 -0
- data/src/main/java/org/sunflow/core/bucket/BucketOrderFactory.java +26 -0
- data/src/main/java/org/sunflow/core/bucket/ColumnBucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/bucket/DiagonalBucketOrder.java +28 -0
- data/src/main/java/org/sunflow/core/bucket/HilbertBucketOrder.java +65 -0
- data/src/main/java/org/sunflow/core/bucket/InvertedBucketOrder.java +28 -0
- data/src/main/java/org/sunflow/core/bucket/RandomBucketOrder.java +49 -0
- data/src/main/java/org/sunflow/core/bucket/RowBucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/bucket/SpiralBucketOrder.java +43 -0
- data/src/main/java/org/sunflow/core/camera/FisheyeLens.java +25 -0
- data/src/main/java/org/sunflow/core/camera/PinholeLens.java +43 -0
- data/src/main/java/org/sunflow/core/camera/SphericalLens.java +22 -0
- data/src/main/java/org/sunflow/core/camera/ThinLens.java +107 -0
- data/src/main/java/org/sunflow/core/display/FastDisplay.java +119 -0
- data/src/main/java/org/sunflow/core/display/FileDisplay.java +83 -0
- data/src/main/java/org/sunflow/core/display/FrameDisplay.java +97 -0
- data/src/main/java/org/sunflow/core/display/ImgPipeDisplay.java +109 -0
- data/src/main/java/org/sunflow/core/filter/BlackmanHarrisFilter.java +28 -0
- data/src/main/java/org/sunflow/core/filter/BoxFilter.java +16 -0
- data/src/main/java/org/sunflow/core/filter/CatmullRomFilter.java +29 -0
- data/src/main/java/org/sunflow/core/filter/CubicBSpline.java +32 -0
- data/src/main/java/org/sunflow/core/filter/GaussianFilter.java +24 -0
- data/src/main/java/org/sunflow/core/filter/LanczosFilter.java +30 -0
- data/src/main/java/org/sunflow/core/filter/MitchellFilter.java +28 -0
- data/src/main/java/org/sunflow/core/filter/SincFilter.java +25 -0
- data/src/main/java/org/sunflow/core/filter/TriangleFilter.java +16 -0
- data/src/main/java/org/sunflow/core/gi/AmbientOcclusionGIEngine.java +57 -0
- data/src/main/java/org/sunflow/core/gi/FakeGIEngine.java +48 -0
- data/src/main/java/org/sunflow/core/gi/InstantGI.java +194 -0
- data/src/main/java/org/sunflow/core/gi/IrradianceCacheGIEngine.java +268 -0
- data/src/main/java/org/sunflow/core/gi/PathTracingGIEngine.java +65 -0
- data/src/main/java/org/sunflow/core/light/DirectionalSpotlight.java +103 -0
- data/src/main/java/org/sunflow/core/light/ImageBasedLight.java +303 -0
- data/src/main/java/org/sunflow/core/light/PointLight.java +72 -0
- data/src/main/java/org/sunflow/core/light/SphereLight.java +166 -0
- data/src/main/java/org/sunflow/core/light/SunSkyLight.java +362 -0
- data/src/main/java/org/sunflow/core/light/TriangleMeshLight.java +296 -0
- data/src/main/java/org/sunflow/core/modifiers/BumpMappingModifier.java +37 -0
- data/src/main/java/org/sunflow/core/modifiers/NormalMapModifier.java +34 -0
- data/src/main/java/org/sunflow/core/modifiers/PerlinModifier.java +80 -0
- data/src/main/java/org/sunflow/core/parser/Keyword.java +39 -0
- data/src/main/java/org/sunflow/core/parser/RA2Parser.java +107 -0
- data/src/main/java/org/sunflow/core/parser/RA3Parser.java +68 -0
- data/src/main/java/org/sunflow/core/parser/SCAbstractParser.java +299 -0
- data/src/main/java/org/sunflow/core/parser/SCAsciiParser.java +251 -0
- data/src/main/java/org/sunflow/core/parser/SCBinaryParser.java +156 -0
- data/src/main/java/org/sunflow/core/parser/SCParser.java +1403 -0
- data/src/main/java/org/sunflow/core/parser/ShaveRibParser.java +174 -0
- data/src/main/java/org/sunflow/core/parser/TriParser.java +79 -0
- data/src/main/java/org/sunflow/core/photonmap/CausticPhotonMap.java +429 -0
- data/src/main/java/org/sunflow/core/photonmap/GlobalPhotonMap.java +530 -0
- data/src/main/java/org/sunflow/core/photonmap/GridPhotonMap.java +308 -0
- data/src/main/java/org/sunflow/core/primitive/Background.java +55 -0
- data/src/main/java/org/sunflow/core/primitive/BanchoffSurface.java +100 -0
- data/src/main/java/org/sunflow/core/primitive/Box.java +210 -0
- data/src/main/java/org/sunflow/core/primitive/CornellBox.java +476 -0
- data/src/main/java/org/sunflow/core/primitive/CubeGrid.java +318 -0
- data/src/main/java/org/sunflow/core/primitive/Cylinder.java +104 -0
- data/src/main/java/org/sunflow/core/primitive/Hair.java +275 -0
- data/src/main/java/org/sunflow/core/primitive/JuliaFractal.java +266 -0
- data/src/main/java/org/sunflow/core/primitive/ParticleSurface.java +114 -0
- data/src/main/java/org/sunflow/core/primitive/Plane.java +163 -0
- data/src/main/java/org/sunflow/core/primitive/QuadMesh.java +413 -0
- data/src/main/java/org/sunflow/core/primitive/Sphere.java +101 -0
- data/src/main/java/org/sunflow/core/primitive/SphereFlake.java +234 -0
- data/src/main/java/org/sunflow/core/primitive/Torus.java +145 -0
- data/src/main/java/org/sunflow/core/primitive/TriangleMesh.java +849 -0
- data/src/main/java/org/sunflow/core/renderer/BucketRenderer.java +491 -0
- data/src/main/java/org/sunflow/core/renderer/MultipassRenderer.java +237 -0
- data/src/main/java/org/sunflow/core/renderer/ProgressiveRenderer.java +171 -0
- data/src/main/java/org/sunflow/core/renderer/SimpleRenderer.java +106 -0
- data/src/main/java/org/sunflow/core/shader/AmbientOcclusionShader.java +53 -0
- data/src/main/java/org/sunflow/core/shader/AnisotropicWardShader.java +216 -0
- data/src/main/java/org/sunflow/core/shader/ConstantShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/DiffuseShader.java +65 -0
- data/src/main/java/org/sunflow/core/shader/GlassShader.java +147 -0
- data/src/main/java/org/sunflow/core/shader/IDShader.java +27 -0
- data/src/main/java/org/sunflow/core/shader/MirrorShader.java +68 -0
- data/src/main/java/org/sunflow/core/shader/NormalShader.java +32 -0
- data/src/main/java/org/sunflow/core/shader/PhongShader.java +89 -0
- data/src/main/java/org/sunflow/core/shader/PrimIDShader.java +30 -0
- data/src/main/java/org/sunflow/core/shader/QuickGrayShader.java +63 -0
- data/src/main/java/org/sunflow/core/shader/ShinyDiffuseShader.java +98 -0
- data/src/main/java/org/sunflow/core/shader/SimpleShader.java +24 -0
- data/src/main/java/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedDiffuseShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedPhongShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedShinyDiffuseShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedWardShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/UVShader.java +27 -0
- data/src/main/java/org/sunflow/core/shader/UberShader.java +149 -0
- data/src/main/java/org/sunflow/core/shader/ViewCausticsShader.java +33 -0
- data/src/main/java/org/sunflow/core/shader/ViewGlobalPhotonsShader.java +25 -0
- data/src/main/java/org/sunflow/core/shader/ViewIrradianceShader.java +25 -0
- data/src/main/java/org/sunflow/core/shader/WireframeShader.java +83 -0
- data/src/main/java/org/sunflow/core/tesselatable/BezierMesh.java +254 -0
- data/src/main/java/org/sunflow/core/tesselatable/FileMesh.java +251 -0
- data/src/main/java/org/sunflow/core/tesselatable/Gumbo.java +1147 -0
- data/src/main/java/org/sunflow/core/tesselatable/Teapot.java +237 -0
- data/src/main/java/org/sunflow/image/Bitmap.java +15 -0
- data/src/main/java/org/sunflow/image/BitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/BitmapWriter.java +79 -0
- data/src/main/java/org/sunflow/image/BlackbodySpectrum.java +16 -0
- data/src/main/java/org/sunflow/image/ChromaticitySpectrum.java +55 -0
- data/src/main/java/org/sunflow/image/Color.java +374 -0
- data/src/main/java/org/sunflow/image/ColorEncoder.java +94 -0
- data/src/main/java/org/sunflow/image/ColorFactory.java +122 -0
- data/src/main/java/org/sunflow/image/ConstantSpectralCurve.java +21 -0
- data/src/main/java/org/sunflow/image/IrregularSpectralCurve.java +57 -0
- data/src/main/java/org/sunflow/image/RGBSpace.java +207 -0
- data/src/main/java/org/sunflow/image/RegularSpectralCurve.java +30 -0
- data/src/main/java/org/sunflow/image/SpectralCurve.java +118 -0
- data/src/main/java/org/sunflow/image/XYZColor.java +50 -0
- data/src/main/java/org/sunflow/image/formats/BitmapBlack.java +27 -0
- data/src/main/java/org/sunflow/image/formats/BitmapG8.java +36 -0
- data/src/main/java/org/sunflow/image/formats/BitmapGA8.java +30 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGB8.java +40 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGBA8.java +40 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGBE.java +60 -0
- data/src/main/java/org/sunflow/image/formats/BitmapXYZ.java +38 -0
- data/src/main/java/org/sunflow/image/formats/GenericBitmap.java +73 -0
- data/src/main/java/org/sunflow/image/readers/BMPBitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/readers/HDRBitmapReader.java +155 -0
- data/src/main/java/org/sunflow/image/readers/IGIBitmapReader.java +104 -0
- data/src/main/java/org/sunflow/image/readers/JPGBitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/readers/PNGBitmapReader.java +40 -0
- data/src/main/java/org/sunflow/image/readers/TGABitmapReader.java +141 -0
- data/src/main/java/org/sunflow/image/writers/EXRBitmapWriter.java +395 -0
- data/src/main/java/org/sunflow/image/writers/HDRBitmapWriter.java +54 -0
- data/src/main/java/org/sunflow/image/writers/IGIBitmapWriter.java +75 -0
- data/src/main/java/org/sunflow/image/writers/PNGBitmapWriter.java +39 -0
- data/src/main/java/org/sunflow/image/writers/TGABitmapWriter.java +63 -0
- data/src/main/java/org/sunflow/math/BoundingBox.java +340 -0
- data/src/main/java/org/sunflow/math/MathUtils.java +159 -0
- data/src/main/java/org/sunflow/math/Matrix4.java +573 -0
- data/src/main/java/org/sunflow/math/MovingMatrix4.java +119 -0
- data/src/main/java/org/sunflow/math/OrthoNormalBasis.java +110 -0
- data/src/main/java/org/sunflow/math/PerlinScalar.java +331 -0
- data/src/main/java/org/sunflow/math/PerlinVector.java +132 -0
- data/src/main/java/org/sunflow/math/Point2.java +36 -0
- data/src/main/java/org/sunflow/math/Point3.java +133 -0
- data/src/main/java/org/sunflow/math/QMC.java +209 -0
- data/src/main/java/org/sunflow/math/Solvers.java +142 -0
- data/src/main/java/org/sunflow/math/Vector3.java +197 -0
- data/src/main/java/org/sunflow/system/BenchmarkFramework.java +73 -0
- data/src/main/java/org/sunflow/system/BenchmarkTest.java +17 -0
- data/src/main/java/org/sunflow/system/ByteUtil.java +119 -0
- data/src/main/java/org/sunflow/system/FileUtils.java +27 -0
- data/src/main/java/org/sunflow/system/ImagePanel.java +282 -0
- data/src/main/java/org/sunflow/system/Memory.java +18 -0
- data/src/main/java/org/sunflow/system/Parser.java +162 -0
- data/src/main/java/org/sunflow/system/Plugins.java +142 -0
- data/src/main/java/org/sunflow/system/RenderGlobalsPanel.java +209 -0
- data/src/main/java/org/sunflow/system/SearchPath.java +67 -0
- data/src/main/java/org/sunflow/system/Timer.java +53 -0
- data/src/main/java/org/sunflow/system/UI.java +112 -0
- data/src/main/java/org/sunflow/system/UserInterface.java +46 -0
- data/src/main/java/org/sunflow/system/ui/ConsoleInterface.java +48 -0
- data/src/main/java/org/sunflow/system/ui/SilentInterface.java +28 -0
- data/src/main/java/org/sunflow/util/FastHashMap.java +220 -0
- data/src/main/java/org/sunflow/util/FloatArray.java +77 -0
- data/src/main/java/org/sunflow/util/IntArray.java +77 -0
- data/src/test/java/a_maintest.java +129 -0
- metadata +300 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
package org.sunflow.core.photonmap;
|
|
2
|
+
|
|
3
|
+
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
4
|
+
|
|
5
|
+
import org.sunflow.core.GlobalPhotonMapInterface;
|
|
6
|
+
import org.sunflow.core.Options;
|
|
7
|
+
import org.sunflow.core.ShadingState;
|
|
8
|
+
import org.sunflow.image.Color;
|
|
9
|
+
import org.sunflow.math.BoundingBox;
|
|
10
|
+
import org.sunflow.math.MathUtils;
|
|
11
|
+
import org.sunflow.math.Point3;
|
|
12
|
+
import org.sunflow.math.Vector3;
|
|
13
|
+
import org.sunflow.system.UI;
|
|
14
|
+
import org.sunflow.system.UI.Module;
|
|
15
|
+
|
|
16
|
+
public class GridPhotonMap implements GlobalPhotonMapInterface {
|
|
17
|
+
|
|
18
|
+
private int numGather;
|
|
19
|
+
private float gatherRadius;
|
|
20
|
+
private int numStoredPhotons;
|
|
21
|
+
private int nx, ny, nz;
|
|
22
|
+
private BoundingBox bounds;
|
|
23
|
+
private PhotonGroup[] cellHash;
|
|
24
|
+
private int hashSize;
|
|
25
|
+
private int hashPrime;
|
|
26
|
+
private final ReentrantReadWriteLock rwl;
|
|
27
|
+
private int numEmit;
|
|
28
|
+
private static final float NORMAL_THRESHOLD = (float) Math.cos(10.0 * Math.PI / 180.0);
|
|
29
|
+
private static final int[] PRIMES = {11, 19, 37, 109, 163, 251, 367, 557,
|
|
30
|
+
823, 1237, 1861, 2777, 4177, 6247, 9371, 21089, 31627, 47431,
|
|
31
|
+
71143, 106721, 160073, 240101, 360163, 540217, 810343, 1215497,
|
|
32
|
+
1823231, 2734867, 4102283, 6153409, 9230113, 13845163};
|
|
33
|
+
|
|
34
|
+
public GridPhotonMap() {
|
|
35
|
+
numStoredPhotons = 0;
|
|
36
|
+
hashSize = 0; // number of unique IDs in the hash
|
|
37
|
+
rwl = new ReentrantReadWriteLock();
|
|
38
|
+
numEmit = 100000;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@Override
|
|
42
|
+
public void prepare(Options options, BoundingBox sceneBounds) {
|
|
43
|
+
// get settings
|
|
44
|
+
numEmit = options.getInt("gi.irr-cache.gmap.emit", 100000);
|
|
45
|
+
numGather = options.getInt("gi.irr-cache.gmap.gather", 50);
|
|
46
|
+
gatherRadius = options.getFloat("gi.irr-cache.gmap.radius", 0.5f);
|
|
47
|
+
|
|
48
|
+
bounds = new BoundingBox(sceneBounds);
|
|
49
|
+
bounds.enlargeUlps();
|
|
50
|
+
Vector3 w = bounds.getExtents();
|
|
51
|
+
nx = (int) Math.max(((w.x / gatherRadius) + 0.5f), 1);
|
|
52
|
+
ny = (int) Math.max(((w.y / gatherRadius) + 0.5f), 1);
|
|
53
|
+
nz = (int) Math.max(((w.z / gatherRadius) + 0.5f), 1);
|
|
54
|
+
int numCells = nx * ny * nz;
|
|
55
|
+
UI.printInfo(Module.LIGHT, "Initializing grid photon map:");
|
|
56
|
+
UI.printInfo(Module.LIGHT, " * Resolution: %dx%dx%d", nx, ny, nz);
|
|
57
|
+
UI.printInfo(Module.LIGHT, " * Total cells: %d", numCells);
|
|
58
|
+
for (hashPrime = 0; hashPrime < PRIMES.length; hashPrime++) {
|
|
59
|
+
if (PRIMES[hashPrime] > (numCells / 5)) {
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
cellHash = new PhotonGroup[PRIMES[hashPrime]];
|
|
64
|
+
UI.printInfo(Module.LIGHT, " * Initial hash size: %d", cellHash.length);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public int size() {
|
|
68
|
+
return numStoredPhotons;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@Override
|
|
72
|
+
public void store(ShadingState state, Vector3 dir, Color power, Color diffuse) {
|
|
73
|
+
// don't store on the wrong side of a surface
|
|
74
|
+
if (Vector3.dot(state.getNormal(), dir) > 0) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
Point3 pt = state.getPoint();
|
|
78
|
+
// outside grid bounds ?
|
|
79
|
+
if (!bounds.contains(pt)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
Vector3 ext = bounds.getExtents();
|
|
83
|
+
int ix = (int) (((pt.x - bounds.getMinimum().x) * nx) / ext.x);
|
|
84
|
+
int iy = (int) (((pt.y - bounds.getMinimum().y) * ny) / ext.y);
|
|
85
|
+
int iz = (int) (((pt.z - bounds.getMinimum().z) * nz) / ext.z);
|
|
86
|
+
ix = MathUtils.clamp(ix, 0, nx - 1);
|
|
87
|
+
iy = MathUtils.clamp(iy, 0, ny - 1);
|
|
88
|
+
iz = MathUtils.clamp(iz, 0, nz - 1);
|
|
89
|
+
int id = ix + iy * nx + iz * nx * ny;
|
|
90
|
+
synchronized (this) {
|
|
91
|
+
int hid = id % cellHash.length;
|
|
92
|
+
PhotonGroup g = cellHash[hid];
|
|
93
|
+
PhotonGroup last = null;
|
|
94
|
+
boolean hasID = false;
|
|
95
|
+
while (g != null) {
|
|
96
|
+
if (g.id == id) {
|
|
97
|
+
hasID = true;
|
|
98
|
+
if (Vector3.dot(state.getNormal(), g.normal) > NORMAL_THRESHOLD) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
last = g;
|
|
103
|
+
g = g.next;
|
|
104
|
+
}
|
|
105
|
+
if (g == null) {
|
|
106
|
+
g = new PhotonGroup(id, state.getNormal());
|
|
107
|
+
if (last == null) {
|
|
108
|
+
cellHash[hid] = g;
|
|
109
|
+
} else {
|
|
110
|
+
last.next = g;
|
|
111
|
+
}
|
|
112
|
+
if (!hasID) {
|
|
113
|
+
hashSize++; // we have not seen this ID before
|
|
114
|
+
// resize hash if we have grown too large
|
|
115
|
+
if (hashSize > cellHash.length) {
|
|
116
|
+
growPhotonHash();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
g.count++;
|
|
121
|
+
g.flux.add(power);
|
|
122
|
+
g.diffuse.add(diffuse);
|
|
123
|
+
numStoredPhotons++;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@Override
|
|
128
|
+
public void init() {
|
|
129
|
+
UI.printInfo(Module.LIGHT, "Initializing photon grid ...");
|
|
130
|
+
UI.printInfo(Module.LIGHT, " * Photon hits: %d", numStoredPhotons);
|
|
131
|
+
UI.printInfo(Module.LIGHT, " * Final hash size: %d", cellHash.length);
|
|
132
|
+
int cells = 0;
|
|
133
|
+
for (PhotonGroup cellHash1 : cellHash) {
|
|
134
|
+
for (PhotonGroup g = cellHash1; g != null; g = g.next) {
|
|
135
|
+
g.diffuse.mul(1.0f / g.count);
|
|
136
|
+
cells++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
UI.printInfo(Module.LIGHT, " * Num photon cells: %d", cells);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public void precomputeRadiance(boolean includeDirect, boolean includeCaustics) {
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private void growPhotonHash() {
|
|
146
|
+
// enlarge the hash size:
|
|
147
|
+
if (hashPrime >= PRIMES.length - 1) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
PhotonGroup[] temp = new PhotonGroup[PRIMES[++hashPrime]];
|
|
151
|
+
for (PhotonGroup g : cellHash) {
|
|
152
|
+
while (g != null) {
|
|
153
|
+
// re-hash into the new table
|
|
154
|
+
int hid = g.id % temp.length;
|
|
155
|
+
PhotonGroup last = null;
|
|
156
|
+
for (PhotonGroup gn = temp[hid]; gn != null; gn = gn.next) {
|
|
157
|
+
last = gn;
|
|
158
|
+
}
|
|
159
|
+
if (last == null) {
|
|
160
|
+
temp[hid] = g;
|
|
161
|
+
} else {
|
|
162
|
+
last.next = g;
|
|
163
|
+
}
|
|
164
|
+
PhotonGroup next = g.next;
|
|
165
|
+
g.next = null;
|
|
166
|
+
g = next;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
cellHash = temp;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@Override
|
|
173
|
+
public synchronized Color getRadiance(Point3 p, Vector3 n) {
|
|
174
|
+
if (!bounds.contains(p)) {
|
|
175
|
+
return Color.BLACK;
|
|
176
|
+
}
|
|
177
|
+
Vector3 ext = bounds.getExtents();
|
|
178
|
+
int ix = (int) (((p.x - bounds.getMinimum().x) * nx) / ext.x);
|
|
179
|
+
int iy = (int) (((p.y - bounds.getMinimum().y) * ny) / ext.y);
|
|
180
|
+
int iz = (int) (((p.z - bounds.getMinimum().z) * nz) / ext.z);
|
|
181
|
+
ix = MathUtils.clamp(ix, 0, nx - 1);
|
|
182
|
+
iy = MathUtils.clamp(iy, 0, ny - 1);
|
|
183
|
+
iz = MathUtils.clamp(iz, 0, nz - 1);
|
|
184
|
+
int id = ix + iy * nx + iz * nx * ny;
|
|
185
|
+
rwl.readLock().lock();
|
|
186
|
+
PhotonGroup center = null;
|
|
187
|
+
for (PhotonGroup g = get(ix, iy, iz); g != null; g = g.next) {
|
|
188
|
+
if (g.id == id && Vector3.dot(n, g.normal) > NORMAL_THRESHOLD) {
|
|
189
|
+
if (g.radiance == null) {
|
|
190
|
+
center = g;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
Color r = g.radiance.copy();
|
|
194
|
+
rwl.readLock().unlock();
|
|
195
|
+
return r;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
int vol = 1;
|
|
199
|
+
while (true) {
|
|
200
|
+
int numPhotons = 0;
|
|
201
|
+
int ndiff = 0;
|
|
202
|
+
Color irr = Color.black();
|
|
203
|
+
Color diff = (center == null) ? Color.black() : null;
|
|
204
|
+
for (int z = iz - (vol - 1); z <= iz + (vol - 1); z++) {
|
|
205
|
+
for (int y = iy - (vol - 1); y <= iy + (vol - 1); y++) {
|
|
206
|
+
for (int x = ix - (vol - 1); x <= ix + (vol - 1); x++) {
|
|
207
|
+
int vid = x + y * nx + z * nx * ny;
|
|
208
|
+
for (PhotonGroup g = get(x, y, z); g != null; g = g.next) {
|
|
209
|
+
if (g.id == vid && Vector3.dot(n, g.normal) > NORMAL_THRESHOLD) {
|
|
210
|
+
numPhotons += g.count;
|
|
211
|
+
irr.add(g.flux);
|
|
212
|
+
if (diff != null) {
|
|
213
|
+
diff.add(g.diffuse);
|
|
214
|
+
ndiff++;
|
|
215
|
+
}
|
|
216
|
+
break; // only one valid group can be found,
|
|
217
|
+
// skip the others
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (numPhotons >= numGather || vol >= 3) {
|
|
224
|
+
// we have found enough photons
|
|
225
|
+
// cache irradiance and return
|
|
226
|
+
float area = (2 * vol - 1) / 3.0f * ((ext.x / nx) + (ext.y / ny) + (ext.z / nz));
|
|
227
|
+
area *= area;
|
|
228
|
+
area *= Math.PI;
|
|
229
|
+
irr.mul(1.0f / area);
|
|
230
|
+
// upgrade lock manually
|
|
231
|
+
rwl.readLock().unlock();
|
|
232
|
+
rwl.writeLock().lock();
|
|
233
|
+
try {
|
|
234
|
+
if (center == null) {
|
|
235
|
+
if (ndiff > 0) {
|
|
236
|
+
diff.mul(1.0f / ndiff);
|
|
237
|
+
}
|
|
238
|
+
center = new PhotonGroup(id, n);
|
|
239
|
+
center.diffuse.set(diff);
|
|
240
|
+
center.next = cellHash[id % cellHash.length];
|
|
241
|
+
cellHash[id % cellHash.length] = center;
|
|
242
|
+
}
|
|
243
|
+
irr.mul(center.diffuse);
|
|
244
|
+
center.radiance = irr.copy();
|
|
245
|
+
} finally {
|
|
246
|
+
rwl.writeLock().unlock();
|
|
247
|
+
}
|
|
248
|
+
return irr;
|
|
249
|
+
}
|
|
250
|
+
vol++;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private PhotonGroup get(int x, int y, int z) {
|
|
255
|
+
// returns the list associated with the specified location
|
|
256
|
+
if (x < 0 || x >= nx) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
if (y < 0 || y >= ny) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
if (z < 0 || z >= nz) {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
return cellHash[(x + y * nx + z * nx * ny) % cellHash.length];
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private class PhotonGroup {
|
|
269
|
+
|
|
270
|
+
int id;
|
|
271
|
+
int count;
|
|
272
|
+
Vector3 normal;
|
|
273
|
+
Color flux;
|
|
274
|
+
Color radiance;
|
|
275
|
+
Color diffuse;
|
|
276
|
+
PhotonGroup next;
|
|
277
|
+
|
|
278
|
+
PhotonGroup(int id, Vector3 n) {
|
|
279
|
+
normal = new Vector3(n);
|
|
280
|
+
flux = Color.black();
|
|
281
|
+
diffuse = Color.black();
|
|
282
|
+
radiance = null;
|
|
283
|
+
count = 0;
|
|
284
|
+
this.id = id;
|
|
285
|
+
next = null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@Override
|
|
290
|
+
public boolean allowDiffuseBounced() {
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@Override
|
|
295
|
+
public boolean allowReflectionBounced() {
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
@Override
|
|
300
|
+
public boolean allowRefractionBounced() {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
@Override
|
|
305
|
+
public int numEmit() {
|
|
306
|
+
return numEmit;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
package org.sunflow.core.primitive;
|
|
2
|
+
|
|
3
|
+
import org.sunflow.SunflowAPI;
|
|
4
|
+
import org.sunflow.core.IntersectionState;
|
|
5
|
+
import org.sunflow.core.ParameterList;
|
|
6
|
+
import org.sunflow.core.PrimitiveList;
|
|
7
|
+
import org.sunflow.core.Ray;
|
|
8
|
+
import org.sunflow.core.ShadingState;
|
|
9
|
+
import org.sunflow.math.BoundingBox;
|
|
10
|
+
import org.sunflow.math.Matrix4;
|
|
11
|
+
|
|
12
|
+
public class Background implements PrimitiveList {
|
|
13
|
+
|
|
14
|
+
public Background() {
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@Override
|
|
18
|
+
public boolean update(ParameterList pl, SunflowAPI api) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Override
|
|
23
|
+
public void prepareShadingState(ShadingState state) {
|
|
24
|
+
if (state.getDepth() == 0) {
|
|
25
|
+
state.setShader(state.getInstance().getShader(0));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
public int getNumPrimitives() {
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@Override
|
|
35
|
+
public float getPrimitiveBound(int primID, int i) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Override
|
|
40
|
+
public BoundingBox getWorldBounds(Matrix4 o2w) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Override
|
|
45
|
+
public void intersectPrimitive(Ray r, int primID, IntersectionState state) {
|
|
46
|
+
if (r.getMax() == Float.POSITIVE_INFINITY) {
|
|
47
|
+
state.setIntersection(0);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@Override
|
|
52
|
+
public PrimitiveList getBakingPrimitives() {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
package org.sunflow.core.primitive;
|
|
2
|
+
|
|
3
|
+
import org.sunflow.SunflowAPI;
|
|
4
|
+
import org.sunflow.core.Instance;
|
|
5
|
+
import org.sunflow.core.IntersectionState;
|
|
6
|
+
import org.sunflow.core.ParameterList;
|
|
7
|
+
import org.sunflow.core.PrimitiveList;
|
|
8
|
+
import org.sunflow.core.Ray;
|
|
9
|
+
import org.sunflow.core.ShadingState;
|
|
10
|
+
import org.sunflow.math.BoundingBox;
|
|
11
|
+
import org.sunflow.math.Matrix4;
|
|
12
|
+
import org.sunflow.math.OrthoNormalBasis;
|
|
13
|
+
import org.sunflow.math.Point3;
|
|
14
|
+
import org.sunflow.math.Solvers;
|
|
15
|
+
import org.sunflow.math.Vector3;
|
|
16
|
+
|
|
17
|
+
public class BanchoffSurface implements PrimitiveList {
|
|
18
|
+
|
|
19
|
+
@Override
|
|
20
|
+
public boolean update(ParameterList pl, SunflowAPI api) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@Override
|
|
25
|
+
public BoundingBox getWorldBounds(Matrix4 o2w) {
|
|
26
|
+
BoundingBox bounds = new BoundingBox(1.5f);
|
|
27
|
+
if (o2w != null) {
|
|
28
|
+
bounds = o2w.transform(bounds);
|
|
29
|
+
}
|
|
30
|
+
return bounds;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Override
|
|
34
|
+
public float getPrimitiveBound(int primID, int i) {
|
|
35
|
+
return (i & 1) == 0 ? -1.5f : 1.5f;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@Override
|
|
39
|
+
public int getNumPrimitives() {
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@Override
|
|
44
|
+
public void prepareShadingState(ShadingState state) {
|
|
45
|
+
state.init();
|
|
46
|
+
state.getRay().getPoint(state.getPoint());
|
|
47
|
+
Instance parent = state.getInstance();
|
|
48
|
+
Point3 n = state.transformWorldToObject(state.getPoint());
|
|
49
|
+
state.getNormal().set(n.x * (2 * n.x * n.x - 1), n.y * (2 * n.y * n.y - 1), n.z * (2 * n.z * n.z - 1));
|
|
50
|
+
state.getNormal().normalize();
|
|
51
|
+
state.setShader(parent.getShader(0));
|
|
52
|
+
state.setModifier(parent.getModifier(0));
|
|
53
|
+
// into world space
|
|
54
|
+
Vector3 worldNormal = state.transformNormalObjectToWorld(state.getNormal());
|
|
55
|
+
state.getNormal().set(worldNormal);
|
|
56
|
+
state.getNormal().normalize();
|
|
57
|
+
state.getGeoNormal().set(state.getNormal());
|
|
58
|
+
// create basis in world space
|
|
59
|
+
state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@Override
|
|
63
|
+
public void intersectPrimitive(Ray r, int primID, IntersectionState state) {
|
|
64
|
+
// intersect in local space
|
|
65
|
+
float rd2x = r.dx * r.dx;
|
|
66
|
+
float rd2y = r.dy * r.dy;
|
|
67
|
+
float rd2z = r.dz * r.dz;
|
|
68
|
+
float ro2x = r.ox * r.ox;
|
|
69
|
+
float ro2y = r.oy * r.oy;
|
|
70
|
+
float ro2z = r.oz * r.oz;
|
|
71
|
+
// setup the quartic coefficients
|
|
72
|
+
// some common terms could probably be shared across these
|
|
73
|
+
double A = (rd2y * rd2y + rd2z * rd2z + rd2x * rd2x);
|
|
74
|
+
double B = 4 * (r.oy * rd2y * r.dy + r.oz * r.dz * rd2z + r.ox * r.dx * rd2x);
|
|
75
|
+
double C = (-rd2x - rd2y - rd2z + 6 * (ro2y * rd2y + ro2z * rd2z + ro2x * rd2x));
|
|
76
|
+
double D = 2 * (2 * ro2z * r.oz * r.dz - r.oz * r.dz + 2 * ro2x * r.ox * r.dx + 2 * ro2y * r.oy * r.dy - r.ox * r.dx - r.oy * r.dy);
|
|
77
|
+
double E = 3.0f / 8.0f + (-ro2z + ro2z * ro2z - ro2y + ro2y * ro2y - ro2x + ro2x * ro2x);
|
|
78
|
+
// solve equation
|
|
79
|
+
double[] t = Solvers.solveQuartic(A, B, C, D, E);
|
|
80
|
+
if (t != null) {
|
|
81
|
+
// early rejection
|
|
82
|
+
if (t[0] >= r.getMax() || t[t.length - 1] <= r.getMin()) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// find first intersection in front of the ray
|
|
86
|
+
for (int i = 0; i < t.length; i++) {
|
|
87
|
+
if (t[i] > r.getMin()) {
|
|
88
|
+
r.setMax((float) t[i]);
|
|
89
|
+
state.setIntersection(0);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@Override
|
|
97
|
+
public PrimitiveList getBakingPrimitives() {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|