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.
Files changed (255) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +53 -0
  3. data/.mvn/extensions.xml +8 -0
  4. data/CHANGELOG.md +2 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +674 -0
  7. data/README.md +2 -0
  8. data/Rakefile +43 -0
  9. data/docs/.gitignore +6 -0
  10. data/docs/_config.yml +20 -0
  11. data/docs/_includes/footer.html +38 -0
  12. data/docs/_includes/head.html +15 -0
  13. data/docs/_includes/header.html +27 -0
  14. data/docs/_includes/icon-github.html +1 -0
  15. data/docs/_includes/icon-github.svg +1 -0
  16. data/docs/_includes/icon-twitter.html +1 -0
  17. data/docs/_includes/icon-twitter.svg +1 -0
  18. data/docs/_layouts/default.html +20 -0
  19. data/docs/_layouts/page.html +14 -0
  20. data/docs/_layouts/post.html +15 -0
  21. data/docs/_posts/2017-01-08-animated_ray_tracing.md +72 -0
  22. data/docs/_posts/2017-01-08-welcome.md +78 -0
  23. data/docs/_sass/_base.scss +206 -0
  24. data/docs/_sass/_layout.scss +242 -0
  25. data/docs/_sass/_syntax-highlighting.scss +71 -0
  26. data/docs/about.md +12 -0
  27. data/docs/assets/Animation.ogv +0 -0
  28. data/docs/assets/Animation.png +0 -0
  29. data/docs/assets/basic.png +0 -0
  30. data/docs/assets/basic_traced.png +0 -0
  31. data/docs/css/main.scss +38 -0
  32. data/docs/favicon.ico +0 -0
  33. data/docs/feed.xml +30 -0
  34. data/docs/index.html +38 -0
  35. data/joonsrenderer.gemspec +23 -0
  36. data/lib/joonsrenderer.rb +12 -0
  37. data/lib/joonsrenderer/version.rb +3 -0
  38. data/pom.rb +75 -0
  39. data/pom.xml +163 -0
  40. data/src/main/java/SunflowGUI.java +1354 -0
  41. data/src/main/java/joons/JRFiller.java +79 -0
  42. data/src/main/java/joons/JRImagePanel.java +141 -0
  43. data/src/main/java/joons/JRRecorder.java +183 -0
  44. data/src/main/java/joons/JRStatics.java +199 -0
  45. data/src/main/java/joons/JoonsRenderer.java +837 -0
  46. data/src/main/java/org/sunflow/AsciiFileSunflowAPI.java +98 -0
  47. data/src/main/java/org/sunflow/Benchmark.java +313 -0
  48. data/src/main/java/org/sunflow/BinaryFileSunflowAPI.java +228 -0
  49. data/src/main/java/org/sunflow/FileSunflowAPI.java +354 -0
  50. data/src/main/java/org/sunflow/PluginRegistry.java +322 -0
  51. data/src/main/java/org/sunflow/RealtimeBenchmark.java +125 -0
  52. data/src/main/java/org/sunflow/RenderObjectMap.java +344 -0
  53. data/src/main/java/org/sunflow/SunflowAPI.java +762 -0
  54. data/src/main/java/org/sunflow/SunflowAPIInterface.java +277 -0
  55. data/src/main/java/org/sunflow/core/AccelerationStructure.java +20 -0
  56. data/src/main/java/org/sunflow/core/AccelerationStructureFactory.java +36 -0
  57. data/src/main/java/org/sunflow/core/BucketOrder.java +21 -0
  58. data/src/main/java/org/sunflow/core/Camera.java +125 -0
  59. data/src/main/java/org/sunflow/core/CameraLens.java +29 -0
  60. data/src/main/java/org/sunflow/core/CausticPhotonMapInterface.java +15 -0
  61. data/src/main/java/org/sunflow/core/Display.java +78 -0
  62. data/src/main/java/org/sunflow/core/Filter.java +27 -0
  63. data/src/main/java/org/sunflow/core/GIEngine.java +42 -0
  64. data/src/main/java/org/sunflow/core/Geometry.java +157 -0
  65. data/src/main/java/org/sunflow/core/GlobalPhotonMapInterface.java +21 -0
  66. data/src/main/java/org/sunflow/core/ImageSampler.java +26 -0
  67. data/src/main/java/org/sunflow/core/Instance.java +224 -0
  68. data/src/main/java/org/sunflow/core/InstanceList.java +83 -0
  69. data/src/main/java/org/sunflow/core/IntersectionState.java +120 -0
  70. data/src/main/java/org/sunflow/core/LightSample.java +104 -0
  71. data/src/main/java/org/sunflow/core/LightServer.java +382 -0
  72. data/src/main/java/org/sunflow/core/LightSource.java +67 -0
  73. data/src/main/java/org/sunflow/core/Modifier.java +16 -0
  74. data/src/main/java/org/sunflow/core/Options.java +20 -0
  75. data/src/main/java/org/sunflow/core/ParameterList.java +758 -0
  76. data/src/main/java/org/sunflow/core/PhotonStore.java +62 -0
  77. data/src/main/java/org/sunflow/core/PrimitiveList.java +70 -0
  78. data/src/main/java/org/sunflow/core/Ray.java +219 -0
  79. data/src/main/java/org/sunflow/core/RenderObject.java +25 -0
  80. data/src/main/java/org/sunflow/core/Scene.java +377 -0
  81. data/src/main/java/org/sunflow/core/SceneParser.java +58 -0
  82. data/src/main/java/org/sunflow/core/Shader.java +30 -0
  83. data/src/main/java/org/sunflow/core/ShadingCache.java +84 -0
  84. data/src/main/java/org/sunflow/core/ShadingState.java +939 -0
  85. data/src/main/java/org/sunflow/core/Statistics.java +85 -0
  86. data/src/main/java/org/sunflow/core/Tesselatable.java +36 -0
  87. data/src/main/java/org/sunflow/core/Texture.java +128 -0
  88. data/src/main/java/org/sunflow/core/TextureCache.java +48 -0
  89. data/src/main/java/org/sunflow/core/accel/BoundingIntervalHierarchy.java +652 -0
  90. data/src/main/java/org/sunflow/core/accel/KDTree.java +833 -0
  91. data/src/main/java/org/sunflow/core/accel/NullAccelerator.java +30 -0
  92. data/src/main/java/org/sunflow/core/accel/UniformGrid.java +329 -0
  93. data/src/main/java/org/sunflow/core/bucket/BucketOrderFactory.java +26 -0
  94. data/src/main/java/org/sunflow/core/bucket/ColumnBucketOrder.java +21 -0
  95. data/src/main/java/org/sunflow/core/bucket/DiagonalBucketOrder.java +28 -0
  96. data/src/main/java/org/sunflow/core/bucket/HilbertBucketOrder.java +65 -0
  97. data/src/main/java/org/sunflow/core/bucket/InvertedBucketOrder.java +28 -0
  98. data/src/main/java/org/sunflow/core/bucket/RandomBucketOrder.java +49 -0
  99. data/src/main/java/org/sunflow/core/bucket/RowBucketOrder.java +21 -0
  100. data/src/main/java/org/sunflow/core/bucket/SpiralBucketOrder.java +43 -0
  101. data/src/main/java/org/sunflow/core/camera/FisheyeLens.java +25 -0
  102. data/src/main/java/org/sunflow/core/camera/PinholeLens.java +43 -0
  103. data/src/main/java/org/sunflow/core/camera/SphericalLens.java +22 -0
  104. data/src/main/java/org/sunflow/core/camera/ThinLens.java +107 -0
  105. data/src/main/java/org/sunflow/core/display/FastDisplay.java +119 -0
  106. data/src/main/java/org/sunflow/core/display/FileDisplay.java +83 -0
  107. data/src/main/java/org/sunflow/core/display/FrameDisplay.java +97 -0
  108. data/src/main/java/org/sunflow/core/display/ImgPipeDisplay.java +109 -0
  109. data/src/main/java/org/sunflow/core/filter/BlackmanHarrisFilter.java +28 -0
  110. data/src/main/java/org/sunflow/core/filter/BoxFilter.java +16 -0
  111. data/src/main/java/org/sunflow/core/filter/CatmullRomFilter.java +29 -0
  112. data/src/main/java/org/sunflow/core/filter/CubicBSpline.java +32 -0
  113. data/src/main/java/org/sunflow/core/filter/GaussianFilter.java +24 -0
  114. data/src/main/java/org/sunflow/core/filter/LanczosFilter.java +30 -0
  115. data/src/main/java/org/sunflow/core/filter/MitchellFilter.java +28 -0
  116. data/src/main/java/org/sunflow/core/filter/SincFilter.java +25 -0
  117. data/src/main/java/org/sunflow/core/filter/TriangleFilter.java +16 -0
  118. data/src/main/java/org/sunflow/core/gi/AmbientOcclusionGIEngine.java +57 -0
  119. data/src/main/java/org/sunflow/core/gi/FakeGIEngine.java +48 -0
  120. data/src/main/java/org/sunflow/core/gi/InstantGI.java +194 -0
  121. data/src/main/java/org/sunflow/core/gi/IrradianceCacheGIEngine.java +268 -0
  122. data/src/main/java/org/sunflow/core/gi/PathTracingGIEngine.java +65 -0
  123. data/src/main/java/org/sunflow/core/light/DirectionalSpotlight.java +103 -0
  124. data/src/main/java/org/sunflow/core/light/ImageBasedLight.java +303 -0
  125. data/src/main/java/org/sunflow/core/light/PointLight.java +72 -0
  126. data/src/main/java/org/sunflow/core/light/SphereLight.java +166 -0
  127. data/src/main/java/org/sunflow/core/light/SunSkyLight.java +362 -0
  128. data/src/main/java/org/sunflow/core/light/TriangleMeshLight.java +296 -0
  129. data/src/main/java/org/sunflow/core/modifiers/BumpMappingModifier.java +37 -0
  130. data/src/main/java/org/sunflow/core/modifiers/NormalMapModifier.java +34 -0
  131. data/src/main/java/org/sunflow/core/modifiers/PerlinModifier.java +80 -0
  132. data/src/main/java/org/sunflow/core/parser/Keyword.java +39 -0
  133. data/src/main/java/org/sunflow/core/parser/RA2Parser.java +107 -0
  134. data/src/main/java/org/sunflow/core/parser/RA3Parser.java +68 -0
  135. data/src/main/java/org/sunflow/core/parser/SCAbstractParser.java +299 -0
  136. data/src/main/java/org/sunflow/core/parser/SCAsciiParser.java +251 -0
  137. data/src/main/java/org/sunflow/core/parser/SCBinaryParser.java +156 -0
  138. data/src/main/java/org/sunflow/core/parser/SCParser.java +1403 -0
  139. data/src/main/java/org/sunflow/core/parser/ShaveRibParser.java +174 -0
  140. data/src/main/java/org/sunflow/core/parser/TriParser.java +79 -0
  141. data/src/main/java/org/sunflow/core/photonmap/CausticPhotonMap.java +429 -0
  142. data/src/main/java/org/sunflow/core/photonmap/GlobalPhotonMap.java +530 -0
  143. data/src/main/java/org/sunflow/core/photonmap/GridPhotonMap.java +308 -0
  144. data/src/main/java/org/sunflow/core/primitive/Background.java +55 -0
  145. data/src/main/java/org/sunflow/core/primitive/BanchoffSurface.java +100 -0
  146. data/src/main/java/org/sunflow/core/primitive/Box.java +210 -0
  147. data/src/main/java/org/sunflow/core/primitive/CornellBox.java +476 -0
  148. data/src/main/java/org/sunflow/core/primitive/CubeGrid.java +318 -0
  149. data/src/main/java/org/sunflow/core/primitive/Cylinder.java +104 -0
  150. data/src/main/java/org/sunflow/core/primitive/Hair.java +275 -0
  151. data/src/main/java/org/sunflow/core/primitive/JuliaFractal.java +266 -0
  152. data/src/main/java/org/sunflow/core/primitive/ParticleSurface.java +114 -0
  153. data/src/main/java/org/sunflow/core/primitive/Plane.java +163 -0
  154. data/src/main/java/org/sunflow/core/primitive/QuadMesh.java +413 -0
  155. data/src/main/java/org/sunflow/core/primitive/Sphere.java +101 -0
  156. data/src/main/java/org/sunflow/core/primitive/SphereFlake.java +234 -0
  157. data/src/main/java/org/sunflow/core/primitive/Torus.java +145 -0
  158. data/src/main/java/org/sunflow/core/primitive/TriangleMesh.java +849 -0
  159. data/src/main/java/org/sunflow/core/renderer/BucketRenderer.java +491 -0
  160. data/src/main/java/org/sunflow/core/renderer/MultipassRenderer.java +237 -0
  161. data/src/main/java/org/sunflow/core/renderer/ProgressiveRenderer.java +171 -0
  162. data/src/main/java/org/sunflow/core/renderer/SimpleRenderer.java +106 -0
  163. data/src/main/java/org/sunflow/core/shader/AmbientOcclusionShader.java +53 -0
  164. data/src/main/java/org/sunflow/core/shader/AnisotropicWardShader.java +216 -0
  165. data/src/main/java/org/sunflow/core/shader/ConstantShader.java +31 -0
  166. data/src/main/java/org/sunflow/core/shader/DiffuseShader.java +65 -0
  167. data/src/main/java/org/sunflow/core/shader/GlassShader.java +147 -0
  168. data/src/main/java/org/sunflow/core/shader/IDShader.java +27 -0
  169. data/src/main/java/org/sunflow/core/shader/MirrorShader.java +68 -0
  170. data/src/main/java/org/sunflow/core/shader/NormalShader.java +32 -0
  171. data/src/main/java/org/sunflow/core/shader/PhongShader.java +89 -0
  172. data/src/main/java/org/sunflow/core/shader/PrimIDShader.java +30 -0
  173. data/src/main/java/org/sunflow/core/shader/QuickGrayShader.java +63 -0
  174. data/src/main/java/org/sunflow/core/shader/ShinyDiffuseShader.java +98 -0
  175. data/src/main/java/org/sunflow/core/shader/SimpleShader.java +24 -0
  176. data/src/main/java/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java +31 -0
  177. data/src/main/java/org/sunflow/core/shader/TexturedDiffuseShader.java +31 -0
  178. data/src/main/java/org/sunflow/core/shader/TexturedPhongShader.java +31 -0
  179. data/src/main/java/org/sunflow/core/shader/TexturedShinyDiffuseShader.java +31 -0
  180. data/src/main/java/org/sunflow/core/shader/TexturedWardShader.java +31 -0
  181. data/src/main/java/org/sunflow/core/shader/UVShader.java +27 -0
  182. data/src/main/java/org/sunflow/core/shader/UberShader.java +149 -0
  183. data/src/main/java/org/sunflow/core/shader/ViewCausticsShader.java +33 -0
  184. data/src/main/java/org/sunflow/core/shader/ViewGlobalPhotonsShader.java +25 -0
  185. data/src/main/java/org/sunflow/core/shader/ViewIrradianceShader.java +25 -0
  186. data/src/main/java/org/sunflow/core/shader/WireframeShader.java +83 -0
  187. data/src/main/java/org/sunflow/core/tesselatable/BezierMesh.java +254 -0
  188. data/src/main/java/org/sunflow/core/tesselatable/FileMesh.java +251 -0
  189. data/src/main/java/org/sunflow/core/tesselatable/Gumbo.java +1147 -0
  190. data/src/main/java/org/sunflow/core/tesselatable/Teapot.java +237 -0
  191. data/src/main/java/org/sunflow/image/Bitmap.java +15 -0
  192. data/src/main/java/org/sunflow/image/BitmapReader.java +39 -0
  193. data/src/main/java/org/sunflow/image/BitmapWriter.java +79 -0
  194. data/src/main/java/org/sunflow/image/BlackbodySpectrum.java +16 -0
  195. data/src/main/java/org/sunflow/image/ChromaticitySpectrum.java +55 -0
  196. data/src/main/java/org/sunflow/image/Color.java +374 -0
  197. data/src/main/java/org/sunflow/image/ColorEncoder.java +94 -0
  198. data/src/main/java/org/sunflow/image/ColorFactory.java +122 -0
  199. data/src/main/java/org/sunflow/image/ConstantSpectralCurve.java +21 -0
  200. data/src/main/java/org/sunflow/image/IrregularSpectralCurve.java +57 -0
  201. data/src/main/java/org/sunflow/image/RGBSpace.java +207 -0
  202. data/src/main/java/org/sunflow/image/RegularSpectralCurve.java +30 -0
  203. data/src/main/java/org/sunflow/image/SpectralCurve.java +118 -0
  204. data/src/main/java/org/sunflow/image/XYZColor.java +50 -0
  205. data/src/main/java/org/sunflow/image/formats/BitmapBlack.java +27 -0
  206. data/src/main/java/org/sunflow/image/formats/BitmapG8.java +36 -0
  207. data/src/main/java/org/sunflow/image/formats/BitmapGA8.java +30 -0
  208. data/src/main/java/org/sunflow/image/formats/BitmapRGB8.java +40 -0
  209. data/src/main/java/org/sunflow/image/formats/BitmapRGBA8.java +40 -0
  210. data/src/main/java/org/sunflow/image/formats/BitmapRGBE.java +60 -0
  211. data/src/main/java/org/sunflow/image/formats/BitmapXYZ.java +38 -0
  212. data/src/main/java/org/sunflow/image/formats/GenericBitmap.java +73 -0
  213. data/src/main/java/org/sunflow/image/readers/BMPBitmapReader.java +39 -0
  214. data/src/main/java/org/sunflow/image/readers/HDRBitmapReader.java +155 -0
  215. data/src/main/java/org/sunflow/image/readers/IGIBitmapReader.java +104 -0
  216. data/src/main/java/org/sunflow/image/readers/JPGBitmapReader.java +39 -0
  217. data/src/main/java/org/sunflow/image/readers/PNGBitmapReader.java +40 -0
  218. data/src/main/java/org/sunflow/image/readers/TGABitmapReader.java +141 -0
  219. data/src/main/java/org/sunflow/image/writers/EXRBitmapWriter.java +395 -0
  220. data/src/main/java/org/sunflow/image/writers/HDRBitmapWriter.java +54 -0
  221. data/src/main/java/org/sunflow/image/writers/IGIBitmapWriter.java +75 -0
  222. data/src/main/java/org/sunflow/image/writers/PNGBitmapWriter.java +39 -0
  223. data/src/main/java/org/sunflow/image/writers/TGABitmapWriter.java +63 -0
  224. data/src/main/java/org/sunflow/math/BoundingBox.java +340 -0
  225. data/src/main/java/org/sunflow/math/MathUtils.java +159 -0
  226. data/src/main/java/org/sunflow/math/Matrix4.java +573 -0
  227. data/src/main/java/org/sunflow/math/MovingMatrix4.java +119 -0
  228. data/src/main/java/org/sunflow/math/OrthoNormalBasis.java +110 -0
  229. data/src/main/java/org/sunflow/math/PerlinScalar.java +331 -0
  230. data/src/main/java/org/sunflow/math/PerlinVector.java +132 -0
  231. data/src/main/java/org/sunflow/math/Point2.java +36 -0
  232. data/src/main/java/org/sunflow/math/Point3.java +133 -0
  233. data/src/main/java/org/sunflow/math/QMC.java +209 -0
  234. data/src/main/java/org/sunflow/math/Solvers.java +142 -0
  235. data/src/main/java/org/sunflow/math/Vector3.java +197 -0
  236. data/src/main/java/org/sunflow/system/BenchmarkFramework.java +73 -0
  237. data/src/main/java/org/sunflow/system/BenchmarkTest.java +17 -0
  238. data/src/main/java/org/sunflow/system/ByteUtil.java +119 -0
  239. data/src/main/java/org/sunflow/system/FileUtils.java +27 -0
  240. data/src/main/java/org/sunflow/system/ImagePanel.java +282 -0
  241. data/src/main/java/org/sunflow/system/Memory.java +18 -0
  242. data/src/main/java/org/sunflow/system/Parser.java +162 -0
  243. data/src/main/java/org/sunflow/system/Plugins.java +142 -0
  244. data/src/main/java/org/sunflow/system/RenderGlobalsPanel.java +209 -0
  245. data/src/main/java/org/sunflow/system/SearchPath.java +67 -0
  246. data/src/main/java/org/sunflow/system/Timer.java +53 -0
  247. data/src/main/java/org/sunflow/system/UI.java +112 -0
  248. data/src/main/java/org/sunflow/system/UserInterface.java +46 -0
  249. data/src/main/java/org/sunflow/system/ui/ConsoleInterface.java +48 -0
  250. data/src/main/java/org/sunflow/system/ui/SilentInterface.java +28 -0
  251. data/src/main/java/org/sunflow/util/FastHashMap.java +220 -0
  252. data/src/main/java/org/sunflow/util/FloatArray.java +77 -0
  253. data/src/main/java/org/sunflow/util/IntArray.java +77 -0
  254. data/src/test/java/a_maintest.java +129 -0
  255. metadata +300 -0
