joonsrenderer 1.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +53 -0
- data/.mvn/extensions.xml +8 -0
- data/CHANGELOG.md +2 -0
- data/Gemfile +6 -0
- data/LICENSE +674 -0
- data/README.md +2 -0
- data/Rakefile +43 -0
- data/docs/.gitignore +6 -0
- data/docs/_config.yml +20 -0
- data/docs/_includes/footer.html +38 -0
- data/docs/_includes/head.html +15 -0
- data/docs/_includes/header.html +27 -0
- data/docs/_includes/icon-github.html +1 -0
- data/docs/_includes/icon-github.svg +1 -0
- data/docs/_includes/icon-twitter.html +1 -0
- data/docs/_includes/icon-twitter.svg +1 -0
- data/docs/_layouts/default.html +20 -0
- data/docs/_layouts/page.html +14 -0
- data/docs/_layouts/post.html +15 -0
- data/docs/_posts/2017-01-08-animated_ray_tracing.md +72 -0
- data/docs/_posts/2017-01-08-welcome.md +78 -0
- data/docs/_sass/_base.scss +206 -0
- data/docs/_sass/_layout.scss +242 -0
- data/docs/_sass/_syntax-highlighting.scss +71 -0
- data/docs/about.md +12 -0
- data/docs/assets/Animation.ogv +0 -0
- data/docs/assets/Animation.png +0 -0
- data/docs/assets/basic.png +0 -0
- data/docs/assets/basic_traced.png +0 -0
- data/docs/css/main.scss +38 -0
- data/docs/favicon.ico +0 -0
- data/docs/feed.xml +30 -0
- data/docs/index.html +38 -0
- data/joonsrenderer.gemspec +23 -0
- data/lib/joonsrenderer.rb +12 -0
- data/lib/joonsrenderer/version.rb +3 -0
- data/pom.rb +75 -0
- data/pom.xml +163 -0
- data/src/main/java/SunflowGUI.java +1354 -0
- data/src/main/java/joons/JRFiller.java +79 -0
- data/src/main/java/joons/JRImagePanel.java +141 -0
- data/src/main/java/joons/JRRecorder.java +183 -0
- data/src/main/java/joons/JRStatics.java +199 -0
- data/src/main/java/joons/JoonsRenderer.java +837 -0
- data/src/main/java/org/sunflow/AsciiFileSunflowAPI.java +98 -0
- data/src/main/java/org/sunflow/Benchmark.java +313 -0
- data/src/main/java/org/sunflow/BinaryFileSunflowAPI.java +228 -0
- data/src/main/java/org/sunflow/FileSunflowAPI.java +354 -0
- data/src/main/java/org/sunflow/PluginRegistry.java +322 -0
- data/src/main/java/org/sunflow/RealtimeBenchmark.java +125 -0
- data/src/main/java/org/sunflow/RenderObjectMap.java +344 -0
- data/src/main/java/org/sunflow/SunflowAPI.java +762 -0
- data/src/main/java/org/sunflow/SunflowAPIInterface.java +277 -0
- data/src/main/java/org/sunflow/core/AccelerationStructure.java +20 -0
- data/src/main/java/org/sunflow/core/AccelerationStructureFactory.java +36 -0
- data/src/main/java/org/sunflow/core/BucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/Camera.java +125 -0
- data/src/main/java/org/sunflow/core/CameraLens.java +29 -0
- data/src/main/java/org/sunflow/core/CausticPhotonMapInterface.java +15 -0
- data/src/main/java/org/sunflow/core/Display.java +78 -0
- data/src/main/java/org/sunflow/core/Filter.java +27 -0
- data/src/main/java/org/sunflow/core/GIEngine.java +42 -0
- data/src/main/java/org/sunflow/core/Geometry.java +157 -0
- data/src/main/java/org/sunflow/core/GlobalPhotonMapInterface.java +21 -0
- data/src/main/java/org/sunflow/core/ImageSampler.java +26 -0
- data/src/main/java/org/sunflow/core/Instance.java +224 -0
- data/src/main/java/org/sunflow/core/InstanceList.java +83 -0
- data/src/main/java/org/sunflow/core/IntersectionState.java +120 -0
- data/src/main/java/org/sunflow/core/LightSample.java +104 -0
- data/src/main/java/org/sunflow/core/LightServer.java +382 -0
- data/src/main/java/org/sunflow/core/LightSource.java +67 -0
- data/src/main/java/org/sunflow/core/Modifier.java +16 -0
- data/src/main/java/org/sunflow/core/Options.java +20 -0
- data/src/main/java/org/sunflow/core/ParameterList.java +758 -0
- data/src/main/java/org/sunflow/core/PhotonStore.java +62 -0
- data/src/main/java/org/sunflow/core/PrimitiveList.java +70 -0
- data/src/main/java/org/sunflow/core/Ray.java +219 -0
- data/src/main/java/org/sunflow/core/RenderObject.java +25 -0
- data/src/main/java/org/sunflow/core/Scene.java +377 -0
- data/src/main/java/org/sunflow/core/SceneParser.java +58 -0
- data/src/main/java/org/sunflow/core/Shader.java +30 -0
- data/src/main/java/org/sunflow/core/ShadingCache.java +84 -0
- data/src/main/java/org/sunflow/core/ShadingState.java +939 -0
- data/src/main/java/org/sunflow/core/Statistics.java +85 -0
- data/src/main/java/org/sunflow/core/Tesselatable.java +36 -0
- data/src/main/java/org/sunflow/core/Texture.java +128 -0
- data/src/main/java/org/sunflow/core/TextureCache.java +48 -0
- data/src/main/java/org/sunflow/core/accel/BoundingIntervalHierarchy.java +652 -0
- data/src/main/java/org/sunflow/core/accel/KDTree.java +833 -0
- data/src/main/java/org/sunflow/core/accel/NullAccelerator.java +30 -0
- data/src/main/java/org/sunflow/core/accel/UniformGrid.java +329 -0
- data/src/main/java/org/sunflow/core/bucket/BucketOrderFactory.java +26 -0
- data/src/main/java/org/sunflow/core/bucket/ColumnBucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/bucket/DiagonalBucketOrder.java +28 -0
- data/src/main/java/org/sunflow/core/bucket/HilbertBucketOrder.java +65 -0
- data/src/main/java/org/sunflow/core/bucket/InvertedBucketOrder.java +28 -0
- data/src/main/java/org/sunflow/core/bucket/RandomBucketOrder.java +49 -0
- data/src/main/java/org/sunflow/core/bucket/RowBucketOrder.java +21 -0
- data/src/main/java/org/sunflow/core/bucket/SpiralBucketOrder.java +43 -0
- data/src/main/java/org/sunflow/core/camera/FisheyeLens.java +25 -0
- data/src/main/java/org/sunflow/core/camera/PinholeLens.java +43 -0
- data/src/main/java/org/sunflow/core/camera/SphericalLens.java +22 -0
- data/src/main/java/org/sunflow/core/camera/ThinLens.java +107 -0
- data/src/main/java/org/sunflow/core/display/FastDisplay.java +119 -0
- data/src/main/java/org/sunflow/core/display/FileDisplay.java +83 -0
- data/src/main/java/org/sunflow/core/display/FrameDisplay.java +97 -0
- data/src/main/java/org/sunflow/core/display/ImgPipeDisplay.java +109 -0
- data/src/main/java/org/sunflow/core/filter/BlackmanHarrisFilter.java +28 -0
- data/src/main/java/org/sunflow/core/filter/BoxFilter.java +16 -0
- data/src/main/java/org/sunflow/core/filter/CatmullRomFilter.java +29 -0
- data/src/main/java/org/sunflow/core/filter/CubicBSpline.java +32 -0
- data/src/main/java/org/sunflow/core/filter/GaussianFilter.java +24 -0
- data/src/main/java/org/sunflow/core/filter/LanczosFilter.java +30 -0
- data/src/main/java/org/sunflow/core/filter/MitchellFilter.java +28 -0
- data/src/main/java/org/sunflow/core/filter/SincFilter.java +25 -0
- data/src/main/java/org/sunflow/core/filter/TriangleFilter.java +16 -0
- data/src/main/java/org/sunflow/core/gi/AmbientOcclusionGIEngine.java +57 -0
- data/src/main/java/org/sunflow/core/gi/FakeGIEngine.java +48 -0
- data/src/main/java/org/sunflow/core/gi/InstantGI.java +194 -0
- data/src/main/java/org/sunflow/core/gi/IrradianceCacheGIEngine.java +268 -0
- data/src/main/java/org/sunflow/core/gi/PathTracingGIEngine.java +65 -0
- data/src/main/java/org/sunflow/core/light/DirectionalSpotlight.java +103 -0
- data/src/main/java/org/sunflow/core/light/ImageBasedLight.java +303 -0
- data/src/main/java/org/sunflow/core/light/PointLight.java +72 -0
- data/src/main/java/org/sunflow/core/light/SphereLight.java +166 -0
- data/src/main/java/org/sunflow/core/light/SunSkyLight.java +362 -0
- data/src/main/java/org/sunflow/core/light/TriangleMeshLight.java +296 -0
- data/src/main/java/org/sunflow/core/modifiers/BumpMappingModifier.java +37 -0
- data/src/main/java/org/sunflow/core/modifiers/NormalMapModifier.java +34 -0
- data/src/main/java/org/sunflow/core/modifiers/PerlinModifier.java +80 -0
- data/src/main/java/org/sunflow/core/parser/Keyword.java +39 -0
- data/src/main/java/org/sunflow/core/parser/RA2Parser.java +107 -0
- data/src/main/java/org/sunflow/core/parser/RA3Parser.java +68 -0
- data/src/main/java/org/sunflow/core/parser/SCAbstractParser.java +299 -0
- data/src/main/java/org/sunflow/core/parser/SCAsciiParser.java +251 -0
- data/src/main/java/org/sunflow/core/parser/SCBinaryParser.java +156 -0
- data/src/main/java/org/sunflow/core/parser/SCParser.java +1403 -0
- data/src/main/java/org/sunflow/core/parser/ShaveRibParser.java +174 -0
- data/src/main/java/org/sunflow/core/parser/TriParser.java +79 -0
- data/src/main/java/org/sunflow/core/photonmap/CausticPhotonMap.java +429 -0
- data/src/main/java/org/sunflow/core/photonmap/GlobalPhotonMap.java +530 -0
- data/src/main/java/org/sunflow/core/photonmap/GridPhotonMap.java +308 -0
- data/src/main/java/org/sunflow/core/primitive/Background.java +55 -0
- data/src/main/java/org/sunflow/core/primitive/BanchoffSurface.java +100 -0
- data/src/main/java/org/sunflow/core/primitive/Box.java +210 -0
- data/src/main/java/org/sunflow/core/primitive/CornellBox.java +476 -0
- data/src/main/java/org/sunflow/core/primitive/CubeGrid.java +318 -0
- data/src/main/java/org/sunflow/core/primitive/Cylinder.java +104 -0
- data/src/main/java/org/sunflow/core/primitive/Hair.java +275 -0
- data/src/main/java/org/sunflow/core/primitive/JuliaFractal.java +266 -0
- data/src/main/java/org/sunflow/core/primitive/ParticleSurface.java +114 -0
- data/src/main/java/org/sunflow/core/primitive/Plane.java +163 -0
- data/src/main/java/org/sunflow/core/primitive/QuadMesh.java +413 -0
- data/src/main/java/org/sunflow/core/primitive/Sphere.java +101 -0
- data/src/main/java/org/sunflow/core/primitive/SphereFlake.java +234 -0
- data/src/main/java/org/sunflow/core/primitive/Torus.java +145 -0
- data/src/main/java/org/sunflow/core/primitive/TriangleMesh.java +849 -0
- data/src/main/java/org/sunflow/core/renderer/BucketRenderer.java +491 -0
- data/src/main/java/org/sunflow/core/renderer/MultipassRenderer.java +237 -0
- data/src/main/java/org/sunflow/core/renderer/ProgressiveRenderer.java +171 -0
- data/src/main/java/org/sunflow/core/renderer/SimpleRenderer.java +106 -0
- data/src/main/java/org/sunflow/core/shader/AmbientOcclusionShader.java +53 -0
- data/src/main/java/org/sunflow/core/shader/AnisotropicWardShader.java +216 -0
- data/src/main/java/org/sunflow/core/shader/ConstantShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/DiffuseShader.java +65 -0
- data/src/main/java/org/sunflow/core/shader/GlassShader.java +147 -0
- data/src/main/java/org/sunflow/core/shader/IDShader.java +27 -0
- data/src/main/java/org/sunflow/core/shader/MirrorShader.java +68 -0
- data/src/main/java/org/sunflow/core/shader/NormalShader.java +32 -0
- data/src/main/java/org/sunflow/core/shader/PhongShader.java +89 -0
- data/src/main/java/org/sunflow/core/shader/PrimIDShader.java +30 -0
- data/src/main/java/org/sunflow/core/shader/QuickGrayShader.java +63 -0
- data/src/main/java/org/sunflow/core/shader/ShinyDiffuseShader.java +98 -0
- data/src/main/java/org/sunflow/core/shader/SimpleShader.java +24 -0
- data/src/main/java/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedDiffuseShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedPhongShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedShinyDiffuseShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/TexturedWardShader.java +31 -0
- data/src/main/java/org/sunflow/core/shader/UVShader.java +27 -0
- data/src/main/java/org/sunflow/core/shader/UberShader.java +149 -0
- data/src/main/java/org/sunflow/core/shader/ViewCausticsShader.java +33 -0
- data/src/main/java/org/sunflow/core/shader/ViewGlobalPhotonsShader.java +25 -0
- data/src/main/java/org/sunflow/core/shader/ViewIrradianceShader.java +25 -0
- data/src/main/java/org/sunflow/core/shader/WireframeShader.java +83 -0
- data/src/main/java/org/sunflow/core/tesselatable/BezierMesh.java +254 -0
- data/src/main/java/org/sunflow/core/tesselatable/FileMesh.java +251 -0
- data/src/main/java/org/sunflow/core/tesselatable/Gumbo.java +1147 -0
- data/src/main/java/org/sunflow/core/tesselatable/Teapot.java +237 -0
- data/src/main/java/org/sunflow/image/Bitmap.java +15 -0
- data/src/main/java/org/sunflow/image/BitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/BitmapWriter.java +79 -0
- data/src/main/java/org/sunflow/image/BlackbodySpectrum.java +16 -0
- data/src/main/java/org/sunflow/image/ChromaticitySpectrum.java +55 -0
- data/src/main/java/org/sunflow/image/Color.java +374 -0
- data/src/main/java/org/sunflow/image/ColorEncoder.java +94 -0
- data/src/main/java/org/sunflow/image/ColorFactory.java +122 -0
- data/src/main/java/org/sunflow/image/ConstantSpectralCurve.java +21 -0
- data/src/main/java/org/sunflow/image/IrregularSpectralCurve.java +57 -0
- data/src/main/java/org/sunflow/image/RGBSpace.java +207 -0
- data/src/main/java/org/sunflow/image/RegularSpectralCurve.java +30 -0
- data/src/main/java/org/sunflow/image/SpectralCurve.java +118 -0
- data/src/main/java/org/sunflow/image/XYZColor.java +50 -0
- data/src/main/java/org/sunflow/image/formats/BitmapBlack.java +27 -0
- data/src/main/java/org/sunflow/image/formats/BitmapG8.java +36 -0
- data/src/main/java/org/sunflow/image/formats/BitmapGA8.java +30 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGB8.java +40 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGBA8.java +40 -0
- data/src/main/java/org/sunflow/image/formats/BitmapRGBE.java +60 -0
- data/src/main/java/org/sunflow/image/formats/BitmapXYZ.java +38 -0
- data/src/main/java/org/sunflow/image/formats/GenericBitmap.java +73 -0
- data/src/main/java/org/sunflow/image/readers/BMPBitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/readers/HDRBitmapReader.java +155 -0
- data/src/main/java/org/sunflow/image/readers/IGIBitmapReader.java +104 -0
- data/src/main/java/org/sunflow/image/readers/JPGBitmapReader.java +39 -0
- data/src/main/java/org/sunflow/image/readers/PNGBitmapReader.java +40 -0
- data/src/main/java/org/sunflow/image/readers/TGABitmapReader.java +141 -0
- data/src/main/java/org/sunflow/image/writers/EXRBitmapWriter.java +395 -0
- data/src/main/java/org/sunflow/image/writers/HDRBitmapWriter.java +54 -0
- data/src/main/java/org/sunflow/image/writers/IGIBitmapWriter.java +75 -0
- data/src/main/java/org/sunflow/image/writers/PNGBitmapWriter.java +39 -0
- data/src/main/java/org/sunflow/image/writers/TGABitmapWriter.java +63 -0
- data/src/main/java/org/sunflow/math/BoundingBox.java +340 -0
- data/src/main/java/org/sunflow/math/MathUtils.java +159 -0
- data/src/main/java/org/sunflow/math/Matrix4.java +573 -0
- data/src/main/java/org/sunflow/math/MovingMatrix4.java +119 -0
- data/src/main/java/org/sunflow/math/OrthoNormalBasis.java +110 -0
- data/src/main/java/org/sunflow/math/PerlinScalar.java +331 -0
- data/src/main/java/org/sunflow/math/PerlinVector.java +132 -0
- data/src/main/java/org/sunflow/math/Point2.java +36 -0
- data/src/main/java/org/sunflow/math/Point3.java +133 -0
- data/src/main/java/org/sunflow/math/QMC.java +209 -0
- data/src/main/java/org/sunflow/math/Solvers.java +142 -0
- data/src/main/java/org/sunflow/math/Vector3.java +197 -0
- data/src/main/java/org/sunflow/system/BenchmarkFramework.java +73 -0
- data/src/main/java/org/sunflow/system/BenchmarkTest.java +17 -0
- data/src/main/java/org/sunflow/system/ByteUtil.java +119 -0
- data/src/main/java/org/sunflow/system/FileUtils.java +27 -0
- data/src/main/java/org/sunflow/system/ImagePanel.java +282 -0
- data/src/main/java/org/sunflow/system/Memory.java +18 -0
- data/src/main/java/org/sunflow/system/Parser.java +162 -0
- data/src/main/java/org/sunflow/system/Plugins.java +142 -0
- data/src/main/java/org/sunflow/system/RenderGlobalsPanel.java +209 -0
- data/src/main/java/org/sunflow/system/SearchPath.java +67 -0
- data/src/main/java/org/sunflow/system/Timer.java +53 -0
- data/src/main/java/org/sunflow/system/UI.java +112 -0
- data/src/main/java/org/sunflow/system/UserInterface.java +46 -0
- data/src/main/java/org/sunflow/system/ui/ConsoleInterface.java +48 -0
- data/src/main/java/org/sunflow/system/ui/SilentInterface.java +28 -0
- data/src/main/java/org/sunflow/util/FastHashMap.java +220 -0
- data/src/main/java/org/sunflow/util/FloatArray.java +77 -0
- data/src/main/java/org/sunflow/util/IntArray.java +77 -0
- data/src/test/java/a_maintest.java +129 -0
- metadata +300 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
package org.sunflow;
|
|
2
|
+
|
|
3
|
+
import java.io.BufferedOutputStream;
|
|
4
|
+
import java.io.FileOutputStream;
|
|
5
|
+
import java.io.IOException;
|
|
6
|
+
import java.io.OutputStream;
|
|
7
|
+
import java.util.Locale;
|
|
8
|
+
|
|
9
|
+
import org.sunflow.core.ParameterList.InterpolationType;
|
|
10
|
+
import org.sunflow.core.parser.Keyword;
|
|
11
|
+
import org.sunflow.math.Matrix4;
|
|
12
|
+
|
|
13
|
+
class AsciiFileSunflowAPI extends FileSunflowAPI {
|
|
14
|
+
|
|
15
|
+
private OutputStream stream;
|
|
16
|
+
|
|
17
|
+
AsciiFileSunflowAPI(String filename) throws IOException {
|
|
18
|
+
stream = new BufferedOutputStream(new FileOutputStream(filename));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Override
|
|
22
|
+
protected void writeBoolean(boolean value) {
|
|
23
|
+
if (value) {
|
|
24
|
+
writeString("true");
|
|
25
|
+
} else {
|
|
26
|
+
writeString("false");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Override
|
|
31
|
+
protected void writeFloat(float value) {
|
|
32
|
+
writeString(String.format("%s", value));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Override
|
|
36
|
+
protected void writeInt(int value) {
|
|
37
|
+
writeString(String.format("%d", value));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
protected void writeInterpolationType(InterpolationType interp) {
|
|
42
|
+
writeString(String.format("%s", interp.toString().toLowerCase(Locale.ENGLISH)));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Override
|
|
46
|
+
protected void writeKeyword(Keyword keyword) {
|
|
47
|
+
writeString(String.format("%s", keyword.toString().toLowerCase(Locale.ENGLISH).replace("_array", "[]")));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Override
|
|
51
|
+
protected void writeMatrix(Matrix4 value) {
|
|
52
|
+
writeString("row");
|
|
53
|
+
for (float f : value.asRowMajor()) {
|
|
54
|
+
writeFloat(f);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@Override
|
|
59
|
+
protected void writeNewline(int indentNext) {
|
|
60
|
+
try {
|
|
61
|
+
stream.write('\n');
|
|
62
|
+
for (int i = 0; i < indentNext; i++) {
|
|
63
|
+
stream.write('\t');
|
|
64
|
+
}
|
|
65
|
+
} catch (IOException e) {
|
|
66
|
+
throw new RuntimeException(e.getMessage());
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@Override
|
|
71
|
+
protected void writeString(String string) {
|
|
72
|
+
try {
|
|
73
|
+
// check if we need to write string with quotes
|
|
74
|
+
if (string.contains(" ") && !string.contains("<code>")) {
|
|
75
|
+
stream.write(String.format("\"%s\"", string).getBytes());
|
|
76
|
+
} else {
|
|
77
|
+
stream.write(string.getBytes());
|
|
78
|
+
}
|
|
79
|
+
stream.write(' ');
|
|
80
|
+
} catch (IOException e) {
|
|
81
|
+
throw new RuntimeException(e.getMessage());
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Override
|
|
86
|
+
protected void writeVerbatimString(String string) {
|
|
87
|
+
writeString(String.format("<code>%s\n</code> ", string));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@Override
|
|
91
|
+
public void close() {
|
|
92
|
+
try {
|
|
93
|
+
stream.close();
|
|
94
|
+
} catch (IOException e) {
|
|
95
|
+
throw new RuntimeException(e.getMessage());
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
package org.sunflow;
|
|
2
|
+
|
|
3
|
+
import java.awt.image.BufferedImage;
|
|
4
|
+
import java.io.IOException;
|
|
5
|
+
import java.net.URL;
|
|
6
|
+
|
|
7
|
+
import javax.imageio.ImageIO;
|
|
8
|
+
|
|
9
|
+
import org.sunflow.core.Display;
|
|
10
|
+
import org.sunflow.core.display.FileDisplay;
|
|
11
|
+
import org.sunflow.core.display.FrameDisplay;
|
|
12
|
+
import org.sunflow.image.Color;
|
|
13
|
+
import org.sunflow.math.Matrix4;
|
|
14
|
+
import org.sunflow.math.Point3;
|
|
15
|
+
import org.sunflow.math.Vector3;
|
|
16
|
+
import org.sunflow.system.BenchmarkFramework;
|
|
17
|
+
import org.sunflow.system.BenchmarkTest;
|
|
18
|
+
import org.sunflow.system.UI;
|
|
19
|
+
import org.sunflow.system.UserInterface;
|
|
20
|
+
import org.sunflow.system.UI.Module;
|
|
21
|
+
import org.sunflow.system.UI.PrintLevel;
|
|
22
|
+
|
|
23
|
+
public class Benchmark implements BenchmarkTest, UserInterface, Display {
|
|
24
|
+
|
|
25
|
+
private int resolution;
|
|
26
|
+
private boolean showOutput;
|
|
27
|
+
private boolean showBenchmarkOutput;
|
|
28
|
+
private boolean saveOutput;
|
|
29
|
+
private boolean showWindow;
|
|
30
|
+
private int threads;
|
|
31
|
+
private int[] referenceImage;
|
|
32
|
+
private int[] validationImage;
|
|
33
|
+
private int errorThreshold;
|
|
34
|
+
final String DIFFUSE = "diffuse";
|
|
35
|
+
final String TRANSFORM = "transform";
|
|
36
|
+
final String TEAPOT = "teapot";
|
|
37
|
+
|
|
38
|
+
public static void main(String[] args) {
|
|
39
|
+
if (args.length == 0) {
|
|
40
|
+
System.out.println("Benchmark options:");
|
|
41
|
+
System.out.println(" -regen Regenerate reference images for a variety of sizes");
|
|
42
|
+
System.out.println(" -bench [threads] [resolution] Run a single iteration of the benchmark using the specified thread count and image resolution");
|
|
43
|
+
System.out.println(" Default: threads=0 (auto-detect cpus), resolution=256");
|
|
44
|
+
System.out.println(" -show Render the benchmark scene into a window without performing validation");
|
|
45
|
+
} else if (args[0].equals("-regen")) {
|
|
46
|
+
int[] sizes = {32, 64, 96, 128, 256, 384, 512};
|
|
47
|
+
for (int s : sizes) {
|
|
48
|
+
// run a single iteration to generate the reference image
|
|
49
|
+
Benchmark b = new Benchmark(s, true, false, true);
|
|
50
|
+
b.kernelMain();
|
|
51
|
+
}
|
|
52
|
+
} else if (args[0].equals("-bench")) {
|
|
53
|
+
int threads = 0, resolution = 256;
|
|
54
|
+
if (args.length > 1) {
|
|
55
|
+
threads = Integer.parseInt(args[1]);
|
|
56
|
+
}
|
|
57
|
+
if (args.length > 2) {
|
|
58
|
+
resolution = Integer.parseInt(args[2]);
|
|
59
|
+
}
|
|
60
|
+
Benchmark benchmark = new Benchmark(resolution, false, true, false, threads, false);
|
|
61
|
+
benchmark.kernelBegin();
|
|
62
|
+
benchmark.kernelMain();
|
|
63
|
+
benchmark.kernelEnd();
|
|
64
|
+
} else if (args[0].equals("-show")) {
|
|
65
|
+
Benchmark benchmark = new Benchmark(512, true, true, false, 0, true);
|
|
66
|
+
benchmark.kernelMain();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public Benchmark() {
|
|
71
|
+
this(384, false, true, false);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public Benchmark(int resolution, boolean showOutput, boolean showBenchmarkOutput, boolean saveOutput) {
|
|
75
|
+
this(resolution, showOutput, showBenchmarkOutput, saveOutput, 0, false);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public Benchmark(int resolution, boolean showOutput, boolean showBenchmarkOutput, boolean saveOutput, int threads, boolean showWindow) {
|
|
79
|
+
UI.set(this);
|
|
80
|
+
this.resolution = resolution;
|
|
81
|
+
this.showOutput = showOutput;
|
|
82
|
+
this.showBenchmarkOutput = showBenchmarkOutput;
|
|
83
|
+
this.saveOutput = saveOutput;
|
|
84
|
+
this.showWindow = showWindow;
|
|
85
|
+
this.threads = threads;
|
|
86
|
+
errorThreshold = 6;
|
|
87
|
+
// fetch reference image from resources (jar file or classpath)
|
|
88
|
+
if (saveOutput) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
URL imageURL = Benchmark.class.getResource(String.format("/resources/golden_%04X.png", resolution));
|
|
92
|
+
if (imageURL == null) {
|
|
93
|
+
UI.printError(Module.BENCH, "Unable to find reference frame!");
|
|
94
|
+
}
|
|
95
|
+
UI.printInfo(Module.BENCH, "Loading reference image from: %s", imageURL);
|
|
96
|
+
try {
|
|
97
|
+
BufferedImage bi = ImageIO.read(imageURL);
|
|
98
|
+
if (bi.getWidth() != resolution || bi.getHeight() != resolution) {
|
|
99
|
+
UI.printError(Module.BENCH, "Reference image has invalid resolution! Expected %dx%d found %dx%d", resolution, resolution, bi.getWidth(), bi.getHeight());
|
|
100
|
+
}
|
|
101
|
+
referenceImage = new int[resolution * resolution];
|
|
102
|
+
for (int y = 0, i = 0; y < resolution; y++) {
|
|
103
|
+
for (int x = 0; x < resolution; x++, i++) {
|
|
104
|
+
referenceImage[i] = bi.getRGB(x, resolution - 1 - y); // flip
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} catch (IOException e) {
|
|
108
|
+
UI.printError(Module.BENCH, "Unable to load reference frame!");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public void execute() {
|
|
113
|
+
// 10 iterations maximum - 10 minute time limit
|
|
114
|
+
BenchmarkFramework framework = new BenchmarkFramework(10, 600);
|
|
115
|
+
framework.execute(this);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private class BenchmarkScene extends SunflowAPI {
|
|
119
|
+
|
|
120
|
+
final String GRAY_SHADER = "gray_shader";
|
|
121
|
+
final String SHADERS = "shaders";
|
|
122
|
+
|
|
123
|
+
public BenchmarkScene() {
|
|
124
|
+
build();
|
|
125
|
+
render(SunflowAPI.DEFAULT_OPTIONS, showWindow ? new FrameDisplay() : saveOutput ? new FileDisplay(String.format("resources/golden_%04X.png", resolution)) : Benchmark.this);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@Override
|
|
129
|
+
public final void build() {
|
|
130
|
+
// settings
|
|
131
|
+
parameter("threads", threads);
|
|
132
|
+
// spawn regular priority threads
|
|
133
|
+
parameter("threads.lowPriority", false);
|
|
134
|
+
parameter("resolutionX", resolution);
|
|
135
|
+
parameter("resolutionY", resolution);
|
|
136
|
+
parameter("aa.min", -1);
|
|
137
|
+
parameter("aa.max", 1);
|
|
138
|
+
parameter("filter", "triangle");
|
|
139
|
+
parameter("depths.diffuse", 2);
|
|
140
|
+
parameter("depths.reflection", 2);
|
|
141
|
+
parameter("depths.refraction", 2);
|
|
142
|
+
parameter("bucket.order", "hilbert");
|
|
143
|
+
parameter("bucket.size", 32);
|
|
144
|
+
// gi options
|
|
145
|
+
parameter("gi.engine", "igi");
|
|
146
|
+
parameter("gi.igi.samples", 90);
|
|
147
|
+
parameter("gi.igi.c", 0.000008f);
|
|
148
|
+
options(SunflowAPI.DEFAULT_OPTIONS);
|
|
149
|
+
buildCornellBox();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private void buildCornellBox() {
|
|
153
|
+
// camera
|
|
154
|
+
parameter(TRANSFORM, Matrix4.lookAt(new Point3(0, 0, -600), new Point3(0, 0, 0), new Vector3(0, 1, 0)));
|
|
155
|
+
parameter("fov", 45.0f);
|
|
156
|
+
camera("main_camera", "pinhole");
|
|
157
|
+
parameter("camera", "main_camera");
|
|
158
|
+
options(SunflowAPI.DEFAULT_OPTIONS);
|
|
159
|
+
// cornell box
|
|
160
|
+
float minX = -200;
|
|
161
|
+
float maxX = 200;
|
|
162
|
+
float minY = -160;
|
|
163
|
+
float maxY = minY + 400;
|
|
164
|
+
float minZ = -250;
|
|
165
|
+
float maxZ = 200;
|
|
166
|
+
|
|
167
|
+
float[] verts = new float[]{minX, minY, minZ, maxX, minY, minZ,
|
|
168
|
+
maxX, minY, maxZ, minX, minY, maxZ, minX, maxY, minZ, maxX,
|
|
169
|
+
maxY, minZ, maxX, maxY, maxZ, minX, maxY, maxZ,};
|
|
170
|
+
int[] indices = new int[]{0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 1,
|
|
171
|
+
2, 5, 5, 6, 2, 2, 3, 6, 6, 7, 3, 0, 3, 4, 4, 7, 3};
|
|
172
|
+
|
|
173
|
+
parameter(DIFFUSE, null, 0.70f, 0.70f, 0.70f);
|
|
174
|
+
shader(GRAY_SHADER, DIFFUSE);
|
|
175
|
+
parameter(DIFFUSE, null, 0.80f, 0.25f, 0.25f);
|
|
176
|
+
shader("red_shader", DIFFUSE);
|
|
177
|
+
parameter(DIFFUSE, null, 0.25f, 0.25f, 0.80f);
|
|
178
|
+
shader("blue_shader", DIFFUSE);
|
|
179
|
+
|
|
180
|
+
// build walls
|
|
181
|
+
parameter("triangles", indices);
|
|
182
|
+
parameter("points", "point", "vertex", verts);
|
|
183
|
+
parameter("faceshaders", new int[]{0, 0, 0, 0, 1, 1, 0, 0, 2, 2});
|
|
184
|
+
geometry("walls", "triangle_mesh");
|
|
185
|
+
|
|
186
|
+
// instance walls
|
|
187
|
+
parameter(SHADERS, new String[]{GRAY_SHADER, "red_shader",
|
|
188
|
+
"blue_shader"});
|
|
189
|
+
instance("walls.instance", "walls");
|
|
190
|
+
|
|
191
|
+
// create mesh light
|
|
192
|
+
parameter("points", "point", "vertex", new float[]{-50, maxY - 1,
|
|
193
|
+
-50, 50, maxY - 1, -50, 50, maxY - 1, 50, -50, maxY - 1, 50});
|
|
194
|
+
parameter("triangles", new int[]{0, 1, 2, 2, 3, 0});
|
|
195
|
+
parameter("radiance", null, 15, 15, 15);
|
|
196
|
+
parameter("samples", 8);
|
|
197
|
+
light("light", "triangle_mesh");
|
|
198
|
+
|
|
199
|
+
// spheres
|
|
200
|
+
parameter("eta", 1.6f);
|
|
201
|
+
shader("Glass", "glass");
|
|
202
|
+
sphere("glass_sphere", "Glass", -120, minY + 55, -150, 50);
|
|
203
|
+
parameter("color", null, 0.70f, 0.70f, 0.70f);
|
|
204
|
+
shader("Mirror", "mirror");
|
|
205
|
+
sphere("mirror_sphere", "Mirror", 100, minY + 60, -50, 50);
|
|
206
|
+
|
|
207
|
+
// scanned model
|
|
208
|
+
geometry(TEAPOT, TEAPOT);
|
|
209
|
+
parameter(TRANSFORM, Matrix4.translation(80, -50, 100).multiply(Matrix4.rotateX((float) -Math.PI / 6)).multiply(Matrix4.rotateY((float) Math.PI / 4)).multiply(Matrix4.rotateX((float) -Math.PI / 2).multiply(Matrix4.scale(1.2f))));
|
|
210
|
+
parameter(SHADERS, GRAY_SHADER);
|
|
211
|
+
instance("teapot.instance1", TEAPOT);
|
|
212
|
+
parameter(TRANSFORM, Matrix4.translation(-80, -160, 50).multiply(Matrix4.rotateY((float) Math.PI / 4)).multiply(Matrix4.rotateX((float) -Math.PI / 2).multiply(Matrix4.scale(1.2f))));
|
|
213
|
+
parameter(SHADERS, GRAY_SHADER);
|
|
214
|
+
instance("teapot.instance2", TEAPOT);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private void sphere(String name, String shaderName, float x, float y, float z, float radius) {
|
|
218
|
+
geometry(name, "sphere");
|
|
219
|
+
parameter(TRANSFORM, Matrix4.translation(x, y, z).multiply(Matrix4.scale(radius)));
|
|
220
|
+
parameter(SHADERS, shaderName);
|
|
221
|
+
instance(name + ".instance", name);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
@Override
|
|
226
|
+
public void kernelBegin() {
|
|
227
|
+
// allocate a fresh validation target
|
|
228
|
+
validationImage = new int[resolution * resolution];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
@Override
|
|
232
|
+
public void kernelMain() {
|
|
233
|
+
// this builds and renders the scene
|
|
234
|
+
new BenchmarkScene();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@Override
|
|
238
|
+
public void kernelEnd() {
|
|
239
|
+
// make sure the rendered image was correct
|
|
240
|
+
int diff = 0;
|
|
241
|
+
if (referenceImage != null && validationImage.length == referenceImage.length) {
|
|
242
|
+
for (int i = 0; i < validationImage.length; i++) {
|
|
243
|
+
// count absolute RGB differences
|
|
244
|
+
diff += Math.abs((validationImage[i] & 0xFF) - (referenceImage[i] & 0xFF));
|
|
245
|
+
diff += Math.abs(((validationImage[i] >> 8) & 0xFF) - ((referenceImage[i] >> 8) & 0xFF));
|
|
246
|
+
diff += Math.abs(((validationImage[i] >> 16) & 0xFF) - ((referenceImage[i] >> 16) & 0xFF));
|
|
247
|
+
}
|
|
248
|
+
if (diff > errorThreshold) {
|
|
249
|
+
UI.printError(Module.BENCH, "Image check failed! - #errors: %d", diff);
|
|
250
|
+
} else {
|
|
251
|
+
UI.printInfo(Module.BENCH, "Image check passed!");
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
UI.printError(Module.BENCH, "Image check failed! - reference is not comparable");
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@Override
|
|
260
|
+
public void print(Module m, PrintLevel level, String s) {
|
|
261
|
+
if (showOutput || (showBenchmarkOutput && m == Module.BENCH)) {
|
|
262
|
+
System.out.println(UI.formatOutput(m, level, s));
|
|
263
|
+
}
|
|
264
|
+
if (level == PrintLevel.ERROR) {
|
|
265
|
+
throw new RuntimeException(s);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@Override
|
|
270
|
+
public void taskStart(String s, int min, int max) {
|
|
271
|
+
// render progress display not needed
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
@Override
|
|
275
|
+
public void taskStop() {
|
|
276
|
+
// render progress display not needed
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@Override
|
|
280
|
+
public void taskUpdate(int current) {
|
|
281
|
+
// render progress display not needed
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
@Override
|
|
285
|
+
public void imageBegin(int w, int h, int bucketSize) {
|
|
286
|
+
// we can assume w == h == resolution
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@Override
|
|
290
|
+
public void imageEnd() {
|
|
291
|
+
// nothing needs to be done - image verification is done externally
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@Override
|
|
295
|
+
public void imageFill(int x, int y, int w, int h, Color c, float alpha) {
|
|
296
|
+
// this is not used
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
@Override
|
|
300
|
+
public void imagePrepare(int x, int y, int w, int h, int id) {
|
|
301
|
+
// this is not needed
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
@Override
|
|
305
|
+
public void imageUpdate(int x, int y, int w, int h, Color[] data, float[] alpha) {
|
|
306
|
+
// copy bucket data to validation image
|
|
307
|
+
for (int j = 0, index = 0; j < h; j++, y++) {
|
|
308
|
+
for (int i = 0, offset = x + resolution * (resolution - 1 - y); i < w; i++, index++, offset++) {
|
|
309
|
+
validationImage[offset] = data[index].copy().toNonLinear().toRGB();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
package org.sunflow;
|
|
2
|
+
|
|
3
|
+
import java.io.BufferedOutputStream;
|
|
4
|
+
import java.io.DataOutputStream;
|
|
5
|
+
import java.io.FileNotFoundException;
|
|
6
|
+
import java.io.FileOutputStream;
|
|
7
|
+
import java.io.IOException;
|
|
8
|
+
|
|
9
|
+
import org.sunflow.core.ParameterList.InterpolationType;
|
|
10
|
+
import org.sunflow.core.parser.Keyword;
|
|
11
|
+
import org.sunflow.math.Matrix4;
|
|
12
|
+
|
|
13
|
+
class BinaryFileSunflowAPI extends FileSunflowAPI {
|
|
14
|
+
|
|
15
|
+
private DataOutputStream stream;
|
|
16
|
+
|
|
17
|
+
BinaryFileSunflowAPI(String filename) throws FileNotFoundException {
|
|
18
|
+
stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@Override
|
|
22
|
+
protected void writeBoolean(boolean value) {
|
|
23
|
+
try {
|
|
24
|
+
if (value) {
|
|
25
|
+
stream.write(1);
|
|
26
|
+
} else {
|
|
27
|
+
stream.write(0);
|
|
28
|
+
}
|
|
29
|
+
} catch (IOException e) {
|
|
30
|
+
// throw as a silent exception to avoid having to propage throw
|
|
31
|
+
// declarations upwards
|
|
32
|
+
throw new RuntimeException(e.getMessage());
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Override
|
|
37
|
+
protected void writeFloat(float value) {
|
|
38
|
+
writeInt(Float.floatToRawIntBits(value));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@Override
|
|
42
|
+
protected void writeInt(int value) {
|
|
43
|
+
try {
|
|
44
|
+
// little endian, LSB first
|
|
45
|
+
stream.write(value & 0xFF);
|
|
46
|
+
stream.write((value >>> 8) & 0xFF);
|
|
47
|
+
stream.write((value >>> 16) & 0xFF);
|
|
48
|
+
stream.write((value >>> 24) & 0xFF);
|
|
49
|
+
} catch (IOException e) {
|
|
50
|
+
throw new RuntimeException(e.getMessage());
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@Override
|
|
55
|
+
protected void writeInterpolationType(InterpolationType interp) {
|
|
56
|
+
try {
|
|
57
|
+
switch (interp) {
|
|
58
|
+
case NONE:
|
|
59
|
+
stream.write('n');
|
|
60
|
+
break;
|
|
61
|
+
case VERTEX:
|
|
62
|
+
stream.write('v');
|
|
63
|
+
break;
|
|
64
|
+
case FACE:
|
|
65
|
+
stream.write('p');
|
|
66
|
+
break;
|
|
67
|
+
case FACEVARYING:
|
|
68
|
+
stream.write('f');
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
throw new RuntimeException(String.format("Unknown interpolation type \"%s\"", interp.toString()));
|
|
72
|
+
}
|
|
73
|
+
} catch (IOException e) {
|
|
74
|
+
throw new RuntimeException(e.getMessage());
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@Override
|
|
79
|
+
protected void writeKeyword(Keyword keyword) {
|
|
80
|
+
try {
|
|
81
|
+
switch (keyword) {
|
|
82
|
+
case RESET:
|
|
83
|
+
writeExtendedKeyword('R');
|
|
84
|
+
break;
|
|
85
|
+
case PARAMETER:
|
|
86
|
+
stream.write('p');
|
|
87
|
+
break;
|
|
88
|
+
case GEOMETRY:
|
|
89
|
+
stream.write('g');
|
|
90
|
+
break;
|
|
91
|
+
case INSTANCE:
|
|
92
|
+
stream.write('i');
|
|
93
|
+
break;
|
|
94
|
+
case SHADER:
|
|
95
|
+
stream.write('s');
|
|
96
|
+
break;
|
|
97
|
+
case MODIFIER:
|
|
98
|
+
stream.write('m');
|
|
99
|
+
break;
|
|
100
|
+
case LIGHT:
|
|
101
|
+
stream.write('l');
|
|
102
|
+
break;
|
|
103
|
+
case CAMERA:
|
|
104
|
+
stream.write('c');
|
|
105
|
+
break;
|
|
106
|
+
case OPTIONS:
|
|
107
|
+
stream.write('o');
|
|
108
|
+
break;
|
|
109
|
+
case INCLUDE:
|
|
110
|
+
writeExtendedKeyword('i');
|
|
111
|
+
break;
|
|
112
|
+
case REMOVE:
|
|
113
|
+
writeExtendedKeyword('r');
|
|
114
|
+
break;
|
|
115
|
+
case FRAME:
|
|
116
|
+
writeExtendedKeyword('f');
|
|
117
|
+
break;
|
|
118
|
+
case PLUGIN:
|
|
119
|
+
writeExtendedKeyword('p');
|
|
120
|
+
break;
|
|
121
|
+
case SEARCHPATH:
|
|
122
|
+
writeExtendedKeyword('s');
|
|
123
|
+
break;
|
|
124
|
+
case STRING:
|
|
125
|
+
writeDatatypeKeyword('s', false);
|
|
126
|
+
break;
|
|
127
|
+
case BOOL:
|
|
128
|
+
writeDatatypeKeyword('b', false);
|
|
129
|
+
break;
|
|
130
|
+
case INT:
|
|
131
|
+
writeDatatypeKeyword('i', false);
|
|
132
|
+
break;
|
|
133
|
+
case FLOAT:
|
|
134
|
+
writeDatatypeKeyword('f', false);
|
|
135
|
+
break;
|
|
136
|
+
case COLOR:
|
|
137
|
+
writeDatatypeKeyword('c', false);
|
|
138
|
+
break;
|
|
139
|
+
case POINT:
|
|
140
|
+
writeDatatypeKeyword('p', false);
|
|
141
|
+
break;
|
|
142
|
+
case VECTOR:
|
|
143
|
+
writeDatatypeKeyword('v', false);
|
|
144
|
+
break;
|
|
145
|
+
case TEXCOORD:
|
|
146
|
+
writeDatatypeKeyword('t', false);
|
|
147
|
+
break;
|
|
148
|
+
case MATRIX:
|
|
149
|
+
writeDatatypeKeyword('m', false);
|
|
150
|
+
break;
|
|
151
|
+
case STRING_ARRAY:
|
|
152
|
+
writeDatatypeKeyword('s', true);
|
|
153
|
+
break;
|
|
154
|
+
case INT_ARRAY:
|
|
155
|
+
writeDatatypeKeyword('i', true);
|
|
156
|
+
break;
|
|
157
|
+
case FLOAT_ARRAY:
|
|
158
|
+
writeDatatypeKeyword('f', true);
|
|
159
|
+
break;
|
|
160
|
+
case POINT_ARRAY:
|
|
161
|
+
writeDatatypeKeyword('p', true);
|
|
162
|
+
break;
|
|
163
|
+
case VECTOR_ARRAY:
|
|
164
|
+
writeDatatypeKeyword('v', true);
|
|
165
|
+
break;
|
|
166
|
+
case TEXCOORD_ARRAY:
|
|
167
|
+
writeDatatypeKeyword('t', true);
|
|
168
|
+
break;
|
|
169
|
+
case MATRIX_ARRAY:
|
|
170
|
+
writeDatatypeKeyword('m', true);
|
|
171
|
+
break;
|
|
172
|
+
default:
|
|
173
|
+
throw new RuntimeException(String.format("Unknown keyword \"%s\" requested", keyword.toString()));
|
|
174
|
+
}
|
|
175
|
+
} catch (IOException e) {
|
|
176
|
+
throw new RuntimeException(e.getMessage());
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private void writeExtendedKeyword(int code) throws IOException {
|
|
181
|
+
stream.write('x');
|
|
182
|
+
stream.write(code);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// helper routine for datatype keywords
|
|
186
|
+
private void writeDatatypeKeyword(int type, boolean isArray) throws IOException {
|
|
187
|
+
stream.write('t');
|
|
188
|
+
stream.write(type);
|
|
189
|
+
writeBoolean(isArray);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@Override
|
|
193
|
+
protected void writeMatrix(Matrix4 value) {
|
|
194
|
+
for (float f : value.asRowMajor()) {
|
|
195
|
+
writeFloat(f);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
@Override
|
|
200
|
+
protected void writeString(String string) {
|
|
201
|
+
try {
|
|
202
|
+
byte[] data = string.getBytes("UTF-8");
|
|
203
|
+
writeInt(data.length);
|
|
204
|
+
stream.write(data);
|
|
205
|
+
} catch (Exception e) {
|
|
206
|
+
throw new RuntimeException(e.getMessage());
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
@Override
|
|
211
|
+
protected void writeVerbatimString(String string) {
|
|
212
|
+
writeString(string);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@Override
|
|
216
|
+
protected void writeNewline(int indentNext) {
|
|
217
|
+
// does nothing
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
@Override
|
|
221
|
+
public void close() {
|
|
222
|
+
try {
|
|
223
|
+
stream.close();
|
|
224
|
+
} catch (IOException e) {
|
|
225
|
+
throw new RuntimeException(e.getMessage());
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|