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,413 @@
1
+ package org.sunflow.core.primitive;
2
+
3
+ import java.io.FileWriter;
4
+ import java.io.IOException;
5
+ import java.util.Locale;
6
+ import java.util.logging.Level;
7
+ import java.util.logging.Logger;
8
+
9
+ import org.sunflow.SunflowAPI;
10
+ import org.sunflow.core.Instance;
11
+ import org.sunflow.core.IntersectionState;
12
+ import org.sunflow.core.ParameterList;
13
+ import org.sunflow.core.PrimitiveList;
14
+ import org.sunflow.core.Ray;
15
+ import org.sunflow.core.ShadingState;
16
+ import org.sunflow.core.ParameterList.FloatParameter;
17
+ import org.sunflow.core.ParameterList.InterpolationType;
18
+ import org.sunflow.math.BoundingBox;
19
+ import org.sunflow.math.MathUtils;
20
+ import org.sunflow.math.Matrix4;
21
+ import org.sunflow.math.OrthoNormalBasis;
22
+ import org.sunflow.math.Point3;
23
+ import org.sunflow.math.Vector3;
24
+ import org.sunflow.system.UI;
25
+ import org.sunflow.system.UI.Module;
26
+
27
+ public class QuadMesh implements PrimitiveList {
28
+
29
+ protected float[] points;
30
+ protected int[] quads;
31
+ private FloatParameter normals;
32
+ private FloatParameter uvs;
33
+ private byte[] faceShaders;
34
+
35
+ public QuadMesh() {
36
+ quads = null;
37
+ points = null;
38
+ normals = uvs = new FloatParameter();
39
+ faceShaders = null;
40
+ }
41
+
42
+ public void writeObj(String filename) {
43
+ try {
44
+ FileWriter file = new FileWriter(filename);
45
+ file.write(String.format("o object\n"));
46
+ for (int i = 0; i < points.length; i += 3) {
47
+ file.write(String.format("v %g %g %g\n", points[i], points[i + 1], points[i + 2]));
48
+ }
49
+ file.write("s off\n");
50
+ for (int i = 0; i < quads.length; i += 4) {
51
+ file.write(String.format("f %d %d %d %d\n", quads[i] + 1, quads[i + 1] + 1, quads[i + 2] + 1, quads[i + 3] + 1));
52
+ }
53
+ file.close();
54
+ } catch (IOException e) {
55
+ Logger.getLogger(QuadMesh.class.getName()).log(Level.SEVERE, null, e);
56
+ }
57
+ }
58
+
59
+ @Override
60
+ public boolean update(ParameterList pl, SunflowAPI api) {
61
+ {
62
+ int[] quadsu = pl.getIntArray("quads");
63
+ if (quadsu != null) {
64
+ this.quads = quadsu;
65
+ }
66
+ }
67
+ if (quads == null) {
68
+ UI.printError(Module.GEOM, "Unable to update mesh - quad indices are missing");
69
+ return false;
70
+ }
71
+ if (quads.length % 4 != 0) {
72
+ UI.printWarning(Module.GEOM, "Quad index data is not a multiple of 4 - some quads may be missing");
73
+ }
74
+ pl.setFaceCount(quads.length / 4);
75
+ {
76
+ FloatParameter pointsP = pl.getPointArray("points");
77
+ if (pointsP != null) {
78
+ if (pointsP.interp != InterpolationType.VERTEX) {
79
+ UI.printError(Module.GEOM, "Point interpolation type must be set to \"vertex\" - was \"%s\"", pointsP.interp.name().toLowerCase(Locale.ENGLISH));
80
+ } else {
81
+ points = pointsP.data;
82
+ }
83
+ }
84
+ }
85
+ if (points == null) {
86
+ UI.printError(Module.GEOM, "Unabled to update mesh - vertices are missing");
87
+ return false;
88
+ }
89
+ pl.setVertexCount(points.length / 3);
90
+ pl.setFaceVertexCount(4 * (quads.length / 4));
91
+ FloatParameter normalsp = pl.getVectorArray("normals");
92
+ if (normalsp != null) {
93
+ this.normals = normalsp;
94
+ }
95
+ FloatParameter uvsp = pl.getTexCoordArray("uvs");
96
+ if (uvsp != null) {
97
+ this.uvs = uvsp;
98
+ }
99
+ int[] faceShadersl = pl.getIntArray("faceshaders");
100
+ if (faceShadersl != null && faceShadersl.length == quads.length / 4) {
101
+ this.faceShaders = new byte[faceShadersl.length];
102
+ for (int i = 0; i < faceShadersl.length; i++) {
103
+ int v = faceShadersl[i];
104
+ if (v > 255) {
105
+ UI.printWarning(Module.GEOM, "Shader index too large on quad %d", i);
106
+ }
107
+ this.faceShaders[i] = (byte) (v & 0xFF);
108
+ }
109
+ }
110
+ return true;
111
+ }
112
+
113
+ @Override
114
+ public float getPrimitiveBound(int primID, int i) {
115
+ int quad = 4 * primID;
116
+ int a = 3 * quads[quad + 0];
117
+ int b = 3 * quads[quad + 1];
118
+ int c = 3 * quads[quad + 2];
119
+ int d = 3 * quads[quad + 3];
120
+ int axis = i >>> 1;
121
+ if ((i & 1) == 0) {
122
+ return MathUtils.min(points[a + axis], points[b + axis], points[c + axis], points[d + axis]);
123
+ } else {
124
+ return MathUtils.max(points[a + axis], points[b + axis], points[c + axis], points[d + axis]);
125
+ }
126
+ }
127
+
128
+ @Override
129
+ public BoundingBox getWorldBounds(Matrix4 o2w) {
130
+ BoundingBox bounds = new BoundingBox();
131
+ if (o2w == null) {
132
+ for (int i = 0; i < points.length; i += 3) {
133
+ bounds.include(points[i], points[i + 1], points[i + 2]);
134
+ }
135
+ } else {
136
+ // transform vertices first
137
+ for (int i = 0; i < points.length; i += 3) {
138
+ float x = points[i];
139
+ float y = points[i + 1];
140
+ float z = points[i + 2];
141
+ float wx = o2w.transformPX(x, y, z);
142
+ float wy = o2w.transformPY(x, y, z);
143
+ float wz = o2w.transformPZ(x, y, z);
144
+ bounds.include(wx, wy, wz);
145
+ }
146
+ }
147
+ return bounds;
148
+ }
149
+
150
+ @Override
151
+ public void intersectPrimitive(Ray r, int primID, IntersectionState state) {
152
+ // ray/bilinear patch intersection adapted from "Production Rendering:
153
+ // Design and Implementation" by Ian Stephenson (Ed.)
154
+ int quad = 4 * primID;
155
+ int p0 = 3 * quads[quad + 0];
156
+ int p1 = 3 * quads[quad + 1];
157
+ int p2 = 3 * quads[quad + 2];
158
+ int p3 = 3 * quads[quad + 3];
159
+ // transform patch into Hilbert space
160
+ final float A[] = {
161
+ points[p2 + 0] - points[p3 + 0] - points[p1 + 0] + points[p0 + 0],
162
+ points[p2 + 1] - points[p3 + 1] - points[p1 + 1] + points[p0 + 1],
163
+ points[p2 + 2] - points[p3 + 2] - points[p1 + 2] + points[p0 + 2]};
164
+ final float B[] = {points[p1 + 0] - points[p0 + 0],
165
+ points[p1 + 1] - points[p0 + 1],
166
+ points[p1 + 2] - points[p0 + 2]};
167
+ final float C[] = {points[p3 + 0] - points[p0 + 0],
168
+ points[p3 + 1] - points[p0 + 1],
169
+ points[p3 + 2] - points[p0 + 2]};
170
+ final float R[] = {r.ox - points[p0 + 0], r.oy - points[p0 + 1],
171
+ r.oz - points[p0 + 2]};
172
+ final float Q[] = {r.dx, r.dy, r.dz};
173
+
174
+ // pick major direction
175
+ float absqx = Math.abs(r.dx);
176
+ float absqy = Math.abs(r.dy);
177
+ float absqz = Math.abs(r.dz);
178
+
179
+ int X = 0, Y = 1, Z = 2;
180
+ if (absqx > absqy && absqx > absqz) {
181
+ // X = 0, Y = 1, Z = 2
182
+ } else if (absqy > absqz) {
183
+ // X = 1, Y = 0, Z = 2
184
+ X = 1;
185
+ Y = 0;
186
+ } else {
187
+ // X = 2, Y = 1, Z = 0
188
+ X = 2;
189
+ Z = 0;
190
+ }
191
+
192
+ float Cxz = C[X] * Q[Z] - C[Z] * Q[X];
193
+ float Cyx = C[Y] * Q[X] - C[X] * Q[Y];
194
+ float Czy = C[Z] * Q[Y] - C[Y] * Q[Z];
195
+ float Rxz = R[X] * Q[Z] - R[Z] * Q[X];
196
+ float Ryx = R[Y] * Q[X] - R[X] * Q[Y];
197
+ float Rzy = R[Z] * Q[Y] - R[Y] * Q[Z];
198
+ float Bxy = B[X] * Q[Y] - B[Y] * Q[X];
199
+ float Byz = B[Y] * Q[Z] - B[Z] * Q[Y];
200
+ float Bzx = B[Z] * Q[X] - B[X] * Q[Z];
201
+ float a = A[X] * Byz + A[Y] * Bzx + A[Z] * Bxy;
202
+ if (a == 0) {
203
+ // setup for linear equation
204
+ float b = B[X] * Czy + B[Y] * Cxz + B[Z] * Cyx;
205
+ float c = C[X] * Rzy + C[Y] * Rxz + C[Z] * Ryx;
206
+ float u = -c / b;
207
+ if (u >= 0 && u <= 1) {
208
+ float v = (u * Bxy + Ryx) / Cyx;
209
+ if (v >= 0 && v <= 1) {
210
+ float t = (B[X] * u + C[X] * v - R[X]) / Q[X];
211
+ if (r.isInside(t)) {
212
+ r.setMax(t);
213
+ state.setIntersection(primID, u, v);
214
+ }
215
+ }
216
+ }
217
+ } else {
218
+ // setup for quadratic equation
219
+ float b = A[X] * Rzy + A[Y] * Rxz + A[Z] * Ryx + B[X] * Czy + B[Y] * Cxz + B[Z] * Cyx;
220
+ float c = C[X] * Rzy + C[Y] * Rxz + C[Z] * Ryx;
221
+ float discrim = b * b - 4 * a * c;
222
+ // reject trivial cases
223
+ if (c * (a + b + c) > 0 && (discrim < 0 || a * c < 0 || b / a > 0 || b / a < -2)) {
224
+ return;
225
+ }
226
+ // solve quadratic
227
+ float q = b > 0 ? -0.5f * (b + (float) Math.sqrt(discrim)) : -0.5f * (b - (float) Math.sqrt(discrim));
228
+ // check first solution
229
+ float Axy = A[X] * Q[Y] - A[Y] * Q[X];
230
+ float u = q / a;
231
+ if (u >= 0 && u <= 1) {
232
+ float d = u * Axy - Cyx;
233
+ float v = -(u * Bxy + Ryx) / d;
234
+ if (v >= 0 && v <= 1) {
235
+ float t = (A[X] * u * v + B[X] * u + C[X] * v - R[X]) / Q[X];
236
+ if (r.isInside(t)) {
237
+ r.setMax(t);
238
+ state.setIntersection(primID, u, v);
239
+ }
240
+ }
241
+ }
242
+ u = c / q;
243
+ if (u >= 0 && u <= 1) {
244
+ float d = u * Axy - Cyx;
245
+ float v = -(u * Bxy + Ryx) / d;
246
+ if (v >= 0 && v <= 1) {
247
+ float t = (A[X] * u * v + B[X] * u + C[X] * v - R[X]) / Q[X];
248
+ if (r.isInside(t)) {
249
+ r.setMax(t);
250
+ state.setIntersection(primID, u, v);
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+
257
+ @Override
258
+ public int getNumPrimitives() {
259
+ return quads.length / 4;
260
+ }
261
+
262
+ @Override
263
+ public void prepareShadingState(ShadingState state) {
264
+ state.init();
265
+ Instance parent = state.getInstance();
266
+ int primID = state.getPrimitiveID();
267
+ float u = state.getU();
268
+ float v = state.getV();
269
+ state.getRay().getPoint(state.getPoint());
270
+ int quad = 4 * primID;
271
+ int index0 = quads[quad + 0];
272
+ int index1 = quads[quad + 1];
273
+ int index2 = quads[quad + 2];
274
+ int index3 = quads[quad + 3];
275
+ Point3 v0p = getPoint(index0);
276
+ Point3 v1p = getPoint(index1);
277
+ Point3 v2p = getPoint(index2);
278
+ Point3 v3p = getPoint(index2);
279
+ float tanux = (1 - v) * (v1p.x - v0p.x) + v * (v2p.x - v3p.x);
280
+ float tanuy = (1 - v) * (v1p.y - v0p.y) + v * (v2p.y - v3p.y);
281
+ float tanuz = (1 - v) * (v1p.z - v0p.z) + v * (v2p.z - v3p.z);
282
+
283
+ float tanvx = (1 - u) * (v3p.x - v0p.x) + u * (v2p.x - v1p.x);
284
+ float tanvy = (1 - u) * (v3p.y - v0p.y) + u * (v2p.y - v1p.y);
285
+ float tanvz = (1 - u) * (v3p.z - v0p.z) + u * (v2p.z - v1p.z);
286
+
287
+ float nx = tanuy * tanvz - tanuz * tanvy;
288
+ float ny = tanuz * tanvx - tanux * tanvz;
289
+ float nz = tanux * tanvy - tanuy * tanvx;
290
+
291
+ Vector3 ng = new Vector3(nx, ny, nz);
292
+ ng = state.transformNormalObjectToWorld(ng);
293
+ ng.normalize();
294
+ state.getGeoNormal().set(ng);
295
+
296
+ float k00 = (1 - u) * (1 - v);
297
+ float k10 = u * (1 - v);
298
+ float k01 = (1 - u) * v;
299
+ float k11 = u * v;
300
+
301
+ switch (normals.interp) {
302
+ case NONE:
303
+ case FACE: {
304
+ state.getNormal().set(ng);
305
+ break;
306
+ }
307
+ case VERTEX: {
308
+ int i30 = 3 * index0;
309
+ int i31 = 3 * index1;
310
+ int i32 = 3 * index2;
311
+ int i33 = 3 * index3;
312
+ float[] normalsv = this.normals.data;
313
+ state.getNormal().x = k00 * normalsv[i30 + 0] + k10 * normalsv[i31 + 0] + k11 * normalsv[i32 + 0] + k01 * normalsv[i33 + 0];
314
+ state.getNormal().y = k00 * normalsv[i30 + 1] + k10 * normalsv[i31 + 1] + k11 * normalsv[i32 + 1] + k01 * normalsv[i33 + 1];
315
+ state.getNormal().z = k00 * normalsv[i30 + 2] + k10 * normalsv[i31 + 2] + k11 * normalsv[i32 + 2] + k01 * normalsv[i33 + 2];
316
+ state.getNormal().set(state.transformNormalObjectToWorld(state.getNormal()));
317
+ state.getNormal().normalize();
318
+ break;
319
+ }
320
+ case FACEVARYING: {
321
+ int idx = 3 * quad;
322
+ float[] normalsf = this.normals.data;
323
+ state.getNormal().x = k00 * normalsf[idx + 0] + k10 * normalsf[idx + 3] + k11 * normalsf[idx + 6] + k01 * normalsf[idx + 9];
324
+ state.getNormal().y = k00 * normalsf[idx + 1] + k10 * normalsf[idx + 4] + k11 * normalsf[idx + 7] + k01 * normalsf[idx + 10];
325
+ state.getNormal().z = k00 * normalsf[idx + 2] + k10 * normalsf[idx + 5] + k11 * normalsf[idx + 8] + k01 * normalsf[idx + 11];
326
+ state.getNormal().set(state.transformNormalObjectToWorld(state.getNormal()));
327
+ state.getNormal().normalize();
328
+ break;
329
+ }
330
+ }
331
+ float uv00 = 0, uv01 = 0, uv10 = 0, uv11 = 0, uv20 = 0, uv21 = 0, uv30 = 0, uv31 = 0;
332
+ switch (uvs.interp) {
333
+ case NONE:
334
+ case FACE: {
335
+ state.getUV().x = 0;
336
+ state.getUV().y = 0;
337
+ break;
338
+ }
339
+ case VERTEX: {
340
+ int i20 = 2 * index0;
341
+ int i21 = 2 * index1;
342
+ int i22 = 2 * index2;
343
+ int i23 = 2 * index3;
344
+ float[] uvsv = this.uvs.data;
345
+ uv00 = uvsv[i20 + 0];
346
+ uv01 = uvsv[i20 + 1];
347
+ uv10 = uvsv[i21 + 0];
348
+ uv11 = uvsv[i21 + 1];
349
+ uv20 = uvsv[i22 + 0];
350
+ uv21 = uvsv[i22 + 1];
351
+ uv20 = uvsv[i23 + 0];
352
+ uv21 = uvsv[i23 + 1];
353
+ break;
354
+ }
355
+ case FACEVARYING: {
356
+ int idx = quad << 1;
357
+ float[] uvsf = this.uvs.data;
358
+ uv00 = uvsf[idx + 0];
359
+ uv01 = uvsf[idx + 1];
360
+ uv10 = uvsf[idx + 2];
361
+ uv11 = uvsf[idx + 3];
362
+ uv20 = uvsf[idx + 4];
363
+ uv21 = uvsf[idx + 5];
364
+ uv30 = uvsf[idx + 6];
365
+ uv31 = uvsf[idx + 7];
366
+ break;
367
+ }
368
+ }
369
+ if (uvs.interp != InterpolationType.NONE) {
370
+ // get exact uv coords and compute tangent vectors
371
+ state.getUV().x = k00 * uv00 + k10 * uv10 + k11 * uv20 + k01 * uv30;
372
+ state.getUV().y = k00 * uv01 + k10 * uv11 + k11 * uv21 + k01 * uv31;
373
+ float du1 = uv00 - uv20;
374
+ float du2 = uv10 - uv20;
375
+ float dv1 = uv01 - uv21;
376
+ float dv2 = uv11 - uv21;
377
+ Vector3 dp1 = Point3.sub(v0p, v2p, new Vector3()), dp2 = Point3.sub(v1p, v2p, new Vector3());
378
+ float determinant = du1 * dv2 - dv1 * du2;
379
+ if (determinant == 0.0f) {
380
+ // create basis in world space
381
+ state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
382
+ } else {
383
+ float invdet = 1.f / determinant;
384
+ // Vector3 dpdu = new Vector3();
385
+ // dpdu.x = (dv2 * dp1.x - dv1 * dp2.x) * invdet;
386
+ // dpdu.y = (dv2 * dp1.y - dv1 * dp2.y) * invdet;
387
+ // dpdu.z = (dv2 * dp1.z - dv1 * dp2.z) * invdet;
388
+ Vector3 dpdv = new Vector3();
389
+ dpdv.x = (-du2 * dp1.x + du1 * dp2.x) * invdet;
390
+ dpdv.y = (-du2 * dp1.y + du1 * dp2.y) * invdet;
391
+ dpdv.z = (-du2 * dp1.z + du1 * dp2.z) * invdet;
392
+ dpdv = state.transformVectorObjectToWorld(dpdv);
393
+ // create basis in world space
394
+ state.setBasis(OrthoNormalBasis.makeFromWV(state.getNormal(), dpdv));
395
+ }
396
+ } else {
397
+ state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
398
+ }
399
+ int shaderIndex = faceShaders == null ? 0 : (faceShaders[primID] & 0xFF);
400
+ state.setShader(parent.getShader(shaderIndex));
401
+ state.setModifier(parent.getModifier(shaderIndex));
402
+ }
403
+
404
+ protected Point3 getPoint(int i) {
405
+ i *= 3;
406
+ return new Point3(points[i], points[i + 1], points[i + 2]);
407
+ }
408
+
409
+ @Override
410
+ public PrimitiveList getBakingPrimitives() {
411
+ return null;
412
+ }
413
+ }
@@ -0,0 +1,101 @@
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 Sphere 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);
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 : 1;
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 localPoint = state.transformWorldToObject(state.getPoint());
49
+ state.getNormal().set(localPoint.x, localPoint.y, localPoint.z);
50
+ state.getNormal().normalize();
51
+
52
+ float phi = (float) Math.atan2(state.getNormal().y, state.getNormal().x);
53
+ if (phi < 0) {
54
+ phi += 2 * Math.PI;
55
+ }
56
+ float theta = (float) Math.acos(state.getNormal().z);
57
+ state.getUV().y = theta / (float) Math.PI;
58
+ state.getUV().x = phi / (float) (2 * Math.PI);
59
+ Vector3 v = new Vector3();
60
+ v.x = -2 * (float) Math.PI * state.getNormal().y;
61
+ v.y = 2 * (float) Math.PI * state.getNormal().x;
62
+ v.z = 0;
63
+ state.setShader(parent.getShader(0));
64
+ state.setModifier(parent.getModifier(0));
65
+ // into world space
66
+ Vector3 worldNormal = state.transformNormalObjectToWorld(state.getNormal());
67
+ v = state.transformVectorObjectToWorld(v);
68
+ state.getNormal().set(worldNormal);
69
+ state.getNormal().normalize();
70
+ state.getGeoNormal().set(state.getNormal());
71
+ // compute basis in world space
72
+ state.setBasis(OrthoNormalBasis.makeFromWV(state.getNormal(), v));
73
+
74
+ }
75
+
76
+ @Override
77
+ public void intersectPrimitive(Ray r, int primID, IntersectionState state) {
78
+ // intersect in local space
79
+ float qa = r.dx * r.dx + r.dy * r.dy + r.dz * r.dz;
80
+ float qb = 2 * ((r.dx * r.ox) + (r.dy * r.oy) + (r.dz * r.oz));
81
+ float qc = ((r.ox * r.ox) + (r.oy * r.oy) + (r.oz * r.oz)) - 1;
82
+ double[] t = Solvers.solveQuadric(qa, qb, qc);
83
+ if (t != null) {
84
+ // early rejection
85
+ if (t[0] >= r.getMax() || t[1] <= r.getMin()) {
86
+ return;
87
+ }
88
+ if (t[0] > r.getMin()) {
89
+ r.setMax((float) t[0]);
90
+ } else {
91
+ r.setMax((float) t[1]);
92
+ }
93
+ state.setIntersection(0);
94
+ }
95
+ }
96
+
97
+ @Override
98
+ public PrimitiveList getBakingPrimitives() {
99
+ return null;
100
+ }
101
+ }