@@ -0,0 +1,62 @@
1
+ package org.sunflow.core;
2
+
3
+ import org.sunflow.image.Color;
4
+ import org.sunflow.math.BoundingBox;
5
+ import org.sunflow.math.Vector3;
6
+
7
+ /**
8
+ * Describes an object which can store photons.
9
+ */
10
+ public interface PhotonStore {
11
+
12
+ /**
13
+ * Number of photons to emit from this surface.
14
+ *
15
+ * @return number of photons
16
+ */
17
+ int numEmit();
18
+
19
+ /**
20
+ * Initialize this object for the specified scene size.
21
+ *
22
+ * @param sceneBounds scene bounding box
23
+ */
24
+ void prepare(Options options, BoundingBox sceneBounds);
25
+
26
+ /**
27
+ * Store the specified photon.
28
+ *
29
+ * @param state shading state
30
+ * @param dir photon direction
31
+ * @param power photon power
32
+ * @param diffuse diffuse color at the hit point
33
+ */
34
+ void store(ShadingState state, Vector3 dir, Color power, Color diffuse);
35
+
36
+ /**
37
+ * Initialize the map after all photons have been stored. This can be used
38
+ * to balance a kd-tree based photon map for example.
39
+ */
40
+ void init();
41
+
42
+ /**
43
+ * Allow photons reflected diffusely?
44
+ *
45
+ * @return <code>true</code> if diffuse bounces should be traced
46
+ */
47
+ boolean allowDiffuseBounced();
48
+
49
+ /**
50
+ * Allow specularly reflected photons?
51
+ *
52
+ * @return <code>true</code> if specular reflection bounces should be traced
53
+ */
54
+ boolean allowReflectionBounced();
55
+
56
+ /**
57
+ * Allow refracted photons?
58
+ *
59
+ * @return <code>true</code> if refracted bounces should be traced
60
+ */
61
+ boolean allowRefractionBounced();
62
+ }
@@ -0,0 +1,70 @@
1
+ package org.sunflow.core;
2
+
3
+ import org.sunflow.math.BoundingBox;
4
+ import org.sunflow.math.Matrix4;
5
+
6
+ /**
7
+ * This class represents an object made up of many primitives.
8
+ */
9
+ public interface PrimitiveList extends RenderObject {
10
+
11
+ /**
12
+ * Compute a bounding box of this object in world space, using the specified
13
+ * object-to-world transformation matrix. The bounds should be as exact as
14
+ * possible, if they are difficult or expensive to compute exactly, you may
15
+ * use {@link Matrix4#transform(BoundingBox)}. If the matrix is
16
+ * <code>null</code> no transformation is needed, and object space is
17
+ * equivalent to world space.
18
+ *
19
+ * @param o2w object to world transformation matrix
20
+ * @return object bounding box in world space
21
+ */
22
+ public BoundingBox getWorldBounds(Matrix4 o2w);
23
+
24
+ /**
25
+ * Returns the number of individual primtives in this aggregate object.
26
+ *
27
+ * @return number of primitives
28
+ */
29
+ public int getNumPrimitives();
30
+
31
+ /**
32
+ * Retrieve the bounding box component of a particular primitive in object
33
+ * space. Even indexes get minimum values, while odd indexes get the maximum
34
+ * values for each axis.
35
+ *
36
+ * @param primID primitive index
37
+ * @param i bounding box side index
38
+ * @return value of the request bound
39
+ */
40
+ public float getPrimitiveBound(int primID, int i);
41
+
42
+ /**
43
+ * Intersect the specified primitive in local space.
44
+ *
45
+ * @param r ray in the object's local space
46
+ * @param primID primitive index to intersect
47
+ * @param state intersection state
48
+ * @see Ray#setMax(float)
49
+ * @see IntersectionState#setIntersection(int, float, float)
50
+ */
51
+ public void intersectPrimitive(Ray r, int primID, IntersectionState state);
52
+
53
+ /**
54
+ * Prepare the specified {@link ShadingState} by setting all of its internal
55
+ * parameters.
56
+ *
57
+ * @param state shading state to fill in
58
+ */
59
+ public void prepareShadingState(ShadingState state);
60
+
61
+ /**
62
+ * Create a new {@link PrimitiveList} object suitable for baking lightmaps.
63
+ * This means a set of primitives laid out in the unit square UV space. This
64
+ * method is optional, objects which do not support it should simply return
65
+ * <code>null</code>.
66
+ *
67
+ * @return a list of baking primitives
68
+ */
69
+ public PrimitiveList getBakingPrimitives();
70
+ }
@@ -0,0 +1,219 @@
1
+ package org.sunflow.core;
2
+
3
+ import org.sunflow.math.Matrix4;
4
+ import org.sunflow.math.Point3;
5
+ import org.sunflow.math.Vector3;
6
+
7
+ /**
8
+ * This class represents a ray as a oriented half line segment. The ray
9
+ * direction is always normalized. The valid region is delimted by two distances
10
+ * along the ray, tMin and tMax.
11
+ */
12
+ public final class Ray {
13
+
14
+ public float ox, oy, oz;
15
+ public float dx, dy, dz;
16
+ private float tMin;
17
+ private float tMax;
18
+ private static final float EPSILON = 0;// 0.01f;
19
+
20
+ private Ray() {
21
+ }
22
+
23
+ /**
24
+ * Creates a new ray that points from the given origin to the given
25
+ * direction. The ray has infinite length. The direction vector is
26
+ * normalized.
27
+ *
28
+ * @param ox ray origin x
29
+ * @param oy ray origin y
30
+ * @param oz ray origin z
31
+ * @param dx ray direction x
32
+ * @param dy ray direction y
33
+ * @param dz ray direction z
34
+ */
35
+ public Ray(float ox, float oy, float oz, float dx, float dy, float dz) {
36
+ this.ox = ox;
37
+ this.oy = oy;
38
+ this.oz = oz;
39
+ this.dx = dx;
40
+ this.dy = dy;
41
+ this.dz = dz;
42
+ float in = 1.0f / (float) Math.sqrt(dx * dx + dy * dy + dz * dz);
43
+ this.dx *= in;
44
+ this.dy *= in;
45
+ this.dz *= in;
46
+ tMin = EPSILON;
47
+ tMax = Float.POSITIVE_INFINITY;
48
+ }
49
+
50
+ /**
51
+ * Creates a new ray that points from the given origin to the given
52
+ * direction. The ray has infinite length. The direction vector is
53
+ * normalized.
54
+ *
55
+ * @param o ray origin
56
+ * @param d ray direction (need not be normalized)
57
+ */
58
+ public Ray(Point3 o, Vector3 d) {
59
+ ox = o.x;
60
+ oy = o.y;
61
+ oz = o.z;
62
+ dx = d.x;
63
+ dy = d.y;
64
+ dz = d.z;
65
+ float in = 1.0f / (float) Math.sqrt(dx * dx + dy * dy + dz * dz);
66
+ dx *= in;
67
+ dy *= in;
68
+ dz *= in;
69
+ tMin = EPSILON;
70
+ tMax = Float.POSITIVE_INFINITY;
71
+ }
72
+
73
+ /**
74
+ * Creates a new ray that points from point a to point b. The created ray
75
+ * will set tMin and tMax to limit the ray to the segment (a,b)
76
+ * (non-inclusive of a and b). This is often used to create shadow rays.
77
+ *
78
+ * @param a start point
79
+ * @param b end point
80
+ */
81
+ public Ray(Point3 a, Point3 b) {
82
+ ox = a.x;
83
+ oy = a.y;
84
+ oz = a.z;
85
+ dx = b.x - ox;
86
+ dy = b.y - oy;
87
+ dz = b.z - oz;
88
+ tMin = EPSILON;
89
+ float n = (float) Math.sqrt(dx * dx + dy * dy + dz * dz);
90
+ float in = 1.0f / n;
91
+ dx *= in;
92
+ dy *= in;
93
+ dz *= in;
94
+ tMax = n - EPSILON;
95
+ }
96
+
97
+ /**
98
+ * Create a new ray by transforming the supplied one by the given matrix. If
99
+ * the matrix is
100
+ * <code>null</code>, the original ray is returned.
101
+ *
102
+ * @param m matrix to transform the ray by
103
+ */
104
+ public Ray transform(Matrix4 m) {
105
+ if (m == null) {
106
+ return this;
107
+ }
108
+ Ray r = new Ray();
109
+ r.ox = m.transformPX(ox, oy, oz);
110
+ r.oy = m.transformPY(ox, oy, oz);
111
+ r.oz = m.transformPZ(ox, oy, oz);
112
+ r.dx = m.transformVX(dx, dy, dz);
113
+ r.dy = m.transformVY(dx, dy, dz);
114
+ r.dz = m.transformVZ(dx, dy, dz);
115
+ r.tMin = tMin;
116
+ r.tMax = tMax;
117
+ return r;
118
+ }
119
+
120
+ /**
121
+ * Normalize the direction component of the ray.
122
+ */
123
+ public void normalize() {
124
+ float in = 1.0f / (float) Math.sqrt(dx * dx + dy * dy + dz * dz);
125
+ dx *= in;
126
+ dy *= in;
127
+ dz *= in;
128
+ }
129
+
130
+ /**
131
+ * Gets the minimum distance along the ray - usually 0.
132
+ *
133
+ * @return value of the smallest distance along the ray
134
+ */
135
+ public final float getMin() {
136
+ return tMin;
137
+ }
138
+
139
+ /**
140
+ * Gets the maximum distance along the ray. May be infinite.
141
+ *
142
+ * @return value of the largest distance along the ray
143
+ */
144
+ public final float getMax() {
145
+ return tMax;
146
+ }
147
+
148
+ /**
149
+ * Creates a vector to represent the direction of the ray.
150
+ *
151
+ * @return a vector equal to the direction of this ray
152
+ */
153
+ public final Vector3 getDirection() {
154
+ return new Vector3(dx, dy, dz);
155
+ }
156
+
157
+ /**
158
+ * Checks to see if the specified distance falls within the valid range on
159
+ * this ray. This should always be used before an intersection with the ray
160
+ * is detected.
161
+ *
162
+ * @param t distance to be tested
163
+ * @return <code>true</code> if t falls between the minimum and maximum
164
+ * distance of this ray, <code>false</code> otherwise
165
+ */
166
+ public final boolean isInside(float t) {
167
+ return (tMin < t) && (t < tMax);
168
+ }
169
+
170
+ /**
171
+ * Gets the end point of the ray. A reference to
172
+ * <code>dest</code> is returned to support chaining.
173
+ *
174
+ * @param dest reference to the point to store
175
+ * @return reference to <code>dest</code>
176
+ */
177
+ public final Point3 getPoint(Point3 dest) {
178
+ dest.x = ox + (tMax * dx);
179
+ dest.y = oy + (tMax * dy);
180
+ dest.z = oz + (tMax * dz);
181
+ return dest;
182
+ }
183
+
184
+ /**
185
+ * Computes the dot product of an arbitrary vector with the direction of the
186
+ * ray. This method avoids having to call getDirection() which would
187
+ * instantiate a new Vector object.
188
+ *
189
+ * @param v vector
190
+ * @return dot product of the ray direction and the specified vector
191
+ */
192
+ public final float dot(Vector3 v) {
193
+ return dx * v.x + dy * v.y + dz * v.z;
194
+ }
195
+
196
+ /**
197
+ * Computes the dot product of an arbitrary vector with the direction of the
198
+ * ray. This method avoids having to call getDirection() which would
199
+ * instantiate a new Vector object.
200
+ *
201
+ * @param vx vector x coordinate
202
+ * @param vy vector y coordinate
203
+ * @param vz vector z coordinate
204
+ * @return dot product of the ray direction and the specified vector
205
+ */
206
+ public final float dot(float vx, float vy, float vz) {
207
+ return dx * vx + dy * vy + dz * vz;
208
+ }
209
+
210
+ /**
211
+ * Updates the maximum to the specified distance if and only if the new
212
+ * distance is smaller than the current one.
213
+ *
214
+ * @param t new maximum distance
215
+ */
216
+ public final void setMax(float t) {
217
+ tMax = t;
218
+ }
219
+ }
@@ -0,0 +1,25 @@
1
+ package org.sunflow.core;
2
+
3
+ import org.sunflow.SunflowAPI;
4
+
5
+ /**
6
+ * This is the base interface for all public rendering object interfaces. It
7
+ * handles incremental updates via {@link ParameterList} objects.
8
+ */
9
+ public interface RenderObject {
10
+
11
+ /**
12
+ * Update this object given a list of parameters. This method is guarenteed
13
+ * to be called at least once on every object, but it should correctly
14
+ * handle empty parameter lists. This means that the object should be in a
15
+ * valid state from the time it is constructed. This method should also
16
+ * return true or false depending on whether the update was succesfull or
17
+ * not.
18
+ *
19
+ * @param pl list of parameters to read from
20
+ * @param api reference to the current scene
21
+ * @return <code>true</code> if the update is succesfull, <code>false</code>
22
+ * otherwise
23
+ */
24
+ public boolean update(ParameterList pl, SunflowAPI api);
25
+ }
@@ -0,0 +1,377 @@
1
+ package org.sunflow.core;
2
+
3
+ import java.util.ArrayList;
4
+
5
+ import org.sunflow.core.display.FrameDisplay;
6
+ import org.sunflow.image.Color;
7
+ import org.sunflow.math.BoundingBox;
8
+ import org.sunflow.math.MathUtils;
9
+ import org.sunflow.math.Point3;
10
+ import org.sunflow.math.Vector3;
11
+ import org.sunflow.system.UI;
12
+ import org.sunflow.system.UI.Module;
13
+
14
+ /**
15
+ * Represents a entire scene, defined as a collection of instances viewed by a
16
+ * camera.
17
+ */
18
+ public class Scene {
19
+ // scene storage
20
+
21
+ private LightServer lightServer;
22
+ private InstanceList instanceList;
23
+ private InstanceList infiniteInstanceList;
24
+ private Camera camera;
25
+ private AccelerationStructure intAccel;
26
+ private String acceltype;
27
+ private Statistics stats;
28
+ // baking
29
+ private boolean bakingViewDependent;
30
+ private Instance bakingInstance;
31
+ private PrimitiveList bakingPrimitives;
32
+ private AccelerationStructure bakingAccel;
33
+ private boolean rebuildAccel;
34
+ // image size
35
+ private int imageWidth;
36
+ private int imageHeight;
37
+ // global options
38
+ private int threads;
39
+ private boolean lowPriority;
40
+
41
+ /**
42
+ * Creates an empty scene.
43
+ */
44
+ public Scene() {
45
+ lightServer = new LightServer(this);
46
+ instanceList = new InstanceList();
47
+ infiniteInstanceList = new InstanceList();
48
+ acceltype = "auto";
49
+ stats = new Statistics();
50
+
51
+ bakingViewDependent = false;
52
+ bakingInstance = null;
53
+ bakingPrimitives = null;
54
+ bakingAccel = null;
55
+
56
+ camera = null;
57
+ imageWidth = 640;
58
+ imageHeight = 480;
59
+ threads = 0;
60
+ lowPriority = true;
61
+
62
+ rebuildAccel = true;
63
+ }
64
+
65
+ /**
66
+ * Get number of allowed threads for multi-threaded operations.
67
+ *
68
+ * @return number of threads that can be started
69
+ */
70
+ public int getThreads() {
71
+ return threads <= 0 ? Runtime.getRuntime().availableProcessors() : threads;
72
+ }
73
+
74
+ /**
75
+ * Get the priority level to assign to multi-threaded operations.
76
+ *
77
+ * @return thread priority
78
+ */
79
+ public int getThreadPriority() {
80
+ return lowPriority ? Thread.MIN_PRIORITY : Thread.NORM_PRIORITY;
81
+ }
82
+
83
+ /**
84
+ * Sets the current camera (no support for multiple cameras yet).
85
+ *
86
+ * @param camera camera to be used as the viewpoint for the scene
87
+ */
88
+ public void setCamera(Camera camera) {
89
+ this.camera = camera;
90
+ }
91
+
92
+ Camera getCamera() {
93
+ return camera;
94
+ }
95
+
96
+ /**
97
+ * Update the instance lists for this scene.
98
+ *
99
+ * @param instances regular instances
100
+ * @param infinite infinite instances (no bounds)
101
+ */
102
+ public void setInstanceLists(Instance[] instances, Instance[] infinite) {
103
+ infiniteInstanceList = new InstanceList(infinite);
104
+ instanceList = new InstanceList(instances);
105
+ rebuildAccel = true;
106
+ }
107
+
108
+ /**
109
+ * Update the light list for this scene.
110
+ *
111
+ * @param lights array of light source objects
112
+ */
113
+ public void setLightList(LightSource[] lights) {
114
+ lightServer.setLights(lights);
115
+ }
116
+
117
+ /**
118
+ * Enables shader overiding (set null to disable). The specified shader will
119
+ * be used to shade all surfaces
120
+ *
121
+ * @param shader shader to run over all surfaces, or <code>null</code> to
122
+ * disable overriding
123
+ * @param photonOverride <code>true</code> to override photon scattering
124
+ * with this shader or <code>false</code> to run the regular shaders
125
+ */
126
+ public void setShaderOverride(Shader shader, boolean photonOverride) {
127
+ lightServer.setShaderOverride(shader, photonOverride);
128
+ }
129
+
130
+ /**
131
+ * The provided instance will be considered for lightmap baking. If the
132
+ * specified instance is
133
+ * <code>null</code>, lightmap baking will be disabled and normal rendering
134
+ * will occur.
135
+ *
136
+ * @param instance instance to bake
137
+ */
138
+ public void setBakingInstance(Instance instance) {
139
+ bakingInstance = instance;
140
+ }
141
+
142
+ /**
143
+ * Get the radiance seen through a particular pixel
144
+ *
145
+ * @param istate intersection state for ray tracing
146
+ * @param rx pixel x coordinate
147
+ * @param ry pixel y coordinate
148
+ * @param lensU DOF sampling variable
149
+ * @param lensV DOF sampling variable
150
+ * @param time motion blur sampling variable
151
+ * @param instance QMC instance seed
152
+ * @return a shading state for the intersected primitive, or
153
+ * <code>null</code> if nothing is seen through the specifieFd point
154
+ */
155
+ public ShadingState getRadiance(IntersectionState istate, float rx, float ry, double lensU, double lensV, double time, int instance, int dim, ShadingCache cache) {
156
+ istate.numEyeRays++;
157
+ float sceneTime = camera.getTime((float) time);
158
+ if (bakingPrimitives == null) {
159
+ Ray r = camera.getRay(rx, ry, imageWidth, imageHeight, lensU, lensV, sceneTime);
160
+ return r != null ? lightServer.getRadiance(rx, ry, sceneTime, instance, dim, r, istate, cache) : null;
161
+ } else {
162
+ Ray r = new Ray(rx / imageWidth, ry / imageHeight, -1, 0, 0, 1);
163
+ traceBake(r, istate);
164
+ if (!istate.hit()) {
165
+ return null;
166
+ }
167
+ ShadingState state = ShadingState.createState(istate, rx, ry, sceneTime, r, instance, dim, lightServer);
168
+ bakingPrimitives.prepareShadingState(state);
169
+ if (bakingViewDependent) {
170
+ state.setRay(camera.getRay(state.getPoint(), sceneTime));
171
+ } else {
172
+ Point3 p = state.getPoint();
173
+ Vector3 n = state.getNormal();
174
+ // create a ray coming from directly above the point being
175
+ // shaded
176
+ Ray incoming = new Ray(p.x + n.x, p.y + n.y, p.z + n.z, -n.x, -n.y, -n.z);
177
+ incoming.setMax(1);
178
+ state.setRay(incoming);
179
+ }
180
+ lightServer.shadeBakeResult(state);
181
+ return state;
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Get scene world space bounding box.
187
+ *
188
+ * @return scene bounding box
189
+ */
190
+ public BoundingBox getBounds() {
191
+ return instanceList.getWorldBounds(null);
192
+ }
193
+
194
+ public void accumulateStats(IntersectionState state) {
195
+ stats.accumulate(state);
196
+ }
197
+
198
+ public void accumulateStats(ShadingCache cache) {
199
+ stats.accumulate(cache);
200
+ }
201
+
202
+ void trace(Ray r, IntersectionState state) {
203
+ // stats
204
+ state.numRays++;
205
+ // reset object
206
+ state.instance = null;
207
+ state.current = null;
208
+ for (int i = 0; i < infiniteInstanceList.getNumPrimitives(); i++) {
209
+ infiniteInstanceList.intersectPrimitive(r, i, state);
210
+ }
211
+ // reset for next accel structure
212
+ state.current = null;
213
+ intAccel.intersect(r, state);
214
+ }
215
+
216
+ Color traceShadow(Ray r, IntersectionState state) {
217
+ state.numShadowRays++;
218
+ trace(r, state);
219
+ return state.hit() ? Color.WHITE : Color.BLACK;
220
+ }
221
+
222
+ void traceBake(Ray r, IntersectionState state) {
223
+ // set the instance as if tracing a regular instanced object
224
+ state.current = bakingInstance;
225
+ // reset object
226
+ state.instance = null;
227
+ bakingAccel.intersect(r, state);
228
+ }
229
+
230
+ private void createAreaLightInstances() {
231
+ ArrayList<Instance> infiniteAreaLights = null;
232
+ ArrayList<Instance> areaLights = null;
233
+ // create an area light instance from each light source if possible
234
+ for (LightSource l : lightServer.lights) {
235
+ Instance lightInstance = l.createInstance();
236
+ if (lightInstance != null) {
237
+ if (lightInstance.getBounds() == null) {
238
+ if (infiniteAreaLights == null) {
239
+ infiniteAreaLights = new ArrayList<Instance>();
240
+ }
241
+ infiniteAreaLights.add(lightInstance);
242
+ } else {
243
+ if (areaLights == null) {
244
+ areaLights = new ArrayList<Instance>();
245
+ }
246
+ areaLights.add(lightInstance);
247
+ }
248
+ }
249
+ }
250
+ // add area light sources to the list of instances if they exist
251
+ if (infiniteAreaLights != null && infiniteAreaLights.size() > 0) {
252
+ infiniteInstanceList.addLightSourceInstances(infiniteAreaLights.toArray(new Instance[infiniteAreaLights.size()]));
253
+ } else {
254
+ infiniteInstanceList.clearLightSources();
255
+ }
256
+ if (areaLights != null && areaLights.size() > 0) {
257
+ instanceList.addLightSourceInstances(areaLights.toArray(new Instance[areaLights.size()]));
258
+ } else {
259
+ instanceList.clearLightSources();
260
+ }
261
+ // FIXME: this _could_ be done incrementally to avoid top-level rebuilds
262
+ // each frame
263
+ rebuildAccel = true;
264
+ }
265
+
266
+ private void removeAreaLightInstances() {
267
+ infiniteInstanceList.clearLightSources();
268
+ instanceList.clearLightSources();
269
+ }
270
+
271
+ /**
272
+ * Render the scene using the specified options, image sampler and display.
273
+ *
274
+ * @param options rendering options object
275
+ * @param sampler image sampler
276
+ * @param display display to send the final image to, a default display will
277
+ * be created if <code>null</code>
278
+ */
279
+ public void render(Options options, ImageSampler sampler, Display display) {
280
+ stats.reset();
281
+ if (display == null) {
282
+ display = new FrameDisplay();
283
+ }
284
+
285
+ if (bakingInstance != null) {
286
+ UI.printDetailed(Module.SCENE, "Creating primitives for lightmapping ...");
287
+ bakingPrimitives = bakingInstance.getBakingPrimitives();
288
+ if (bakingPrimitives == null) {
289
+ UI.printError(Module.SCENE, "Lightmap baking is not supported for the given instance.");
290
+ return;
291
+ }
292
+ int n = bakingPrimitives.getNumPrimitives();
293
+ UI.printInfo(Module.SCENE, "Building acceleration structure for lightmapping (%d num primitives) ...", n);
294
+ bakingAccel = AccelerationStructureFactory.create("auto", n, true);
295
+ bakingAccel.build(bakingPrimitives);
296
+ } else {
297
+ bakingPrimitives = null;
298
+ bakingAccel = null;
299
+ }
300
+ bakingViewDependent = options.getBoolean("baking.viewdep", bakingViewDependent);
301
+
302
+ if ((bakingInstance != null && bakingViewDependent && camera == null) || (bakingInstance == null && camera == null)) {
303
+ UI.printError(Module.SCENE, "No camera found");
304
+ return;
305
+ }
306
+
307
+ // read from options
308
+ threads = options.getInt("threads", 0);
309
+ lowPriority = options.getBoolean("threads.lowPriority", true);
310
+ imageWidth = options.getInt("resolutionX", 640);
311
+ imageHeight = options.getInt("resolutionY", 480);
312
+ // limit resolution to 16k
313
+ imageWidth = MathUtils.clamp(imageWidth, 1, 1 << 14);
314
+ imageHeight = MathUtils.clamp(imageHeight, 1, 1 << 14);
315
+
316
+ // prepare lights
317
+ createAreaLightInstances();
318
+
319
+ // get acceleration structure info
320
+ // count scene primitives
321
+ long numPrimitives = 0;
322
+ for (int i = 0; i < instanceList.getNumPrimitives(); i++) {
323
+ numPrimitives += instanceList.getNumPrimitives(i);
324
+ }
325
+ UI.printInfo(Module.SCENE, "Scene stats:");
326
+ UI.printInfo(Module.SCENE, " * Infinite instances: %d", infiniteInstanceList.getNumPrimitives());
327
+ UI.printInfo(Module.SCENE, " * Instances: %d", instanceList.getNumPrimitives());
328
+ UI.printInfo(Module.SCENE, " * Primitives: %d", numPrimitives);
329
+ String accelName = options.getString("accel", null);
330
+ if (accelName != null) {
331
+ rebuildAccel = rebuildAccel || !acceltype.equals(accelName);
332
+ acceltype = accelName;
333
+ }
334
+ UI.printInfo(Module.SCENE, " * Instance accel: %s", acceltype);
335
+ if (rebuildAccel) {
336
+ intAccel = AccelerationStructureFactory.create(acceltype, instanceList.getNumPrimitives(), false);
337
+ intAccel.build(instanceList);
338
+ rebuildAccel = false;
339
+ }
340
+ UI.printInfo(Module.SCENE, " * Scene bounds: %s", getBounds());
341
+ UI.printInfo(Module.SCENE, " * Scene center: %s", getBounds().getCenter());
342
+ UI.printInfo(Module.SCENE, " * Scene diameter: %.2f", getBounds().getExtents().length());
343
+ UI.printInfo(Module.SCENE, " * Lightmap bake: %s", bakingInstance != null ? (bakingViewDependent ? "view" : "ortho") : "off");
344
+ if (sampler == null) {
345
+ return;
346
+ }
347
+ if (!lightServer.build(options)) {
348
+ return;
349
+ }
350
+ // render
351
+ UI.printInfo(Module.SCENE, "Rendering ...");
352
+ stats.setResolution(imageWidth, imageHeight);
353
+ sampler.prepare(options, this, imageWidth, imageHeight);
354
+ sampler.render(display);
355
+ // show statistics
356
+ stats.displayStats();
357
+ lightServer.showStats();
358
+ // discard area lights
359
+ removeAreaLightInstances();
360
+ // discard baking tesselation/accel structure
361
+ bakingPrimitives = null;
362
+ bakingAccel = null;
363
+ UI.printInfo(Module.SCENE, "Done.");
364
+ }
365
+
366
+ /**
367
+ * Create a photon map as prescribed by the given {@link PhotonStore}.
368
+ *
369
+ * @param map object that will recieve shot photons
370
+ * @param type type of photons being shot
371
+ * @param seed QMC seed parameter
372
+ * @return <code>true</code> upon success
373
+ */
374
+ public boolean calculatePhotons(PhotonStore map, String type, int seed, Options options) {
375
+ return lightServer.calculatePhotons(map, type, seed, options);
376
+ }
377
+ }