toxiclibs 0.2-java → 0.5.0-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 +4 -4
- data/.gitignore +16 -0
- data/CHANGELOG.md +4 -0
- data/LICENSE +675 -0
- data/README.md +12 -5
- data/Rakefile +25 -82
- data/examples/attract_repel/attract_repel.rb +30 -0
- data/examples/attract_repel/attractor.rb +23 -0
- data/examples/attract_repel/particle.rb +27 -0
- data/examples/data/ti_yong.png +0 -0
- data/examples/force_directed/cluster.rb +76 -0
- data/examples/force_directed/force_directed_graph.rb +92 -0
- data/examples/force_directed/node.rb +26 -0
- data/examples/gray_scott_image.rb +75 -0
- data/examples/gray_scott_tone_map.rb +77 -0
- data/examples/implicit.rb +139 -0
- data/examples/inflate_mesh.rb +89 -0
- data/examples/model_align.rb +44 -0
- data/examples/povmesh/ftest.rb +46 -0
- data/examples/povmesh/tentacle.rb +73 -0
- data/examples/simple_cluster/cluster.rb +47 -0
- data/examples/simple_cluster/node.rb +27 -0
- data/examples/simple_cluster/simple_cluster.rb +60 -0
- data/examples/soft_body/blanket.rb +45 -0
- data/examples/soft_body/connection.rb +16 -0
- data/examples/soft_body/particle.rb +22 -0
- data/examples/soft_body/soft_body_square_adapted.rb +55 -0
- data/lib/toxiclibs.jar +0 -0
- data/lib/toxiclibs.rb +91 -32
- data/lib/toxiclibs/version.rb +1 -1
- data/pom.xml +122 -0
- data/src/com/toxi/net/ClientListener.java +41 -0
- data/src/com/toxi/net/ServerListener.java +70 -0
- data/src/com/toxi/net/ServerListenerAdapter.java +47 -0
- data/src/com/toxi/net/ServerState.java +18 -0
- data/src/com/toxi/net/UDPConnection.java +66 -0
- data/src/com/toxi/net/UDPSyncClient.java +81 -0
- data/src/com/toxi/net/UDPSyncServer.java +450 -0
- data/src/com/toxi/nio/UDPClient.java +121 -0
- data/src/com/toxi/nio/UDPClientState.java +32 -0
- data/src/com/toxi/nio/UDPServer.java +129 -0
- data/src/toxi/color/AccessCriteria.java +114 -0
- data/src/toxi/color/AlphaAccessor.java +67 -0
- data/src/toxi/color/CMYKAccessor.java +122 -0
- data/src/toxi/color/CMYKDistanceProxy.java +40 -0
- data/src/toxi/color/ColorGradient.java +260 -0
- data/src/toxi/color/ColorList.java +699 -0
- data/src/toxi/color/ColorRange.java +671 -0
- data/src/toxi/color/ColorTheme.java +163 -0
- data/src/toxi/color/DistanceProxy.java +44 -0
- data/src/toxi/color/HSVAccessor.java +113 -0
- data/src/toxi/color/HSVDistanceProxy.java +40 -0
- data/src/toxi/color/HistEntry.java +85 -0
- data/src/toxi/color/Histogram.java +185 -0
- data/src/toxi/color/Hue.java +249 -0
- data/src/toxi/color/LuminanceAccessor.java +78 -0
- data/src/toxi/color/NamedColor.java +935 -0
- data/src/toxi/color/ProximityComparator.java +70 -0
- data/src/toxi/color/RGBAccessor.java +113 -0
- data/src/toxi/color/RGBDistanceProxy.java +41 -0
- data/src/toxi/color/ReadonlyTColor.java +296 -0
- data/src/toxi/color/TColor.java +1677 -0
- data/src/toxi/color/TColorAdapter.java +68 -0
- data/src/toxi/color/ToneMap.java +218 -0
- data/src/toxi/color/theory/AnalogousStrategy.java +140 -0
- data/src/toxi/color/theory/ColorTheoryRegistry.java +139 -0
- data/src/toxi/color/theory/ColorTheoryStrategy.java +56 -0
- data/src/toxi/color/theory/ComplementaryStrategy.java +111 -0
- data/src/toxi/color/theory/CompoundTheoryStrategy.java +143 -0
- data/src/toxi/color/theory/LeftSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/MonochromeTheoryStrategy.java +103 -0
- data/src/toxi/color/theory/RightSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/SingleComplementStrategy.java +76 -0
- data/src/toxi/color/theory/SplitComplementaryStrategy.java +77 -0
- data/src/toxi/color/theory/TetradTheoryStrategy.java +114 -0
- data/src/toxi/color/theory/TriadTheoryStrategy.java +77 -0
- data/src/toxi/data/csv/CSVAdapter.java +74 -0
- data/src/toxi/data/csv/CSVFieldMapper.java +212 -0
- data/src/toxi/data/csv/CSVListener.java +61 -0
- data/src/toxi/data/csv/CSVParser.java +202 -0
- data/src/toxi/data/feeds/AtomAuthor.java +49 -0
- data/src/toxi/data/feeds/AtomContent.java +50 -0
- data/src/toxi/data/feeds/AtomEntry.java +111 -0
- data/src/toxi/data/feeds/AtomFeed.java +129 -0
- data/src/toxi/data/feeds/AtomLink.java +62 -0
- data/src/toxi/data/feeds/RSSChannel.java +88 -0
- data/src/toxi/data/feeds/RSSEnclosure.java +60 -0
- data/src/toxi/data/feeds/RSSFeed.java +99 -0
- data/src/toxi/data/feeds/RSSItem.java +104 -0
- data/src/toxi/data/feeds/util/EntityStripper.java +2480 -0
- data/src/toxi/data/feeds/util/Iso8601DateAdapter.java +101 -0
- data/src/toxi/data/feeds/util/Rfc822DateAdapter.java +93 -0
- data/src/toxi/geom/AABB.java +658 -0
- data/src/toxi/geom/Axis3D.java +116 -0
- data/src/toxi/geom/AxisAlignedCylinder.java +163 -0
- data/src/toxi/geom/BernsteinPolynomial.java +94 -0
- data/src/toxi/geom/BezierCurve2D.java +159 -0
- data/src/toxi/geom/BezierCurve3D.java +148 -0
- data/src/toxi/geom/BooleanShapeBuilder.java +185 -0
- data/src/toxi/geom/BoxIntersector.java +52 -0
- data/src/toxi/geom/Circle.java +230 -0
- data/src/toxi/geom/CircleIntersector.java +85 -0
- data/src/toxi/geom/Cone.java +150 -0
- data/src/toxi/geom/ConvexPolygonClipper.java +136 -0
- data/src/toxi/geom/CoordinateExtractor.java +16 -0
- data/src/toxi/geom/Ellipse.java +250 -0
- data/src/toxi/geom/GMatrix.java +2599 -0
- data/src/toxi/geom/GVector.java +833 -0
- data/src/toxi/geom/GlobalGridTesselator.java +54 -0
- data/src/toxi/geom/GridTesselator.java +108 -0
- data/src/toxi/geom/Intersector2D.java +49 -0
- data/src/toxi/geom/Intersector3D.java +51 -0
- data/src/toxi/geom/IsectData2D.java +103 -0
- data/src/toxi/geom/IsectData3D.java +103 -0
- data/src/toxi/geom/Line2D.java +534 -0
- data/src/toxi/geom/Line3D.java +471 -0
- data/src/toxi/geom/LineStrip2D.java +430 -0
- data/src/toxi/geom/LineStrip3D.java +230 -0
- data/src/toxi/geom/LocalGridTesselator.java +57 -0
- data/src/toxi/geom/Matrix3d.java +3048 -0
- data/src/toxi/geom/Matrix4f.java +3446 -0
- data/src/toxi/geom/Matrix4x4.java +1076 -0
- data/src/toxi/geom/MatrixSizeException.java +58 -0
- data/src/toxi/geom/OctreeVisitor.java +44 -0
- data/src/toxi/geom/Origin3D.java +148 -0
- data/src/toxi/geom/Plane.java +293 -0
- data/src/toxi/geom/PlaneIntersector.java +57 -0
- data/src/toxi/geom/PointCloud3D.java +253 -0
- data/src/toxi/geom/PointOctree.java +502 -0
- data/src/toxi/geom/PointQuadtree.java +375 -0
- data/src/toxi/geom/Polygon2D.java +1038 -0
- data/src/toxi/geom/PolygonClipper2D.java +45 -0
- data/src/toxi/geom/PolygonTesselator.java +20 -0
- data/src/toxi/geom/QuadtreeVisitor.java +44 -0
- data/src/toxi/geom/Quaternion.java +641 -0
- data/src/toxi/geom/Ray2D.java +146 -0
- data/src/toxi/geom/Ray3D.java +150 -0
- data/src/toxi/geom/Ray3DIntersector.java +75 -0
- data/src/toxi/geom/ReadonlyVec2D.java +575 -0
- data/src/toxi/geom/ReadonlyVec3D.java +628 -0
- data/src/toxi/geom/ReadonlyVec4D.java +431 -0
- data/src/toxi/geom/Rect.java +720 -0
- data/src/toxi/geom/Reflector3D.java +58 -0
- data/src/toxi/geom/Shape2D.java +94 -0
- data/src/toxi/geom/Shape3D.java +42 -0
- data/src/toxi/geom/SingularMatrixException.java +57 -0
- data/src/toxi/geom/SpatialBins.java +182 -0
- data/src/toxi/geom/SpatialIndex.java +61 -0
- data/src/toxi/geom/Sphere.java +224 -0
- data/src/toxi/geom/SphereIntersectorReflector.java +196 -0
- data/src/toxi/geom/Spline2D.java +349 -0
- data/src/toxi/geom/Spline3D.java +351 -0
- data/src/toxi/geom/SutherlandHodgemanClipper.java +151 -0
- data/src/toxi/geom/Triangle2D.java +422 -0
- data/src/toxi/geom/Triangle3D.java +456 -0
- data/src/toxi/geom/TriangleIntersector.java +105 -0
- data/src/toxi/geom/Vec2D.java +1328 -0
- data/src/toxi/geom/Vec3D.java +1832 -0
- data/src/toxi/geom/Vec4D.java +985 -0
- data/src/toxi/geom/VecMathUtil.java +100 -0
- data/src/toxi/geom/XAxisCylinder.java +64 -0
- data/src/toxi/geom/YAxisCylinder.java +65 -0
- data/src/toxi/geom/ZAxisCylinder.java +64 -0
- data/src/toxi/geom/mesh/BezierPatch.java +200 -0
- data/src/toxi/geom/mesh/BoxSelector.java +62 -0
- data/src/toxi/geom/mesh/DefaultSTLColorModel.java +67 -0
- data/src/toxi/geom/mesh/DefaultSelector.java +50 -0
- data/src/toxi/geom/mesh/Face.java +176 -0
- data/src/toxi/geom/mesh/LaplacianSmooth.java +80 -0
- data/src/toxi/geom/mesh/MaterialiseSTLColorModel.java +150 -0
- data/src/toxi/geom/mesh/Mesh3D.java +224 -0
- data/src/toxi/geom/mesh/MeshIntersector.java +91 -0
- data/src/toxi/geom/mesh/OBJWriter.java +194 -0
- data/src/toxi/geom/mesh/PLYWriter.java +167 -0
- data/src/toxi/geom/mesh/PlaneSelector.java +90 -0
- data/src/toxi/geom/mesh/STLColorModel.java +54 -0
- data/src/toxi/geom/mesh/STLReader.java +185 -0
- data/src/toxi/geom/mesh/STLWriter.java +323 -0
- data/src/toxi/geom/mesh/SphereFunction.java +156 -0
- data/src/toxi/geom/mesh/SphericalHarmonics.java +110 -0
- data/src/toxi/geom/mesh/SuperEllipsoid.java +110 -0
- data/src/toxi/geom/mesh/SurfaceFunction.java +75 -0
- data/src/toxi/geom/mesh/SurfaceMeshBuilder.java +149 -0
- data/src/toxi/geom/mesh/Terrain.java +451 -0
- data/src/toxi/geom/mesh/TriangleMesh.java +1201 -0
- data/src/toxi/geom/mesh/Vertex.java +78 -0
- data/src/toxi/geom/mesh/VertexSelector.java +193 -0
- data/src/toxi/geom/mesh/WEFace.java +100 -0
- data/src/toxi/geom/mesh/WEMeshFilterStrategy.java +51 -0
- data/src/toxi/geom/mesh/WETriangleMesh.java +761 -0
- data/src/toxi/geom/mesh/WEVertex.java +134 -0
- data/src/toxi/geom/mesh/WingedEdge.java +115 -0
- data/src/toxi/geom/mesh/subdiv/CentroidSubdiv.java +37 -0
- data/src/toxi/geom/mesh/subdiv/DisplacementSubdivision.java +85 -0
- data/src/toxi/geom/mesh/subdiv/DualDisplacementSubdivision.java +94 -0
- data/src/toxi/geom/mesh/subdiv/DualSubdivision.java +49 -0
- data/src/toxi/geom/mesh/subdiv/EdgeLengthComparator.java +50 -0
- data/src/toxi/geom/mesh/subdiv/FaceCountComparator.java +51 -0
- data/src/toxi/geom/mesh/subdiv/MidpointDisplacementSubdivision.java +80 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdiv.java +42 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdivision.java +48 -0
- data/src/toxi/geom/mesh/subdiv/NewSubdivStrategy.java +23 -0
- data/src/toxi/geom/mesh/subdiv/NormalDisplacementSubdivision.java +74 -0
- data/src/toxi/geom/mesh/subdiv/SubdivisionStrategy.java +83 -0
- data/src/toxi/geom/mesh/subdiv/TriSubdivision.java +51 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangle.java +222 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangulation.java +327 -0
- data/src/toxi/geom/mesh2d/DelaunayVertex.java +560 -0
- data/src/toxi/geom/mesh2d/Voronoi.java +149 -0
- data/src/toxi/geom/nurbs/BasicNurbsCurve.java +210 -0
- data/src/toxi/geom/nurbs/BasicNurbsSurface.java +233 -0
- data/src/toxi/geom/nurbs/ControlNet.java +148 -0
- data/src/toxi/geom/nurbs/CurveCreator.java +112 -0
- data/src/toxi/geom/nurbs/CurveUtils.java +259 -0
- data/src/toxi/geom/nurbs/InterpolationException.java +65 -0
- data/src/toxi/geom/nurbs/KnotVector.java +333 -0
- data/src/toxi/geom/nurbs/NurbsCreator.java +815 -0
- data/src/toxi/geom/nurbs/NurbsCurve.java +120 -0
- data/src/toxi/geom/nurbs/NurbsMeshCreator.java +145 -0
- data/src/toxi/geom/nurbs/NurbsSurface.java +147 -0
- data/src/toxi/image/util/Filter8bit.java +331 -0
- data/src/toxi/image/util/TiledFrameExporter.java +162 -0
- data/src/toxi/math/BezierInterpolation.java +102 -0
- data/src/toxi/math/CircularInterpolation.java +88 -0
- data/src/toxi/math/CosineInterpolation.java +51 -0
- data/src/toxi/math/DecimatedInterpolation.java +77 -0
- data/src/toxi/math/ExponentialInterpolation.java +68 -0
- data/src/toxi/math/InterpolateStrategy.java +60 -0
- data/src/toxi/math/Interpolation2D.java +93 -0
- data/src/toxi/math/LinearInterpolation.java +46 -0
- data/src/toxi/math/MathUtils.java +990 -0
- data/src/toxi/math/NonLinearScaleMap.java +101 -0
- data/src/toxi/math/ScaleMap.java +183 -0
- data/src/toxi/math/SigmoidInterpolation.java +78 -0
- data/src/toxi/math/SinCosLUT.java +141 -0
- data/src/toxi/math/ThresholdInterpolation.java +58 -0
- data/src/toxi/math/ZoomLensInterpolation.java +126 -0
- data/src/toxi/math/conversion/UnitTranslator.java +161 -0
- data/src/toxi/math/noise/PerlinNoise.java +281 -0
- data/src/toxi/math/noise/SimplexNoise.java +542 -0
- data/src/toxi/math/waves/AMFMSineWave.java +143 -0
- data/src/toxi/math/waves/AbstractWave.java +248 -0
- data/src/toxi/math/waves/ConstantWave.java +48 -0
- data/src/toxi/math/waves/FMHarmonicSquareWave.java +155 -0
- data/src/toxi/math/waves/FMSawtoothWave.java +144 -0
- data/src/toxi/math/waves/FMSineWave.java +142 -0
- data/src/toxi/math/waves/FMSquareWave.java +143 -0
- data/src/toxi/math/waves/FMTriangleWave.java +126 -0
- data/src/toxi/math/waves/SineWave.java +81 -0
- data/src/toxi/math/waves/Wave2D.java +68 -0
- data/src/toxi/math/waves/WaveState.java +69 -0
- data/src/toxi/music/scale/AbstractScale.java +117 -0
- data/src/toxi/music/scale/GenericScale.java +66 -0
- data/src/toxi/music/scale/MajorScale.java +41 -0
- data/src/toxi/newmesh/AttributedEdge.java +106 -0
- data/src/toxi/newmesh/AttributedFace.java +63 -0
- data/src/toxi/newmesh/IndexedTriangleMesh.java +809 -0
- data/src/toxi/newmesh/MeshAttributeCompiler.java +45 -0
- data/src/toxi/newmesh/MeshFaceNormalCompiler.java +52 -0
- data/src/toxi/newmesh/MeshUVCompiler.java +52 -0
- data/src/toxi/newmesh/MeshVertexColorCompiler.java +49 -0
- data/src/toxi/newmesh/MeshVertexCompiler.java +54 -0
- data/src/toxi/newmesh/MeshVertexNormalCompiler.java +55 -0
- data/src/toxi/newmesh/SpatialIndex.java +78 -0
- data/src/toxi/physics2d/ParticlePath2D.java +100 -0
- data/src/toxi/physics2d/ParticleString2D.java +184 -0
- data/src/toxi/physics2d/PullBackSpring2D.java +51 -0
- data/src/toxi/physics2d/VerletConstrainedSpring2D.java +89 -0
- data/src/toxi/physics2d/VerletMinDistanceSpring2D.java +57 -0
- data/src/toxi/physics2d/VerletParticle2D.java +457 -0
- data/src/toxi/physics2d/VerletPhysics2D.java +448 -0
- data/src/toxi/physics2d/VerletSpring2D.java +181 -0
- data/src/toxi/physics2d/behaviors/AttractionBehavior2D.java +212 -0
- data/src/toxi/physics2d/behaviors/ConstantForceBehavior2D.java +112 -0
- data/src/toxi/physics2d/behaviors/GravityBehavior2D.java +61 -0
- data/src/toxi/physics2d/behaviors/ParticleBehavior2D.java +66 -0
- data/src/toxi/physics2d/constraints/AngularConstraint.java +83 -0
- data/src/toxi/physics2d/constraints/AxisConstraint.java +71 -0
- data/src/toxi/physics2d/constraints/CircularConstraint.java +69 -0
- data/src/toxi/physics2d/constraints/MaxConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/MinConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/ParticleConstraint2D.java +47 -0
- data/src/toxi/physics2d/constraints/PolygonConstraint.java +93 -0
- data/src/toxi/physics2d/constraints/RectConstraint.java +114 -0
- data/src/toxi/physics3d/ParticlePath3D.java +100 -0
- data/src/toxi/physics3d/ParticleString3D.java +184 -0
- data/src/toxi/physics3d/PullBackSpring3D.java +50 -0
- data/src/toxi/physics3d/VerletConstrainedSpring3D.java +88 -0
- data/src/toxi/physics3d/VerletMinDistanceSpring3D.java +56 -0
- data/src/toxi/physics3d/VerletParticle3D.java +385 -0
- data/src/toxi/physics3d/VerletPhysics3D.java +417 -0
- data/src/toxi/physics3d/VerletSpring3D.java +180 -0
- data/src/toxi/physics3d/behaviors/AttractionBehavior3D.java +182 -0
- data/src/toxi/physics3d/behaviors/ConstantForceBehavior3D.java +92 -0
- data/src/toxi/physics3d/behaviors/GravityBehavior3D.java +61 -0
- data/src/toxi/physics3d/behaviors/ParticleBehavior3D.java +52 -0
- data/src/toxi/physics3d/constraints/AxisConstraint.java +68 -0
- data/src/toxi/physics3d/constraints/BoxConstraint.java +121 -0
- data/src/toxi/physics3d/constraints/CylinderConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/MaxConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/MinConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/ParticleConstraint3D.java +49 -0
- data/src/toxi/physics3d/constraints/PlaneConstraint.java +78 -0
- data/src/toxi/physics3d/constraints/SoftBoxConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/SphereConstraint.java +108 -0
- data/src/toxi/processing/ArrowModifier.java +116 -0
- data/src/toxi/processing/DashedLineModifier.java +48 -0
- data/src/toxi/processing/DeltaOrientationMapper.java +57 -0
- data/src/toxi/processing/Line2DRenderModifier.java +18 -0
- data/src/toxi/processing/MeshToVBO.java +94 -0
- data/src/toxi/processing/NormalMapper.java +18 -0
- data/src/toxi/processing/POVInterface.java +121 -0
- data/src/toxi/processing/POVMesh.java +219 -0
- data/src/toxi/processing/POVWriter.java +460 -0
- data/src/toxi/processing/RCOpaque.java +77 -0
- data/src/toxi/processing/RCTransp.java +78 -0
- data/src/toxi/processing/TextureBuilder.java +232 -0
- data/src/toxi/processing/Textures.java +110 -0
- data/src/toxi/processing/ToxiclibsSupport.java +1239 -0
- data/src/toxi/processing/Tracing.java +25 -0
- data/src/toxi/processing/XYZNormalMapper.java +30 -0
- data/src/toxi/sim/automata/CAMatrix.java +297 -0
- data/src/toxi/sim/automata/CARule.java +76 -0
- data/src/toxi/sim/automata/CARule2D.java +354 -0
- data/src/toxi/sim/automata/CAWolfram1D.java +309 -0
- data/src/toxi/sim/automata/EvolvableMatrix.java +61 -0
- data/src/toxi/sim/automata/MatrixEvolver.java +42 -0
- data/src/toxi/sim/dla/BottomUpOrder.java +76 -0
- data/src/toxi/sim/dla/DLA.java +497 -0
- data/src/toxi/sim/dla/DLAConfiguration.java +364 -0
- data/src/toxi/sim/dla/DLAEventAdapter.java +64 -0
- data/src/toxi/sim/dla/DLAEventListener.java +57 -0
- data/src/toxi/sim/dla/DLAGuideLines.java +219 -0
- data/src/toxi/sim/dla/DLAParticle.java +102 -0
- data/src/toxi/sim/dla/DLASegment.java +88 -0
- data/src/toxi/sim/dla/PipelineOrder.java +50 -0
- data/src/toxi/sim/dla/RadialDistanceOrder.java +92 -0
- data/src/toxi/sim/erosion/ErosionFunction.java +122 -0
- data/src/toxi/sim/erosion/TalusAngleErosion.java +145 -0
- data/src/toxi/sim/erosion/ThermalErosion.java +75 -0
- data/src/toxi/sim/fluids/FluidSolver2D.java +762 -0
- data/src/toxi/sim/fluids/FluidSolver3D.java +326 -0
- data/src/toxi/sim/grayscott/GrayScott.java +469 -0
- data/src/toxi/util/DateUtils.java +141 -0
- data/src/toxi/util/FileSequenceDescriptor.java +181 -0
- data/src/toxi/util/FileUtils.java +467 -0
- data/src/toxi/util/datatypes/ArraySet.java +128 -0
- data/src/toxi/util/datatypes/ArrayUtil.java +404 -0
- data/src/toxi/util/datatypes/BiasedDoubleRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedFloatRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedIntegerRange.java +141 -0
- data/src/toxi/util/datatypes/DoubleRange.java +251 -0
- data/src/toxi/util/datatypes/FloatRange.java +251 -0
- data/src/toxi/util/datatypes/GenericSet.java +215 -0
- data/src/toxi/util/datatypes/IntegerRange.java +247 -0
- data/src/toxi/util/datatypes/IntegerSet.java +149 -0
- data/src/toxi/util/datatypes/ItemIndex.java +72 -0
- data/src/toxi/util/datatypes/SingletonRegistry.java +91 -0
- data/src/toxi/util/datatypes/TypedProperties.java +291 -0
- data/src/toxi/util/datatypes/UndirectedGraph.java +134 -0
- data/src/toxi/util/datatypes/UniqueItemIndex.java +223 -0
- data/src/toxi/util/datatypes/WeightedRandomEntry.java +76 -0
- data/src/toxi/util/datatypes/WeightedRandomSet.java +125 -0
- data/src/toxi/util/events/EventDispatcher.java +86 -0
- data/src/toxi/volume/AdditiveBrush.java +19 -0
- data/src/toxi/volume/ArrayIsoSurface.java +297 -0
- data/src/toxi/volume/BoxBrush.java +100 -0
- data/src/toxi/volume/BrushMode.java +16 -0
- data/src/toxi/volume/HashIsoSurface.java +354 -0
- data/src/toxi/volume/IsoSurface.java +59 -0
- data/src/toxi/volume/MarchingCubesIndex.java +312 -0
- data/src/toxi/volume/MeshLatticeBuilder.java +358 -0
- data/src/toxi/volume/MeshVoxelizer.java +216 -0
- data/src/toxi/volume/MultiplyBrush.java +20 -0
- data/src/toxi/volume/PeakBrush.java +21 -0
- data/src/toxi/volume/ReplaceBrush.java +19 -0
- data/src/toxi/volume/RoundBrush.java +113 -0
- data/src/toxi/volume/VolumetricBrush.java +160 -0
- data/src/toxi/volume/VolumetricHashMap.java +179 -0
- data/src/toxi/volume/VolumetricSpace.java +195 -0
- data/src/toxi/volume/VolumetricSpaceArray.java +214 -0
- data/toxiclibs.gemspec +34 -0
- metadata +424 -27
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.sim.dla;
|
|
29
|
+
|
|
30
|
+
import java.util.Comparator;
|
|
31
|
+
|
|
32
|
+
import toxi.geom.Line3D;
|
|
33
|
+
import toxi.geom.Vec3D;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* This comparator sorts segments based on their mid-point's distance to a given
|
|
37
|
+
* origin point. This creates a circular growth. The order can be reversed via a
|
|
38
|
+
* constructor flag and then causes the DLA system to grow from the outside
|
|
39
|
+
* towards the given origin point.
|
|
40
|
+
*/
|
|
41
|
+
public class RadialDistanceOrder implements Comparator<Line3D> {
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
public Vec3D origin;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
*/
|
|
51
|
+
public boolean isFlipped;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
public RadialDistanceOrder() {
|
|
57
|
+
this(new Vec3D(), false);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* @param origin
|
|
63
|
+
* @param isFlipped
|
|
64
|
+
*/
|
|
65
|
+
public RadialDistanceOrder(Vec3D origin, boolean isFlipped) {
|
|
66
|
+
this.origin = origin;
|
|
67
|
+
this.isFlipped = isFlipped;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
*
|
|
72
|
+
* @param a
|
|
73
|
+
* @param b
|
|
74
|
+
* @return
|
|
75
|
+
*/
|
|
76
|
+
@Override
|
|
77
|
+
public int compare(Line3D a, Line3D b) {
|
|
78
|
+
float da = origin.sub(a.getMidPoint()).magSquared();
|
|
79
|
+
float db = origin.sub(b.getMidPoint()).magSquared();
|
|
80
|
+
if (isFlipped) {
|
|
81
|
+
da *= -1;
|
|
82
|
+
db *= -1;
|
|
83
|
+
}
|
|
84
|
+
if (da < db) {
|
|
85
|
+
return -1;
|
|
86
|
+
}
|
|
87
|
+
if (da > db) {
|
|
88
|
+
return 1;
|
|
89
|
+
}
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.sim.erosion;
|
|
29
|
+
|
|
30
|
+
import toxi.geom.Polygon2D;
|
|
31
|
+
import toxi.geom.Rect;
|
|
32
|
+
import toxi.geom.Vec2D;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Abstract parent class for various 2D erosion simulations, implemented as
|
|
36
|
+
* sub-classes.
|
|
37
|
+
*/
|
|
38
|
+
public abstract class ErosionFunction {
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
protected float[] elevation;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
*/
|
|
48
|
+
protected int width;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
*/
|
|
53
|
+
protected int height;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
protected float[] d = new float[9];
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
*/
|
|
63
|
+
protected float[] h = new float[9];
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
protected int[] off;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Destructively erodes the given array.
|
|
72
|
+
*
|
|
73
|
+
*/
|
|
74
|
+
public void erodeAll() {
|
|
75
|
+
for (int y = 1, w1 = width - 1, h1 = height - 1; y < h1; y++) {
|
|
76
|
+
for (int x = 1; x < w1; x++) {
|
|
77
|
+
erodeAt(x, y);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
*
|
|
84
|
+
* @param x
|
|
85
|
+
* @param y
|
|
86
|
+
*/
|
|
87
|
+
public abstract void erodeAt(int x, int y);
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
* @param poly
|
|
92
|
+
*/
|
|
93
|
+
public void erodeWithinPolygon(Polygon2D poly) {
|
|
94
|
+
Rect bounds = poly.getBounds().intersectionRectWith(
|
|
95
|
+
new Rect(1, 1, width - 2, height - 2));
|
|
96
|
+
Vec2D pos = new Vec2D();
|
|
97
|
+
for (int y = (int) bounds.getTop(), y2 = (int) bounds.getBottom(); y < y2; y++) {
|
|
98
|
+
for (int x = (int) bounds.getLeft(), x2 = (int) bounds.getRight(); x < x2; x++) {
|
|
99
|
+
if (poly.containsPoint(pos.set(x, y))) {
|
|
100
|
+
erodeAt(x, y);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
*
|
|
108
|
+
* @param elevation
|
|
109
|
+
* @param width
|
|
110
|
+
* @param height
|
|
111
|
+
*/
|
|
112
|
+
public void setElevation(float[] elevation, final int width,
|
|
113
|
+
final int height) {
|
|
114
|
+
this.elevation = elevation;
|
|
115
|
+
this.width = width;
|
|
116
|
+
this.height = height;
|
|
117
|
+
off = new int[] {
|
|
118
|
+
-width - 1, -width, -width + 1, -1, 0, 1, width - 1, width,
|
|
119
|
+
width + 1
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.sim.erosion;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* For each neighbour it's computed the difference between the processed cell
|
|
32
|
+
* and the neighbour:
|
|
33
|
+
*
|
|
34
|
+
* <pre>
|
|
35
|
+
* d[i] = h - h[i];
|
|
36
|
+
* </pre>
|
|
37
|
+
*
|
|
38
|
+
* the maximum positive difference is stored in d_max, and the sum of all the
|
|
39
|
+
* positive differences that are bigger than T (this numer is n), the talus
|
|
40
|
+
* angle, is stored in d_tot.
|
|
41
|
+
*
|
|
42
|
+
* Now it's possible to update all the n cells (where d[i] is bigger than T)
|
|
43
|
+
* using this formula:
|
|
44
|
+
*
|
|
45
|
+
* <pre>
|
|
46
|
+
* h[i] = h[i] + c * (d_max - T) * (d[i] / d_tot);
|
|
47
|
+
* </pre>
|
|
48
|
+
*
|
|
49
|
+
* and the main cell with this other formula:
|
|
50
|
+
*
|
|
51
|
+
* <pre>
|
|
52
|
+
* h = h - (d_max - (n * d_max * T / d_tot));
|
|
53
|
+
* </pre>
|
|
54
|
+
*
|
|
55
|
+
* The Talus angle T is a threshold that determines which slopes are affected by
|
|
56
|
+
* the erosion, instead the c constant determines how much material is eroded.
|
|
57
|
+
*/
|
|
58
|
+
public class TalusAngleErosion extends ErosionFunction {
|
|
59
|
+
|
|
60
|
+
private float theta;
|
|
61
|
+
private float amount;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @param theta
|
|
65
|
+
* talus angle
|
|
66
|
+
* @param amount
|
|
67
|
+
* material transport amount
|
|
68
|
+
*/
|
|
69
|
+
public TalusAngleErosion(float theta, float amount) {
|
|
70
|
+
this.theta = theta;
|
|
71
|
+
this.amount = amount;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
* @param x
|
|
77
|
+
* @param y
|
|
78
|
+
*/
|
|
79
|
+
@Override
|
|
80
|
+
public void erodeAt(int x, int y) {
|
|
81
|
+
int idx = y * width + x;
|
|
82
|
+
float maxD = 0;
|
|
83
|
+
float sumD = 0;
|
|
84
|
+
int n = 0;
|
|
85
|
+
for (int i = 0; i < 9; i++) {
|
|
86
|
+
h[i] = elevation[idx + off[i]];
|
|
87
|
+
d[i] = elevation[idx] - h[i];
|
|
88
|
+
if (d[i] > theta) {
|
|
89
|
+
sumD += d[i];
|
|
90
|
+
n++;
|
|
91
|
+
if (d[i] > maxD) {
|
|
92
|
+
maxD = d[i];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (sumD > 0) {
|
|
97
|
+
elevation[idx] -= (maxD - (n * maxD * theta / sumD));
|
|
98
|
+
for (int i = 0; i < 9; i++) {
|
|
99
|
+
if (d[i] > theta) {
|
|
100
|
+
elevation[idx + off[i]] = h[i] + amount * (maxD - theta)
|
|
101
|
+
* (d[i] / sumD);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @return the amount
|
|
109
|
+
*/
|
|
110
|
+
public float getAmount() {
|
|
111
|
+
return amount;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @return the theta
|
|
116
|
+
*/
|
|
117
|
+
public float getTheta() {
|
|
118
|
+
return theta;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @param amount
|
|
123
|
+
* the amount to set
|
|
124
|
+
*/
|
|
125
|
+
public void setAmount(float amount) {
|
|
126
|
+
this.amount = amount;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @param theta
|
|
131
|
+
* the theta to set
|
|
132
|
+
*/
|
|
133
|
+
public void setTheta(float theta) {
|
|
134
|
+
this.theta = theta;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
*
|
|
139
|
+
* @return
|
|
140
|
+
*/
|
|
141
|
+
@Override
|
|
142
|
+
public String toString() {
|
|
143
|
+
return getClass().getName() + ": theta=" + theta + " amount=" + amount;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.sim.erosion;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Applies thermal erosion to the given elevation data. Based on the description
|
|
32
|
+
* here: http://www.m3xbox.com/GPU_blog/?p=37
|
|
33
|
+
*/
|
|
34
|
+
public class ThermalErosion extends ErosionFunction {
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @param x
|
|
39
|
+
* @param y
|
|
40
|
+
*/
|
|
41
|
+
@Override
|
|
42
|
+
public void erodeAt(int x, int y) {
|
|
43
|
+
int idx = y * width + x;
|
|
44
|
+
float minD = Float.MAX_VALUE;
|
|
45
|
+
float sumD = 0;
|
|
46
|
+
int n = 0;
|
|
47
|
+
for (int i = 0; i < 9; i++) {
|
|
48
|
+
h[i] = elevation[idx + off[i]];
|
|
49
|
+
d[i] = elevation[idx] - h[i];
|
|
50
|
+
if (d[i] > 0) {
|
|
51
|
+
if (d[i] < minD) {
|
|
52
|
+
minD = d[i];
|
|
53
|
+
}
|
|
54
|
+
sumD += d[i];
|
|
55
|
+
n++;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
float hOut = n * minD / (n + 1.0f);
|
|
59
|
+
elevation[idx] = elevation[idx] - hOut;
|
|
60
|
+
for (int i = 0; i < 9; i++) {
|
|
61
|
+
if (d[i] > 0) {
|
|
62
|
+
elevation[idx + off[i]] = h[i] + hOut * (d[i] / sumD);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
* @return
|
|
70
|
+
*/
|
|
71
|
+
@Override
|
|
72
|
+
public String toString() {
|
|
73
|
+
return getClass().getName();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,762 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
package toxi.sim.fluids;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Optimized Jos Stam style fluid solver with vorticity confinement and buoyancy
|
|
32
|
+
* force.
|
|
33
|
+
*
|
|
34
|
+
* @author Alexander McKenzie
|
|
35
|
+
* @author Karsten Schmidt
|
|
36
|
+
*
|
|
37
|
+
* <p>
|
|
38
|
+
* optimized by toxi 2006-02-09
|
|
39
|
+
* <ul>
|
|
40
|
+
* <li>reduced nesting level of loops</li>
|
|
41
|
+
* <li>removed need for I() util method by unrolling all index
|
|
42
|
+
* calculations</li>
|
|
43
|
+
* <li>renamed variables for better legibility</li>
|
|
44
|
+
* </ul>
|
|
45
|
+
* </p>
|
|
46
|
+
**/
|
|
47
|
+
public class FluidSolver2D {
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
protected int numIterations = 10;
|
|
53
|
+
|
|
54
|
+
protected int width,
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
*/
|
|
63
|
+
totalWidth,
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
*/
|
|
72
|
+
height,
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
*/
|
|
81
|
+
totalHeight;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
*/
|
|
86
|
+
protected int size;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
protected float timeStep;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
*
|
|
95
|
+
*/
|
|
96
|
+
protected float viscosity = 0;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
*
|
|
100
|
+
*/
|
|
101
|
+
protected float diffusion = 0.000001f;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
*
|
|
105
|
+
*/
|
|
106
|
+
protected float buoyancyA = 0.000625f;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
*
|
|
110
|
+
*/
|
|
111
|
+
protected float buoyancyB = 0.025f;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
*
|
|
115
|
+
*/
|
|
116
|
+
// protected float[] tmp;
|
|
117
|
+
protected float[] d,
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
*/
|
|
126
|
+
dOld;
|
|
127
|
+
protected float[] u,
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
*
|
|
131
|
+
*/
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
*
|
|
135
|
+
*/
|
|
136
|
+
uOld;
|
|
137
|
+
protected float[] v,
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
*
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
*
|
|
145
|
+
*/
|
|
146
|
+
vOld;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
*
|
|
150
|
+
*/
|
|
151
|
+
protected float[] curl;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Creates a new instance of the given dimension uses the specified time
|
|
155
|
+
* step.
|
|
156
|
+
*
|
|
157
|
+
* @param w
|
|
158
|
+
* matrix width
|
|
159
|
+
* @param h
|
|
160
|
+
* matrix height
|
|
161
|
+
* @param timeStep
|
|
162
|
+
*/
|
|
163
|
+
public FluidSolver2D(int w, int h, float timeStep) {
|
|
164
|
+
this.width = w;
|
|
165
|
+
this.height = h;
|
|
166
|
+
this.totalWidth = w + 2;
|
|
167
|
+
this.totalHeight = h + 2;
|
|
168
|
+
this.timeStep = timeStep;
|
|
169
|
+
size = totalWidth * totalHeight;
|
|
170
|
+
d = new float[size];
|
|
171
|
+
dOld = new float[size];
|
|
172
|
+
u = new float[size];
|
|
173
|
+
uOld = new float[size];
|
|
174
|
+
v = new float[size];
|
|
175
|
+
vOld = new float[size];
|
|
176
|
+
curl = new float[size];
|
|
177
|
+
reset();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @param buffer
|
|
183
|
+
* @param prev
|
|
184
|
+
*/
|
|
185
|
+
protected void addSource(float[] buffer, float[] prev) {
|
|
186
|
+
for (int i = 0; i < size; i++) {
|
|
187
|
+
buffer[i] += timeStep * prev[i];
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Calculate the input array after advection. We start with an input array
|
|
193
|
+
* from the previous timestep and an and output array. For all grid cells we
|
|
194
|
+
* need to calculate for the next timestep, we trace the cell's center
|
|
195
|
+
* position backwards through the velocity field. Then we interpolate from
|
|
196
|
+
* the grid of the previous timestep and assign this value to the current
|
|
197
|
+
* grid cell.
|
|
198
|
+
*
|
|
199
|
+
* @param b
|
|
200
|
+
* Flag specifying how to handle boundries.
|
|
201
|
+
* @param d
|
|
202
|
+
* Array to store the advected field.
|
|
203
|
+
* @param d0
|
|
204
|
+
* The array to advect.
|
|
205
|
+
* @param du
|
|
206
|
+
* The x component of the velocity field.
|
|
207
|
+
* @param dv
|
|
208
|
+
* The y component of the velocity field.
|
|
209
|
+
**/
|
|
210
|
+
|
|
211
|
+
protected void advect(int b, float[] d, float[] d0, float[] du, float[] dv) {
|
|
212
|
+
int i0, j0;
|
|
213
|
+
float x, y, s0, t0, s1, t1, scaledTime;
|
|
214
|
+
float wmax = width + 0.5f;
|
|
215
|
+
float hmax = height + 0.5f;
|
|
216
|
+
|
|
217
|
+
scaledTime = timeStep * width;
|
|
218
|
+
|
|
219
|
+
for (int i = 1, j = 1, idx = i + totalWidth; j <= height;) {
|
|
220
|
+
// go backwards through velocity field
|
|
221
|
+
x = i - scaledTime * du[idx];
|
|
222
|
+
y = j - scaledTime * dv[idx];
|
|
223
|
+
|
|
224
|
+
// interpolate results
|
|
225
|
+
if (x > wmax) {
|
|
226
|
+
x = wmax;
|
|
227
|
+
}
|
|
228
|
+
if (x < 0.5f) {
|
|
229
|
+
x = 0.5f;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
i0 = (int) x;
|
|
233
|
+
|
|
234
|
+
if (y > hmax) {
|
|
235
|
+
y = hmax;
|
|
236
|
+
}
|
|
237
|
+
if (y < 0.5f) {
|
|
238
|
+
y = 0.5f;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
j0 = (int) y;
|
|
242
|
+
|
|
243
|
+
s1 = x - i0;
|
|
244
|
+
s0 = 1 - s1;
|
|
245
|
+
t1 = y - j0;
|
|
246
|
+
t0 = 1 - t1;
|
|
247
|
+
|
|
248
|
+
int idx0 = i0 + j0 * totalWidth;
|
|
249
|
+
d[idx] = s0 * (t0 * d0[idx0] + t1 * d0[idx0 + totalWidth]) + s1
|
|
250
|
+
* (t0 * d0[idx0 + 1] + t1 * d0[idx0 + totalWidth + 1]);
|
|
251
|
+
|
|
252
|
+
if (i < width) {
|
|
253
|
+
i++;
|
|
254
|
+
idx++;
|
|
255
|
+
} else {
|
|
256
|
+
i = 1;
|
|
257
|
+
j++;
|
|
258
|
+
idx += 3;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
setBoundary(b, d);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Calculate the buoyancy force as part of the velocity solver. Fbuoy =
|
|
266
|
+
* -a*d*Y + b*(T-Tamb)*Y where Y = (0,1). The constants a and b are positive
|
|
267
|
+
* with appropriate (physically meaningful) units. T is the temperature at
|
|
268
|
+
* the current cell, Tamb is the average temperature of the fluid grid. The
|
|
269
|
+
* density d provides a mass that counteracts the buoyancy force.
|
|
270
|
+
*
|
|
271
|
+
* In this simplified implementation, we say that the temperature is
|
|
272
|
+
* synonymous with density (since smoke is *hot*) and because there are no
|
|
273
|
+
* other heat sources we can just use the density field instead of a new,
|
|
274
|
+
* seperate temperature field.
|
|
275
|
+
*
|
|
276
|
+
* @param buoy
|
|
277
|
+
* Array to store buoyancy force for each cell.
|
|
278
|
+
**/
|
|
279
|
+
|
|
280
|
+
protected void buoyancy(float[] buoy) {
|
|
281
|
+
float avgTemperature = 0;
|
|
282
|
+
|
|
283
|
+
// sum all temperatures
|
|
284
|
+
for (int i = 1, idx = 1 + totalWidth, j = 1; j <= height;) {
|
|
285
|
+
avgTemperature += d[idx];
|
|
286
|
+
if (i < width) {
|
|
287
|
+
i++;
|
|
288
|
+
idx++;
|
|
289
|
+
} else {
|
|
290
|
+
i = 1;
|
|
291
|
+
j++;
|
|
292
|
+
idx += 3;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// get average temperature
|
|
297
|
+
avgTemperature /= (width * height);
|
|
298
|
+
|
|
299
|
+
// for each cell compute buoyancy force
|
|
300
|
+
for (int i = 1, idx = 1 + totalWidth, j = 1; j <= height;) {
|
|
301
|
+
float currD = d[idx];
|
|
302
|
+
buoy[idx] = buoyancyA * currD - buoyancyB
|
|
303
|
+
* (currD - avgTemperature);
|
|
304
|
+
if (i < width) {
|
|
305
|
+
i++;
|
|
306
|
+
idx++;
|
|
307
|
+
} else {
|
|
308
|
+
i = 1;
|
|
309
|
+
j++;
|
|
310
|
+
idx += 3;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Calculate the curl
|
|
317
|
+
*
|
|
318
|
+
* @param idx
|
|
319
|
+
* @return
|
|
320
|
+
**/
|
|
321
|
+
|
|
322
|
+
protected final float curl(int idx) {
|
|
323
|
+
float du_dy = (u[idx + totalWidth] - u[idx - totalWidth]) * 0.5f;
|
|
324
|
+
float dv_dx = (v[idx + 1] - v[idx - 1]) * 0.5f;
|
|
325
|
+
return du_dy - dv_dx;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
*
|
|
330
|
+
* @param decay
|
|
331
|
+
*/
|
|
332
|
+
public final void decay(float decay) {
|
|
333
|
+
for (int i = 0; i < size; i++) {
|
|
334
|
+
u[i] *= decay;
|
|
335
|
+
v[i] *= decay;
|
|
336
|
+
d[i] *= decay;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* The basic density solving routine.
|
|
342
|
+
**/
|
|
343
|
+
public void densitySolver() {
|
|
344
|
+
// add density input by mouse
|
|
345
|
+
addSource(d, dOld);
|
|
346
|
+
float[] temp = d;
|
|
347
|
+
d = dOld;
|
|
348
|
+
dOld = temp;
|
|
349
|
+
diffusion(0, d, dOld, diffusion);
|
|
350
|
+
temp = d;
|
|
351
|
+
d = dOld;
|
|
352
|
+
dOld = temp;
|
|
353
|
+
advect(0, d, dOld, u, v);
|
|
354
|
+
|
|
355
|
+
// clear input density array for next frame
|
|
356
|
+
for (int i = 0; i < size; i++) {
|
|
357
|
+
dOld[i] = 0;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Recalculate the input array with diffusion effects. Here we consider a
|
|
363
|
+
* stable method of diffusion by finding the densities, which when diffusion
|
|
364
|
+
* used backward in time yield the same densities we started with. This is
|
|
365
|
+
* achieved through use of a linear solver to solve the sparse matrix built
|
|
366
|
+
* from this linear system.
|
|
367
|
+
*
|
|
368
|
+
* @param b
|
|
369
|
+
* Flag to specify how boundaries should be handled.
|
|
370
|
+
* @param c
|
|
371
|
+
* The array to store the results of the diffusion computation.
|
|
372
|
+
* @param c0
|
|
373
|
+
* The input array on which we should compute diffusion.
|
|
374
|
+
* @param diffusion
|
|
375
|
+
* The factor of diffusion.
|
|
376
|
+
**/
|
|
377
|
+
|
|
378
|
+
protected void diffusion(int b, float[] c, float[] c0, float diffusion) {
|
|
379
|
+
float a = timeStep * diffusion * width * height;
|
|
380
|
+
linearSolver(b, c, c0, a, 1 + 4 * a);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* @return the buoyancyA
|
|
385
|
+
*/
|
|
386
|
+
public float getBuoyancyA() {
|
|
387
|
+
return buoyancyA;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* @return the buoyancyB
|
|
392
|
+
*/
|
|
393
|
+
public float getBuoyancyB() {
|
|
394
|
+
return buoyancyB;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* @return the curl
|
|
399
|
+
*/
|
|
400
|
+
public float[] getCurl() {
|
|
401
|
+
return curl;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* @return the d
|
|
406
|
+
*/
|
|
407
|
+
public float[] getDensityField() {
|
|
408
|
+
return d;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* @return the diffusion
|
|
413
|
+
*/
|
|
414
|
+
public float getDiffusion() {
|
|
415
|
+
return diffusion;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* @return the numIterations
|
|
420
|
+
*/
|
|
421
|
+
public int getNumIterations() {
|
|
422
|
+
return numIterations;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* @return the timeStep
|
|
427
|
+
*/
|
|
428
|
+
public float getTimeStep() {
|
|
429
|
+
return timeStep;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* @return the totalHeight
|
|
434
|
+
*/
|
|
435
|
+
public int getTotalHeight() {
|
|
436
|
+
return totalHeight;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* @return the totalWidth
|
|
441
|
+
*/
|
|
442
|
+
public int getTotalWidth() {
|
|
443
|
+
return totalWidth;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* @return the u
|
|
448
|
+
*/
|
|
449
|
+
public float[] getVelocityFieldU() {
|
|
450
|
+
return u;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* @return the v
|
|
455
|
+
*/
|
|
456
|
+
public float[] getVelocityFieldV() {
|
|
457
|
+
return v;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* @return the viscosity
|
|
462
|
+
*/
|
|
463
|
+
public float getViscosity() {
|
|
464
|
+
return viscosity;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Iterative linear system solver using the Gauss-Seidel relaxation
|
|
469
|
+
* technique. Room for much improvement here...
|
|
470
|
+
*
|
|
471
|
+
* @param b
|
|
472
|
+
* @param x
|
|
473
|
+
* @param x0
|
|
474
|
+
* @param a
|
|
475
|
+
* @param c
|
|
476
|
+
**/
|
|
477
|
+
|
|
478
|
+
protected void linearSolver(int b, float[] x, float[] x0, float a, float c) {
|
|
479
|
+
c = 1f / c;
|
|
480
|
+
for (int k = 0; k < numIterations; k++) {
|
|
481
|
+
for (int i = 1, idx = 1 + totalWidth, j = 1; j <= height;) {
|
|
482
|
+
x[idx] = (a
|
|
483
|
+
* (x[idx - 1] + x[idx + 1] + x[idx - totalWidth] + x[idx
|
|
484
|
+
+ totalWidth]) + x0[idx])
|
|
485
|
+
* c;
|
|
486
|
+
if (i < width) {
|
|
487
|
+
i++;
|
|
488
|
+
idx++;
|
|
489
|
+
} else {
|
|
490
|
+
i = 1;
|
|
491
|
+
j++;
|
|
492
|
+
idx = j * totalWidth + 1;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
setBoundary(b, x);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Use project() to make the velocity a mass conserving, incompressible
|
|
501
|
+
* field. Achieved through a Hodge decomposition. First we calculate the
|
|
502
|
+
* divergence field of our velocity using the mean finite diffusionernce
|
|
503
|
+
* approach, and apply the linear solver to compute the Poisson equation and
|
|
504
|
+
* obtain a "height" field. Now we subtract the gradient of this field to
|
|
505
|
+
* obtain our mass conserving velocity field.
|
|
506
|
+
*
|
|
507
|
+
* @param x
|
|
508
|
+
* The array in which the x component of our final velocity field
|
|
509
|
+
* is stored.
|
|
510
|
+
* @param y
|
|
511
|
+
* The array in which the y component of our final velocity field
|
|
512
|
+
* is stored.
|
|
513
|
+
* @param p
|
|
514
|
+
* A temporary array we can use in the computation.
|
|
515
|
+
* @param div
|
|
516
|
+
* Another temporary array we use to hold the velocity divergence
|
|
517
|
+
* field.
|
|
518
|
+
*
|
|
519
|
+
**/
|
|
520
|
+
|
|
521
|
+
protected void project(float[] x, float[] y, float[] p, float[] div) {
|
|
522
|
+
float fact = -0.5f / width;
|
|
523
|
+
for (int i = 1, idx = 1 + totalWidth, j = 1; j <= height;) {
|
|
524
|
+
div[idx] = (x[idx + 1] - x[idx - 1] + y[idx + totalWidth] - y[idx
|
|
525
|
+
- totalWidth])
|
|
526
|
+
* fact;
|
|
527
|
+
p[idx] = 0;
|
|
528
|
+
if (i < width) {
|
|
529
|
+
i++;
|
|
530
|
+
idx++;
|
|
531
|
+
} else {
|
|
532
|
+
i = 1;
|
|
533
|
+
j++;
|
|
534
|
+
idx += 3;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
setBoundary(0, div);
|
|
539
|
+
setBoundary(0, p);
|
|
540
|
+
|
|
541
|
+
linearSolver(0, p, div, 1, 4);
|
|
542
|
+
|
|
543
|
+
fact = -0.5f * width;
|
|
544
|
+
for (int i = 1, idx = 1 + totalWidth, j = 1; j <= height;) {
|
|
545
|
+
x[idx] += fact * (p[idx + 1] - p[idx - 1]);
|
|
546
|
+
y[idx] += fact * (p[idx + totalWidth] - p[idx - totalWidth]);
|
|
547
|
+
if (i < width) {
|
|
548
|
+
i++;
|
|
549
|
+
idx++;
|
|
550
|
+
} else {
|
|
551
|
+
i = 1;
|
|
552
|
+
idx += 3;
|
|
553
|
+
j++;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
setBoundary(1, x);
|
|
558
|
+
setBoundary(2, y);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Reset the datastructures. We use 1d arrays for speed.
|
|
563
|
+
**/
|
|
564
|
+
public final void reset() {
|
|
565
|
+
for (int i = 0; i < size; i++) {
|
|
566
|
+
u[i] = uOld[i] = v[i] = vOld[i] = 0.0f;
|
|
567
|
+
d[i] = dOld[i] = curl[i] = 0.0f;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* specifies simple boundary conditions.
|
|
573
|
+
*
|
|
574
|
+
* @param b
|
|
575
|
+
* @param x
|
|
576
|
+
*/
|
|
577
|
+
protected void setBoundary(int b, float[] x) {
|
|
578
|
+
int idn = height * totalWidth;
|
|
579
|
+
for (int i = 1, idi = totalWidth; i <= width; i++) {
|
|
580
|
+
x[idi] = b == 1 ? -x[idi + 1] : x[idi + 1];
|
|
581
|
+
x[width + 1 + idi] = b == 1 ? -x[idi + width] : x[idi + width];
|
|
582
|
+
x[i] = b == 2 ? -x[totalWidth + i] : x[totalWidth + i];
|
|
583
|
+
x[i + idn + totalWidth] = b == 2 ? -x[idn + i] : x[idn + i];
|
|
584
|
+
idi += totalWidth;
|
|
585
|
+
}
|
|
586
|
+
x[0] = 0.5f * (x[1] + x[totalWidth]);
|
|
587
|
+
x[idn + totalWidth] = 0.5f * (x[1 + totalWidth + idn] + x[idn]);
|
|
588
|
+
x[width + 1] = 0.5f * (x[width] + x[width + 1 + totalWidth]);
|
|
589
|
+
x[width + 1 + totalWidth + idn] = 0.5f * (x[width + totalWidth + idn] + x[width
|
|
590
|
+
+ 1 + idn]);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* @param buoyancyA
|
|
595
|
+
* the buoyancyA to set
|
|
596
|
+
*/
|
|
597
|
+
public void setBuoyancyA(float buoyancyA) {
|
|
598
|
+
this.buoyancyA = buoyancyA;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* @param buoyancyB
|
|
603
|
+
* the buoyancyB to set
|
|
604
|
+
*/
|
|
605
|
+
public void setBuoyancyB(float buoyancyB) {
|
|
606
|
+
this.buoyancyB = buoyancyB;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* @param curl
|
|
611
|
+
* the curl to set
|
|
612
|
+
*/
|
|
613
|
+
public void setCurl(float[] curl) {
|
|
614
|
+
this.curl = curl;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* @param diffusion
|
|
619
|
+
* the diffusion to set
|
|
620
|
+
*/
|
|
621
|
+
public void setDiffusion(float diffusion) {
|
|
622
|
+
this.diffusion = diffusion;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* @param numIterations
|
|
627
|
+
* the numIterations to set
|
|
628
|
+
*/
|
|
629
|
+
public void setNumIterations(int numIterations) {
|
|
630
|
+
this.numIterations = numIterations;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* @param timeStep
|
|
635
|
+
* the timeStep to set
|
|
636
|
+
*/
|
|
637
|
+
public void setTimeStep(float timeStep) {
|
|
638
|
+
this.timeStep = timeStep;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* @param viscosity
|
|
643
|
+
* the viscosity to set
|
|
644
|
+
*/
|
|
645
|
+
public void setViscosity(float viscosity) {
|
|
646
|
+
this.viscosity = viscosity;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* The basic velocity solving routine as described by Stam.
|
|
651
|
+
**/
|
|
652
|
+
|
|
653
|
+
public void velocitySolver() {
|
|
654
|
+
|
|
655
|
+
// add velocity that was input by mouse
|
|
656
|
+
addSource(u, uOld);
|
|
657
|
+
addSource(v, vOld);
|
|
658
|
+
|
|
659
|
+
// add in vorticity confinement force
|
|
660
|
+
vorticityConfinement(uOld, vOld);
|
|
661
|
+
addSource(u, uOld);
|
|
662
|
+
addSource(v, vOld);
|
|
663
|
+
|
|
664
|
+
// add in buoyancy force
|
|
665
|
+
buoyancy(vOld);
|
|
666
|
+
addSource(v, vOld);
|
|
667
|
+
|
|
668
|
+
float [] temp = u;
|
|
669
|
+
u = uOld;
|
|
670
|
+
uOld = temp;
|
|
671
|
+
diffusion(0, u, uOld, viscosity);
|
|
672
|
+
temp = v;
|
|
673
|
+
v = vOld;
|
|
674
|
+
vOld = temp;
|
|
675
|
+
diffusion(0, v, vOld, viscosity);
|
|
676
|
+
|
|
677
|
+
// we create an incompressible field
|
|
678
|
+
// for more effective advection.
|
|
679
|
+
project(u, v, uOld, vOld);
|
|
680
|
+
temp = u;
|
|
681
|
+
u = uOld;
|
|
682
|
+
uOld = temp;
|
|
683
|
+
temp = v;
|
|
684
|
+
v = vOld;
|
|
685
|
+
vOld = temp;
|
|
686
|
+
|
|
687
|
+
// self advect velocities
|
|
688
|
+
advect(1, u, uOld, uOld, vOld);
|
|
689
|
+
advect(2, v, vOld, uOld, vOld);
|
|
690
|
+
|
|
691
|
+
// make an incompressible field
|
|
692
|
+
project(u, v, uOld, vOld);
|
|
693
|
+
|
|
694
|
+
// clear all input velocities for next frame
|
|
695
|
+
for (int i = 0; i < size; i++) {
|
|
696
|
+
uOld[i] = vOld[i] = 0;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Calculate the vorticity confinement force for each cell in the fluid
|
|
702
|
+
* grid. At a point (i,j), Fvc = N x width where width is the curl at (i,j)
|
|
703
|
+
* and N = del |width| / |del |width||. N is the vector pointing to the
|
|
704
|
+
* vortex center, hence we add force perpendicular to N.
|
|
705
|
+
*
|
|
706
|
+
* @param Fvc_x
|
|
707
|
+
* The array to store the x component of the vorticity
|
|
708
|
+
* confinement force for each cell.
|
|
709
|
+
* @param Fvc_y
|
|
710
|
+
* The array to store the y component of the vorticity
|
|
711
|
+
* confinement force for each cell.
|
|
712
|
+
**/
|
|
713
|
+
|
|
714
|
+
public void vorticityConfinement(float[] Fvc_x, float[] Fvc_y) {
|
|
715
|
+
float dw_dx, dw_dy;
|
|
716
|
+
float length;
|
|
717
|
+
float vort;
|
|
718
|
+
|
|
719
|
+
// Calculate magnitude of curl(u,v) for each cell. (|width|)
|
|
720
|
+
for (int i = 1, j = 1, idx = i + totalWidth; j <= height;) {
|
|
721
|
+
float c = curl(idx);
|
|
722
|
+
curl[idx] = c > 0 ? c : -c;
|
|
723
|
+
if (i < width) {
|
|
724
|
+
i++;
|
|
725
|
+
idx++;
|
|
726
|
+
} else {
|
|
727
|
+
i = 1;
|
|
728
|
+
j++;
|
|
729
|
+
idx += 3; // j*totalWidth+1;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
for (int i = 2, j = 2, idx = i + totalWidth * j; j < height;) {
|
|
734
|
+
// Find derivative of the magnitude (n = del |width|)
|
|
735
|
+
dw_dx = (curl[idx + 1] - curl[idx - 1]) * 0.5f;
|
|
736
|
+
dw_dy = (curl[idx + totalWidth] - curl[idx - totalWidth]) * 0.5f;
|
|
737
|
+
|
|
738
|
+
// Calculate vector length. (|n|)
|
|
739
|
+
// Add small factor to prevent divide by zeros.
|
|
740
|
+
length = 1f / ((float) Math.sqrt(dw_dx * dw_dx + dw_dy * dw_dy) + 0.000001f);
|
|
741
|
+
|
|
742
|
+
// N = ( n/|n| )
|
|
743
|
+
dw_dx *= length;
|
|
744
|
+
dw_dy *= length;
|
|
745
|
+
|
|
746
|
+
vort = curl[idx];
|
|
747
|
+
|
|
748
|
+
// N x width
|
|
749
|
+
Fvc_x[idx] = dw_dy * -vort;
|
|
750
|
+
Fvc_y[idx] = dw_dx * vort;
|
|
751
|
+
|
|
752
|
+
if (i < width - 1) {
|
|
753
|
+
i++;
|
|
754
|
+
idx++;
|
|
755
|
+
} else {
|
|
756
|
+
i = 2;
|
|
757
|
+
j++;
|
|
758
|
+
idx += 5; // j*totalWidth+2;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|