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,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
|
+
}
|