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,762 @@
|
|
|
1
|
+
package org.sunflow;
|
|
2
|
+
|
|
3
|
+
import java.io.File;
|
|
4
|
+
import java.io.FileInputStream;
|
|
5
|
+
import java.io.IOException;
|
|
6
|
+
import java.io.StringReader;
|
|
7
|
+
import java.util.Locale;
|
|
8
|
+
import java.util.logging.Level;
|
|
9
|
+
import java.util.logging.Logger;
|
|
10
|
+
import org.codehaus.commons.compiler.CompileException;
|
|
11
|
+
import org.codehaus.janino.ClassBodyEvaluator;
|
|
12
|
+
import org.codehaus.janino.Scanner;
|
|
13
|
+
import org.sunflow.core.Camera;
|
|
14
|
+
import org.sunflow.core.CameraLens;
|
|
15
|
+
import org.sunflow.core.Display;
|
|
16
|
+
import org.sunflow.core.Geometry;
|
|
17
|
+
import org.sunflow.core.ImageSampler;
|
|
18
|
+
import org.sunflow.core.Instance;
|
|
19
|
+
import org.sunflow.core.LightSource;
|
|
20
|
+
import org.sunflow.core.Modifier;
|
|
21
|
+
import org.sunflow.core.Options;
|
|
22
|
+
import org.sunflow.core.ParameterList;
|
|
23
|
+
import org.sunflow.core.PrimitiveList;
|
|
24
|
+
import org.sunflow.core.Scene;
|
|
25
|
+
import org.sunflow.core.SceneParser;
|
|
26
|
+
import org.sunflow.core.Shader;
|
|
27
|
+
import org.sunflow.core.Tesselatable;
|
|
28
|
+
import org.sunflow.core.ParameterList.InterpolationType;
|
|
29
|
+
import org.sunflow.image.ColorFactory;
|
|
30
|
+
import org.sunflow.image.ColorFactory.ColorSpecificationException;
|
|
31
|
+
import org.sunflow.math.BoundingBox;
|
|
32
|
+
import org.sunflow.math.Matrix4;
|
|
33
|
+
import org.sunflow.math.Point2;
|
|
34
|
+
import org.sunflow.math.Point3;
|
|
35
|
+
import org.sunflow.math.Vector3;
|
|
36
|
+
import org.sunflow.system.FileUtils;
|
|
37
|
+
import org.sunflow.system.SearchPath;
|
|
38
|
+
import org.sunflow.system.Timer;
|
|
39
|
+
import org.sunflow.system.UI;
|
|
40
|
+
import org.sunflow.system.UI.Module;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* This API gives a simple interface for creating scenes procedurally. This is
|
|
44
|
+
* the main entry point to Sunflow. To use this class, extend from it and
|
|
45
|
+
* implement the build method which may execute arbitrary code to create a
|
|
46
|
+
* scene.
|
|
47
|
+
*/
|
|
48
|
+
public class SunflowAPI implements SunflowAPIInterface {
|
|
49
|
+
|
|
50
|
+
public static final String VERSION = "1.0.0";
|
|
51
|
+
public static final String DEFAULT_OPTIONS = "::options";
|
|
52
|
+
private Scene scene;
|
|
53
|
+
private SearchPath includeSearchPath;
|
|
54
|
+
private SearchPath textureSearchPath;
|
|
55
|
+
private ParameterList parameterList;
|
|
56
|
+
private RenderObjectMap renderObjects;
|
|
57
|
+
private int currentFrame;
|
|
58
|
+
static String COULDNT_MESSAGE_FORMAT = "Could not compile: \"%s\"";
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* This is a quick system test which verifies that the user has launched
|
|
62
|
+
* Java properly.
|
|
63
|
+
*/
|
|
64
|
+
public static void runSystemCheck() {
|
|
65
|
+
final long RECOMMENDED_MAX_SIZE = 800;
|
|
66
|
+
long maxMb = Runtime.getRuntime().maxMemory() / 1048576;
|
|
67
|
+
if (maxMb < RECOMMENDED_MAX_SIZE) {
|
|
68
|
+
UI.printError(Module.API, "JVM available memory is below %d MB (found %d MB only).\nPlease make sure you launched the program with the -Xmx command line options.", RECOMMENDED_MAX_SIZE, maxMb);
|
|
69
|
+
}
|
|
70
|
+
String compiler = System.getProperty("java.vm.name");
|
|
71
|
+
if (compiler == null || !(compiler.contains("HotSpot") && compiler.contains("Server"))) {
|
|
72
|
+
UI.printError(Module.API, "You do not appear to be running Sun's server JVM\nPerformance may suffer");
|
|
73
|
+
}
|
|
74
|
+
UI.printDetailed(Module.API, "Java environment settings:");
|
|
75
|
+
UI.printDetailed(Module.API, " * Max memory available : %d MB", maxMb);
|
|
76
|
+
UI.printDetailed(Module.API, " * Virtual machine name : %s", compiler == null ? "<unknown" : compiler);
|
|
77
|
+
UI.printDetailed(Module.API, " * Operating system : %s", System.getProperty("os.name"));
|
|
78
|
+
UI.printDetailed(Module.API, " * CPU architecture : %s", System.getProperty("os.arch"));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates an empty scene.
|
|
83
|
+
*/
|
|
84
|
+
public SunflowAPI() {
|
|
85
|
+
reset();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@Override
|
|
89
|
+
public final void reset() {
|
|
90
|
+
scene = new Scene();
|
|
91
|
+
includeSearchPath = new SearchPath("include");
|
|
92
|
+
textureSearchPath = new SearchPath("texture");
|
|
93
|
+
parameterList = new ParameterList();
|
|
94
|
+
renderObjects = new RenderObjectMap();
|
|
95
|
+
currentFrame = 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@Override
|
|
99
|
+
public final void plugin(String type, String name, String code) {
|
|
100
|
+
switch (type) {
|
|
101
|
+
case "primitive":
|
|
102
|
+
PluginRegistry.PRIMITIVE_PLUGINS.registerPlugin(name, code);
|
|
103
|
+
break;
|
|
104
|
+
case "tesselatable":
|
|
105
|
+
PluginRegistry.TESSELATABLE_PLUGINS.registerPlugin(name, code);
|
|
106
|
+
break;
|
|
107
|
+
case "shader":
|
|
108
|
+
PluginRegistry.SHADER_PLUGINS.registerPlugin(name, code);
|
|
109
|
+
break;
|
|
110
|
+
case "modifier":
|
|
111
|
+
PluginRegistry.MODIFIER_PLUGINS.registerPlugin(name, code);
|
|
112
|
+
break;
|
|
113
|
+
case "camera_lens":
|
|
114
|
+
PluginRegistry.CAMERA_LENS_PLUGINS.registerPlugin(name, code);
|
|
115
|
+
break;
|
|
116
|
+
case "light":
|
|
117
|
+
PluginRegistry.LIGHT_SOURCE_PLUGINS.registerPlugin(name, code);
|
|
118
|
+
break;
|
|
119
|
+
case "accel":
|
|
120
|
+
PluginRegistry.ACCEL_PLUGINS.registerPlugin(name, code);
|
|
121
|
+
break;
|
|
122
|
+
case "bucket_order":
|
|
123
|
+
PluginRegistry.BUCKET_ORDER_PLUGINS.registerPlugin(name, code);
|
|
124
|
+
break;
|
|
125
|
+
case "filter":
|
|
126
|
+
PluginRegistry.FILTER_PLUGINS.registerPlugin(name, code);
|
|
127
|
+
break;
|
|
128
|
+
case "gi_engine":
|
|
129
|
+
PluginRegistry.GI_ENGINE_PLUGINS.registerPlugin(name, code);
|
|
130
|
+
break;
|
|
131
|
+
case "caustic_photon_map":
|
|
132
|
+
PluginRegistry.CAUSTIC_PHOTON_MAP_PLUGINS.registerPlugin(name, code);
|
|
133
|
+
break;
|
|
134
|
+
case "global_photon_map":
|
|
135
|
+
PluginRegistry.GLOBAL_PHOTON_MAP_PLUGINS.registerPlugin(name, code);
|
|
136
|
+
break;
|
|
137
|
+
case "image_sampler":
|
|
138
|
+
PluginRegistry.IMAGE_SAMPLE_PLUGINS.registerPlugin(name, code);
|
|
139
|
+
break;
|
|
140
|
+
case "parser":
|
|
141
|
+
PluginRegistry.PARSER_PLUGINS.registerPlugin(name, code);
|
|
142
|
+
break;
|
|
143
|
+
case "bitmap_reader":
|
|
144
|
+
PluginRegistry.BITMAP_READER_PLUGINS.registerPlugin(name, code);
|
|
145
|
+
break;
|
|
146
|
+
case "bitmap_writer":
|
|
147
|
+
PluginRegistry.BITMAP_WRITER_PLUGINS.registerPlugin(name, code);
|
|
148
|
+
break;
|
|
149
|
+
default:
|
|
150
|
+
UI.printWarning(Module.API, "Unrecognized plugin type: \"%s\" - ignoring declaration of \"%s\"", type, name);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
@Override
|
|
156
|
+
public final void parameter(String name, String value) {
|
|
157
|
+
parameterList.addString(name, value);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@Override
|
|
161
|
+
public final void parameter(String name, boolean value) {
|
|
162
|
+
parameterList.addBoolean(name, value);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@Override
|
|
166
|
+
public final void parameter(String name, int value) {
|
|
167
|
+
parameterList.addInteger(name, value);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@Override
|
|
171
|
+
public final void parameter(String name, float value) {
|
|
172
|
+
parameterList.addFloat(name, value);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@Override
|
|
176
|
+
public final void parameter(String name, String colorspace, float... data) {
|
|
177
|
+
try {
|
|
178
|
+
parameterList.addColor(name, ColorFactory.createColor(colorspace, data));
|
|
179
|
+
} catch (ColorSpecificationException e) {
|
|
180
|
+
UI.printError(Module.API, "Unable to specify color: %s - ignoring parameter \"%s\"", e.getMessage(), name);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@Override
|
|
185
|
+
public final void parameter(String name, Point3 value) {
|
|
186
|
+
parameterList.addPoints(name, InterpolationType.NONE, new float[]{
|
|
187
|
+
value.x, value.y, value.z});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@Override
|
|
191
|
+
public final void parameter(String name, Vector3 value) {
|
|
192
|
+
parameterList.addVectors(name, InterpolationType.NONE, new float[]{
|
|
193
|
+
value.x, value.y, value.z});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@Override
|
|
197
|
+
public final void parameter(String name, Point2 value) {
|
|
198
|
+
parameterList.addTexCoords(name, InterpolationType.NONE, new float[]{
|
|
199
|
+
value.x, value.y});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
@Override
|
|
203
|
+
public final void parameter(String name, Matrix4 value) {
|
|
204
|
+
parameterList.addMatrices(name, InterpolationType.NONE, value.asRowMajor());
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
@Override
|
|
208
|
+
public final void parameter(String name, int[] value) {
|
|
209
|
+
parameterList.addIntegerArray(name, value);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@Override
|
|
213
|
+
public final void parameter(String name, String[] value) {
|
|
214
|
+
parameterList.addStringArray(name, value);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@Override
|
|
218
|
+
public final void parameter(String name, String type, String interpolation, float[] data) {
|
|
219
|
+
InterpolationType interp;
|
|
220
|
+
try {
|
|
221
|
+
interp = InterpolationType.valueOf(interpolation.toUpperCase(Locale.ENGLISH));
|
|
222
|
+
} catch (IllegalArgumentException e) {
|
|
223
|
+
UI.printError(Module.API, "Unknown interpolation type: %s -- ignoring parameter \"%s\"", interpolation, name);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
switch (type) {
|
|
227
|
+
case "float":
|
|
228
|
+
parameterList.addFloats(name, interp, data);
|
|
229
|
+
break;
|
|
230
|
+
case "point":
|
|
231
|
+
parameterList.addPoints(name, interp, data);
|
|
232
|
+
break;
|
|
233
|
+
case "vector":
|
|
234
|
+
parameterList.addVectors(name, interp, data);
|
|
235
|
+
break;
|
|
236
|
+
case "texcoord":
|
|
237
|
+
parameterList.addTexCoords(name, interp, data);
|
|
238
|
+
break;
|
|
239
|
+
case "matrix":
|
|
240
|
+
parameterList.addMatrices(name, interp, data);
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
UI.printError(Module.API, "Unknown parameter type: %s -- ignoring parameter \"%s\"", type, name);
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
@Override
|
|
249
|
+
public void remove(String name) {
|
|
250
|
+
renderObjects.remove(name);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Update the specfied object using the currently active parameter list. The
|
|
255
|
+
* object is removed if the update fails to avoid leaving inconsistently set
|
|
256
|
+
* objects in the list.
|
|
257
|
+
*
|
|
258
|
+
* @param name name of the object to update
|
|
259
|
+
* @return <code>true</code> if the update was succesfull, or
|
|
260
|
+
* <code>false</code> if the update failed
|
|
261
|
+
*/
|
|
262
|
+
private boolean update(String name) {
|
|
263
|
+
boolean success = renderObjects.update(name, parameterList, this);
|
|
264
|
+
parameterList.clear(success);
|
|
265
|
+
return success;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@Override
|
|
269
|
+
public final void searchpath(String type, String path) {
|
|
270
|
+
switch (type) {
|
|
271
|
+
case "include":
|
|
272
|
+
includeSearchPath.addSearchPath(path);
|
|
273
|
+
break;
|
|
274
|
+
case "texture":
|
|
275
|
+
textureSearchPath.addSearchPath(path);
|
|
276
|
+
break;
|
|
277
|
+
default:
|
|
278
|
+
UI.printWarning(Module.API, "Invalid searchpath type: \"%s\"", type);
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Attempts to resolve the specified filename by checking it against the
|
|
285
|
+
* texture search path.
|
|
286
|
+
*
|
|
287
|
+
* @param filename filename
|
|
288
|
+
* @return a path which matches the filename, or filename if no matches are
|
|
289
|
+
* found
|
|
290
|
+
*/
|
|
291
|
+
public final String resolveTextureFilename(String filename) {
|
|
292
|
+
return textureSearchPath.resolvePath(filename);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Attempts to resolve the specified filename by checking it against the
|
|
297
|
+
* include search path.
|
|
298
|
+
*
|
|
299
|
+
* @param filename filename
|
|
300
|
+
* @return a path which matches the filename, or filename if no matches are
|
|
301
|
+
* found
|
|
302
|
+
*/
|
|
303
|
+
public final String resolveIncludeFilename(String filename) {
|
|
304
|
+
return includeSearchPath.resolvePath(filename);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@Override
|
|
308
|
+
public final void shader(String name, String shaderType) {
|
|
309
|
+
if (!isIncremental(shaderType)) {
|
|
310
|
+
// we are declaring a shader for the first time
|
|
311
|
+
if (renderObjects.has(name)) {
|
|
312
|
+
UI.printError(Module.API, "Unable to declare shader \"%s\", name is already in use", name);
|
|
313
|
+
parameterList.clear(true);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
Shader shader = PluginRegistry.SHADER_PLUGINS.createObject(shaderType);
|
|
317
|
+
if (shader == null) {
|
|
318
|
+
UI.printError(Module.API, "Unable to create shader of type \"%s\"", shaderType);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
renderObjects.put(name, shader);
|
|
322
|
+
}
|
|
323
|
+
// update existing shader (only if it is valid)
|
|
324
|
+
if (lookupShader(name) != null) {
|
|
325
|
+
update(name);
|
|
326
|
+
} else {
|
|
327
|
+
UI.printError(Module.API, "Unable to update shader \"%s\" - shader object was not found", name);
|
|
328
|
+
parameterList.clear(true);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
@Override
|
|
333
|
+
public final void modifier(String name, String modifierType) {
|
|
334
|
+
if (!isIncremental(modifierType)) {
|
|
335
|
+
// we are declaring a shader for the first time
|
|
336
|
+
if (renderObjects.has(name)) {
|
|
337
|
+
UI.printError(Module.API, "Unable to declare modifier \"%s\", name is already in use", name);
|
|
338
|
+
parameterList.clear(true);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
Modifier modifier = PluginRegistry.MODIFIER_PLUGINS.createObject(modifierType);
|
|
342
|
+
if (modifier == null) {
|
|
343
|
+
UI.printError(Module.API, "Unable to create modifier of type \"%s\"", modifierType);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
renderObjects.put(name, modifier);
|
|
347
|
+
}
|
|
348
|
+
// update existing shader (only if it is valid)
|
|
349
|
+
if (lookupModifier(name) != null) {
|
|
350
|
+
update(name);
|
|
351
|
+
} else {
|
|
352
|
+
UI.printError(Module.API, "Unable to update modifier \"%s\" - modifier object was not found", name);
|
|
353
|
+
parameterList.clear(true);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
@Override
|
|
358
|
+
public final void geometry(String name, String typeName) {
|
|
359
|
+
if (!isIncremental(typeName)) {
|
|
360
|
+
// we are declaring a geometry for the first time
|
|
361
|
+
if (renderObjects.has(name)) {
|
|
362
|
+
UI.printError(Module.API, "Unable to declare geometry \"%s\", name is already in use", name);
|
|
363
|
+
parameterList.clear(true);
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
// check tesselatable first
|
|
367
|
+
if (PluginRegistry.TESSELATABLE_PLUGINS.hasType(typeName)) {
|
|
368
|
+
Tesselatable tesselatable = PluginRegistry.TESSELATABLE_PLUGINS.createObject(typeName);
|
|
369
|
+
if (tesselatable == null) {
|
|
370
|
+
UI.printError(Module.API, "Unable to create tesselatable object of type \"%s\"", typeName);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
renderObjects.put(name, tesselatable);
|
|
374
|
+
} else {
|
|
375
|
+
PrimitiveList primitives = PluginRegistry.PRIMITIVE_PLUGINS.createObject(typeName);
|
|
376
|
+
if (primitives == null) {
|
|
377
|
+
UI.printError(Module.API, "Unable to create primitive of type \"%s\"", typeName);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
renderObjects.put(name, primitives);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (lookupGeometry(name) != null) {
|
|
384
|
+
update(name);
|
|
385
|
+
} else {
|
|
386
|
+
UI.printError(Module.API, "Unable to update geometry \"%s\" - geometry object was not found", name);
|
|
387
|
+
parameterList.clear(true);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
@Override
|
|
392
|
+
public final void instance(String name, String geoname) {
|
|
393
|
+
if (!isIncremental(geoname)) {
|
|
394
|
+
// we are declaring this instance for the first time
|
|
395
|
+
if (renderObjects.has(name)) {
|
|
396
|
+
UI.printError(Module.API, "Unable to declare instance \"%s\", name is already in use", name);
|
|
397
|
+
parameterList.clear(true);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
parameter("geometry", geoname);
|
|
401
|
+
renderObjects.put(name, new Instance());
|
|
402
|
+
}
|
|
403
|
+
if (lookupInstance(name) != null) {
|
|
404
|
+
update(name);
|
|
405
|
+
} else {
|
|
406
|
+
UI.printError(Module.API, "Unable to update instance \"%s\" - instance object was not found", name);
|
|
407
|
+
parameterList.clear(true);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
@Override
|
|
412
|
+
public final void light(String name, String lightType) {
|
|
413
|
+
if (!isIncremental(lightType)) {
|
|
414
|
+
// we are declaring this light for the first time
|
|
415
|
+
if (renderObjects.has(name)) {
|
|
416
|
+
UI.printError(Module.API, "Unable to declare light \"%s\", name is already in use", name);
|
|
417
|
+
parameterList.clear(true);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
LightSource light = PluginRegistry.LIGHT_SOURCE_PLUGINS.createObject(lightType);
|
|
421
|
+
if (light == null) {
|
|
422
|
+
UI.printError(Module.API, "Unable to create light source of type \"%s\"", lightType);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
renderObjects.put(name, light);
|
|
426
|
+
}
|
|
427
|
+
if (lookupLight(name) != null) {
|
|
428
|
+
update(name);
|
|
429
|
+
} else {
|
|
430
|
+
UI.printError(Module.API, "Unable to update instance \"%s\" - instance object was not found", name);
|
|
431
|
+
parameterList.clear(true);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
@Override
|
|
436
|
+
public final void camera(String name, String lensType) {
|
|
437
|
+
if (!isIncremental(lensType)) {
|
|
438
|
+
// we are declaring this camera for the first time
|
|
439
|
+
if (renderObjects.has(name)) {
|
|
440
|
+
UI.printError(Module.API, "Unable to declare camera \"%s\", name is already in use", name);
|
|
441
|
+
parameterList.clear(true);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
CameraLens lens = PluginRegistry.CAMERA_LENS_PLUGINS.createObject(lensType);
|
|
445
|
+
if (lens == null) {
|
|
446
|
+
UI.printError(Module.API, "Unable to create a camera lens of type \"%s\"", lensType);
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
renderObjects.put(name, new Camera(lens));
|
|
450
|
+
}
|
|
451
|
+
// update existing shader (only if it is valid)
|
|
452
|
+
if (lookupCamera(name) != null) {
|
|
453
|
+
update(name);
|
|
454
|
+
} else {
|
|
455
|
+
UI.printError(Module.API, "Unable to update camera \"%s\" - camera object was not found", name);
|
|
456
|
+
parameterList.clear(true);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
@Override
|
|
461
|
+
public final void options(String name) {
|
|
462
|
+
if (lookupOptions(name) == null) {
|
|
463
|
+
if (renderObjects.has(name)) {
|
|
464
|
+
UI.printError(Module.API, "Unable to declare options \"%s\", name is already in use", name);
|
|
465
|
+
parameterList.clear(true);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
renderObjects.put(name, new Options());
|
|
469
|
+
}
|
|
470
|
+
assert lookupOptions(name) != null;
|
|
471
|
+
update(name);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
private boolean isIncremental(String typeName) {
|
|
475
|
+
return typeName == null || typeName.equals("incremental");
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Retrieve a geometry object by its name, or
|
|
480
|
+
* <code>null</code> if no geometry was found, or if the specified object is
|
|
481
|
+
* not a geometry.
|
|
482
|
+
*
|
|
483
|
+
* @param name geometry name
|
|
484
|
+
* @return the geometry object associated with that name
|
|
485
|
+
*/
|
|
486
|
+
public final Geometry lookupGeometry(String name) {
|
|
487
|
+
return renderObjects.lookupGeometry(name);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Retrieve an instance object by its name, or
|
|
492
|
+
* <code>null</code> if no instance was found, or if the specified object is
|
|
493
|
+
* not an instance.
|
|
494
|
+
*
|
|
495
|
+
* @param name instance name
|
|
496
|
+
* @return the instance object associated with that name
|
|
497
|
+
*/
|
|
498
|
+
private Instance lookupInstance(String name) {
|
|
499
|
+
return renderObjects.lookupInstance(name);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Retrieve a shader object by its name, or
|
|
504
|
+
* <code>null</code> if no shader was found, or if the specified object is
|
|
505
|
+
* not a shader.
|
|
506
|
+
*
|
|
507
|
+
* @param name camera name
|
|
508
|
+
* @return the camera object associate with that name
|
|
509
|
+
*/
|
|
510
|
+
private Camera lookupCamera(String name) {
|
|
511
|
+
return renderObjects.lookupCamera(name);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
private Options lookupOptions(String name) {
|
|
515
|
+
return renderObjects.lookupOptions(name);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Retrieve a shader object by its name, or
|
|
520
|
+
* <code>null</code> if no shader was found, or if the specified object is
|
|
521
|
+
* not a shader.
|
|
522
|
+
*
|
|
523
|
+
* @param name shader name
|
|
524
|
+
* @return the shader object associated with that name
|
|
525
|
+
*/
|
|
526
|
+
public final Shader lookupShader(String name) {
|
|
527
|
+
return renderObjects.lookupShader(name);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Retrieve a modifier object by its name, or
|
|
532
|
+
* <code>null</code> if no modifier was found, or if the specified object is
|
|
533
|
+
* not a modifier.
|
|
534
|
+
*
|
|
535
|
+
* @param name modifier name
|
|
536
|
+
* @return the modifier object associated with that name
|
|
537
|
+
*/
|
|
538
|
+
public final Modifier lookupModifier(String name) {
|
|
539
|
+
return renderObjects.lookupModifier(name);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Retrieve a light object by its name, or
|
|
544
|
+
* <code>null</code> if no shader was found, or if the specified object is
|
|
545
|
+
* not a light.
|
|
546
|
+
*
|
|
547
|
+
* @param name light name
|
|
548
|
+
* @return the light object associated with that name
|
|
549
|
+
*/
|
|
550
|
+
private LightSource lookupLight(String name) {
|
|
551
|
+
return renderObjects.lookupLight(name);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
@Override
|
|
555
|
+
public final void render(String optionsName, Display display) {
|
|
556
|
+
renderObjects.updateScene(scene);
|
|
557
|
+
Options opt = lookupOptions(optionsName);
|
|
558
|
+
if (opt == null) {
|
|
559
|
+
opt = new Options();
|
|
560
|
+
}
|
|
561
|
+
scene.setCamera(lookupCamera(opt.getString("camera", null)));
|
|
562
|
+
|
|
563
|
+
// shader override
|
|
564
|
+
String shaderOverrideName = opt.getString("override.shader", "none");
|
|
565
|
+
boolean overridePhotons = opt.getBoolean("override.photons", false);
|
|
566
|
+
|
|
567
|
+
if (shaderOverrideName.equals("none")) {
|
|
568
|
+
scene.setShaderOverride(null, false);
|
|
569
|
+
} else {
|
|
570
|
+
Shader shader = lookupShader(shaderOverrideName);
|
|
571
|
+
if (shader == null) {
|
|
572
|
+
UI.printWarning(Module.API, "Unable to find shader \"%s\" for override, disabling", shaderOverrideName);
|
|
573
|
+
}
|
|
574
|
+
scene.setShaderOverride(shader, overridePhotons);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// baking
|
|
578
|
+
String bakingInstanceName = opt.getString("baking.instance", null);
|
|
579
|
+
if (bakingInstanceName != null) {
|
|
580
|
+
Instance bakingInstance = lookupInstance(bakingInstanceName);
|
|
581
|
+
if (bakingInstance == null) {
|
|
582
|
+
UI.printError(Module.API, "Unable to bake instance \"%s\" - not found", bakingInstanceName);
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
scene.setBakingInstance(bakingInstance);
|
|
586
|
+
} else {
|
|
587
|
+
scene.setBakingInstance(null);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
ImageSampler sampler = PluginRegistry.IMAGE_SAMPLE_PLUGINS.createObject(opt.getString("sampler", "bucket"));
|
|
591
|
+
scene.render(opt, sampler, display);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
@Override
|
|
595
|
+
public final boolean include(String filename) {
|
|
596
|
+
if (filename == null) {
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
filename = includeSearchPath.resolvePath(filename);
|
|
600
|
+
String extension = FileUtils.getExtension(filename);
|
|
601
|
+
SceneParser parser = PluginRegistry.PARSER_PLUGINS.createObject(extension);
|
|
602
|
+
if (parser == null) {
|
|
603
|
+
UI.printError(Module.API, "Unable to find a suitable parser for: \"%s\" (extension: %s)", filename, extension);
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
String currentFolder = new File(filename).getAbsoluteFile().getParentFile().getAbsolutePath();
|
|
607
|
+
includeSearchPath.addSearchPath(currentFolder);
|
|
608
|
+
textureSearchPath.addSearchPath(currentFolder);
|
|
609
|
+
return parser.parse(filename, this);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Retrieve the bounding box of the scene. This method will be valid only
|
|
614
|
+
* after a first call to {@link #render(String, Display)} has been made.
|
|
615
|
+
* @return
|
|
616
|
+
*/
|
|
617
|
+
public final BoundingBox getBounds() {
|
|
618
|
+
return scene.getBounds();
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* This method does nothing, but may be overriden to create scenes
|
|
623
|
+
* procedurally.
|
|
624
|
+
*/
|
|
625
|
+
public void build() {
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Create an API object from the specified file. Java files are read by
|
|
630
|
+
* Janino and are expected to implement a build method (they implement a
|
|
631
|
+
* derived class of SunflowAPI. The build method is called if the code
|
|
632
|
+
* compiles succesfully. Other files types are handled by the parse method.
|
|
633
|
+
*
|
|
634
|
+
* @param filename filename to load
|
|
635
|
+
* @param frameNumber
|
|
636
|
+
* @return a valid SunflowAPI object or <code>null</code> on failure
|
|
637
|
+
*/
|
|
638
|
+
public static SunflowAPI create(String filename, int frameNumber) {
|
|
639
|
+
if (filename == null) {
|
|
640
|
+
return new SunflowAPI();
|
|
641
|
+
}
|
|
642
|
+
SunflowAPI api = null;
|
|
643
|
+
if (filename.endsWith(".java")) {
|
|
644
|
+
Timer t = new Timer();
|
|
645
|
+
UI.printInfo(Module.API, "Compiling \"" + filename + "\" ...");
|
|
646
|
+
t.start();
|
|
647
|
+
try {
|
|
648
|
+
try (FileInputStream stream = new FileInputStream(filename)) {
|
|
649
|
+
api = (SunflowAPI) ClassBodyEvaluator.createFastClassBodyEvaluator(new Scanner(filename, stream), SunflowAPI.class, ClassLoader.getSystemClassLoader());
|
|
650
|
+
}
|
|
651
|
+
} catch (CompileException e) {
|
|
652
|
+
UI.printError(Module.API, COULDNT_MESSAGE_FORMAT, filename);
|
|
653
|
+
UI.printError(Module.API, "%s", e.getMessage());
|
|
654
|
+
return null;
|
|
655
|
+
} catch (IOException e) {
|
|
656
|
+
UI.printError(Module.API, COULDNT_MESSAGE_FORMAT, filename);
|
|
657
|
+
UI.printError(Module.API, "%s", e.getMessage());
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
t.end();
|
|
661
|
+
UI.printInfo(Module.API, "Compile time: " + t.toString());
|
|
662
|
+
// allow relative paths
|
|
663
|
+
String currentFolder = new File(filename).getAbsoluteFile().getParentFile().getAbsolutePath();
|
|
664
|
+
api.includeSearchPath.addSearchPath(currentFolder);
|
|
665
|
+
api.textureSearchPath.addSearchPath(currentFolder);
|
|
666
|
+
UI.printInfo(Module.API, "Build script running ...");
|
|
667
|
+
t.start();
|
|
668
|
+
api.currentFrame(frameNumber);
|
|
669
|
+
api.build();
|
|
670
|
+
t.end();
|
|
671
|
+
UI.printInfo(Module.API, "Build script time: %s", t.toString());
|
|
672
|
+
} else {
|
|
673
|
+
api = new SunflowAPI();
|
|
674
|
+
api = api.include(filename) ? api : null;
|
|
675
|
+
}
|
|
676
|
+
return api;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Translate specfied file into the native sunflow scene file format.
|
|
681
|
+
*
|
|
682
|
+
* @param filename input filename
|
|
683
|
+
* @param outputFilename output filename
|
|
684
|
+
* @return <code>true</code> upon success, <code>false</code> otherwise
|
|
685
|
+
*/
|
|
686
|
+
public static boolean translate(String filename, String outputFilename) {
|
|
687
|
+
FileSunflowAPI api = null;
|
|
688
|
+
try {
|
|
689
|
+
if (outputFilename.endsWith(".sca")) {
|
|
690
|
+
api = new AsciiFileSunflowAPI(outputFilename);
|
|
691
|
+
} else if (outputFilename.endsWith(".scb")) {
|
|
692
|
+
api = new BinaryFileSunflowAPI(outputFilename);
|
|
693
|
+
} else {
|
|
694
|
+
UI.printError(Module.API, "Unable to determine output filetype: \"%s\"", outputFilename);
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
} catch (IOException e) {
|
|
698
|
+
UI.printError(Module.API, "Unable to create output file - %s", e.getMessage());
|
|
699
|
+
return false;
|
|
700
|
+
}
|
|
701
|
+
String extension = filename.substring(filename.lastIndexOf('.') + 1);
|
|
702
|
+
SceneParser parser = PluginRegistry.PARSER_PLUGINS.createObject(extension);
|
|
703
|
+
if (parser == null) {
|
|
704
|
+
UI.printError(Module.API, "Unable to find a suitable parser for: \"%s\"", filename);
|
|
705
|
+
return false;
|
|
706
|
+
}
|
|
707
|
+
try {
|
|
708
|
+
return parser.parse(filename, api);
|
|
709
|
+
} catch (RuntimeException e) {
|
|
710
|
+
Logger.getLogger(SunflowAPI.class.getName()).log(Level.SEVERE, null, e);
|
|
711
|
+
UI.printError(Module.API, "Error occured during translation: %s", e.getMessage());
|
|
712
|
+
return false;
|
|
713
|
+
} finally {
|
|
714
|
+
api.close();
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Compile the specified code string via Janino. The code must implement a
|
|
720
|
+
* build method as described above. The build method is not called on the
|
|
721
|
+
* output, it is up the caller to do so.
|
|
722
|
+
*
|
|
723
|
+
* @param code java code string
|
|
724
|
+
* @return a valid SunflowAPI object upon succes, <code>null</code>
|
|
725
|
+
* otherwise.
|
|
726
|
+
*/
|
|
727
|
+
public static SunflowAPI compile(String code) {
|
|
728
|
+
SunflowAPI api = null;
|
|
729
|
+
try {
|
|
730
|
+
Timer t = new Timer();
|
|
731
|
+
t.start();
|
|
732
|
+
|
|
733
|
+
try {
|
|
734
|
+
api = (SunflowAPI) ClassBodyEvaluator.createFastClassBodyEvaluator(new Scanner(null, new StringReader(code)), SunflowAPI.class, (ClassLoader) null);
|
|
735
|
+
} catch (IOException ex) {
|
|
736
|
+
Logger.getLogger(SunflowAPI.class.getName()).log(Level.SEVERE, null, ex);
|
|
737
|
+
}
|
|
738
|
+
t.end();
|
|
739
|
+
UI.printInfo(Module.API, "Compile time: %s", t.toString());
|
|
740
|
+
return api;
|
|
741
|
+
} catch (CompileException e) {
|
|
742
|
+
UI.printError(Module.API, "%s", e.getMessage());
|
|
743
|
+
return null;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Read the value of the current frame. This value is intended only for
|
|
749
|
+
* procedural animation creation. It is not used by the Sunflow core in
|
|
750
|
+
* anyway. The default value is 1.
|
|
751
|
+
*
|
|
752
|
+
* @return current frame number
|
|
753
|
+
*/
|
|
754
|
+
public int currentFrame() {
|
|
755
|
+
return currentFrame;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
@Override
|
|
759
|
+
public void currentFrame(int currentFrame) {
|
|
760
|
+
this.currentFrame = currentFrame;
|
|
761
|
+
}
|
|
762
|
+
}
|