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,110 @@
|
|
|
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.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import toxi.geom.Vec3D;
|
|
31
|
+
import toxi.math.MathUtils;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Spherical harmonics surface evaluator based on code by Paul Bourke:
|
|
35
|
+
* http://local.wasp.uwa.edu.au/~pbourke/geometry/sphericalh/
|
|
36
|
+
*/
|
|
37
|
+
public class SphericalHarmonics implements SurfaceFunction {
|
|
38
|
+
|
|
39
|
+
float[] m;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param m
|
|
44
|
+
*/
|
|
45
|
+
public SphericalHarmonics(float[] m) {
|
|
46
|
+
this.m = m;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// FIXME check where flipped vertex order is coming from sometimes
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @param p
|
|
54
|
+
* @param phi
|
|
55
|
+
* @param theta
|
|
56
|
+
* @return
|
|
57
|
+
*/
|
|
58
|
+
@Override
|
|
59
|
+
public Vec3D computeVertexFor(Vec3D p, float phi, float theta) {
|
|
60
|
+
float r = 0;
|
|
61
|
+
r += Math.pow(MathUtils.sin(m[0] * theta), m[1]);
|
|
62
|
+
r += Math.pow(MathUtils.cos(m[2] * theta), m[3]);
|
|
63
|
+
r += Math.pow(MathUtils.sin(m[4] * phi), m[5]);
|
|
64
|
+
r += Math.pow(MathUtils.cos(m[6] * phi), m[7]);
|
|
65
|
+
|
|
66
|
+
float sinTheta = MathUtils.sin(theta);
|
|
67
|
+
p.x = r * sinTheta * MathUtils.cos(phi);
|
|
68
|
+
p.y = r * MathUtils.cos(theta);
|
|
69
|
+
p.z = r * sinTheta * MathUtils.sin(phi);
|
|
70
|
+
return p;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @return
|
|
76
|
+
*/
|
|
77
|
+
@Override
|
|
78
|
+
public float getPhiRange() {
|
|
79
|
+
return MathUtils.TWO_PI;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
*
|
|
84
|
+
* @param res
|
|
85
|
+
* @return
|
|
86
|
+
*/
|
|
87
|
+
@Override
|
|
88
|
+
public int getPhiResolutionLimit(int res) {
|
|
89
|
+
return res;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* @return
|
|
95
|
+
*/
|
|
96
|
+
@Override
|
|
97
|
+
public float getThetaRange() {
|
|
98
|
+
return MathUtils.PI;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* @param res
|
|
104
|
+
* @return
|
|
105
|
+
*/
|
|
106
|
+
@Override
|
|
107
|
+
public int getThetaResolutionLimit(int res) {
|
|
108
|
+
return res;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
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.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import toxi.geom.Vec3D;
|
|
31
|
+
import toxi.math.MathUtils;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Super ellipsoid surface evaluator based on code by Paul Bourke:
|
|
35
|
+
* http://local.wasp.uwa.edu.au/~pbourke/geometry/superellipse/
|
|
36
|
+
*/
|
|
37
|
+
public class SuperEllipsoid implements SurfaceFunction {
|
|
38
|
+
|
|
39
|
+
private float p1;
|
|
40
|
+
private float p2;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @param n1
|
|
45
|
+
* @param n2
|
|
46
|
+
*/
|
|
47
|
+
public SuperEllipsoid(float n1, float n2) {
|
|
48
|
+
this.p1 = n1;
|
|
49
|
+
this.p2 = n2;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
*
|
|
54
|
+
* @param p
|
|
55
|
+
* @param phi
|
|
56
|
+
* @param theta
|
|
57
|
+
* @return
|
|
58
|
+
*/
|
|
59
|
+
public Vec3D computeVertexFor(Vec3D p, float phi, float theta) {
|
|
60
|
+
phi -= MathUtils.HALF_PI;
|
|
61
|
+
float cosPhi = MathUtils.cos(phi);
|
|
62
|
+
float cosTheta = MathUtils.cos(theta);
|
|
63
|
+
float sinPhi = MathUtils.sin(phi);
|
|
64
|
+
float sinTheta = MathUtils.sin(theta);
|
|
65
|
+
|
|
66
|
+
float t = MathUtils.sign(cosPhi)
|
|
67
|
+
* (float) Math.pow(MathUtils.abs(cosPhi), p1);
|
|
68
|
+
p.x = t * MathUtils.sign(cosTheta)
|
|
69
|
+
* (float) Math.pow(MathUtils.abs(cosTheta), p2);
|
|
70
|
+
p.y = MathUtils.sign(sinPhi)
|
|
71
|
+
* (float) Math.pow(MathUtils.abs(sinPhi), p1);
|
|
72
|
+
p.z = t * MathUtils.sign(sinTheta)
|
|
73
|
+
* (float) Math.pow(MathUtils.abs(sinTheta), p2);
|
|
74
|
+
return p;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @return
|
|
80
|
+
*/
|
|
81
|
+
public float getPhiRange() {
|
|
82
|
+
return MathUtils.TWO_PI;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* @param res
|
|
88
|
+
* @return
|
|
89
|
+
*/
|
|
90
|
+
public int getPhiResolutionLimit(int res) {
|
|
91
|
+
return res / 2;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
*
|
|
96
|
+
* @return
|
|
97
|
+
*/
|
|
98
|
+
public float getThetaRange() {
|
|
99
|
+
return MathUtils.TWO_PI;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
*
|
|
104
|
+
* @param res
|
|
105
|
+
* @return
|
|
106
|
+
*/
|
|
107
|
+
public int getThetaResolutionLimit(int res) {
|
|
108
|
+
return res;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -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.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import toxi.geom.Vec3D;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* This interface defines a functor for evaluating the coordinates of a surface
|
|
34
|
+
* mesh used by {@link SurfaceMeshBuilder}.
|
|
35
|
+
*
|
|
36
|
+
* It is assumed the implementation creates vertices within the unit sphere
|
|
37
|
+
* (normalized).
|
|
38
|
+
*/
|
|
39
|
+
public interface SurfaceFunction {
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param p
|
|
44
|
+
* @param phi
|
|
45
|
+
* @param theta
|
|
46
|
+
* @return
|
|
47
|
+
*/
|
|
48
|
+
public Vec3D computeVertexFor(Vec3D p, float phi, float theta);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
*
|
|
52
|
+
* @return
|
|
53
|
+
*/
|
|
54
|
+
public float getPhiRange();
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param res
|
|
59
|
+
* @return
|
|
60
|
+
*/
|
|
61
|
+
public int getPhiResolutionLimit(int res);
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
* @return
|
|
66
|
+
*/
|
|
67
|
+
public float getThetaRange();
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param res
|
|
72
|
+
* @return
|
|
73
|
+
*/
|
|
74
|
+
public int getThetaResolutionLimit(int res);
|
|
75
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
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.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import toxi.geom.Vec2D;
|
|
31
|
+
import toxi.geom.Vec3D;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* An extensible builder class for {@link TriangleMesh}es based on 3D surface
|
|
35
|
+
* functions using spherical coordinates. In order to create a mesh, you'll need
|
|
36
|
+
* to supply a {@link SurfaceFunction} implementation to the builder.
|
|
37
|
+
*/
|
|
38
|
+
public class SurfaceMeshBuilder {
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
protected SurfaceFunction function;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param function
|
|
48
|
+
*/
|
|
49
|
+
public SurfaceMeshBuilder(SurfaceFunction function) {
|
|
50
|
+
this.function = function;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @param res
|
|
56
|
+
* @return
|
|
57
|
+
*/
|
|
58
|
+
public Mesh3D createMesh(int res) {
|
|
59
|
+
return createMesh(null, res, 1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param mesh
|
|
65
|
+
* @param res
|
|
66
|
+
* @param size
|
|
67
|
+
* @return
|
|
68
|
+
*/
|
|
69
|
+
public Mesh3D createMesh(Mesh3D mesh, int res, float size) {
|
|
70
|
+
return createMesh(mesh, res, size, true);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @param mesh
|
|
76
|
+
* @param res
|
|
77
|
+
* @param size
|
|
78
|
+
* @param isClosed
|
|
79
|
+
* @return
|
|
80
|
+
*/
|
|
81
|
+
public Mesh3D createMesh(Mesh3D mesh, int res, float size, boolean isClosed) {
|
|
82
|
+
if (mesh == null) {
|
|
83
|
+
mesh = new TriangleMesh();
|
|
84
|
+
}
|
|
85
|
+
Vec3D a = new Vec3D();
|
|
86
|
+
Vec3D b = new Vec3D();
|
|
87
|
+
Vec3D pa = new Vec3D(), pb = new Vec3D();
|
|
88
|
+
Vec3D a0 = new Vec3D(), b0 = new Vec3D();
|
|
89
|
+
int phiRes = function.getPhiResolutionLimit(res);
|
|
90
|
+
float phiRange = function.getPhiRange();
|
|
91
|
+
int thetaRes = function.getThetaResolutionLimit(res);
|
|
92
|
+
float thetaRange = function.getThetaRange();
|
|
93
|
+
float pres = 1f / phiRes;
|
|
94
|
+
float tres = 1f / thetaRes;
|
|
95
|
+
float ires = 1f / res;
|
|
96
|
+
Vec2D pauv = new Vec2D();
|
|
97
|
+
Vec2D pbuv = new Vec2D();
|
|
98
|
+
Vec2D auv = new Vec2D();
|
|
99
|
+
Vec2D buv = new Vec2D();
|
|
100
|
+
for (int p = 0; p < phiRes; p++) {
|
|
101
|
+
float phi = p * phiRange * ires;
|
|
102
|
+
float phiNext = (p + 1) * phiRange * ires;
|
|
103
|
+
for (int t = 0; t <= thetaRes; t++) {
|
|
104
|
+
float theta;
|
|
105
|
+
theta = t * thetaRange * ires;
|
|
106
|
+
a = function.computeVertexFor(a, phiNext, theta)
|
|
107
|
+
.scaleSelf(size);
|
|
108
|
+
auv.set(t * tres, 1 - (p + 1) * pres);
|
|
109
|
+
b = function.computeVertexFor(b, phi, theta).scaleSelf(size);
|
|
110
|
+
buv.set(t * tres, 1 - p * pres);
|
|
111
|
+
if (b.equalsWithTolerance(a, 0.0001f)) {
|
|
112
|
+
b.set(a);
|
|
113
|
+
}
|
|
114
|
+
if (t > 0) {
|
|
115
|
+
if (t == thetaRes && isClosed) {
|
|
116
|
+
a.set(a0);
|
|
117
|
+
b.set(b0);
|
|
118
|
+
}
|
|
119
|
+
mesh.addFace(pa, pb, a, pauv.copy(), pbuv.copy(),
|
|
120
|
+
auv.copy());
|
|
121
|
+
mesh.addFace(pb, b, a, pbuv.copy(), buv.copy(), auv.copy());
|
|
122
|
+
} else {
|
|
123
|
+
a0.set(a);
|
|
124
|
+
b0.set(b);
|
|
125
|
+
}
|
|
126
|
+
pa.set(a);
|
|
127
|
+
pb.set(b);
|
|
128
|
+
pauv.set(auv);
|
|
129
|
+
pbuv.set(buv);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return mesh;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @return the function
|
|
137
|
+
*/
|
|
138
|
+
public SurfaceFunction getFunction() {
|
|
139
|
+
return function;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param function
|
|
144
|
+
* the function to set
|
|
145
|
+
*/
|
|
146
|
+
public void setFunction(SurfaceFunction function) {
|
|
147
|
+
this.function = function;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,451 @@
|
|
|
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.geom.mesh;
|
|
29
|
+
|
|
30
|
+
import toxi.geom.IsectData3D;
|
|
31
|
+
import toxi.geom.Ray3D;
|
|
32
|
+
import toxi.geom.Triangle3D;
|
|
33
|
+
import toxi.geom.TriangleIntersector;
|
|
34
|
+
import toxi.geom.Vec2D;
|
|
35
|
+
import toxi.geom.Vec3D;
|
|
36
|
+
import toxi.math.Interpolation2D;
|
|
37
|
+
import toxi.math.MathUtils;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Implementation of a 2D grid based heightfield with basic intersection
|
|
41
|
+
* features and conversion to {@link TriangleMesh}. The terrain is always
|
|
42
|
+
* located in the XZ plane with the positive Y axis as up vector.
|
|
43
|
+
*/
|
|
44
|
+
public class Terrain {
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
protected float[] elevation;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
*/
|
|
54
|
+
protected Vec3D[] vertices;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
protected int width;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
*/
|
|
64
|
+
protected int depth;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
*/
|
|
69
|
+
protected Vec2D scale;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Constructs a new and initially flat terrain of the given size in the XZ
|
|
73
|
+
* plane, centred around the world origin.
|
|
74
|
+
*
|
|
75
|
+
* @param width
|
|
76
|
+
* @param depth
|
|
77
|
+
* @param scale
|
|
78
|
+
*/
|
|
79
|
+
public Terrain(int width, int depth, float scale) {
|
|
80
|
+
this(width, depth, new Vec2D(scale, scale));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @param width
|
|
86
|
+
* @param depth
|
|
87
|
+
* @param scale
|
|
88
|
+
*/
|
|
89
|
+
public Terrain(int width, int depth, Vec2D scale) {
|
|
90
|
+
this.width = width;
|
|
91
|
+
this.depth = depth;
|
|
92
|
+
this.scale = scale;
|
|
93
|
+
this.elevation = new float[width * depth];
|
|
94
|
+
this.vertices = new Vec3D[elevation.length];
|
|
95
|
+
Vec3D offset = new Vec3D(width / 2, 0, depth / 2);
|
|
96
|
+
Vec3D scaleXZ = scale.to3DXZ();
|
|
97
|
+
for (int z = 0, i = 0; z < depth; z++) {
|
|
98
|
+
for (int x = 0; x < width; x++) {
|
|
99
|
+
vertices[i++] = new Vec3D(x, 0, z).subSelf(offset).scaleSelf(
|
|
100
|
+
scaleXZ);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
*
|
|
107
|
+
* @return
|
|
108
|
+
*/
|
|
109
|
+
public Terrain clear() {
|
|
110
|
+
for (int i = 0; i < elevation.length; i++) {
|
|
111
|
+
elevation[i] = 0;
|
|
112
|
+
}
|
|
113
|
+
return updateElevation();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @return number of grid cells along the Z axis.
|
|
118
|
+
*/
|
|
119
|
+
public int getDepth() {
|
|
120
|
+
return depth;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
* @return
|
|
126
|
+
*/
|
|
127
|
+
public float[] getElevation() {
|
|
128
|
+
return elevation;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @param x
|
|
133
|
+
* @param z
|
|
134
|
+
* @return the elevation at grid point
|
|
135
|
+
*/
|
|
136
|
+
public float getHeightAtCell(int x, int z) {
|
|
137
|
+
return elevation[getIndex(x, z)];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Computes the elevation of the terrain at the given 2D world coordinate
|
|
142
|
+
* (based on current terrain scale).
|
|
143
|
+
*
|
|
144
|
+
* @param x
|
|
145
|
+
* scaled world coord x
|
|
146
|
+
* @param z
|
|
147
|
+
* scaled world coord z
|
|
148
|
+
* @return interpolated elevation
|
|
149
|
+
*/
|
|
150
|
+
public float getHeightAtPoint(float x, float z) {
|
|
151
|
+
float xx = x / scale.x + width * 0.5f;
|
|
152
|
+
float zz = z / scale.y + depth * 0.5f;
|
|
153
|
+
float y = 0;
|
|
154
|
+
if (xx >= 0 && xx < width && zz >= 0 && zz < depth) {
|
|
155
|
+
int x2 = (int) MathUtils.min(xx + 1, width - 1);
|
|
156
|
+
int z2 = (int) MathUtils.min(zz + 1, depth - 1);
|
|
157
|
+
float a = getHeightAtCell((int) xx, (int) zz);
|
|
158
|
+
float b = getHeightAtCell(x2, (int) zz);
|
|
159
|
+
float c = getHeightAtCell((int) xx, z2);
|
|
160
|
+
float d = getHeightAtCell(x2, z2);
|
|
161
|
+
y = Interpolation2D.bilinear(xx, zz, (int) xx, (int) zz, x2, z2, a,
|
|
162
|
+
b, c, d);
|
|
163
|
+
}
|
|
164
|
+
return y;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Computes the array index for the given cell coords & checks if they're in
|
|
169
|
+
* bounds. If not an {@link IndexOutOfBoundsException} is thrown.
|
|
170
|
+
*
|
|
171
|
+
* @param x
|
|
172
|
+
* @param z
|
|
173
|
+
* @return array index
|
|
174
|
+
*/
|
|
175
|
+
protected final int getIndex(int x, int z) {
|
|
176
|
+
int idx = z * width + x;
|
|
177
|
+
if (idx < 0 || idx > elevation.length) {
|
|
178
|
+
throw new IndexOutOfBoundsException(
|
|
179
|
+
"the given terrain cell is invalid: " + x + ";" + z);
|
|
180
|
+
}
|
|
181
|
+
return idx;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @return the scale
|
|
186
|
+
*/
|
|
187
|
+
public Vec2D getScale() {
|
|
188
|
+
return scale;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
*
|
|
193
|
+
* @param x
|
|
194
|
+
* @param z
|
|
195
|
+
* @return
|
|
196
|
+
*/
|
|
197
|
+
protected Vec3D getVertexAtCell(int x, int z) {
|
|
198
|
+
return vertices[getIndex(x, z)];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* @return number of grid cells along the X axis.
|
|
203
|
+
*/
|
|
204
|
+
public int getWidth() {
|
|
205
|
+
return width;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Computes the 3D position (with elevation) and normal vector at the given
|
|
210
|
+
* 2D location in the terrain. The position is in scaled world coordinates
|
|
211
|
+
* based on the given terrain scale. The returned data is encapsulated in a
|
|
212
|
+
* {@link toxi.geom.IsectData3D} instance.
|
|
213
|
+
*
|
|
214
|
+
* @param x
|
|
215
|
+
* @param z
|
|
216
|
+
* @return intersection data parcel
|
|
217
|
+
*/
|
|
218
|
+
public IsectData3D intersectAtPoint(float x, float z) {
|
|
219
|
+
float xx = x / scale.x + width * 0.5f;
|
|
220
|
+
float zz = z / scale.y + depth * 0.5f;
|
|
221
|
+
IsectData3D isec = new IsectData3D();
|
|
222
|
+
if (xx >= 0 && xx < width && zz >= 0 && zz < depth) {
|
|
223
|
+
int x2 = (int) MathUtils.min(xx + 1, width - 1);
|
|
224
|
+
int z2 = (int) MathUtils.min(zz + 1, depth - 1);
|
|
225
|
+
Vec3D a = getVertexAtCell((int) xx, (int) zz);
|
|
226
|
+
Vec3D b = getVertexAtCell(x2, (int) zz);
|
|
227
|
+
Vec3D c = getVertexAtCell(x2, z2);
|
|
228
|
+
Vec3D d = getVertexAtCell((int) xx, z2);
|
|
229
|
+
Ray3D r = new Ray3D(new Vec3D(x, 10000, z), new Vec3D(0, -1, 0));
|
|
230
|
+
TriangleIntersector i = new TriangleIntersector(new Triangle3D(a,
|
|
231
|
+
b, d));
|
|
232
|
+
if (i.intersectsRay(r)) {
|
|
233
|
+
isec = i.getIntersectionData();
|
|
234
|
+
} else {
|
|
235
|
+
i.setTriangle(new Triangle3D(b, c, d));
|
|
236
|
+
i.intersectsRay(r);
|
|
237
|
+
isec = i.getIntersectionData();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return isec;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Sets the elevation of all cells to those of the given array values.
|
|
245
|
+
*
|
|
246
|
+
* @param elevation
|
|
247
|
+
* array of height values
|
|
248
|
+
* @return itself
|
|
249
|
+
*/
|
|
250
|
+
public Terrain setElevation(float[] elevation) {
|
|
251
|
+
if (this.elevation.length == elevation.length) {
|
|
252
|
+
this.elevation = elevation;
|
|
253
|
+
updateElevation();
|
|
254
|
+
} else {
|
|
255
|
+
throw new IllegalArgumentException(
|
|
256
|
+
"the given elevation array size does not match existing terrain size");
|
|
257
|
+
}
|
|
258
|
+
return this;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Sets the elevation for a single given grid cell.
|
|
263
|
+
*
|
|
264
|
+
* @param x
|
|
265
|
+
* @param z
|
|
266
|
+
* @param h
|
|
267
|
+
* new elevation value
|
|
268
|
+
* @return itself
|
|
269
|
+
*/
|
|
270
|
+
public Terrain setHeightAtCell(int x, int z, float h) {
|
|
271
|
+
int index = getIndex(x, z);
|
|
272
|
+
elevation[index] = h;
|
|
273
|
+
vertices[index].y = h;
|
|
274
|
+
return this;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
*
|
|
279
|
+
* @param scale
|
|
280
|
+
*/
|
|
281
|
+
public void setScale(float scale) {
|
|
282
|
+
setScale(new Vec2D(scale, scale));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* @param scale
|
|
287
|
+
* the scale to set
|
|
288
|
+
*/
|
|
289
|
+
public void setScale(Vec2D scale) {
|
|
290
|
+
this.scale.set(scale);
|
|
291
|
+
Vec3D offset = new Vec3D(width / 2, 0, depth / 2);
|
|
292
|
+
for (int z = 0, i = 0; z < depth; z++) {
|
|
293
|
+
for (int x = 0; x < width; x++, i++) {
|
|
294
|
+
vertices[i].set((x - offset.x) * scale.x, vertices[i].y,
|
|
295
|
+
(z - offset.z) * scale.y);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
*
|
|
302
|
+
* @return
|
|
303
|
+
*/
|
|
304
|
+
public Mesh3D toMesh() {
|
|
305
|
+
return toMesh(null);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
*
|
|
310
|
+
* @param groundLevel
|
|
311
|
+
* @return
|
|
312
|
+
*/
|
|
313
|
+
public Mesh3D toMesh(float groundLevel) {
|
|
314
|
+
return toMesh(null, groundLevel);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Creates a {@link TriangleMesh} instance of the terrain surface or adds
|
|
319
|
+
* its geometry to an existing mesh.
|
|
320
|
+
*
|
|
321
|
+
* @param mesh
|
|
322
|
+
* @return mesh instance
|
|
323
|
+
*/
|
|
324
|
+
public Mesh3D toMesh(Mesh3D mesh) {
|
|
325
|
+
return toMesh(mesh, 0, 0, width, depth);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Creates a {@link TriangleMesh} instance of the terrain and constructs
|
|
330
|
+
* side panels and a bottom plane to form a fully enclosed mesh volume, e.g.
|
|
331
|
+
* suitable for CNC fabrication or 3D printing. The bottom plane will be
|
|
332
|
+
* created at the given ground level (can also be negative) and the sides
|
|
333
|
+
* are extended downward to that level too.
|
|
334
|
+
*
|
|
335
|
+
* @param mesh
|
|
336
|
+
* existing mesh or null
|
|
337
|
+
* @param groundLevel
|
|
338
|
+
* @return mesh
|
|
339
|
+
*/
|
|
340
|
+
public Mesh3D toMesh(Mesh3D mesh, float groundLevel) {
|
|
341
|
+
return toMesh(mesh, 0, 0, width, depth, groundLevel);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
*
|
|
346
|
+
* @param mesh
|
|
347
|
+
* @param minX
|
|
348
|
+
* @param minZ
|
|
349
|
+
* @param maxX
|
|
350
|
+
* @param maxZ
|
|
351
|
+
* @return
|
|
352
|
+
*/
|
|
353
|
+
public Mesh3D toMesh(Mesh3D mesh, int minX, int minZ, int maxX, int maxZ) {
|
|
354
|
+
if (mesh == null) {
|
|
355
|
+
mesh = new TriangleMesh("terrain", vertices.length,
|
|
356
|
+
vertices.length * 2);
|
|
357
|
+
}
|
|
358
|
+
minX = MathUtils.clip(minX, 0, width - 1);
|
|
359
|
+
maxX = MathUtils.clip(maxX, 0, width);
|
|
360
|
+
minZ = MathUtils.clip(minZ, 0, depth - 1);
|
|
361
|
+
maxZ = MathUtils.clip(maxZ, 0, depth);
|
|
362
|
+
minX++;
|
|
363
|
+
minZ++;
|
|
364
|
+
for (int z = minZ, idx = minX * width; z < maxZ; z++, idx += width) {
|
|
365
|
+
for (int x = minX; x < maxX; x++) {
|
|
366
|
+
mesh.addFace(vertices[idx - width + x - 1], vertices[idx
|
|
367
|
+
- width + x], vertices[idx + x - 1]);
|
|
368
|
+
mesh.addFace(vertices[idx - width + x], vertices[idx + x],
|
|
369
|
+
vertices[idx + x - 1]);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return mesh;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
*
|
|
377
|
+
* @param mesh
|
|
378
|
+
* @param mix
|
|
379
|
+
* @param miz
|
|
380
|
+
* @param mxx
|
|
381
|
+
* @param mxz
|
|
382
|
+
* @param groundLevel
|
|
383
|
+
* @return
|
|
384
|
+
*/
|
|
385
|
+
public Mesh3D toMesh(Mesh3D mesh, int mix, int miz, int mxx, int mxz,
|
|
386
|
+
float groundLevel) {
|
|
387
|
+
mesh = toMesh(mesh, mix, miz, mxx, mxz);
|
|
388
|
+
mix = MathUtils.clip(mix, 0, width - 1);
|
|
389
|
+
mxx = MathUtils.clip(mxx, 0, width);
|
|
390
|
+
miz = MathUtils.clip(miz, 0, depth - 1);
|
|
391
|
+
mxz = MathUtils.clip(mxz, 0, depth);
|
|
392
|
+
Vec3D offset = new Vec3D(width, 0, depth).scaleSelf(0.5f);
|
|
393
|
+
float minX = (mix - offset.x) * scale.x;
|
|
394
|
+
float minZ = (miz - offset.z) * scale.y;
|
|
395
|
+
float maxX = (mxx - offset.x) * scale.x;
|
|
396
|
+
float maxZ = (mxz - offset.z) * scale.y;
|
|
397
|
+
for (int z = miz + 1; z < mxz; z++) {
|
|
398
|
+
Vec3D a = new Vec3D(minX, groundLevel, (z - 1 - offset.z) * scale.y);
|
|
399
|
+
Vec3D b = new Vec3D(minX, groundLevel, (z - offset.z) * scale.y);
|
|
400
|
+
// left
|
|
401
|
+
mesh.addFace(getVertexAtCell(mix, z - 1), getVertexAtCell(mix, z),
|
|
402
|
+
a);
|
|
403
|
+
mesh.addFace(getVertexAtCell(mix, z), b, a);
|
|
404
|
+
// right
|
|
405
|
+
a.x = b.x = maxX - scale.x;
|
|
406
|
+
mesh.addFace(getVertexAtCell(mxx - 1, z),
|
|
407
|
+
getVertexAtCell(mxx - 1, z - 1), b);
|
|
408
|
+
mesh.addFace(getVertexAtCell(mxx - 1, z - 1), a, b);
|
|
409
|
+
}
|
|
410
|
+
for (int x = mix + 1; x < mxx; x++) {
|
|
411
|
+
Vec3D a = new Vec3D((x - 1 - offset.x) * scale.x, groundLevel, minZ);
|
|
412
|
+
Vec3D b = new Vec3D((x - offset.x) * scale.x, groundLevel, minZ);
|
|
413
|
+
// back
|
|
414
|
+
mesh.addFace(getVertexAtCell(x, miz), getVertexAtCell(x - 1, miz),
|
|
415
|
+
b);
|
|
416
|
+
mesh.addFace(getVertexAtCell(x - 1, miz), a, b);
|
|
417
|
+
// front
|
|
418
|
+
a.z = b.z = maxZ - scale.y;
|
|
419
|
+
mesh.addFace(getVertexAtCell(x - 1, mxz - 1),
|
|
420
|
+
getVertexAtCell(x, mxz - 1), a);
|
|
421
|
+
mesh.addFace(getVertexAtCell(x, mxz - 1), b, a);
|
|
422
|
+
}
|
|
423
|
+
// bottom plane
|
|
424
|
+
for (int z = miz + 1; z < mxz; z++) {
|
|
425
|
+
for (int x = mix + 1; x < mxx; x++) {
|
|
426
|
+
Vec3D a = getVertexAtCell(x - 1, z - 1).copy();
|
|
427
|
+
Vec3D b = getVertexAtCell(x, z - 1).copy();
|
|
428
|
+
Vec3D c = getVertexAtCell(x - 1, z).copy();
|
|
429
|
+
Vec3D d = getVertexAtCell(x, z).copy();
|
|
430
|
+
a.y = groundLevel;
|
|
431
|
+
b.y = groundLevel;
|
|
432
|
+
c.y = groundLevel;
|
|
433
|
+
d.y = groundLevel;
|
|
434
|
+
mesh.addFace(a, c, d);
|
|
435
|
+
mesh.addFace(a, d, b);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
return mesh;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
*
|
|
443
|
+
* @return
|
|
444
|
+
*/
|
|
445
|
+
public Terrain updateElevation() {
|
|
446
|
+
for (int i = 0; i < elevation.length; i++) {
|
|
447
|
+
vertices[i].y = elevation[i];
|
|
448
|
+
}
|
|
449
|
+
return this;
|
|
450
|
+
}
|
|
451
|
+
}
|