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,254 @@
|
|
|
1
|
+
package org.sunflow.core.tesselatable;
|
|
2
|
+
|
|
3
|
+
import org.sunflow.SunflowAPI;
|
|
4
|
+
import org.sunflow.core.ParameterList;
|
|
5
|
+
import org.sunflow.core.PrimitiveList;
|
|
6
|
+
import org.sunflow.core.Tesselatable;
|
|
7
|
+
import org.sunflow.core.ParameterList.FloatParameter;
|
|
8
|
+
import org.sunflow.core.ParameterList.InterpolationType;
|
|
9
|
+
import org.sunflow.core.primitive.QuadMesh;
|
|
10
|
+
import org.sunflow.core.primitive.TriangleMesh;
|
|
11
|
+
import org.sunflow.math.BoundingBox;
|
|
12
|
+
import org.sunflow.math.Matrix4;
|
|
13
|
+
import org.sunflow.math.Point3;
|
|
14
|
+
import org.sunflow.math.Vector3;
|
|
15
|
+
import org.sunflow.system.UI;
|
|
16
|
+
import org.sunflow.system.UI.Module;
|
|
17
|
+
|
|
18
|
+
public class BezierMesh implements Tesselatable {
|
|
19
|
+
|
|
20
|
+
private int subdivs;
|
|
21
|
+
private boolean smooth;
|
|
22
|
+
private boolean quads;
|
|
23
|
+
private float[][] patches;
|
|
24
|
+
|
|
25
|
+
public BezierMesh() {
|
|
26
|
+
this(null);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public BezierMesh(float[][] patches) {
|
|
30
|
+
subdivs = 8;
|
|
31
|
+
smooth = true;
|
|
32
|
+
quads = false;
|
|
33
|
+
// convert to single precision
|
|
34
|
+
this.patches = patches;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Override
|
|
38
|
+
public BoundingBox getWorldBounds(Matrix4 o2w) {
|
|
39
|
+
BoundingBox bounds = new BoundingBox();
|
|
40
|
+
if (o2w == null) {
|
|
41
|
+
for (float[] patch : patches) {
|
|
42
|
+
for (int j = 0; j < patch.length; j += 3) {
|
|
43
|
+
bounds.include(patch[j], patch[j + 1], patch[j + 2]);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
// transform vertices first
|
|
48
|
+
for (float[] patch : patches) {
|
|
49
|
+
for (int j = 0; j < patch.length; j += 3) {
|
|
50
|
+
float x = patch[j];
|
|
51
|
+
float y = patch[j + 1];
|
|
52
|
+
float z = patch[j + 2];
|
|
53
|
+
float wx = o2w.transformPX(x, y, z);
|
|
54
|
+
float wy = o2w.transformPY(x, y, z);
|
|
55
|
+
float wz = o2w.transformPZ(x, y, z);
|
|
56
|
+
bounds.include(wx, wy, wz);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return bounds;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private float[] bernstein(float u) {
|
|
64
|
+
float[] b = new float[4];
|
|
65
|
+
float i = 1 - u;
|
|
66
|
+
b[0] = i * i * i;
|
|
67
|
+
b[1] = 3 * u * i * i;
|
|
68
|
+
b[2] = 3 * u * u * i;
|
|
69
|
+
b[3] = u * u * u;
|
|
70
|
+
return b;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private float[] bernsteinDeriv(float u) {
|
|
74
|
+
if (!smooth) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
float[] b = new float[4];
|
|
78
|
+
float i = 1 - u;
|
|
79
|
+
b[0] = 3 * (0 - i * i);
|
|
80
|
+
b[1] = 3 * (i * i - 2 * u * i);
|
|
81
|
+
b[2] = 3 * (2 * u * i - u * u);
|
|
82
|
+
b[3] = 3 * (u * u - 0);
|
|
83
|
+
return b;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private void getPatchPoint(float u, float v, float[] ctrl, float[] bu, float[] bv, float[] bdu, float[] bdv, Point3 p, Vector3 n) {
|
|
87
|
+
float px = 0;
|
|
88
|
+
float py = 0;
|
|
89
|
+
float pz = 0;
|
|
90
|
+
for (int i = 0, index = 0; i < 4; i++) {
|
|
91
|
+
for (int j = 0; j < 4; j++, index += 3) {
|
|
92
|
+
float scale = bu[j] * bv[i];
|
|
93
|
+
px += ctrl[index + 0] * scale;
|
|
94
|
+
py += ctrl[index + 1] * scale;
|
|
95
|
+
pz += ctrl[index + 2] * scale;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
p.x = px;
|
|
99
|
+
p.y = py;
|
|
100
|
+
p.z = pz;
|
|
101
|
+
if (n != null) {
|
|
102
|
+
float dpdux = 0;
|
|
103
|
+
float dpduy = 0;
|
|
104
|
+
float dpduz = 0;
|
|
105
|
+
float dpdvx = 0;
|
|
106
|
+
float dpdvy = 0;
|
|
107
|
+
float dpdvz = 0;
|
|
108
|
+
for (int i = 0, index = 0; i < 4; i++) {
|
|
109
|
+
for (int j = 0; j < 4; j++, index += 3) {
|
|
110
|
+
float scaleu = bdu[j] * bv[i];
|
|
111
|
+
dpdux += ctrl[index + 0] * scaleu;
|
|
112
|
+
dpduy += ctrl[index + 1] * scaleu;
|
|
113
|
+
dpduz += ctrl[index + 2] * scaleu;
|
|
114
|
+
float scalev = bu[j] * bdv[i];
|
|
115
|
+
dpdvx += ctrl[index + 0] * scalev;
|
|
116
|
+
dpdvy += ctrl[index + 1] * scalev;
|
|
117
|
+
dpdvz += ctrl[index + 2] * scalev;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// surface normal
|
|
121
|
+
n.x = (dpduy * dpdvz - dpduz * dpdvy);
|
|
122
|
+
n.y = (dpduz * dpdvx - dpdux * dpdvz);
|
|
123
|
+
n.z = (dpdux * dpdvy - dpduy * dpdvx);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@Override
|
|
128
|
+
public PrimitiveList tesselate() {
|
|
129
|
+
float[] vertices = new float[patches.length * (subdivs + 1) * (subdivs + 1) * 3];
|
|
130
|
+
float[] normals = smooth ? new float[patches.length * (subdivs + 1) * (subdivs + 1) * 3] : null;
|
|
131
|
+
float[] uvs = new float[patches.length * (subdivs + 1) * (subdivs + 1) * 2];
|
|
132
|
+
int[] indices = new int[patches.length * subdivs * subdivs * (quads ? 4 : (2 * 3))];
|
|
133
|
+
|
|
134
|
+
int vidx = 0, pidx = 0;
|
|
135
|
+
float step = 1.0f / subdivs;
|
|
136
|
+
int vstride = subdivs + 1;
|
|
137
|
+
Point3 p = new Point3();
|
|
138
|
+
Vector3 n = smooth ? new Vector3() : null;
|
|
139
|
+
for (float[] patch : patches) {
|
|
140
|
+
// create patch vertices
|
|
141
|
+
for (int i = 0, voff = 0; i <= subdivs; i++) {
|
|
142
|
+
float u = i * step;
|
|
143
|
+
float[] bu = bernstein(u);
|
|
144
|
+
float[] bdu = bernsteinDeriv(u);
|
|
145
|
+
for (int j = 0; j <= subdivs; j++, voff += 3) {
|
|
146
|
+
float v = j * step;
|
|
147
|
+
float[] bv = bernstein(v);
|
|
148
|
+
float[] bdv = bernsteinDeriv(v);
|
|
149
|
+
getPatchPoint(u, v, patch, bu, bv, bdu, bdv, p, n);
|
|
150
|
+
vertices[vidx + voff + 0] = p.x;
|
|
151
|
+
vertices[vidx + voff + 1] = p.y;
|
|
152
|
+
vertices[vidx + voff + 2] = p.z;
|
|
153
|
+
if (smooth) {
|
|
154
|
+
normals[vidx + voff + 0] = n.x;
|
|
155
|
+
normals[vidx + voff + 1] = n.y;
|
|
156
|
+
normals[vidx + voff + 2] = n.z;
|
|
157
|
+
}
|
|
158
|
+
uvs[(vidx + voff) / 3 * 2 + 0] = u;
|
|
159
|
+
uvs[(vidx + voff) / 3 * 2 + 1] = v;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// generate patch triangles
|
|
163
|
+
for (int i = 0, vbase = vidx / 3; i < subdivs; i++) {
|
|
164
|
+
for (int j = 0; j < subdivs; j++) {
|
|
165
|
+
int v00 = (i + 0) * vstride + (j + 0);
|
|
166
|
+
int v10 = (i + 1) * vstride + (j + 0);
|
|
167
|
+
int v01 = (i + 0) * vstride + (j + 1);
|
|
168
|
+
int v11 = (i + 1) * vstride + (j + 1);
|
|
169
|
+
if (quads) {
|
|
170
|
+
indices[pidx + 0] = vbase + v01;
|
|
171
|
+
indices[pidx + 1] = vbase + v00;
|
|
172
|
+
indices[pidx + 2] = vbase + v10;
|
|
173
|
+
indices[pidx + 3] = vbase + v11;
|
|
174
|
+
pidx += 4;
|
|
175
|
+
} else {
|
|
176
|
+
// add 2 triangles
|
|
177
|
+
indices[pidx + 0] = vbase + v00;
|
|
178
|
+
indices[pidx + 1] = vbase + v10;
|
|
179
|
+
indices[pidx + 2] = vbase + v01;
|
|
180
|
+
indices[pidx + 3] = vbase + v10;
|
|
181
|
+
indices[pidx + 4] = vbase + v11;
|
|
182
|
+
indices[pidx + 5] = vbase + v01;
|
|
183
|
+
pidx += 6;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
vidx += vstride * vstride * 3;
|
|
188
|
+
}
|
|
189
|
+
ParameterList pl = new ParameterList();
|
|
190
|
+
pl.addPoints("points", InterpolationType.VERTEX, vertices);
|
|
191
|
+
if (quads) {
|
|
192
|
+
pl.addIntegerArray("quads", indices);
|
|
193
|
+
} else {
|
|
194
|
+
pl.addIntegerArray("triangles", indices);
|
|
195
|
+
}
|
|
196
|
+
pl.addTexCoords("uvs", InterpolationType.VERTEX, uvs);
|
|
197
|
+
if (smooth) {
|
|
198
|
+
pl.addVectors("normals", InterpolationType.VERTEX, normals);
|
|
199
|
+
}
|
|
200
|
+
PrimitiveList m = quads ? new QuadMesh() : new TriangleMesh();
|
|
201
|
+
m.update(pl, null);
|
|
202
|
+
pl.clear(true);
|
|
203
|
+
return m;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@Override
|
|
207
|
+
public boolean update(ParameterList pl, SunflowAPI api) {
|
|
208
|
+
subdivs = pl.getInt("subdivs", subdivs);
|
|
209
|
+
smooth = pl.getBoolean("smooth", smooth);
|
|
210
|
+
quads = pl.getBoolean("quads", quads);
|
|
211
|
+
int nu = pl.getInt("nu", 0);
|
|
212
|
+
int nv = pl.getInt("nv", 0);
|
|
213
|
+
pl.setVertexCount(nu * nv);
|
|
214
|
+
boolean uwrap = pl.getBoolean("uwrap", false);
|
|
215
|
+
boolean vwrap = pl.getBoolean("vwrap", false);
|
|
216
|
+
FloatParameter points = pl.getPointArray("points");
|
|
217
|
+
if (points != null && points.interp == InterpolationType.VERTEX) {
|
|
218
|
+
int numUPatches = uwrap ? nu / 3 : (nu - 4) / 3 + 1;
|
|
219
|
+
int numVPatches = vwrap ? nv / 3 : (nv - 4) / 3 + 1;
|
|
220
|
+
if (numUPatches < 1 || numVPatches < 1) {
|
|
221
|
+
UI.printError(Module.GEOM, "Invalid number of patches for bezier mesh - ignoring");
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
// generate patches
|
|
225
|
+
patches = new float[numUPatches * numVPatches][];
|
|
226
|
+
for (int v = 0, p = 0; v < numVPatches; v++) {
|
|
227
|
+
for (int u = 0; u < numUPatches; u++, p++) {
|
|
228
|
+
float[] patch = patches[p] = new float[16 * 3];
|
|
229
|
+
int up = u * 3;
|
|
230
|
+
int vp = v * 3;
|
|
231
|
+
for (int pv = 0; pv < 4; pv++) {
|
|
232
|
+
for (int pu = 0; pu < 4; pu++) {
|
|
233
|
+
int meshU = (up + pu) % nu;
|
|
234
|
+
int meshV = (vp + pv) % nv;
|
|
235
|
+
// copy point
|
|
236
|
+
patch[3 * (pv * 4 + pu) + 0] = points.data[3 * (meshU + nu * meshV) + 0];
|
|
237
|
+
patch[3 * (pv * 4 + pu) + 1] = points.data[3 * (meshU + nu * meshV) + 1];
|
|
238
|
+
patch[3 * (pv * 4 + pu) + 2] = points.data[3 * (meshU + nu * meshV) + 2];
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (subdivs < 1) {
|
|
245
|
+
UI.printError(Module.GEOM, "Invalid subdivisions for bezier mesh - ignoring");
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
if (patches == null) {
|
|
249
|
+
UI.printError(Module.GEOM, "No patch data present in bezier mesh - ignoring");
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
package org.sunflow.core.tesselatable;
|
|
2
|
+
|
|
3
|
+
import java.io.BufferedInputStream;
|
|
4
|
+
import java.io.BufferedReader;
|
|
5
|
+
import java.io.DataInputStream;
|
|
6
|
+
import java.io.File;
|
|
7
|
+
import java.io.FileInputStream;
|
|
8
|
+
import java.io.FileNotFoundException;
|
|
9
|
+
import java.io.FileReader;
|
|
10
|
+
import java.io.IOException;
|
|
11
|
+
import java.nio.ByteOrder;
|
|
12
|
+
import java.nio.FloatBuffer;
|
|
13
|
+
import java.nio.IntBuffer;
|
|
14
|
+
import java.nio.MappedByteBuffer;
|
|
15
|
+
import java.nio.channels.FileChannel;
|
|
16
|
+
import java.util.logging.Level;
|
|
17
|
+
import java.util.logging.Logger;
|
|
18
|
+
|
|
19
|
+
import org.sunflow.SunflowAPI;
|
|
20
|
+
import org.sunflow.core.ParameterList;
|
|
21
|
+
import org.sunflow.core.PrimitiveList;
|
|
22
|
+
import org.sunflow.core.Tesselatable;
|
|
23
|
+
import org.sunflow.core.ParameterList.InterpolationType;
|
|
24
|
+
import org.sunflow.core.primitive.TriangleMesh;
|
|
25
|
+
import org.sunflow.math.BoundingBox;
|
|
26
|
+
import org.sunflow.math.Matrix4;
|
|
27
|
+
import org.sunflow.math.Point3;
|
|
28
|
+
import org.sunflow.math.Vector3;
|
|
29
|
+
import org.sunflow.system.Memory;
|
|
30
|
+
import org.sunflow.system.UI;
|
|
31
|
+
import org.sunflow.system.UI.Module;
|
|
32
|
+
import org.sunflow.util.FloatArray;
|
|
33
|
+
import org.sunflow.util.IntArray;
|
|
34
|
+
|
|
35
|
+
public class FileMesh implements Tesselatable {
|
|
36
|
+
|
|
37
|
+
private String filename = null;
|
|
38
|
+
private boolean smoothNormals = false;
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public BoundingBox getWorldBounds(Matrix4 o2w) {
|
|
42
|
+
// world bounds can't be computed without reading file
|
|
43
|
+
// return null so the mesh will be loaded right away
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Override
|
|
48
|
+
public PrimitiveList tesselate() {
|
|
49
|
+
if (filename.endsWith(".ra3")) {
|
|
50
|
+
try {
|
|
51
|
+
UI.printInfo(Module.GEOM, "RA3 - Reading geometry: \"%s\" ...", filename);
|
|
52
|
+
File file = new File(filename);
|
|
53
|
+
float[] verts;
|
|
54
|
+
int[] tris;
|
|
55
|
+
try (FileInputStream stream = new FileInputStream(filename)) {
|
|
56
|
+
MappedByteBuffer map = stream.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
|
|
57
|
+
map.order(ByteOrder.LITTLE_ENDIAN);
|
|
58
|
+
IntBuffer ints = map.asIntBuffer();
|
|
59
|
+
FloatBuffer buffer = map.asFloatBuffer();
|
|
60
|
+
int numVerts = ints.get(0);
|
|
61
|
+
int numTris = ints.get(1);
|
|
62
|
+
UI.printInfo(Module.GEOM, "RA3 - * Reading %d vertices ...", numVerts);
|
|
63
|
+
verts = new float[3 * numVerts];
|
|
64
|
+
for (int i = 0; i < verts.length; i++) {
|
|
65
|
+
verts[i] = buffer.get(2 + i);
|
|
66
|
+
} UI.printInfo(Module.GEOM, "RA3 - * Reading %d triangles ...", numTris);
|
|
67
|
+
tris = new int[3 * numTris];
|
|
68
|
+
for (int i = 0; i < tris.length; i++) {
|
|
69
|
+
tris[i] = ints.get(2 + verts.length + i);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
UI.printInfo(Module.GEOM, "RA3 - * Creating mesh ...");
|
|
73
|
+
return generate(tris, verts, smoothNormals);
|
|
74
|
+
} catch (FileNotFoundException e) {
|
|
75
|
+
Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
|
|
76
|
+
UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - file not found", filename);
|
|
77
|
+
} catch (IOException e) {
|
|
78
|
+
Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
|
|
79
|
+
UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - I/O error occured", filename);
|
|
80
|
+
}
|
|
81
|
+
} else if (filename.endsWith(".obj")) {
|
|
82
|
+
int lineNumber = 1;
|
|
83
|
+
try {
|
|
84
|
+
UI.printInfo(Module.GEOM, "OBJ - Reading geometry: \"%s\" ...", filename);
|
|
85
|
+
FloatArray verts = new FloatArray();
|
|
86
|
+
IntArray tris = new IntArray();
|
|
87
|
+
FileReader file = new FileReader(filename);
|
|
88
|
+
BufferedReader bf = new BufferedReader(file);
|
|
89
|
+
String line;
|
|
90
|
+
while ((line = bf.readLine()) != null) {
|
|
91
|
+
if (line.startsWith("v")) {
|
|
92
|
+
String[] v = line.split("\\s+");
|
|
93
|
+
verts.add(Float.parseFloat(v[1]));
|
|
94
|
+
verts.add(Float.parseFloat(v[2]));
|
|
95
|
+
verts.add(Float.parseFloat(v[3]));
|
|
96
|
+
} else if (line.startsWith("f")) {
|
|
97
|
+
String[] f = line.split("\\s+");
|
|
98
|
+
if (f.length == 5) {
|
|
99
|
+
tris.add(Integer.parseInt(f[1]) - 1);
|
|
100
|
+
tris.add(Integer.parseInt(f[2]) - 1);
|
|
101
|
+
tris.add(Integer.parseInt(f[3]) - 1);
|
|
102
|
+
tris.add(Integer.parseInt(f[1]) - 1);
|
|
103
|
+
tris.add(Integer.parseInt(f[3]) - 1);
|
|
104
|
+
tris.add(Integer.parseInt(f[4]) - 1);
|
|
105
|
+
} else if (f.length == 4) {
|
|
106
|
+
tris.add(Integer.parseInt(f[1]) - 1);
|
|
107
|
+
tris.add(Integer.parseInt(f[2]) - 1);
|
|
108
|
+
tris.add(Integer.parseInt(f[3]) - 1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (lineNumber % 100000 == 0) {
|
|
112
|
+
UI.printInfo(Module.GEOM, "OBJ - * Parsed %7d lines ...", lineNumber);
|
|
113
|
+
}
|
|
114
|
+
lineNumber++;
|
|
115
|
+
}
|
|
116
|
+
file.close();
|
|
117
|
+
UI.printInfo(Module.GEOM, "OBJ - * Creating mesh ...");
|
|
118
|
+
return generate(tris.trim(), verts.trim(), smoothNormals);
|
|
119
|
+
} catch (FileNotFoundException e) {
|
|
120
|
+
Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
|
|
121
|
+
UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - file not found", filename);
|
|
122
|
+
} catch (NumberFormatException e) {
|
|
123
|
+
Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
|
|
124
|
+
UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - syntax error at line %d", lineNumber);
|
|
125
|
+
} catch (IOException e) {
|
|
126
|
+
Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
|
|
127
|
+
UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - I/O error occured", filename);
|
|
128
|
+
}
|
|
129
|
+
} else if (filename.endsWith(".stl")) {
|
|
130
|
+
try {
|
|
131
|
+
UI.printInfo(Module.GEOM, "STL - Reading geometry: \"%s\" ...", filename);
|
|
132
|
+
FileInputStream file = new FileInputStream(filename);
|
|
133
|
+
DataInputStream stream = new DataInputStream(new BufferedInputStream(file));
|
|
134
|
+
file.skip(80);
|
|
135
|
+
int numTris = getLittleEndianInt(stream.readInt());
|
|
136
|
+
UI.printInfo(Module.GEOM, "STL - * Reading %d triangles ...", numTris);
|
|
137
|
+
long filesize = new File(filename).length();
|
|
138
|
+
if (filesize != (84 + 50 * numTris)) {
|
|
139
|
+
UI.printWarning(Module.GEOM, "STL - Size of file mismatch (expecting %s, found %s)", Memory.bytesToString(84 + 14 * numTris), Memory.bytesToString(filesize));
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
int[] tris = new int[3 * numTris];
|
|
143
|
+
float[] verts = new float[9 * numTris];
|
|
144
|
+
for (int i = 0, i3 = 0, index = 0; i < numTris; i++, i3 += 3) {
|
|
145
|
+
// skip normal
|
|
146
|
+
stream.readInt();
|
|
147
|
+
stream.readInt();
|
|
148
|
+
stream.readInt();
|
|
149
|
+
for (int j = 0; j < 3; j++, index += 3) {
|
|
150
|
+
tris[i3 + j] = i3 + j;
|
|
151
|
+
// get xyz
|
|
152
|
+
verts[index + 0] = getLittleEndianFloat(stream.readInt());
|
|
153
|
+
verts[index + 1] = getLittleEndianFloat(stream.readInt());
|
|
154
|
+
verts[index + 2] = getLittleEndianFloat(stream.readInt());
|
|
155
|
+
}
|
|
156
|
+
stream.readShort();
|
|
157
|
+
if ((i + 1) % 100000 == 0) {
|
|
158
|
+
UI.printInfo(Module.GEOM, "STL - * Parsed %7d triangles ...", i + 1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
file.close();
|
|
162
|
+
// create geometry
|
|
163
|
+
UI.printInfo(Module.GEOM, "STL - * Creating mesh ...");
|
|
164
|
+
if (smoothNormals) {
|
|
165
|
+
UI.printWarning(Module.GEOM, "STL - format does not support shared vertices - normal smoothing disabled");
|
|
166
|
+
}
|
|
167
|
+
return generate(tris, verts, false);
|
|
168
|
+
} catch (FileNotFoundException e) {
|
|
169
|
+
Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
|
|
170
|
+
UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - file not found", filename);
|
|
171
|
+
} catch (IOException e) {
|
|
172
|
+
Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
|
|
173
|
+
UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - I/O error occured", filename);
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
UI.printWarning(Module.GEOM, "Unable to read mesh file \"%s\" - unrecognized format", filename);
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private TriangleMesh generate(int[] tris, float[] verts, boolean smoothNormals) {
|
|
182
|
+
ParameterList pl = new ParameterList();
|
|
183
|
+
pl.addIntegerArray("triangles", tris);
|
|
184
|
+
pl.addPoints("points", InterpolationType.VERTEX, verts);
|
|
185
|
+
if (smoothNormals) {
|
|
186
|
+
float[] normals = new float[verts.length]; // filled with 0's
|
|
187
|
+
Point3 p0 = new Point3();
|
|
188
|
+
Point3 p1 = new Point3();
|
|
189
|
+
Point3 p2 = new Point3();
|
|
190
|
+
Vector3 n = new Vector3();
|
|
191
|
+
for (int i3 = 0; i3 < tris.length; i3 += 3) {
|
|
192
|
+
int v0 = tris[i3 + 0];
|
|
193
|
+
int v1 = tris[i3 + 1];
|
|
194
|
+
int v2 = tris[i3 + 2];
|
|
195
|
+
p0.set(verts[3 * v0 + 0], verts[3 * v0 + 1], verts[3 * v0 + 2]);
|
|
196
|
+
p1.set(verts[3 * v1 + 0], verts[3 * v1 + 1], verts[3 * v1 + 2]);
|
|
197
|
+
p2.set(verts[3 * v2 + 0], verts[3 * v2 + 1], verts[3 * v2 + 2]);
|
|
198
|
+
Point3.normal(p0, p1, p2, n); // compute normal
|
|
199
|
+
// add face normal to each vertex
|
|
200
|
+
// note that these are not normalized so this in fact weights
|
|
201
|
+
// each normal by the area of the triangle
|
|
202
|
+
normals[3 * v0 + 0] += n.x;
|
|
203
|
+
normals[3 * v0 + 1] += n.y;
|
|
204
|
+
normals[3 * v0 + 2] += n.z;
|
|
205
|
+
normals[3 * v1 + 0] += n.x;
|
|
206
|
+
normals[3 * v1 + 1] += n.y;
|
|
207
|
+
normals[3 * v1 + 2] += n.z;
|
|
208
|
+
normals[3 * v2 + 0] += n.x;
|
|
209
|
+
normals[3 * v2 + 1] += n.y;
|
|
210
|
+
normals[3 * v2 + 2] += n.z;
|
|
211
|
+
}
|
|
212
|
+
// normalize all the vectors
|
|
213
|
+
for (int i3 = 0; i3 < normals.length; i3 += 3) {
|
|
214
|
+
n.set(normals[i3 + 0], normals[i3 + 1], normals[i3 + 2]);
|
|
215
|
+
n.normalize();
|
|
216
|
+
normals[i3 + 0] = n.x;
|
|
217
|
+
normals[i3 + 1] = n.y;
|
|
218
|
+
normals[i3 + 2] = n.z;
|
|
219
|
+
}
|
|
220
|
+
pl.addVectors("normals", InterpolationType.VERTEX, normals);
|
|
221
|
+
}
|
|
222
|
+
TriangleMesh m = new TriangleMesh();
|
|
223
|
+
if (m.update(pl, null)) {
|
|
224
|
+
return m;
|
|
225
|
+
}
|
|
226
|
+
// something failed in creating the mesh, the error message will be
|
|
227
|
+
// printed by the mesh itself - no need to repeat it here
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
public boolean update(ParameterList pl, SunflowAPI api) {
|
|
232
|
+
String file = pl.getString("filename", null);
|
|
233
|
+
if (file != null) {
|
|
234
|
+
filename = api.resolveIncludeFilename(file);
|
|
235
|
+
}
|
|
236
|
+
smoothNormals = pl.getBoolean("smooth_normals", smoothNormals);
|
|
237
|
+
return filename != null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
private int getLittleEndianInt(int i) {
|
|
241
|
+
// input integer has its bytes in big endian byte order
|
|
242
|
+
// swap them around
|
|
243
|
+
return (i >>> 24) | ((i >>> 8) & 0xFF00) | ((i << 8) & 0xFF0000) | (i << 24);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private float getLittleEndianFloat(int i) {
|
|
247
|
+
// input integer has its bytes in big endian byte order
|
|
248
|
+
// swap them around and interpret data as floating point
|
|
249
|
+
return Float.intBitsToFloat(getLittleEndianInt(i));
|
|
250
|
+
}
|
|
251
|
+
}
|