joonsrenderer 1.1-java

Sign up to get free protection for your applications and to get access to all the features.
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
+ }